diff options
-rw-r--r-- | pcap-bpf.c | 8 | ||||
-rw-r--r-- | pcap-dag.c | 10 | ||||
-rw-r--r-- | pcap-dbus.c | 1 | ||||
-rw-r--r-- | pcap-dos.c | 3 | ||||
-rw-r--r-- | pcap-int.h | 9 | ||||
-rw-r--r-- | pcap-linux.c | 10 | ||||
-rw-r--r-- | pcap-septel.c | 7 | ||||
-rw-r--r-- | pcap-snf.c | 4 | ||||
-rw-r--r-- | pcap-tc.c | 13 | ||||
-rw-r--r-- | pcap-win32.c | 10 | ||||
-rw-r--r-- | pcap.c | 78 | ||||
-rw-r--r-- | savefile.c | 4 |
12 files changed, 101 insertions, 56 deletions
@@ -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 @@ -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; @@ -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? */ } /* @@ -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); } @@ -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; @@ -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); } @@ -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); } @@ -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 |