On Tue, Oct 02, 2001 at 04:29:48PM -0400, Alexander Dupuy wrote:
> For programs which want non-blocking behavior, the fact that libpcap
> never calls recvfrom (but rather blocks in calls to poll() with an
> infinite timeout) makes the trick of setting non-blocking mode on the
> file descriptor useless, and the fencepost error in packet_ring_recv
> means that even if, as Guy Harris suggests, you use select or poll
> before calling pcap_dispatch() and you only ask for one packet, you may
> end up blocking waiting for the second packet that you didn't ask for.
> With a narrow filter and/or low traffic, you may block quite a while.
Perhaps there should be "pcap_set_nonblock()" and "pcap_get_nonblock()"
calls, which set and get non-blocking mode on a "pcap_t".
On most UNIXes, with non-memory-mapped capture mechanisms, it'd just use
"fcntl()" to set or get the state of O_NONBLOCK.
On Win32, "pcap_set_nonblock()" would set the read timeout to -1 rather
than to the specified value, to turn non-blocking mode on, and restore
the read timeout to turn it off.
On platforms with a memory-mapped capture mechanism,
"pcap_set_nonblock()" would set a flag in the "pcap_t" to the value
supplied. If that flag is set, at the place where the code would do a
"select()" or "poll()" or whatever to wait for new packets to arrive,
it'd instead just return 0 from "pcap_read()".
This way, an application that really *wants* to use "select()" or
"poll()" (or "WaitForMultipleObjects()" or
"MsgWaitForMultipleObjects()"), so that it can wait for packets to
arrive *or* for something else to happen (e.g., for window system events
to arrive), could do so, and safely read from the capture device.
(Once I get it working on Win32, I'm considering making Ethereal
register the pcap_t's file descriptor (on UNIX) or event handle (on
Win32) with GTK+, so that the main event loop will wait for packets to
arrive.)