tcpdump mailing list archives
Re: Portable way to "block" on pcap_next_ex()
From: Guy Harris <guy () alum mit edu>
Date: Sun, 15 Jan 2012 14:28:03 -0800
On Jan 15, 2012, at 9:36 AM, Fernando Gont wrote:
I'd like a call to pcap_next_ex() to block, waiting for a single packet, with no timeout. So far, the only portable way to do it I've found is to select() on the underlying descriptor. The reason is that if I pcap_open_live() with a "to_ms" of 0, in some systems pcap_next_ex() will remain blocked even if a packet is received (i.e., it will wait for *many* packets).
At least on systems with BPF, it'll block until the BPF buffer fills up, so it could wait indefinitely.
On the other hand, if I use a non-zero "to_ms" in pcap_open_live(), that will mean that my app will be awaken every "to_ms" milliseconds, because of the timeout
"May be awakened", not "will be awakened"; on Solaris, at least when using DLPI, the timer for the timeout is started when the first packet arrives, not when the read is done: http://docs.oracle.com/cd/E23824_01/html/821-1475/bufmod-7m.html "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." Solaris 11 also implements BPF: http://docs.oracle.com/cd/E23824_01/html/821-1475/bpf-7d.html and its timer works the way other BPF timers work - it starts when the read is done. On Linux, either the memory-mapped mechanism isn't being used, in which case each recvfrom() returns a single packet, with no timeout, or it is being used, in which case the timeout is done with an internal poll() call (if the pcap_t isn't in non-blocking mode), so you have a timeout that expires even if no packet has arrived. I haven't looked at TPACKET_V3 in detail, but I suspect, from something I read, that it has a BPF-like timeout, i.e. the timer can expire if no packets are available. No BPF-based platform offers an API to allow libpcap to choose how the timer works.
(which is undesirable).
Is that "undesirable" as in "I have to be able to handle pcap_next_ex() not returning a packet" (which may be annoying but can be dealt with) or "undesirable" as in "causes significant performance problems"?
Any other way of doing the same without relying on select()?
No portable way. Some systems (those with BPF) start the timer when you do a read(), so the timer goes off even if no packets have arrived. Solaris's bufmod starts the timer when the first packet arrives. BPF offers BIOCIMMEDIATE mode, which means that packets are *not* buffered (i.e., each read() returns a single packet) and there's no timeout. The bufmod equivalent would be to set the read timeout to 0. There's currently no API in libpcap to request that, so turning it on would currently have to be done in a platform-dependent fashion.- This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.
Current thread:
- Portable way to "block" on pcap_next_ex() Fernando Gont (Jan 15)
- Re: Portable way to "block" on pcap_next_ex() Guy Harris (Jan 15)
- Re: Portable way to "block" on pcap_next_ex() Fernando Gont (Jan 15)
- Re: Portable way to "block" on pcap_next_ex() Guy Harris (Jan 15)
- Re: Portable way to "block" on pcap_next_ex() Fernando Gont (Jan 16)
- Re: Portable way to "block" on pcap_next_ex() Guy Harris (Jan 16)
- Re: Portable way to "block" on pcap_next_ex() Fernando Gont (Jan 16)
- Re: Portable way to "block" on pcap_next_ex() Guy Harris (Jan 16)
- Re: Portable way to "block" on pcap_next_ex() Fernando Gont (Jan 15)
- Re: Portable way to "block" on pcap_next_ex() Guy Harris (Jan 15)