aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcap-bpf.c8
-rw-r--r--pcap-dag.c10
-rw-r--r--pcap-dbus.c1
-rw-r--r--pcap-dos.c3
-rw-r--r--pcap-int.h9
-rw-r--r--pcap-linux.c10
-rw-r--r--pcap-septel.c7
-rw-r--r--pcap-snf.c4
-rw-r--r--pcap-tc.c13
-rw-r--r--pcap-win32.c10
-rw-r--r--pcap.c78
-rw-r--r--savefile.c4
12 files changed, 101 insertions, 56 deletions
diff --git a/pcap-bpf.c b/pcap-bpf.c
index d4f55238..5e3fe31a 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -252,7 +252,7 @@ static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
* blocking mode.
*/
static int
-pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
+pcap_getnonblock_bpf(pcap_t *p)
{
#ifdef HAVE_ZEROCOPY_BPF
struct pcap_bpf *pb = p->priv;
@@ -260,11 +260,11 @@ pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
if (pb->zerocopy)
return (pb->nonblock);
#endif
- return (pcap_getnonblock_fd(p, errbuf));
+ return (pcap_getnonblock_fd(p));
}
static int
-pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_bpf(pcap_t *p, int nonblock)
{
#ifdef HAVE_ZEROCOPY_BPF
struct pcap_bpf *pb = p->priv;
@@ -274,7 +274,7 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
return (0);
}
#endif
- return (pcap_setnonblock_fd(p, nonblock, errbuf));
+ return (pcap_setnonblock_fd(p, nonblock));
}
#ifdef HAVE_ZEROCOPY_BPF
diff --git a/pcap-dag.c b/pcap-dag.c
index 6a6019b5..d9a03b51 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -214,7 +214,7 @@ static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
static int dag_stats(pcap_t *p, struct pcap_stat *ps);
static int dag_set_datalink(pcap_t *p, int dlt);
static int dag_get_datalink(pcap_t *p);
-static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
+static int dag_setnonblock(pcap_t *p, int nonblock);
static void
delete_pcap_dag(pcap_t *p)
@@ -1129,7 +1129,7 @@ dag_set_datalink(pcap_t *p, int dlt)
}
static int
-dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+dag_setnonblock(pcap_t *p, int nonblock)
{
struct pcap_dag *pd = p->priv;
dag_size_t mindata;
@@ -1142,12 +1142,12 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* and have a "dag_getnonblock()" function that looks at
* "pd->dag_flags".
*/
- if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
+ if (pcap_setnonblock_fd(p, nonblock) < 0)
return (-1);
if (dag_get_stream_poll64(p->fd, pd->dag_stream,
&mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
return -1;
}
@@ -1162,7 +1162,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
if (dag_set_stream_poll64(p->fd, pd->dag_stream,
mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
return -1;
}
diff --git a/pcap-dbus.c b/pcap-dbus.c
index 41f50411..ea3a390f 100644
--- a/pcap-dbus.c
+++ b/pcap-dbus.c
@@ -211,6 +211,7 @@ dbus_activate(pcap_t *handle)
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = dbus_stats;
+ handle->cleanup_op = dbus_cleanup;
handle->selectable_fd = handle->fd = -1;
diff --git a/pcap-dos.c b/pcap-dos.c
index 457db72a..60e9d890 100644
--- a/pcap-dos.c
+++ b/pcap-dos.c
@@ -197,6 +197,7 @@ static int pcap_activate_dos (pcap_t *pcap)
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
{
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
atexit (close_driver);
@@ -206,6 +207,7 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@@ -467,6 +469,7 @@ static void pcap_cleanup_dos (pcap_t *p)
return;
}
close_driver();
+ /* XXX - call pcap_cleanup_live_common? */
}
/*
diff --git a/pcap-int.h b/pcap-int.h
index c4791aee..5c8c1297 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -114,6 +114,7 @@ struct pcap_opt {
int promisc;
int rfmon; /* monitor mode */
int immediate; /* immediate mode - deliver packets as soon as they arrive */
+ int nonblock; /* non-blocking mode - don't wait for packets to be delivered, return "no packets available" */
int tstamp_type;
int tstamp_precision;
};
@@ -125,8 +126,8 @@ typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
-typedef int (*getnonblock_op_t)(pcap_t *, char *);
-typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
+typedef int (*getnonblock_op_t)(pcap_t *);
+typedef int (*setnonblock_op_t)(pcap_t *, int);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef _WIN32
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
@@ -378,8 +379,8 @@ int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
* Routines that most pcap implementations can use for non-blocking mode.
*/
#if !defined(_WIN32) && !defined(MSDOS)
-int pcap_getnonblock_fd(pcap_t *, char *);
-int pcap_setnonblock_fd(pcap_t *p, int, char *);
+int pcap_getnonblock_fd(pcap_t *);
+int pcap_setnonblock_fd(pcap_t *p, int);
#endif
/*
diff --git a/pcap-linux.c b/pcap-linux.c
index 4ba90a80..ee8d3ee4 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -404,8 +404,8 @@ static int pcap_read_linux_mmap_v2(pcap_t *, int, pcap_handler , u_char *);
static int pcap_read_linux_mmap_v3(pcap_t *, int, pcap_handler , u_char *);
#endif
static int pcap_setfilter_linux_mmap(pcap_t *, struct bpf_program *);
-static int pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf);
-static int pcap_getnonblock_mmap(pcap_t *p, char *errbuf);
+static int pcap_setnonblock_mmap(pcap_t *p, int nonblock);
+static int pcap_getnonblock_mmap(pcap_t *p);
static void pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes);
#endif
@@ -4468,7 +4468,7 @@ pcap_cleanup_linux_mmap( pcap_t *handle )
static int
-pcap_getnonblock_mmap(pcap_t *p, char *errbuf)
+pcap_getnonblock_mmap(pcap_t *p)
{
struct pcap_linux *handlep = p->priv;
@@ -4477,7 +4477,7 @@ pcap_getnonblock_mmap(pcap_t *p, char *errbuf)
}
static int
-pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_mmap(pcap_t *p, int nonblock)
{
struct pcap_linux *handlep = p->priv;
@@ -4485,7 +4485,7 @@ pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
* Set the file descriptor to non-blocking mode, as we use
* it for sending packets.
*/
- if (pcap_setnonblock_fd(p, nonblock, errbuf) == -1)
+ if (pcap_setnonblock_fd(p, nonblock) == -1)
return -1;
/*
diff --git a/pcap-septel.c b/pcap-septel.c
index dc120dd5..8d7b5555 100644
--- a/pcap-septel.c
+++ b/pcap-septel.c
@@ -43,7 +43,7 @@
static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
static int septel_stats(pcap_t *p, struct pcap_stat *ps);
-static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
+static int septel_setnonblock(pcap_t *p, int nonblock);
/*
* Private data for capturing on Septel devices.
@@ -237,6 +237,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
return NULL;
p->activate_op = septel_activate;
+ p->setnonblock_op = septel_setnonblock; /* not supported */
return p;
}
@@ -287,9 +288,9 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
static int
-septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+septel_setnonblock(pcap_t *p, int nonblock)
{
- fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
+ fprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
return (-1);
}
diff --git a/pcap-snf.c b/pcap-snf.c
index ca0f3178..0668d0fe 100644
--- a/pcap-snf.c
+++ b/pcap-snf.c
@@ -76,7 +76,7 @@ snf_platform_cleanup(pcap_t *p)
}
static int
-snf_getnonblock(pcap_t *p, char *errbuf)
+snf_getnonblock(pcap_t *p)
{
struct pcap_snf *ps = p->priv;
@@ -84,7 +84,7 @@ snf_getnonblock(pcap_t *p, char *errbuf)
}
static int
-snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+snf_setnonblock(pcap_t *p, int nonblock)
{
struct pcap_snf *ps = p->priv;
diff --git a/pcap-tc.c b/pcap-tc.c
index 1a51a0c3..bedb4f6e 100644
--- a/pcap-tc.c
+++ b/pcap-tc.c
@@ -120,8 +120,8 @@ typedef struct _TC_FUNCTIONS
static pcap_if_t* TcCreatePcapIfFromPort(TC_PORT port);
static int TcSetDatalink(pcap_t *p, int dlt);
-static int TcGetNonBlock(pcap_t *p, char *errbuf);
-static int TcSetNonBlock(pcap_t *p, int nonblock, char *errbuf);
+static int TcGetNonBlock(pcap_t *p);
+static int TcSetNonBlock(pcap_t *p, int nonblock);
static void TcCleanup(pcap_t *p);
static int TcInject(pcap_t *p, const void *buf, size_t size);
static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
@@ -765,6 +765,7 @@ TcCreate(const char *device, char *ebuf, int *is_ours)
return NULL;
p->activate_op = TcActivate;
+ p->setnonblock_op = TcSetNonBlock; /* not supported */
return p;
}
@@ -776,21 +777,17 @@ static int TcSetDatalink(pcap_t *p, int dlt)
return 0;
}
-static int TcGetNonBlock(pcap_t *p, char *errbuf)
+static int TcGetNonBlock(pcap_t *p)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Getting the non blocking status is not available for TurboCap ports");
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Getting the non blocking status is not available for TurboCap ports");
return -1;
}
-static int TcSetNonBlock(pcap_t *p, int nonblock, char *errbuf)
+static int TcSetNonBlock(pcap_t *p, int nonblock)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Setting the non blocking status is not available for TurboCap ports");
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Setting the non blocking status is not available for TurboCap ports");
return -1;
}
diff --git a/pcap-win32.c b/pcap-win32.c
index 2f658e4f..16cb696e 100644
--- a/pcap-win32.c
+++ b/pcap-win32.c
@@ -59,8 +59,8 @@ int* _errno();
static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
-static int pcap_getnonblock_win32(pcap_t *, char *);
-static int pcap_setnonblock_win32(pcap_t *, int, char *);
+static int pcap_getnonblock_win32(pcap_t *);
+static int pcap_setnonblock_win32(pcap_t *, int);
/*dimension of the buffer in the pcap_t structure*/
#define WIN32_DEFAULT_USER_BUFFER_SIZE 256000
@@ -1300,7 +1300,7 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
}
static int
-pcap_getnonblock_win32(pcap_t *p, char *errbuf)
+pcap_getnonblock_win32(pcap_t *p)
{
struct pcap_win *pw = p->priv;
@@ -1313,7 +1313,7 @@ pcap_getnonblock_win32(pcap_t *p, char *errbuf)
}
static int
-pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_win32(pcap_t *p, int nonblock)
{
struct pcap_win *pw = p->priv;
int newtimeout;
@@ -1338,7 +1338,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
pcap_win32_err_to_str(GetLastError(), win_errbuf);
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", win_errbuf);
return (-1);
}
diff --git a/pcap.c b/pcap.c
index f67dc016..3cf4afa2 100644
--- a/pcap.c
+++ b/pcap.c
@@ -1196,6 +1196,18 @@ pcap_create(const char *device, char *errbuf)
return (p);
}
+/*
+ * Set nonblocking mode on an unactivated pcap_t; this sets a flag
+ * checked by pcap_activate(), which sets the mode after calling
+ * the activate routine.
+ */
+static int
+pcap_setnonblock_unactivated(pcap_t *p, int nonblock)
+{
+ p->opt.nonblock = nonblock;
+ return (0);
+}
+
static void
initialize_ops(pcap_t *p)
{
@@ -1210,7 +1222,6 @@ initialize_ops(pcap_t *p)
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
- p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
p->stats_op = (stats_op_t)pcap_not_initialized;
#ifdef _WIN32
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
@@ -1302,6 +1313,13 @@ pcap_create_common(char *ebuf, size_t size)
*/
p->can_set_rfmon_op = pcap_cant_set_rfmon;
+ /*
+ * If pcap_setnonblock() is called on a not-yet-activated
+ * pcap_t, default to setting a flag and turning
+ * on non-blocking mode when activated.
+ */
+ p->setnonblock_op = pcap_setnonblock_unactivated;
+
initialize_ops(p);
/* put in some defaults*/
@@ -1518,9 +1536,25 @@ pcap_activate(pcap_t *p)
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
status = p->activate_op(p);
- if (status >= 0)
+ if (status >= 0) {
+ /*
+ * If somebody requested non-blocking mode before
+ * calling pcap_activate(), turn it on now.
+ */
+ if (p->opt.nonblock) {
+ status = p->setnonblock_op(p, 1);
+ if (status < 0) {
+ /*
+ * Failed. Undo everything done by
+ * the activate operation.
+ */
+ p->cleanup_op(p);
+ initialize_ops(p);
+ return (status);
+ }
+ }
p->activated = 1;
- else {
+ } else {
if (p->errbuf[0] == '\0') {
/*
* No error message supplied by the activate routine;
@@ -2172,14 +2206,18 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
{
int ret;
- ret = p->getnonblock_op(p, errbuf);
+ ret = p->getnonblock_op(p);
if (ret == -1) {
/*
- * In case somebody depended on the bug wherein
- * the error message was put into p->errbuf
- * by pcap_getnonblock_fd().
+ * The get nonblock operation sets p->errbuf; this
+ * function *shouldn't* have had a separate errbuf
+ * argument, as it didn't need one, but I goofed
+ * when adding it.
+ *
+ * We copy the error message to errbuf, so callers
+ * can find it in either place.
*/
- strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -2190,13 +2228,13 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
*/
#if !defined(_WIN32) && !defined(MSDOS)
int
-pcap_getnonblock_fd(pcap_t *p, char *errbuf)
+pcap_getnonblock_fd(pcap_t *p)
{
int fdflags;
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@@ -2212,14 +2250,18 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
int ret;
- ret = p->setnonblock_op(p, nonblock, errbuf);
+ ret = p->setnonblock_op(p, nonblock);
if (ret == -1) {
/*
- * In case somebody depended on the bug wherein
- * the error message was put into p->errbuf
- * by pcap_setnonblock_fd().
+ * The set nonblock operation sets p->errbuf; this
+ * function *shouldn't* have had a separate errbuf
+ * argument, as it didn't need one, but I goofed
+ * when adding it.
+ *
+ * We copy the error message to errbuf, so callers
+ * can find it in either place.
*/
- strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -2232,13 +2274,13 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* needs to do some additional work.)
*/
int
-pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_fd(pcap_t *p, int nonblock)
{
int fdflags;
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@@ -2247,7 +2289,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
else
fdflags &= ~O_NONBLOCK;
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
pcap_strerror(errno));
return (-1);
}
diff --git a/savefile.c b/savefile.c
index 247338c5..f63b45b3 100644
--- a/savefile.c
+++ b/savefile.c
@@ -92,7 +92,7 @@ static pcap_t *pcap_fopen_offline(FILE *, char *);
#endif
static int
-sf_getnonblock(pcap_t *p, char *errbuf)
+sf_getnonblock(pcap_t *p)
{
/*
* This is a savefile, not a live capture file, so never say
@@ -102,7 +102,7 @@ sf_getnonblock(pcap_t *p, char *errbuf)
}
static int
-sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+sf_setnonblock(pcap_t *p, int nonblock)
{
/*
* This is a savefile, not a live capture file, so reject