dect
/
libpcap
Archived
13
0
Fork 0

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:
guy 2001-12-09 05:10:02 +00:00
parent b0ea1152b6
commit a82f1618b8
3 changed files with 99 additions and 3 deletions

35
pcap.3
View File

@ -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 .\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved. .\" 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 .ft
.LP .LP
.ft B .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_datalink(pcap_t *p)
int pcap_snapshot(pcap_t *p) int pcap_snapshot(pcap_t *p)
int pcap_is_swapped(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 has been made the filter program for a pcap structure by a call to
.BR pcap_setfilter() . .BR pcap_setfilter() .
.PP .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() .B pcap_datalink()
returns the link layer type; link layer types it can return include: returns the link layer type; link layer types it can return include:
.PP .PP

63
pcap.c
View File

@ -33,7 +33,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] = 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 #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -46,6 +46,8 @@ static const char rcsid[] =
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_OS_PROTO_H #ifdef HAVE_OS_PROTO_H
#include "os-proto.h" #include "os-proto.h"
@ -168,6 +170,65 @@ pcap_geterr(pcap_t *p)
return (p->errbuf); 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(). * Not all systems have strerror().
*/ */

4
pcap.h
View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 #ifndef lib_pcap_h
@ -170,6 +170,8 @@ const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *); pcap_next(pcap_t *, struct pcap_pkthdr *);
int pcap_stats(pcap_t *, struct pcap_stat *); int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *); 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 *); void pcap_perror(pcap_t *, char *);
char *pcap_strerror(int); char *pcap_strerror(int);
char *pcap_geterr(pcap_t *); char *pcap_geterr(pcap_t *);