On Mar 9, 2009, at 4:10 PM, Chris Morgan wrote:
Opening a live capture as root (using sudo), on a vmware bridge device
on Linux 2.6.27, using a timeout of 1000ms. I'm seeing pcap_next() and
pcap_dispatch() getting stuck reading, no timeouts are occurring. Is
there a robust and efficient way of reading packets that won't block
forever like this?
Well, the first question is "why is blocking forever an issue?"
Is the application also going to, for example, accept input from other
sources while it's reading captured packets?
I'm doing this from that c# library so while I've
thought of using poll() on the devices file descriptor I wanted to
avoid doing low level calls like this so the code would work with
winpcap/pcap on windows/linux platforms.
At least in the case where the app is going to accept input from other
sources, that's what select(), poll(), WaitForMultipleObjects/
MsgWaitForMultipleObjects, etc. are intended for - they'll wake up if
packets arrive or if one of the other sources of input have input
available, rather than having a hack wherein one is (incorrectly)
expecting the timer for the timeout to
1) exist (which it doesn't, on some platforms)
and
2) start timing when you start the read rather than when and *if* the
first packet arrives (which it doesn't, on some platforms, e.g.
Solaris; the Solaris timer starts when the first packet is seen, and,
at least according to the bufmod(7) man page, restarts it on each
packet - the man page says
To ensure that messages do not languish forever in an accumulating
chunk, bufmod maintains a read timeout. Whenever this timeout expires,
the module closes off the current chunk and passes it upward. The
module restarts the timeout period when it receives a read side data
message and a timeout is not currently active. These two rules insure
that bufmod minimizes the number of chunks it produces during periods
of intense message activity and that it periodically disposes of all
messages during slack intervals, but avoids any timeout overhead when
there is no activity.
indicating that the purpose of the timeout is *not* to enable
polling, but to allow batching of packets without having packets
remain undelivered for an indefinite period of time).
Yes, it's platform-dependent, so you might have to find some way to
hide that beneath your C# class.
Given that, note also that there is at least one UN*X where,
unfortunately, poll() *doesn't* work on the descriptor you get for a
pcap_t - Mac OS X, where, unfortunately, in Mac OS X 10.4 and 10.5,
poll() doesn't work on *any* character special files, including not
only the BPF devices that libpcap uses but also ttys and pseudo-ttys
(a source of a number of problems with various bits of software).
select() *does* work on them; unfortunately, a lot of apps - and
libraries such as GLib, as used by GTK+, for example - use poll() in
their event loops.
There are also issues with select() and poll() and BPF devices,
wherein you don't get a wakeup if the read completes due to the timer
expiring, so you need to
1) put the descriptor for the BPF device in non-blocking mode;
2) use a timeout in select() or poll();
3) read from the BPF device when select() or poll() returns,
*regardless* of whether select() or poll() indicates that a read is
possible.
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.