On Tue, Jan 02, 2001 at 11:49:13PM -0800, Hugh Daniel wrote:
> The current (well few hour old) tcpdump cvs version seems to have a
> broken parser in it, as this fails:
>
> root@sky > tcpdump arp
> Warning: Kernel filter failed: Invalid argument
> tcpdump: listening on eth0
That's not the parser. If the parser had failed, it would've complained
with "parse error" and wouldn't have started capturing. That's the code
that tries to tell the kernel to use a BPF program as a socket filter.
What kernel are you running? The 2.2.15 kernel, at least, does
case SO_ATTACH_FILTER:
ret = -EINVAL;
if (optlen == sizeof(struct sock_fprog)) {
struct sock_fprog fprog;
ret = -EFAULT;
if (copy_from_user(&fprog, optval, sizeof(fprog)))
break;
ret = sk_attach_filter(&fprog, sk);
}
break;
to attach the filter, so the length being something other than
"sizeof(struct sock_fprog)" could cause an EINVAL error; however, the
current code does
int
pcap_setfilter(pcap_t *handle, struct bpf_program *filter)
{
#ifdef SO_ATTACH_FILTER
struct sock_fprog fcode;
int can_filter_in_kernel;
#endif
...
if (can_filter_in_kernel) {
if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER,
&fcode, sizeof(fcode)) == 0)
{
/* Installation succeded - using kernel filter. */
handle->md.use_bpf = 1;
}
which looks as if it *should* pass in "sizeof(struct fprog)" as the size
argument.
Other ways in which it could get EINVAL would be:
if it handed a null pointer to the kernel as the "filter" member
of the "sock_fprog", but "fix_program()" should've set it if it
was able to handle the program (and if it wasn't, it should've
returned -1, causing it not to try to hand it to the kernel);
if the program was too long - but just "arp" shouldn't have
been too long;
if the modified program that "fix_program()" produced had an
illegal jump or an illegal memory reference in it - and it looks
as if the "sk_chk_filter()" routine in the 2.2.15 kernel, at
least, might not realize that the BPF *interpreter* allows
certain negative offsets in BPF instructions (the offset field
of the instruction is unsigned in the data structure it's using,
and it checks whether that offset is too large, so a negative
offset would be much too large), and, in order to test the
packet type to see if it's an ARP packet *when capturing in
cooked mode*, it'd have to use a negative offset.
However, it *shouldn't* be using cooked mode for "eth0", so that
particular kernel bug shouldn't be biting us.
At least when I last tried it, it worked on my home machine, running a
2.2.17-prewhatever kernel (whatever comes with Debian 2.2). I'll check
whether "sk_chk_filter()" is fixed in that kernel, although, as noted,
we shouldn't be using negative-offset code on "eth0", we should be able
to get the packet type from an offset of 12.
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe