2016-09-05 1 views
6

Dieser Code funktioniert völlig in Ordnung, auf Ubuntu 16.04 und korrekten Wert druckt (ETHERTYPE_IP), wenn ich um UDP-Bytes über Loopback-Interface werfen:Capturing-Pakete auf Loopback

#include <pcap.h> 
#include <iostream> 
#include <net/ethernet.h> 

int main(int argc,char **argv) 
{ 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    auto pcap = pcap_open_live("lo0", BUFSIZ, 0, 1000, errbuf); 

    pcap_loop(pcap,0, [] (u_char *self, const struct pcap_pkthdr *header, 
          const u_char *packet) { 
     auto eth = (struct ether_header *) packet; 
     auto eth_type = ntohs(eth->ether_type); 
     std::cout << "eth_type: " << std::hex << eth_type << std::endl; 
    }, nullptr); 

    return 0; 
} 

netcat:

➜ ~ nc -uv -l 54321 
Listening on [0.0.0.0] (family 0, port 54321) 

➜ ~ nc -4u localhost 54321 
hello 

Programmausgabe :

➜ ~ sudo ./a.out 
eth_type: 800 

auf OS X 10.11.5 Allerdings druckt es eth_type: 4 011. Interessant, dass es mit en1 Adapter funktioniert.

Warum gibt es einen solchen Unterschied zwischen Loopback- und Non-Loopback-Adaptern und was ist der richtige Weg, um Pakete auf beiden zu erfassen?

Update: tcpdump funktioniert auch:

➜ ~ sudo tcpdump -i lo0 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes 
15:09:00.160664 IP localhost.54321 > localhost.63543: UDP, length 4 
+0

Sie haben könnten „lo0“ und nicht „lo“ zu verwenden. Um dies auf einem Mac zu kompilieren versuchen Sie: clang ++ -std = C++ 11 -stdlib = libC++ -lpcap test.cpp -o test ... Ich bekomme auch Müll-Werte für Ether_Type. – sdsykes

+0

das ist ein Tippfehler in Snippet, es ist in der Tat lo0. – lstipakov

Antwort

1

Als Verbindungstyp nicht Ethernet ist, wird der Header nicht geeignet Daten für ether_header enthalten.

diesen Code hinzufügen, nachdem der Griff mit pcap_open_live Abrufen der Link-Layer-Header-Typ, um zu sehen:

if (pcap_datalink(pcap) != DLT_EN10MB) { 
    fprintf(stderr, "Device doesn't provide Ethernet headers - link type was %d\n", pcap_datalink(pcap)); 
    return 1; 
} 

Laufen bedeutet dies, dass der Wert für linktype lo0 0, DLT_NULL. Die Dokumentation besagt, dass dies "BSD-Loopback-Kapselung bedeutet; der Link-Layer-Header ist ein 4-Byte-Feld in Host-Byte-Reihenfolge, enthält einen PF_ Wert von socket.h für das Netzwerk-Layer-Protokoll des Pakets."

In der Tat, wenn ich auf die ersten 4 Bytes des Ether_dhost-Felds sehe ich den Wert 2, entsprechend PF_INET. Am Ende hilft Ihnen das nicht viel, wenn Sie UDP-Pakete unterscheiden wollen.

können Sie weitere Dokumentation finden Sie hier: http://www.tcpdump.org/linktypes.html