Post by Chris MorganHmm. 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.)
Post by Chris MorganRight. 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.
Post by Chris MorganHow 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.
Post by Chris MorganWouldn'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.
Post by Chris MorganPost by Guy HarrisPost by Chris MorganWouldn'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.
Post by Chris MorganI 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.