diff options
-rw-r--r-- | pcap-nit.c | 1 | ||||
-rw-r--r-- | pcap-pf.c | 1 | ||||
-rw-r--r-- | pcap-snit.c | 1 | ||||
-rw-r--r-- | pcap-snoop.c | 1 | ||||
-rw-r--r-- | pcap-usb-linux.c | 1 | ||||
-rw-r--r-- | pcap.c | 93 |
6 files changed, 64 insertions, 34 deletions
@@ -323,6 +323,7 @@ pcap_activate_nit(pcap_t *p) return (0); bad: + pcap_cleanup_live_common(p); return (PCAP_ERROR); } @@ -494,6 +494,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n", return (0); bad: + pcap_cleanup_live_common(p); return (PCAP_ERROR); } diff --git a/pcap-snit.c b/pcap-snit.c index 2990f7a..fa0c4ef 100644 --- a/pcap-snit.c +++ b/pcap-snit.c @@ -402,6 +402,7 @@ pcap_activate_snit(pcap_t *p) return (0); bad: + pcap_cleanup_live_common(p); return (PCAP_ERROR); } diff --git a/pcap-snoop.c b/pcap-snoop.c index c8259a4..330e01d 100644 --- a/pcap-snoop.c +++ b/pcap-snoop.c @@ -389,6 +389,7 @@ pcap_activate_snoop(pcap_t *p) return (0); bad: + pcap_cleanup_live_common(p); return (PCAP_ERROR); } diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index ba18277..bcbe45a 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -384,6 +384,7 @@ usb_activate(pcap_t* handle) if (!handle->buffer) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); + close(handle->fd); return PCAP_ERROR; } return 0; @@ -174,6 +174,42 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, return (p->read_op(p, 1, pcap_oneshot, (u_char *)&s)); } +static void +initialize_ops(pcap_t *p) +{ + /* + * Set operation pointers for operations that only work on + * an activated pcap_t to point to a routine that returns + * a "this isn't activated" error. + */ + p->read_op = (read_op_t)pcap_not_initialized; + p->inject_op = (inject_op_t)pcap_not_initialized; + p->setfilter_op = (setfilter_op_t)pcap_not_initialized; + 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->setbuff_op = (setbuff_op_t)pcap_not_initialized; + p->setmode_op = (setmode_op_t)pcap_not_initialized; + p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; +#endif + + /* + * Default cleanup operation - implementations can override + * this, but should call pcap_cleanup_live_common() after + * doing their own additional cleanup. + */ + p->cleanup_op = pcap_cleanup_live_common; + + /* + * In most cases, the standard one-short callback can + * be used for pcap_next()/pcap_next_ex(). + */ + p->oneshot_callback = pcap_oneshot; +} + pcap_t * pcap_create_common(const char *source, char *ebuf) { @@ -188,6 +224,8 @@ pcap_create_common(const char *source, char *ebuf) memset(p, 0, sizeof(*p)); #ifndef WIN32 p->fd = -1; /* not opened yet */ + p->selectable_fd = -1; + p->send_fd = -1; #endif p->opt.source = strdup(source); @@ -200,36 +238,13 @@ pcap_create_common(const char *source, char *ebuf) /* * Default to "can't set rfmon mode"; if it's supported by - * a platform, it can set the op to its routine to check - * whether a particular device supports it. + * a platform, the create routine that called us can set + * the op to its routine to check whether a particular + * device supports it. */ p->can_set_rfmon_op = pcap_cant_set_rfmon; - /* - * Some operations can be performed only on activated pcap_t's; - * have those operations handled by a "not supported" handler - * until the pcap_t is activated. - */ - p->read_op = (read_op_t)pcap_not_initialized; - p->inject_op = (inject_op_t)pcap_not_initialized; - p->setfilter_op = (setfilter_op_t)pcap_not_initialized; - 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->setbuff_op = (setbuff_op_t)pcap_not_initialized; - p->setmode_op = (setmode_op_t)pcap_not_initialized; - p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; -#endif - p->cleanup_op = pcap_cleanup_live_common; - - /* - * In most cases, the standard one-short callback can - * be used for pcap_next()/pcap_next_ex(). - */ - p->oneshot_callback = pcap_oneshot; + initialize_ops(p); /* put in some defaults*/ pcap_set_timeout(p, 0); @@ -303,15 +318,23 @@ pcap_activate(pcap_t *p) status = p->activate_op(p); if (status >= 0) p->activated = 1; - else if (p->errbuf[0] == '\0') { + else { + if (p->errbuf[0] == '\0') { + /* + * No error message supplied by the activate routine; + * for the benefit of programs that don't specially + * handle errors other than PCAP_ERROR, return the + * error message corresponding to the status. + */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", + pcap_statustostr(status)); + } + /* - * No error message supplied by the activate routine; - * for the benefit of programs that don't specially - * handle errors other than PCAP_ERROR, return the - * error message corresponding to the status. + * Undo any operation pointer setting, etc. done by + * the activate operation. */ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", - pcap_statustostr(status)); + initialize_ops(p); } return (status); } @@ -1179,6 +1202,8 @@ pcap_cleanup_live_common(pcap_t *p) close(p->fd); p->fd = -1; } + p->selectable_fd = -1; + p->send_fd = -1; #endif } |