tcpdump mailing list archives

Re: forcing pcap_loop() failures


From: Guy Harris <guy () alum mit edu>
Date: Thu, 26 Oct 2006 12:32:54 -0700

Eloy Paris wrote:

However, I think the reason that I am not seeing any broken behavior is
because I use BIOCIMMEDIATE.

Right.

There you mentioned "It works around the problem by getting rid of the
timeout, so that as soon as a packet arrives the packet is made
available, rather than the BPF device holding onto the packet until
either the timeout expires or the buffer fills up."

Guess that's the reason it's working fine for me. However, I wonder
if I really need to use BIOCIMMEDIATE. I mean, my application needs
to respond in real time to traffic received on the packet capture
descriptor.

Then it needs BIOCIMMEDIATE on OSes that use BPF.

Note, for example, that I think some applications that use BPF not to do network traffic capture and analysis, but use it to implement in userland protocols that run directly atop the link layer (e.g., reverse ARP), use BIOCIMMEDIATE for that reason.

I remember that when I tested on FreeBSD (and some of the
other BSDs) unless I used BIOCIMMEDIATE I would no get packets right
away.

Correct, except that it should be "all of the other *BSDs, as well as Mac OS X".

This is by design.

tcpdump on FreeBSD, for example, doesn't seem to print packets in
real time; there's always a delay which seems to be the to_ms specified
in pcap_open_live() in tcpdump.c, which is 1,000 milliseconds.

Yes.

So it
seems like I really need to use BIOCIMMEDIATE and the cost is that no
buffering is done, more reads from the BPF device, and higher CPU, as
you mentioned in the message at the URL above.

Yes. The purpose of the buffering is to reduce the number of reads from the BPF device; a consequence of the buffering is that when a packet arrives, the BPF code doesn't immediately deliver it unless the packet would fill or overfill the packet buffer, because the goal is to fill up that buffer with as much data as possible before supplying the packets in that buffer to a read(). The timeout is there so that it doesn't wait *forever*, but it does have to wait *some* amount of time.

(If the packet would overfill the buffer, the packet isn't put into that buffer - it's put into the "next" buffer. It's not lost unless there isn't a "next" buffer is available. BPF does double-buffering, so if the *previous* buffer hasn't yet been read by the user-mode code, there isn't a "next" buffer available.)

On Linux everything works great without having to use any ioctl()'s, by
the way.

That's because PF_PACKET sockets, which is what are used for packet capture, don't do any such buffering - in effect, they act as if BIOCIMMEDIATE mode is always on, with no mechanism for turning it off.

In my case I need to rely on the timeout provided by select() (the
user can change that timeout value) so I don't think I can use the
workaround you've explained and documented so many times because it
requires using the the timeout passed to pcap_open_live() as the timeout
for the select().

If you're using BIOCIMMEDIATE, you don't need the workaround.

If you need the workaround, you *could* use the minimum of the user-specified timeout and the timeout passed to pcap_open_live().
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: