tcpdump mailing list archives

Re: 32bit libpcap failure on Linux-ppc64 machine


From: Guy Harris <guy () alum mit edu>
Date: Sun, 8 May 2011 12:49:22 -0700


On May 8, 2011, at 8:26 AM, Zvika Meiseles wrote:

I'm writing a program that uses packet capture via libpcap. It is built on
multiple platforms and OS's, and runs fine on most of them. However, the
combination of 32 bit binaries on a PPC64 Linux is failing (kernel
2.6.18-194.el5). 64 bit binaries of the same code work fine.

You probably need a newer kernel.  The original ring buffer mechanism didn't work if the userland code isn't the same 
bit width as the kernel code, because "struct tpacket_hdr" has an "unsigned long" member, which means the structure's 
layout differs between 32-bit and 64-bit.  Somewhere between 2.6.18.2 and 2.6.27.9, a second structure, all of whose 
fields are __u32 or __u16 and thus the same in 32-bit and 64-bit mode, was added, so that users of the ring buffer 
mechanism can either get the old structure by default or can select the new header.

If the new header is available, libpcap will use it.

Unfortunately, I don't know of a way to ask the kernel whether it's 32-bit or 64-bit.  If there's a way to do that, 
libpcap could define its own tpacket_hdr_32 and tpacket_hdr_64 structures, mirroring the kernel structures (which 
assumes they're not going to change; I suspect they won't, but I could be rudely surprised), and use the appropriate 
structure based on the kernel size.  (There's a hack in Debian to try to handle this, but it depends, I think, on the 
system being little-endian - which means it won't help you, as your machine is PPC and thus Linux is running it 
big-endian.)

poll() says I have data to read, but it is ignored because the ring buffer
contains data with (status=TP_STATUS_KERNEL), whatever that means... :-)

If the kernel and userland agree on the layout of the ring buffer, it means that the current packet slot is owned by 
the kernel, into which it can put a packet, rather than by userland, with a packet having been put into that for 
userland consumption.

If they *don't* agree on the layout of the ring buffer, because the kernel is 64-bit and userland is 32-bit, and this 
is on a big-endian machine, it means that the userland code isn't looking at the status field in its entirety, just at 
the upper 32 bits of it, so it always looks as if it's TP_STATUS_KERNEL, which is 0 (all the status values are small 
integers, which does raise the question of why it was an "unsigned long" in the initial version...).
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: