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
.\" 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
View File

@ -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
View File

@ -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 *);