pcap_fileno.3pcap
pcap_findalldevs.3pcap
pcap_freecode.3pcap
+ pcap_get_required_select_timeout.3pcap
pcap_get_selectable_fd.3pcap
pcap_geterr.3pcap
pcap_inject.3pcap
pcap_fileno.3pcap \
pcap_findalldevs.3pcap \
pcap_freecode.3pcap \
+ pcap_get_required_select_timeout.3pcap \
pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \
pcap_inject.3pcap \
int dag_timeout; /* timeout specified to pcap_open_live.
* Same as in linux above, introduce
* generally? */
+ struct timeval required_select_timeout;
+ /* Timeout caller must use in event loops */
};
typedef struct pcap_dag_node {
goto faildetach;
}
+ /* Use the poll time as the required select timeout for callers
+ * who are using select()/etc. in an event loop waiting for
+ * packets to arrive.
+ */
+ pd->required_select_timeout = poll;
+ p->required_select_timeout = &pd->required_select_timeout;
+
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
HANDLE handle;
#else
int fd;
- int selectable_fd;
#endif /* _WIN32 */
/*
u_char *pkt;
#ifdef _WIN32
- struct pcap_stat stat; /* used for pcap_stats_ex() */
+ struct pcap_stat stat; /* used for pcap_stats_ex() */
#endif
/* We're accepting only packets in this direction/these directions. */
*/
int bpf_codegen_flags;
+#ifndef _WIN32
+ int selectable_fd; /* FD on which select()/poll()/epoll()/kevent()/etc. can be done */
+
+ /*
+ * In case there either is no selectable FD, or there is but
+ * it doesn't necessarily work (e.g., if it doesn't get notified
+ * if the packet capture timeout expires before the buffer
+ * fills up), this points to a timeout that should be used
+ * in select()/poll()/epoll()/kevent() call. The pcap_t should
+ * be put into non-blocking mode, and, if the timeout expires on
+ * the call, an attempt should be made to read packets from all
+ * pcap_t's with a required timeout, and the code must be
+ * prepared not to see any packets from the attempt.
+ */
+ struct timeval *required_select_timeout;
+#endif
+
/*
* Placeholder for filter code if bpf not in kernel.
*/
#else
p->fd = -1; /* not opened yet */
p->selectable_fd = -1;
+ p->required_select_timeout = NULL;
#endif
if (size == 0) {
{
return (p->selectable_fd);
}
+
+struct timeval *
+pcap_get_required_select_timeout(pcap_t *p)
+{
+ return (p->required_select_timeout);
+}
#endif
void
*/
PCAP_API int pcap_get_selectable_fd(pcap_t *);
+ PCAP_API struct timeval *pcap_get_required_select_timeout(pcap_t *);
#endif /* _WIN32/MSDOS/UN*X */
--- /dev/null
+.\" Copyright (c) 1994, 1996, 1997
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.TH PCAP_GET_REQUIRED_SELECT_TIMEOUT 3PCAP "19 January 2018"
+.SH NAME
+pcap_get_required_select_timeout \- get a file descriptor on which a
+select() can be done for a live capture
+.SH SYNOPSIS
+.nf
+.ft B
+#include <pcap/pcap.h>
+.ft
+.LP
+.ft B
+struct timeval *pcap_get_required_select_timeout(pcap_t *p);
+.ft
+.fi
+.SH DESCRIPTION
+.B pcap_get_required_select_timeout()
+returns, on UNIX, a pointer to a
+.B struct timeval
+containing a value that must be used as the minimum timeout in
+.BR select() ,
+.BR poll() ,
+.BR epoll() ,
+and
+.B kevent()
+calls if
+.B pcap_get_selectable_fd()
+returns \-1.
+.PP
+The timeout that should be used in those calls must be no larger than
+the smallest of all timeouts returned by
+.B pcap_get_required_select_timeout()
+for devices from which packets will be captured.
+.PP
+The device for which
+.B pcap_get_selectable_fd()
+returned \-1 must be put in non-blocking mode with
+.BR pcap_setnonblock() ,
+and an attempt must always be made to read packets from the device
+when the
+.BR select() ,
+.BR poll() ,
+.BR epoll() ,
+or
+.B kevent()
+call returns.
+.PP
+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
+.B pcap_get_required_select_timeout()
+is not available on Windows.
+.SH RETURN VALUE
+A pointer to a
+.B struct timeval
+is returned if the timeout is required; otherwise
+.B NULL
+is returned.
+.SH SEE ALSO
+pcap(3PCAP), pcap_get_selectable_fd(3PCAP), select(2), poll(2),
+epoll(2), kqueue(2)
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:
.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.
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)