On Sep 17, 2008, at 2:26 PM, Robert Edmonds wrote:
the comparison succeeds because the large unsigned k-value for this
instruction (0xfffffff0) is much larger than the number of remaining
bpf
instructions (flen-pc-1).
It's so large, in fact, that its high-order bit is set - so, in
effect, it's a *negative* offset, making it a backwards branch.
is this a bug in libpcap's protochain filter generation code?
No, it's a *feature* in libpcap's protochain filter generation code.
Protochain requires a loop, as it has to keep looping through IPv6
extension headers until it finds the final header. That means that it
requires backward jumps.
This means that protochain filters cannot be interpreted in any kernel-
based implementation of BPF I know of, as they all prohibit loops so
that you don't put a kernel thread into an infinite loop.
In current releases of libpcap, the BPF (*BSD, Mac OS X, AIX) code in
libpcap checks whether the optimizer was turned off (which is done
forcibly for protochain, as the optimizer assumes the flow graph is
acyclic) and, if it is, doesn't try to hand the filter to the kernel -
it just does the filtering in userland. The Linux code treats any
failure to hand the filter to the kernel as an indication that it
should do the filtering in userland, but treats EINVAL as a reason to
print a warning.
The current top-of-tree version of libpcap doesn't do that, as the
optimizer is turned off for 802.11 filters as well (they do some
header-length calculations where *both* branches of a choice could
result in the packet being accepted and *both* branches could result
in it being rejected, which also confuses the optimizer). Instead,
for BPF, it treats EINVAL as a reason to validate the program itself
(with a check that doesn't reject loops) and, on failure, reports an
error, and otherwise filters in userland. The Linux code should be
changed to do something similar, so it doesn't print a warning for
protochain.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.