From feef04b7a69ce32456477d07dce042b34b7e65e2 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 19 Jan 2018 19:39:29 -0800 Subject: Add a new API to handle some non-select()able devices. DAG adapters don't support blocking until packets arrive; a program using select()/poll()/epoll()/kqueue-based event loop must periodically poll DAG pcap_t's to see if they have packets available. Add pcap_get_required_select_timeout(), which returns a pointer to a struct timeval containing the appropriate timeout interval if polling is required and NULL if polling isn't required or isn't supported. Clean up the pcap_get_selectable_fd() documentation while we're at it. --- pcap_get_selectable_fd.3pcap | 88 +++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'pcap_get_selectable_fd.3pcap') diff --git a/pcap_get_selectable_fd.3pcap b/pcap_get_selectable_fd.3pcap index aa457a23..c1c617c7 100644 --- a/pcap_get_selectable_fd.3pcap +++ b/pcap_get_selectable_fd.3pcap @@ -38,26 +38,41 @@ which one can do a .BR select() , .BR poll() , +.BR epoll() , +.BR kevent() , or other such call to wait for it to be possible to read packets without blocking, if such -a descriptor exists, or \-1, if no such descriptor exists. Some network -devices opened with +a descriptor exists, or \-1, if no such descriptor exists. +.PP +Some network devices opened with .B pcap_create() and .BR pcap_activate() , or with .BR pcap_open_live() , -do not support -.B select() -or -.B poll() -(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace -DAG devices), so \-1 is returned for those devices. +do not support those calls (for example, regular network devices on +FreeBSD 4.3 and 4.4, and Endace DAG devices), so \-1 is returned for +those devices. In that case, those calls must be given a timeout less +than or equal to the timeout returned by +.B pcap_get_required_select_timeout() +for the device for which +.B pcap_get_selectable_fd() +returned \-1, the device must be put in non-blocking mode with a call to +.BR pcap_setnonblock() , +and an attempt must always be made to read packets from the device +when the call returns. If +.B pcap_get_required_select_timeout() +returns +.BR NULL , +it is not possible to wait for packets to arrive on the device in an +event loop. .PP -Note that a descriptor on which a read can be done without blocking may, +Note that a device on which a read can be done without blocking may, on some platforms, not have any packets to read if the packet buffer timeout has expired. A call to .B pcap_dispatch() +or +.B pcap_next_ex() will return 0 in this case, but will not block. .PP Note that in: @@ -70,59 +85,55 @@ OpenBSD prior to OpenBSD 2.4; .IP Mac OS X prior to Mac OS X 10.7; .PP -.B select() +.BR select() , +.BR poll() , and -.B poll() +.B kevent() do not work correctly on BPF devices; .B pcap_get_selectable_fd() will return a file descriptor on most of those versions (the exceptions being FreeBSD 4.3 and 4.4), but a simple -.B select() -or -.B poll() -will not indicate that the descriptor is readable until a full buffer's -worth of packets is received, even if the packet timeout expires before -then. To work around this, an application that uses -.B select() +.BR select() , +.BR poll() , or -.B poll() -to wait for packets to arrive must put the +.B kevent() +call will not indicate that the descriptor is readable until a full +buffer's worth of packets is received, even if the packet timeout +expires before then. To work around this, code that uses +those calls to wait for packets to arrive must put the .B pcap_t -in non-blocking mode, and must arrange that the -.B select() -or -.B poll() +in non-blocking mode, and must arrange that the call have a timeout less than or equal to the packet buffer timeout, and must try to read packets after that timeout expires, regardless of -whether -.B select() -or -.B poll() -indicated that the file descriptor for the +whether the call indicated that the file descriptor for the .B pcap_t is ready to be read or not. (That workaround will not work in FreeBSD -4.3 and later; however, in FreeBSD 4.6 and later, -.B select() -and -.B poll() +4.3 and later; however, in FreeBSD 4.6 and later, those calls work correctly on BPF devices, so the workaround isn't necessary, although it does no harm.) .PP Note also that .B poll() +and +.B kevent() doesn't work on character special files, including BPF devices, in Mac OS X 10.4 and 10.5, so, while .B select() can be used on the descriptor returned by .BR pcap_get_selectable_fd() , .B poll() -cannot be used on it those versions of Mac OS X. Kqueues also don't -work on that descriptor. +and +.B kevent() +cannot be used on it those versions of Mac OS X. .BR poll() , -but not kqueues, work on that descriptor in Mac OS X releases prior to +but not +.BR kevent() , +works on that descriptor in Mac OS X releases prior to 10.4; .B poll() -and kqueues work on that descriptor in Mac OS X 10.6 and later. +and +.B kevent() +work on that descriptor in Mac OS X 10.6 and later. .PP .B pcap_get_selectable_fd() is not available on Windows. @@ -130,4 +141,5 @@ is not available on Windows. A selectable file descriptor is returned if one exists; otherwise, \-1 is returned. .SH SEE ALSO -pcap(3PCAP), select(2), poll(2) +pcap(3PCAP), pcap_get_required_select_timeout(3PCAP), +pcap_setnonblock(3PCAP), select(2), poll(2), epoll(2), kqueue(2) -- cgit v1.2.1