On Mon, Mar 9, 2009 at 7:51 PM, Guy Harris <g...@alum.mit.edu> wrote: > > 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? >
Well I noticed the issue when I was trying to shut the capture down gracefully. Blocking may not be a huge issue. We can forcefully terminate the capture thread if it doesn't respond within a period of time to a flag that indicates it should shutdown, it just wasn't my first thought. One nagging question is the issue of passing the pointer of a managed function into pcap. I'm wondering if terminating the thread will result in additional events from pcap_dispatch(). The man page indicates this is possible with pcap_loop() and pcap_breakloop() so we might as well take care to not have the handler memory be garbage collected too early. >> 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. > We currently create a thread for each capture device and call back the user code when packets arrive. Does this remove the requirement for buffering with timeout since we'll pass the packets off after each arrives? Is the timeout something checked after each packet is received? Is this why pcap_next() is blocking, because no packets are arriving? Chris - This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.