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.