libpcap – La longueur de l’en-tête d’un paquet ip est égale à zéro octet avec les demandes TCP en boucle de rappel

J’essaie de visualiser les informations de charge TCP avec l’aide de libpcap. Pour ce faire, je dois localiser la position de la charge utile en mémoire. J’utilise ce guide de programmation avec Pcap pour déterminer l’emplacement de la charge utile de la demande. Lors de la détection de paquets provenant d’un client résidant sur le même ordinateur que le service (adaptateur de bouclage), la longueur de l’en-tête IP est 0. Je ne parviens pas à trouver l’emplacement de la charge utile de la demande. Est-ce à prévoir lorsque vous écoutez un adaptateur de bouclage? Je travaille sur un système MacOSx 10.8 en écoutant l’adaptateur ‘lo0’.

Voici ce que j’essaye:

//this callback is called when a packet is found void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){ ethernet = (struct sniff_ethernet*)(packet); ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0 size_ip = IP_HL(ip)*4; if (size_ip < 20) { printf(" * Invalid IP header length: %u bytes\n", size_ip); return; } tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp < 20) { printf(" * Invalid TCP header length: %u bytes\n", size_tcp); return; } payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); } 

struct sniff_ip:

 #define SIZE_ETHERNET 14 /* IP header */ struct sniff_ip { u_char ip_vhl; /* version <> 2 */ u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; 

 ethernet = (struct sniff_ethernet*)(packet); ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0 

Si vous capturez sur l'interface de bouclage, ce code est incorrect. Toutes les interfaces sous OS X (ou tout autre système d'exploitation prenant en charge libpcap / WinPcap) ne fournissent pas d'en-têtes Ethernet; vous devez appeler pcap_datalink() pour trouver le type de couche liaison du périphérique de capture (ou le fichier de capture, si vous lisez un fichier de capture avec pcap_open_offline() ) et, en fonction de cela, parsingr les en-têtes de couche lien du paquet.

Voir la liste des types d'en-tête pcap link-layer pour une liste complète.

DLT_EN10MB est le type d’en-tête de couche liaison pour les périphériques Ethernet ("10 Mo" est historique et fait référence à 3 Mo par rapport à 10 Mo Ethernet, qui avait des en-têtes différents; DLT_EN10MB s’applique à 10 Mo et 100 Mo et 1 Go et 10 Go et 40 Go et 100 Go et ... Ethernet), ainsi que certains périphériques non Ethernet qui fournissent de faux en-têtes Ethernet.

DLT_NULL est le type d’en-tête de la couche liaison pour le dispositif de bouclage sur la plupart des BSD et sur OS X. comme l'indique la page des types d'en-tête de couche liaison, elle comporte un en-tête de couche liaison de 4 octets contenant la valeur PF_ du système d' PF_ pour le protocole, qui sera probablement IPv4 ou IPv6.