tcpdump mailing list archives

Re: pcap_next/pcap_dispatch on VMware vmnet


From: Guy Harris <guy () alum mit edu>
Date: Tue, 10 Mar 2009 18:01:01 -0700


On Mar 10, 2009, at 5:40 PM, Chris Morgan wrote:

Hmm. Yeah I'll make sure to put in a comment about mac os support.

Note that select() *does* work with BPF devices on OS X - modulo the traditional BPF bug wherein the timer starts when a read is done, *not* when a select() is done, so you *could* block forever. At this point I think all the *BSDs have fixed that in their BPF implementations, but OS X hasn't fixed it yet.

(If BPF had done Solaris-style timeouts, where the timer is an inter- packet timer, this wouldn't have been an issue in the first place. It might also mean that the timer would have done a better job of batching packets if they're arriving fast and delivering them when there's a pause.)

Right. I was thinking that there might be cases where if the timeout
wasn't supported you would end up with the os buffering packets and
never returning them to the caller.

No. If the timeout isn't supported, the OS doesn't buffer any packets - it delivers them immediately, even if that means that a burst of packets is delivered one packet at a time, with a trip to the kernel done for each packet.

How does it work if there is no timeout and packets get captured but
not enough for the callback to occur?

If there's no timeout, that's because there's no in-kernel buffering to require a timeout, so "enough for the callout to occur" is one packet.

Wouldn't using poll if the timeout was set and not if it wasn't solve
that problem?

No, because tcpdump and dumpcap *do* want a timeout, because they don't want to, for example, block for several hours if you only get one packet an hour. They don't care whether the read blocks forever waiting for the *first* packet to arrive, they just don't want it to block forever waiting for a bufferful of packets to arrive.





Wouldn't
that let you implement the timeout functionality

To what timeout functionality are you referring? A timeout that prevents reads from blocking forever even if no packets arrive is, as noted, not something that all applications need or want - that's *NOT* what the timeout specified in pcap_open_live() is intended to do, and not what it was ever guaranteed to do - and a timeout that just prevents packets from being buffered indefinitely if they're not arriving fast enough is *already*
implemented.
-

Right, I'm referring to the to_ms timeout in pcap_open_live().

That timeout is, at least on Solaris, "a timeout that just prevents packets from being buffered indefinitely if they're not arriving fast enough." On some other OSes, it also happens to prevent reads from blocking forever if no packets arrive, but applications should not be depending on that unless they also call uname() and abort if the OS name string is "SunOS", so that they ensure that they never run on Solaris.

I see
what you mean, the man page certainly disclaims support for the
timeout on all platforms. The documentation on to_ms does sound like
exactly what I'm trying to do though, cause the read to timeout.

I tried as hard as I could to write the documentation *NOT* to sound like that. The problem is that I didn't mention that until the description of pcap_dispatch():

NOTE: when reading a live capture, pcap_dispatch() will not necessarily return when the read times out; on some platforms, the read timeout isn't supported, and, on other platforms, the timer doesn't start until at least one packet arrives. This means that the read timeout should NOT be used in, for example, an interactive application, to allow the packet capture loop to ``poll'' for user input periodically, as there's no guarantee that pcap_dispatch() will return after the timeout
       expires.

In libpcap 1.x, the pcap man page discusses the timeout in some detail, and does explicitly note that it's *NOT* guaranteed to keep reads from blocking forever:

       read timeout
If, when capturing, packets are delivered as soon as they arrive, the application capturing the packets will be woken up for each packet as it arrives, and might have to make one or
              more calls to the operating system to fetch each packet.

If, instead, packets are not delivered as soon as they arrive, but are delivered after a short delay (called a "read timeout"), more than one packet can be accumulated before the packets are delivered, so that a single wakeup would be done for multiple packets, and each set of calls made to the operating system would supply multiple packets, rather than a single packet. This reduces the per-packet CPU overhead if packets are arriving at a high rate, increasing the number of packets per second that
              can be captured.

The read timeout is required so that an application won't wait for the operating system's capture buffer to fill up before packets are delivered; if packets are arriving slowly, that wait
              could take an arbitrarily long period of time.

Not all platforms support a read timeout; on platforms that don't, the read timeout is ignored. A zero value for the time- out, on platforms that support a read timeout, will cause a read to wait forever to allow enough packets to arrive, with no time-
              out.

NOTE: the read timeout cannot be used to cause calls that read packets to return within a limited period of time, because, on some platforms, the read timeout isn't supported, and, on other platforms, the timer doesn't start until at least one packet arrives. This means that the read timeout should NOT be used, for example, in an interactive application to allow the packet capture loop to ``poll'' for user input periodically, as there's no guarantee that a call reading packets will return after the
              timeout expires even if no packets have arrived.

              The read timeout is set with pcap_set_timeout().

and the man pages for the individual routines just refer to the read timeout without giving details.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: