Add APIs to put a "pcap_t" into or out of non-blocking mode, and to get
the current state of non-blocking mode; this allows us to implement, for example, memory-mapped capture devices, where "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive, and hide that implementation detail from applications using this API ("pcap_setnonblock()" would set or clear a non-blocking mode flag in the "pcap_t", and the "select()" or "poll()" would not be done if the "pcap_t" is in non-blocking mode).
This commit is contained in:
parent
b0ea1152b6
commit
a82f1618b8
35
pcap.3
35
pcap.3
|
@ -1,4 +1,4 @@
|
|||
.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.27 2001-10-28 03:54:57 guy Exp $
|
||||
.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.28 2001-12-09 05:10:02 guy Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1994, 1996, 1997
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
|
@ -76,6 +76,11 @@ u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
|
|||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
int pcap_setnonblock(pcap_t *, int nonblock, char *errbuf);
|
||||
int pcap_getnonblock(pcap_t *p, char *errbuf);
|
||||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
int pcap_datalink(pcap_t *p)
|
||||
int pcap_snapshot(pcap_t *p)
|
||||
int pcap_is_swapped(pcap_t *p)
|
||||
|
@ -481,6 +486,34 @@ when that BPF program is no longer needed, for example after it
|
|||
has been made the filter program for a pcap structure by a call to
|
||||
.BR pcap_setfilter() .
|
||||
.PP
|
||||
.B pcap_setnonblock()
|
||||
puts a capture descriptor, opened with
|
||||
.BR pcap_open_live() ,
|
||||
into ``non-blocking'' mode, or takes it out of ``non-blocking'' mode,
|
||||
depending on whether the
|
||||
.I nonblock
|
||||
argument is non-zero or zero. It has no effect on ``savefiles''.
|
||||
If there is an error, \-1 is returned and
|
||||
.I errbuf
|
||||
is filled in with an appropriate error message.
|
||||
In
|
||||
``non-blocking'' mode, an attempt to read from the capture descriptor
|
||||
with
|
||||
.B pcap_dispatch()
|
||||
will, if no packets are currently available to be read, return 0
|
||||
immediately rather than blocking waiting for packets to arrive.
|
||||
.B pcap_loop()
|
||||
and
|
||||
.B pcap_next()
|
||||
will not work in ``non-blocking'' mode.
|
||||
.PP
|
||||
.B pcap_getnonblock()
|
||||
returns the current ``non-blocking'' state of the capture descriptor; it
|
||||
always returns 0 on ``savefiles''.
|
||||
If there is an error, \-1 is returned and
|
||||
.I errbuf
|
||||
is filled in with an appropriate error message.
|
||||
.PP
|
||||
.B pcap_datalink()
|
||||
returns the link layer type; link layer types it can return include:
|
||||
.PP
|
||||
|
|
63
pcap.c
63
pcap.c
|
@ -33,7 +33,7 @@
|
|||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.36 2000-12-16 10:43:31 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.37 2001-12-09 05:10:03 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -46,6 +46,8 @@ static const char rcsid[] =
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
|
@ -168,6 +170,65 @@ pcap_geterr(pcap_t *p)
|
|||
return (p->errbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: in the future, these may need to call platform-dependent routines,
|
||||
* e.g. on platforms with memory-mapped packet-capture mechanisms where
|
||||
* "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive.
|
||||
*/
|
||||
int
|
||||
pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
{
|
||||
int fdflags;
|
||||
|
||||
if (p->sf.rfile != NULL) {
|
||||
/*
|
||||
* This is a savefile, not a live capture file, so
|
||||
* never say it's in non-blocking mode.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (fdflags & O_NONBLOCK)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
int fdflags;
|
||||
|
||||
if (p->sf.rfile != NULL) {
|
||||
/*
|
||||
* This is a savefile, not a live capture file, so
|
||||
* ignore requests to put it in non-blocking mode.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (nonblock)
|
||||
fdflags |= O_NONBLOCK;
|
||||
else
|
||||
fdflags &= ~O_NONBLOCK;
|
||||
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (fdflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Not all systems have strerror().
|
||||
*/
|
||||
|
|
4
pcap.h
4
pcap.h
|
@ -31,7 +31,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.33 2001-10-28 02:31:50 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.34 2001-12-09 05:10:03 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_h
|
||||
|
@ -170,6 +170,8 @@ const u_char*
|
|||
pcap_next(pcap_t *, struct pcap_pkthdr *);
|
||||
int pcap_stats(pcap_t *, struct pcap_stat *);
|
||||
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
int pcap_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
char *pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
|
|
Reference in New Issue