Speaking of radiotap, the current tcpdump snapshot length defaults of 68 (for tcpdump without IPv6 support) and 96 (for tcpdump with IPv6 support) don't correspond to the same amount of payload above the "link layer" on all network types. For most network types, the difference is small - if we include the LLC+SNAP header in the link layer, then it varies between 0 and 24 for most link-layer types, with the most common case for those network types probably being 14 for Ethernet.

However, for 802.11 with a radio header, it can be as much as 176 for the old Prism header, and 96 for the AVS radio header; it might not be as bad for the radiotap header, as that header only includes what's available.

I'm not sure what the right thing to do is here. For the fixed-length radio headers, having the BPF code generator adjust the specified snapshot length by the difference between the link-layer type's off_nl value and 14 would handle this, but it would mean that a user explicitly specified a snapshot length of N, they wouldn't actually get a snapshot length of N.

I'd be inclined to say that, if you ignore the radio header, and perhaps other "pseudo-headers" such as that, not corresponding directly to data on the wire, user-specified snapshot lengths shouldn't be tampered with by libpcap - the user should know what they're doing, and should know how big the headers are on packets, or should at least know how big a snapshot length is "big enough".

However, I'd also be inclined to say that pseudo-headers of that sort really aren't "part of the packet" in the same sense, and that people might not think of them in that sense, so the snapshot length should refer to the packet length minus any pseudo-header lengths. E.g., a snapshot length of N on DLT_EN10MB or DLT_IEEE802 (which means "token ring") or DLT_FDDI or DLT_IEEE802_11 should be used as is, but a snapshot length of N on DLT_PRISM_HEADER should have 144 added to it before being used and a snapshot length of N on DLT_IEEE802_11_RADIO_AVS should have 64 added to it.

That has a problem for radiotap, though, as the header is variable-length. The variable-length radio header also causes some annoyance in the code generator.

One possibility would be to add to the BPF interpreters (the one in libpcap, the ones in various BSDs, and the one in Linux) an extra instruction to set a "pseudo-header offset"; that offset would

        1) be applied to all packet offsets in instructions

and

        2) be applied to the snapshot length.

As long as we're doing that, we might have that instruction fetch it as a 2-byte little-endian value, as that's what's in the radiotap header.

Unfortunately, that means that the code generator now has to know what version of the BPF interpreter is available to it. It can assume that, for filters being interpreted in userland, it has the latest shiniest interpreter, but, for filters being interpreted in the kernel, it'd have to ask the kernel what it has; there's an ioctl for that in BPF, but there's none in Linux - that'd have to be added (or we could use uname(), but I'd prefer to ask "what BPF language do you support?", not "what kernel version are you?").

In addition, at least on Linux, the code attempts to set a filter in the kernel and, if that fails, runs the filter in user mode, although in that case the user mode filter would still run, it just wouldn't work as well.

Note that we probably want to pick up BSD/OS's instruction to do IPv6 header chasing at some point, which would raise the same issue of determining the kernel's filter's capabilities and dealing with kernel vs. user filters.
-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Reply via email to