dect
/
libpcap
Archived
1
0
Fork 0

If an activate routine fails, it needs to clean up the pcap_t, close

anything it's opened, etc..

In addition, the op pointers need to be restored to the un-activated
state; do that in pcap_activate() if the call to the activate op fails.

Also, in the common cleanup code, set the fd's to -1.
master
Guy Harris 13 years ago
parent 2fbb5a5e31
commit 71dac45765
  1. 1
      pcap-nit.c
  2. 1
      pcap-pf.c
  3. 1
      pcap-snit.c
  4. 1
      pcap-snoop.c
  5. 1
      pcap-usb-linux.c
  6. 93
      pcap.c

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

@ -402,6 +402,7 @@ pcap_activate_snit(pcap_t *p)
return (0);
bad:
pcap_cleanup_live_common(p);
return (PCAP_ERROR);
}

@ -389,6 +389,7 @@ pcap_activate_snoop(pcap_t *p)
return (0);
bad:
pcap_cleanup_live_common(p);
return (PCAP_ERROR);
}

@ -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
}