Non-blocking reads from a BPF device not in immediate mode will not rotate the 
buffers even if there's data in the store buffer but not in the hold buffer, 
so, until the store buffer fills up, the reads will return -1 and set errno to 
EWOULDBLOCK.

To reproduce, compile the attached (C++) program, run it on an adapter with the 
filter "icmp" on a reasonably quiet network, and then, on the same machine, 
ping some host the pings to which will go out on the same network. Note that 
the program doesn't report any packets having been seen.

To fix, apply the attached patch.  (A similar bug has been filed against 
FreeBSD - and will be filed against Mac OS X.)

Attachment: libpcaptest.cpp
Description: Binary data


--- bpf.c.orig  2010-02-13 00:31:52.000000000 -0800
+++ bpf.c       2010-02-13 00:33:32.000000000 -0800
@@ -421,9 +421,12 @@
         * have arrived to fill the store buffer.
         */
        while (d->bd_hbuf == NULL) {
-               if ((d->bd_immediate || timed_out) && d->bd_slen != 0) {
+               if ((d->bd_immediate || (ap->a_ioflag & IO_NDELAY) || timed_out)
+                   && d->bd_slen != 0) {
                        /*
-                        * A packet(s) either arrived since the previous
+                        * We're in immediate mode, or are reading
+                        * in non-blocking mode, and a packet(s)
+                        * either arrived since the previous
                         * read or arrived while we were asleep.
                         * Rotate the buffers and return what's here.
                         */

Reply via email to