dect
/
libpcap
Archived
13
0
Fork 0

Turn close_op into cleanup_op; the routine that handles it can also be

used to clean up after a failed pcap_activate() call.  Convert the
existing close_op routines to cleanup_op routines, and use them to clean
up; rename pcap_close_common() to pcap_cleanup_live_common(), and use it
directly if there's no platform-dependent cleanup needed.  That means we
don't have to write the same cleanup code twice (and possibly forget
stuff in the version done on a failed pcap_activate() call).

Have the cleanup routines do whatever is necessary to indicate that
cleanup has been done, and not do any particular cleaning up if it's
already been done (i.e., don't free something if the pointer to it is
null and null out the pointer once it's been freed, don't close an FD if
it's -1 and set it to -1 once it's been closed, etc.).

For device types/platforms where we don't support monitor mode, check
for it and return PCAP_ERROR_RFMON_NOTSUP - but do so after we've
checked whether we can open the device, so we return "no such device" or
"permission denied" rather than "that device doesn't support monitor
mode" if we can't open the device in the first place.

Fix a comment.
This commit is contained in:
guy 2008-04-14 20:40:58 +00:00
parent 0fdc174e4c
commit 2527d1ac88
18 changed files with 146 additions and 174 deletions

View File

@ -20,7 +20,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.109 2008-04-10 03:10:33 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.110 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -870,7 +870,7 @@ bpf_load(char *errbuf)
* Turn off rfmon mode if necessary. * Turn off rfmon mode if necessary.
*/ */
static void static void
pcap_close_bpf(pcap_t *p) pcap_cleanup_bpf(pcap_t *p)
{ {
#ifdef HAVE_BSD_IEEE80211 #ifdef HAVE_BSD_IEEE80211
int sock; int sock;
@ -939,12 +939,14 @@ pcap_close_bpf(pcap_t *p)
* have to take the interface out of some mode. * have to take the interface out of some mode.
*/ */
pcap_remove_from_pcaps_to_close(p); pcap_remove_from_pcaps_to_close(p);
p->md.must_clear = 0;
} }
if (p->md.device != NULL) if (p->md.device != NULL) {
free(p->md.device); free(p->md.device);
p->md.device = NULL; p->md.device = NULL;
pcap_close_common(p); }
pcap_cleanup_live_common(p);
} }
static int static int
@ -1561,7 +1563,7 @@ pcap_activate_bpf(pcap_t *p)
#endif /* _AIX */ #endif /* _AIX */
if (p->opt.promisc) { if (p->opt.promisc) {
/* set promiscuous mode, okay if it fails */ /* set promiscuous mode, just warn if it fails */
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
pcap_strerror(errno)); pcap_strerror(errno));
@ -1668,23 +1670,11 @@ pcap_activate_bpf(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_bpf; p->stats_op = pcap_stats_bpf;
p->close_op = pcap_close_bpf; p->cleanup_op = pcap_cleanup_bpf;
return (status); return (status);
bad: bad:
(void)close(fd); pcap_cleanup_bpf(p);
if (p->dlt_list != NULL) {
free(p->dlt_list);
p->dlt_list = NULL;
}
if (p->md.device != NULL) {
free(p->md.device);
p->md.device = NULL;
}
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
return (status); return (status);
} }

View File

@ -33,7 +33,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.12 2008-04-07 03:57:32 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.13 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -155,6 +155,7 @@ bt_activate(pcap_t* handle)
int opt; int opt;
int dev_id; int dev_id;
struct hci_filter flt; struct hci_filter flt;
int err = PCAP_ERROR;
/* get bt interface id */ /* get bt interface id */
if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1) if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
@ -178,7 +179,6 @@ bt_activate(pcap_t* handle)
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = bt_stats_linux; handle->stats_op = bt_stats_linux;
handle->close_op = bt_close_linux;
handle->md.ifindex = dev_id; handle->md.ifindex = dev_id;
/* Create HCI socket */ /* Create HCI socket */
@ -231,6 +231,14 @@ bt_activate(pcap_t* handle)
goto close_fail; goto close_fail;
} }
if (p->opt.rfmon) {
/*
* Monitor mode doesn't apply to Bluetooth devices.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
goto close_fail;
}
if (handle->opt.buffer_size == 0) { if (handle->opt.buffer_size == 0) {
/* /*
* Set the socket buffer size to the specified value. * Set the socket buffer size to the specified value.
@ -248,8 +256,8 @@ bt_activate(pcap_t* handle)
return 0; return 0;
close_fail: close_fail:
close(handle->fd); pcap_cleanup_live_common(p);
return PCAP_ERROR; return err;
} }
static int static int
@ -322,14 +330,6 @@ bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
} }
static void
bt_close_linux(pcap_t* handle)
{
close(handle->fd);
free(handle->buffer);
}
static int static int
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats) bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{ {

View File

@ -17,7 +17,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.38 2008-04-08 03:00:14 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.39 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -125,7 +125,7 @@ delete_pcap_dag(pcap_t *p)
*/ */
static void static void
dag_platform_close(pcap_t *p) dag_platform_cleanup(pcap_t *p)
{ {
if (p != NULL) { if (p != NULL) {
@ -139,10 +139,14 @@ dag_platform_close(pcap_t *p)
if(dag_stop(p->fd) < 0) if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno)); fprintf(stderr,"dag_stop: %s\n", strerror(errno));
#endif /* HAVE_DAG_STREAMS_API */ #endif /* HAVE_DAG_STREAMS_API */
if(dag_close(p->fd) < 0) if(p->fd != -1) {
fprintf(stderr,"dag_close: %s\n", strerror(errno)); if(dag_close(p->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
p->fd = -1;
}
delete_pcap_dag(p);
pcap_cleanup_live_common(p);
} }
delete_pcap_dag(p);
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */ /* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
} }
@ -151,7 +155,7 @@ atexit_handler(void)
{ {
while (pcap_dags != NULL) { while (pcap_dags != NULL) {
if (pcap_dags->pid == getpid()) { if (pcap_dags->pid == getpid()) {
dag_platform_close(pcap_dags->p); dag_platform_cleanup(pcap_dags->p);
} else { } else {
delete_pcap_dag(pcap_dags->p); delete_pcap_dag(pcap_dags->p);
} }
@ -783,7 +787,7 @@ static int dag_activate(pcap_t* handle)
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = dag_setnonblock; handle->setnonblock_op = dag_setnonblock;
handle->stats_op = dag_stats; handle->stats_op = dag_stats;
handle->close_op = dag_platform_close; handle->cleanup_op = dag_platform_cleanup;
handle->md.stat.ps_drop = 0; handle->md.stat.ps_drop = 0;
handle->md.stat.ps_recv = 0; handle->md.stat.ps_recv = 0;
return 0; return 0;
@ -809,6 +813,7 @@ failclose:
delete_pcap_dag(handle); delete_pcap_dag(handle);
fail: fail:
pcap_cleanup_live_common(handle);
if (newDev != NULL) { if (newDev != NULL) {
free((char *)newDev); free((char *)newDev);
} }

View File

@ -70,7 +70,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.126 2008-04-10 00:50:34 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.127 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -314,11 +314,13 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
#endif /* HAVE_SOLARIS */ #endif /* HAVE_SOLARIS */
static void static void
pcap_close_dlpi(pcap_t *p) pcap_cleanup_dlpi(pcap_t *p)
{ {
pcap_close_common(p); if (p->send_fd >= 0) {
if (p->send_fd >= 0)
close(p->send_fd); close(p->send_fd);
p->send_fd = -1;
}
pcap_cleanup_live_common(p);
} }
static int static int
@ -344,9 +346,6 @@ pcap_activate_dlpi(pcap_t *p)
#endif #endif
int status = PCAP_ERROR; int status = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
#ifdef HAVE_DEV_DLPI #ifdef HAVE_DEV_DLPI
/* /*
** Remove any "/dev/" on the front of the device. ** Remove any "/dev/" on the front of the device.
@ -750,14 +749,11 @@ pcap_activate_dlpi(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_dlpi; p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi; p->cleanup_op = pcap_cleanup_dlpi;
return (status); return (status);
bad: bad:
if (p->fd >= 0) pcap_cleanup_dlpi(p);
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
return (status); return (status);
} }
@ -1686,6 +1682,8 @@ pcap_create(const char *device, char *ebuf)
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
p->send_fd = -1; /* it hasn't been opened yet */
p->activate_op = pcap_activate_dlpi; p->activate_op = pcap_activate_dlpi;
return (p); return (p);
} }

View File

@ -5,7 +5,7 @@
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode * pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers. * network drivers.
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.5 2008-04-14 20:40:58 guy Exp $ (LBL)
*/ */
#include <stdio.h> #include <stdio.h>
@ -177,7 +177,7 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap->snapshot = ETH_MAX; pcap->snapshot = ETH_MAX;
pcap->linktype = DLT_EN10MB; /* !! */ pcap->linktype = DLT_EN10MB; /* !! */
pcap->close_op = pcap_close_dos; pcap->cleanup_op = pcap_cleanup_dos;
pcap->read_op = pcap_read_dos; pcap->read_op = pcap_read_dos;
pcap->stats_op = pcap_stats_dos; pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos; pcap->inject_op = pcap_sendpacket_dos;
@ -430,7 +430,7 @@ u_long pcap_filter_packets (void)
/* /*
* Close pcap device. Not called for offline captures. * Close pcap device. Not called for offline captures.
*/ */
static void pcap_close_dos (pcap_t *p) static void pcap_cleanup_dos (pcap_t *p)
{ {
if (p && !exc_occured) if (p && !exc_occured)
{ {

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.89 2008-04-04 19:37:45 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.90 2008-04-14 20:40:58 guy Exp $ (LBL)
*/ */
#ifndef pcap_int_h #ifndef pcap_int_h
@ -193,7 +193,7 @@ typedef int (*setbuff_op_t)(pcap_t *, int);
typedef int (*setmode_op_t)(pcap_t *, int); typedef int (*setmode_op_t)(pcap_t *, int);
typedef int (*setmintocopy_op_t)(pcap_t *, int); typedef int (*setmintocopy_op_t)(pcap_t *, int);
#endif #endif
typedef void (*close_op_t)(pcap_t *); typedef void (*cleanup_op_t)(pcap_t *);
struct pcap { struct pcap {
#ifdef WIN32 #ifdef WIN32
@ -270,7 +270,7 @@ struct pcap {
setmode_op_t setmode_op; setmode_op_t setmode_op;
setmintocopy_op_t setmintocopy_op; setmintocopy_op_t setmintocopy_op;
#endif #endif
close_op_t close_op; cleanup_op_t cleanup_op;
/* /*
* Placeholder for filter code if bpf not in kernel. * Placeholder for filter code if bpf not in kernel.
@ -391,7 +391,7 @@ pcap_t *pcap_create_common(const char *, char *);
int pcap_do_addexit(pcap_t *); int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *); void pcap_add_to_pcaps_to_close(pcap_t *);
void pcap_remove_from_pcaps_to_close(pcap_t *); void pcap_remove_from_pcaps_to_close(pcap_t *);
void pcap_close_common(pcap_t *); void pcap_cleanup_live_common(pcap_t *);
int pcap_not_initialized(pcap_t *); int pcap_not_initialized(pcap_t *);
int pcap_check_activated(pcap_t *); int pcap_check_activated(pcap_t *);

View File

@ -26,7 +26,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.5 2008-04-09 19:58:02 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.6 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -104,8 +104,6 @@ pcap_activate_libdlpi(pcap_t *p)
dlpi_info_t dlinfo; dlpi_info_t dlinfo;
int err = PCAP_ERROR; int err = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
/* /*
* Enable Solaris raw and passive DLPI extensions; * Enable Solaris raw and passive DLPI extensions;
* dlpi_open() will not fail if the underlying link does not support * dlpi_open() will not fail if the underlying link does not support
@ -211,14 +209,11 @@ pcap_activate_libdlpi(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_dlpi; p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_libdlpi; p->cleanup_op = pcap_cleanup_libdlpi;
return (0); return (0);
bad: bad:
/* Get rid of any link-layer type list we allocated. */ pcap_cleanup_libdlpi(p);
if (p->dlt_list != NULL)
free(p->dlt_list);
dlpi_close(p->dlpi_hd);
return (err); return (err);
} }
@ -338,13 +333,17 @@ pcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size)
} }
/* /*
* Close dlpi handle and deallocate data buffer. * Close dlpi handle.
*/ */
static void static void
pcap_close_libdlpi(pcap_t *p) pcap_cleanup_libdlpi(pcap_t *p)
{ {
dlpi_close(p->dlpi_hd); if (p->dlpi_hd != NULL) {
free(p->buffer); dlpi_close(p->dlpi_hd);
p->dlpi_hd = NULL;
p->fd = -1;
}
pcap_cleanup_live_common(p);
} }
/* /*

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.146 2008-04-10 01:26:43 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.147 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
/* /*
@ -234,14 +234,14 @@ static int pcap_inject_linux(pcap_t *, const void *, size_t);
static int pcap_stats_linux(pcap_t *, struct pcap_stat *); static int pcap_stats_linux(pcap_t *, struct pcap_stat *);
static int pcap_setfilter_linux(pcap_t *, struct bpf_program *); static int pcap_setfilter_linux(pcap_t *, struct bpf_program *);
static int pcap_setdirection_linux(pcap_t *, pcap_direction_t); static int pcap_setdirection_linux(pcap_t *, pcap_direction_t);
static void pcap_close_linux(pcap_t *); static void pcap_cleanup_linux(pcap_t *);
#ifdef HAVE_PACKET_RING #ifdef HAVE_PACKET_RING
#define RING_GET_FRAME(h) (((struct tpacket_hdr**)h->buffer)[h->offset]) #define RING_GET_FRAME(h) (((struct tpacket_hdr**)h->buffer)[h->offset])
static void destroy_ring(pcap_t *handle); static void destroy_ring(pcap_t *handle);
static int create_ring(pcap_t *handle); static int create_ring(pcap_t *handle);
static void pcap_close_linux_mmap(pcap_t *); static void pcap_cleanup_linux_mmap(pcap_t *);
static int pcap_read_linux_mmap(pcap_t *, int, pcap_handler , u_char *); static int pcap_read_linux_mmap(pcap_t *, int, pcap_handler , u_char *);
static int pcap_setfilter_linux_mmap(pcap_t *, struct bpf_program *); 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_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf);
@ -383,7 +383,7 @@ pcap_can_set_rfmon_linux(pcap_t *p)
* Even with newer kernels, we have the same issue with rfmon mode. * Even with newer kernels, we have the same issue with rfmon mode.
*/ */
static void pcap_close_linux( pcap_t *handle ) static void pcap_cleanup_linux( pcap_t *handle )
{ {
struct ifreq ifr; struct ifreq ifr;
#ifdef IW_MODE_MONITOR #ifdef IW_MODE_MONITOR
@ -471,7 +471,7 @@ static void pcap_close_linux( pcap_t *handle )
free(handle->md.device); free(handle->md.device);
handle->md.device = NULL; handle->md.device = NULL;
} }
pcap_close_common(handle); pcap_cleanup_live_common(p);
} }
/* /*
@ -497,7 +497,7 @@ pcap_activate_linux(pcap_t *handle)
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
handle->close_op = pcap_close_linux; handle->cleanup_op = pcap_cleanup_linux;
handle->read_op = pcap_read_linux; handle->read_op = pcap_read_linux;
handle->stats_op = pcap_stats_linux; handle->stats_op = pcap_stats_linux;
@ -590,11 +590,7 @@ pcap_activate_linux(pcap_t *handle)
return status; return status;
fail: fail:
close(handle->fd); pcap_cleanup_linux(handle);
if (handle->md.device != NULL) {
free(handle->md.device);
handle->md.device = NULL;
}
return status; return status;
} }
@ -1824,7 +1820,7 @@ activate_mmap(pcap_t *handle)
* handle->offset is used to get the current position into the rx ring * handle->offset is used to get the current position into the rx ring
* handle->cc is used to store the ring size */ * handle->cc is used to store the ring size */
handle->read_op = pcap_read_linux_mmap; handle->read_op = pcap_read_linux_mmap;
handle->close_op = pcap_close_linux_mmap; handle->cleanup_op = pcap_cleanup_linux_mmap;
handle->setfilter_op = pcap_setfilter_linux_mmap; handle->setfilter_op = pcap_setfilter_linux_mmap;
handle->setnonblock_op = pcap_setnonblock_mmap; handle->setnonblock_op = pcap_setnonblock_mmap;
handle->getnonblock_op = pcap_getnonblock_mmap; handle->getnonblock_op = pcap_getnonblock_mmap;
@ -1942,19 +1938,13 @@ destroy_ring(pcap_t *handle)
munmap(handle->bp, block_size * handle->cc / frames_per_block); munmap(handle->bp, block_size * handle->cc / frames_per_block);
handle->bp = 0; handle->bp = 0;
} }
/* if the header ring is allocated, clear it*/
if (handle->buffer) {
free(handle->buffer);
handle->buffer = 0;
}
} }
static void static void
pcap_close_linux_mmap( pcap_t *handle ) pcap_cleanup_linux_mmap( pcap_t *handle )
{ {
destroy_ring(handle); destroy_ring(handle);
pcap_close_linux(handle); pcap_cleanup_linux(handle);
} }

View File

@ -20,7 +20,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.61 2008-04-04 19:37:45 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.62 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -320,12 +320,9 @@ pcap_activate_nit(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_nit; p->stats_op = pcap_stats_nit;
p->close_op = pcap_close_common;
return (0); return (0);
bad: bad:
if (fd >= 0)
close(fd);
return (PCAP_ERROR); return (PCAP_ERROR);
} }

View File

@ -24,7 +24,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.96 2008-04-04 19:37:45 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.97 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -491,12 +491,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_pf; p->stats_op = pcap_stats_pf;
p->close_op = pcap_close_common;
return (0); return (0);
bad: bad:
if (p->fd >= 0)
close(p->fd);
return (PCAP_ERROR); return (PCAP_ERROR);
} }

View File

@ -16,7 +16,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.3 2008-04-04 19:37:45 guy Exp $"; "@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.4 2008-04-14 20:40:58 guy Exp $";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -59,12 +59,6 @@ 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_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, char *errbuf);
static void septel_platform_close(pcap_t *p) {
}
/* /*
* Read at most max_packets from the capture queue and call the callback * Read at most max_packets from the capture queue and call the callback
* for each of them. Returns the number of packets handled, -1 if an * for each of them. Returns the number of packets handled, -1 if an
@ -223,7 +217,6 @@ static pcap_t *septel_activate(pcap_t* handle) {
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = septel_setnonblock; handle->setnonblock_op = septel_setnonblock;
handle->stats_op = septel_stats; handle->stats_op = septel_stats;
handle->close_op = septel_platform_close;
return 0; return 0;
} }

View File

@ -344,7 +344,7 @@ static void close_with_IOP(int chassis, int geoslot, int flag) {
} }
} }
static void pcap_close_acn(pcap_t *handle) { static void pcap_cleanup_acn(pcap_t *handle) {
int chassis, geoslot; int chassis, geoslot;
unit_t *u; unit_t *u;
@ -353,6 +353,7 @@ static void pcap_close_acn(pcap_t *handle) {
close_with_IOP(chassis, geoslot, LIVE); close_with_IOP(chassis, geoslot, LIVE);
if (u) if (u)
u->first_time = 0; u->first_time = 0;
pcap_cleanup_live_common(handle);
} }
static void send_to_fd(int fd, int len, unsigned char *str) { static void send_to_fd(int fd, int len, unsigned char *str) {
@ -936,7 +937,7 @@ static int pcap_activate_sita(pcap_t *handle) {
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
handle->close_op = pcap_close_acn; handle->cleanup_op = pcap_cleanup_acn;
handle->read_op = pcap_read_acn; handle->read_op = pcap_read_acn;
handle->stats_op = pcap_stats_acn; handle->stats_op = pcap_stats_acn;
@ -954,7 +955,7 @@ static int pcap_activate_sita(pcap_t *handle) {
if (!handle->buffer) { if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno)); "malloc: %s", pcap_strerror(errno));
pcap_close_acn(handle); pcap_cleanup_acn(handle);
return PCAP_ERROR; return PCAP_ERROR;
} }

View File

@ -25,7 +25,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.76 2008-04-04 19:37:45 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.77 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -399,12 +399,9 @@ pcap_activate_snit(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snit; p->stats_op = pcap_stats_snit;
p->close_op = pcap_close_common;
return (0); return (0);
bad: bad:
if (fd >= 0)
close(fd);
return (PCAP_ERROR); return (PCAP_ERROR);
} }

View File

@ -20,7 +20,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.57 2008-04-07 03:57:32 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.58 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -205,14 +205,6 @@ pcap_activate_snoop(pcap_t *p)
int snooplen; int snooplen;
struct ifreq ifr; struct ifreq ifr;
if (p->opt.rfmon) {
/*
* No monitor mode on Irix (no Wi-Fi devices on
* hardware supported by Irix).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) { if (fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
@ -310,6 +302,15 @@ pcap_activate_snoop(pcap_t *p)
"snoop: unknown physical layer type"); "snoop: unknown physical layer type");
goto bad; goto bad;
} }
if (p->opt.rfmon) {
/*
* No monitor mode on Irix (no Wi-Fi devices on
* hardware supported by Irix).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
#ifdef SIOCGIFMTU #ifdef SIOCGIFMTU
/* /*
* XXX - IRIX appears to give you an error if you try to set the * XXX - IRIX appears to give you an error if you try to set the
@ -385,11 +386,9 @@ pcap_activate_snoop(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snoop; p->stats_op = pcap_stats_snoop;
p->close_op = pcap_close_common;
return (0); return (0);
bad: bad:
(void)close(fd);
return (PCAP_ERROR); return (PCAP_ERROR);
} }

View File

@ -34,7 +34,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.22 2008-04-04 19:37:45 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.23 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -126,8 +126,7 @@ static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *);
static int usb_inject_linux(pcap_t *, const void *, size_t); static int usb_inject_linux(pcap_t *, const void *, size_t);
static int usb_setfilter_linux(pcap_t *, struct bpf_program *); static int usb_setfilter_linux(pcap_t *, struct bpf_program *);
static int usb_setdirection_linux(pcap_t *, pcap_direction_t); static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
static void usb_close_linux(pcap_t *); static void usb_cleanup_linux_mmap(pcap_t *);
static void usb_close_linux_mmap(pcap_t *);
/* facility to add an USB device to the device list*/ /* facility to add an USB device to the device list*/
static int static int
@ -213,14 +212,13 @@ usb_activate(pcap_t* handle)
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
handle->close_op = usb_close_linux;
/*get usb bus index from device name */ /*get usb bus index from device name */
if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1) if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1)
{ {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.source); "Can't get USB bus index from %s", handle->opt.source);
return -1; return PCAP_ERROR;
} }
/*now select the read method: try to open binary interface */ /*now select the read method: try to open binary interface */
@ -228,11 +226,18 @@ usb_activate(pcap_t* handle)
handle->fd = open(full_path, O_RDONLY, 0); handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd >= 0) if (handle->fd >= 0)
{ {
if (p->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/* binary api is available, try to use fast mmap access */ /* binary api is available, try to use fast mmap access */
if (usb_mmap(handle)) { if (usb_mmap(handle)) {
handle->stats_op = usb_stats_linux_bin; handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap; handle->read_op = usb_read_linux_mmap;
handle->close_op = usb_close_linux_mmap; handle->cleanup_op = usb_cleanup_linux_mmap;
/* /*
* "handle->fd" is a real file, so "select()" and * "handle->fd" is a real file, so "select()" and
@ -255,12 +260,19 @@ usb_activate(pcap_t* handle)
/* no more fallback, give it up*/ /* no more fallback, give it up*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB bus file %s: %s", full_path, strerror(errno)); "Can't open USB bus file %s: %s", full_path, strerror(errno));
return -1; return PCAP_ERROR;
} }
handle->stats_op = usb_stats_linux; handle->stats_op = usb_stats_linux;
handle->read_op = usb_read_linux; handle->read_op = usb_read_linux;
} }
if (p->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/* /*
* "handle->fd" is a real file, so "select()" and "poll()" * "handle->fd" is a real file, so "select()" and "poll()"
* work on it. * work on it.
@ -273,8 +285,7 @@ usb_activate(pcap_t* handle)
if (!handle->buffer) { if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno)); "malloc: %s", pcap_strerror(errno));
close(handle->fd); return PCAP_ERROR;
return -1;
} }
return 0; return 0;
} }
@ -490,15 +501,6 @@ usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
return (-1); return (-1);
} }
static void
usb_close_linux(pcap_t* handle)
{
/* handle fill be freed in pcap_close() 'common' code */
close(handle->fd);
if (handle->buffer)
free(handle->buffer);
}
static int static int
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{ {
@ -719,9 +721,10 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
} }
static void static void
usb_close_linux_mmap(pcap_t* handle) usb_cleanup_linux_mmap(pcap_t* handle)
{ {
/* handle will be freed in pcap_close() 'common' code, buffer must not /* buffer must not be freed because it's memory mapped */
* be freed because it's memory mapped */ /* XXX - does it need to be unmapped? */
close(handle->fd); handle->buffer = NULL;
pcap_cleanup_live_common(handle);
} }

View File

@ -33,7 +33,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.39 2008-04-09 21:20:26 gianluca Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.40 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#include <pcap-int.h> #include <pcap-int.h>
@ -417,9 +417,8 @@ pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
} }
static void static void
pcap_close_win32(pcap_t *p) pcap_cleanup_win32(pcap_t *p)
{ {
pcap_close_common(p);
if (p->adapter != NULL) { if (p->adapter != NULL) {
PacketCloseAdapter(p->adapter); PacketCloseAdapter(p->adapter);
p->adapter = NULL; p->adapter = NULL;
@ -428,6 +427,7 @@ pcap_close_win32(pcap_t *p)
PacketFreePacket(p->Packet); PacketFreePacket(p->Packet);
p->Packet = NULL; p->Packet = NULL;
} }
pcap_cleanup_live_common(p);
} }
static int static int
@ -688,18 +688,11 @@ pcap_activate_win32(pcap_t *p)
p->setbuff_op = pcap_setbuff_win32; p->setbuff_op = pcap_setbuff_win32;
p->setmode_op = pcap_setmode_win32; p->setmode_op = pcap_setmode_win32;
p->setmintocopy_op = pcap_setmintocopy_win32; p->setmintocopy_op = pcap_setmintocopy_win32;
p->close_op = pcap_close_win32; p->cleanup_op = pcap_cleanup_win32;
return (0); return (0);
bad: bad:
if (p->adapter) pcap_cleanup_win32(p);
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
if(p->Packet)
PacketFreePacket(p->Packet);
return (PCAP_ERROR); return (PCAP_ERROR);
} }

36
pcap.c
View File

@ -33,7 +33,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.119 2008-04-09 21:39:21 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.120 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -108,6 +108,9 @@ pcap_create_common(const char *source, char *ebuf)
return (NULL); return (NULL);
} }
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
#ifndef WIN32
p->fd = -1; /* not opened yet */
#endif
p->opt.source = strdup(source); p->opt.source = strdup(source);
if (p->opt.source == NULL) { if (p->opt.source == NULL) {
@ -142,7 +145,7 @@ pcap_create_common(const char *source, char *ebuf)
p->setmode_op = (setmode_op_t)pcap_not_initialized; p->setmode_op = (setmode_op_t)pcap_not_initialized;
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
#endif #endif
p->close_op = (close_op_t)pcap_close_common; p->cleanup_op = pcap_cleanup_live_common;
/* put in some defaults*/ /* put in some defaults*/
pcap_set_timeout(p, 0); pcap_set_timeout(p, 0);
@ -1127,20 +1130,28 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
} }
void void
pcap_close_common(pcap_t *p) pcap_cleanup_live_common(pcap_t *p)
{ {
if (p->buffer != NULL) if (p->buffer != NULL) {
free(p->buffer); free(p->buffer);
if (p->opt.source != NULL); p->buffer = NULL;
free(p->opt.source); }
if (p->dlt_list != NULL) {
free(p->dlt_list);
p->dlt_list = NULL;
p->dlt_count = 0;
}
pcap_freecode(&p->fcode);
#if !defined(WIN32) && !defined(MSDOS) #if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0) if (p->fd >= 0) {
close(p->fd); close(p->fd);
p->fd = -1;
}
#endif #endif
} }
static void static void
pcap_close_dead(pcap_t *p _U_) pcap_cleanup_dead(pcap_t *p _U_)
{ {
/* Nothing to do. */ /* Nothing to do. */
} }
@ -1162,7 +1173,7 @@ pcap_open_dead(int linktype, int snaplen)
p->setmode_op = pcap_setmode_dead; p->setmode_op = pcap_setmode_dead;
p->setmintocopy_op = pcap_setmintocopy_dead; p->setmintocopy_op = pcap_setmintocopy_dead;
#endif #endif
p->close_op = pcap_close_dead; p->cleanup_op = pcap_cleanup_dead;
p->activated = 1; p->activated = 1;
return p; return p;
} }
@ -1194,10 +1205,9 @@ pcap_inject(pcap_t *p, const void *buf, size_t size)
void void
pcap_close(pcap_t *p) pcap_close(pcap_t *p)
{ {
p->close_op(p); if (p->opt.source != NULL)
if (p->dlt_list != NULL) free(p->opt.source);
free(p->dlt_list); p->cleanup_op(p);
pcap_freecode(&p->fcode);
free(p); free(p);
} }

View File

@ -30,7 +30,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.174 2008-04-06 18:09:48 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.175 2008-04-14 20:40:58 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -1094,7 +1094,7 @@ sf_setdirection(pcap_t *p, pcap_direction_t d)
} }
static void static void
sf_close(pcap_t *p) sf_cleanup(pcap_t *p)
{ {
if (p->sf.rfile != stdin) if (p->sf.rfile != stdin)
(void)fclose(p->sf.rfile); (void)fclose(p->sf.rfile);
@ -1327,7 +1327,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
p->setmode_op = sf_setmode; p->setmode_op = sf_setmode;
p->setmintocopy_op = sf_setmintocopy; p->setmintocopy_op = sf_setmintocopy;
#endif #endif
p->close_op = sf_close; p->cleanup_op = sf_cleanup;
p->activated = 1; p->activated = 1;
return (p); return (p);