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

Reply via email to