2016-09-05 27 views
6

ten kod działa perfekcyjnie na Ubuntu 16.04 i drukuje prawidłową wartość (ETHERTYPE_IP) kiedy wrzucić wokół bajtów UDP poprzez interfejs pętli zwrotnej:przechwytywanie pakietów na sprzężenia zwrotnego

#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: wyjście

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

➜ ~ nc -4u localhost 54321 
hello 

Program :

➜ ~ sudo ./a.out 
eth_type: 800 

jednak na OS X 10.11.5 drukuje to eth_type: 4 011. Interesujące, że działa dobrze z adapterem en1.

Dlaczego istnieje taka różnica między adapterami loopback i nonbackback i jaki jest prawidłowy sposób przechwytywania pakietów w obu?

Aktualizacja: tcpdump działa również:

➜ ~ 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

może trzeba użyć „lo0” a nie „LO”. Aby skompilować to na mac spróbuj: clang ++ -std = C++ 11 -stdlib = libC++ -lpcap test.cpp -o test ... Też dostaję wartości śmieci dla ether_type. – sdsykes

+0

to literówka we fragmencie, to rzeczywiście jest lo0. – lstipakov

Odpowiedz

1

jako typ łącza nie jest ethernet, nagłówek nie zawiera odpowiednich danych dla ether_header.

Dodaj ten kod po pobraniu uchwyt z pcap_open_live zobaczyć typ nagłówka warstwy łącza:

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

Running oznacza to, że wartość linktype dla lo0 wynosi 0, DLT_NULL. Dokumentacja stwierdza, że ​​oznacza to "enkapsulację sprzężenia zwrotnego BSD, nagłówek warstwy łącza jest 4-bajtowym polem, w porządku bajtów hosta, zawierającym wartość PF z socket.h dla protokołu warstwy sieciowej pakietu."

Rzeczywiście, gdy patrzę na pierwsze 4 bajty pola ether_dhost, widzę wartość 2, odpowiadającą PF_INET. Ostatecznie to ci nie pomoże, jeśli próbujesz odróżnić pakiety UDP.

Można znaleźć więcej dokumentacji tutaj: http://www.tcpdump.org/linktypes.html

Powiązane problemy