Hello, I also hit this bug and had to rebuild libpcap0.8, which fixed the issue (since I'm using 2.6.28).
I had to work around this interface problem for older kernels in my application, and came up with the following solution. We may wish to consider a this workaround to avoid breakage on kernels older than 2.6.27. Tested on 2.6.28 with HAVE_TPACKET2 purposely undeffed. Verified with strace that it is working as expected from 32 bit userland to 64 bit kernel even with TPACKET_V1. Simon-
diff --git a/pcap-linux.c b/pcap-linux.c index 8161af0..1fe5d41 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -2198,7 +2198,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, struct sockaddr_ll *sll; struct pcap_pkthdr pcaphdr; unsigned char *bp; - union thdr h; + union thdr h,h32; unsigned int tp_len; unsigned int tp_mac; unsigned int tp_snaplen; @@ -2211,11 +2211,24 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, switch (handle->md.tp_version) { case TPACKET_V1: - tp_len = h.h1->tp_len; - tp_mac = h.h1->tp_mac; - tp_snaplen = h.h1->tp_snaplen; - tp_sec = h.h1->tp_sec; - tp_usec = h.h1->tp_usec; + /* + * Work around the "unsigned long tp_status" + * problem 32 bit userland and 64 bit kernel by + * offsetting the rest of the reads if tp_len + * reads as zero. On little-endian machines, + * tp_status will still update and everything + * will work with this workaround. TPACKET_V2 + * was introduced to solve this in 2.6.27. + * -Simon, 2009-03-19 + */ + h32.raw = h.raw; + if (h32.h1->tp_len == 0) + h32.raw = (unsigned char *)h.raw + 4; + tp_len = h32.h1->tp_len; + tp_mac = h32.h1->tp_mac; + tp_snaplen = h32.h1->tp_snaplen; + tp_sec = h32.h1->tp_sec; + tp_usec = h32.h1->tp_usec; break; #ifdef HAVE_TPACKET2 case TPACKET_V2: