dect
/
libpcap
Archived
13
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.
This commit is contained in:
Guy Harris 2009-09-21 10:45:09 -07:00
parent 2fbb5a5e31
commit 71dac45765
6 changed files with 70 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

105
pcap.c
View File

@ -174,41 +174,13 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
return (p->read_op(p, 1, pcap_oneshot, (u_char *)&s));
}
pcap_t *
pcap_create_common(const char *source, char *ebuf)
static void
initialize_ops(pcap_t *p)
{
pcap_t *p;
p = malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
#ifndef WIN32
p->fd = -1; /* not opened yet */
#endif
p->opt.source = strdup(source);
if (p->opt.source == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
free(p);
return (NULL);
}
/*
* 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.
*/
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.
* 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;
@ -223,6 +195,12 @@ pcap_create_common(const char *source, char *ebuf)
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;
/*
@ -230,6 +208,43 @@ pcap_create_common(const char *source, char *ebuf)
* be used for pcap_next()/pcap_next_ex().
*/
p->oneshot_callback = pcap_oneshot;
}
pcap_t *
pcap_create_common(const char *source, char *ebuf)
{
pcap_t *p;
p = malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
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);
if (p->opt.source == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
free(p);
return (NULL);
}
/*
* Default to "can't set rfmon mode"; if it's supported by
* 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;
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
}