*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.61 2003-07-23 05:29:21 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.62 2003-07-25 03:25:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return (fd);
}
+static void
+pcap_close_bpf(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
/*
* XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
* else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
memset(p->buffer, 0x0, p->bufsize);
#endif
+ p->close_op = pcap_close_bpf;
+
return (p);
bad:
(void)close(fd);
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.1 2003-07-23 05:29:21 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.2 2003-07-25 03:25:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#define dag_platform_finddevs pcap_platform_finddevs
#define dag_setfilter pcap_setfilter
#define dag_set_datalink_platform pcap_set_datalink_platform
-#define dag_platform_close pcap_platform_close
#endif /* DAG_ONLY */
static void delete_pcap_dag(pcap_t *p) {
}
/*
- * Performs a graceful shutdown of the DAG card and frees dynamic memory held
- * in the pcap_t structure.
+ * Performs a graceful shutdown of the DAG card, frees dynamic memory held
+ * in the pcap_t structure, and closes the file descriptor for the DAG card.
*/
-void dag_platform_close(pcap_t *p) {
+static void dag_platform_close(pcap_t *p) {
#ifdef linux
- if (p != NULL && p->md.is_dag && p->md.device != NULL) {
+ if (p != NULL && p->md.device != NULL) {
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop %s: %s\n", p->md.device, strerror(errno));
if(dag_close(p->fd) < 0)
free(p->md.device);
}
#else
- if (p != NULL && p->md.is_dag) {
+ if (p != NULL) {
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
if(dag_close(p->fd) < 0)
}
#endif
delete_pcap_dag(p);
+ /* XXX - does "dag_close()" do this? If so, we don't need to. */
+ close(p->fd);
}
static void atexit_handler(void) {
return NULL;
}
+ handle->close_op = dag_platform_close;
+
return handle;
}
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.85 2003-02-19 08:06:26 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.86 2003-07-25 03:25:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif /* A_PROMISCON_REQ */
#endif /* HAVE_SOLARIS */
+static void
+pcap_close_dlpi(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
pcap_strerror(errno));
goto bad;
}
+
/* Allocate data buffer */
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
+ if (p->buffer == NULL) {
+ strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ goto bad;
+ }
+
+ p->close_op = pcap_close_dlpi;
return (p);
bad:
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.47 2003-07-23 05:29:21 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.48 2003-07-25 03:25:46 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
*/
u_char *pkt;
+ /*
+ * Methods.
+ */
+ void (*close_op)(pcap_t *);
/*
* Placeholder for filter code if bpf not in kernel.
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
const char *, char *);
-#ifdef linux
-void pcap_close_linux(pcap_t *);
-#endif
-
#ifdef WIN32
char *pcap_win32strerror(void);
#endif
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.90 2003-07-23 05:29:22 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.91 2003-07-25 03:25:46 guy Exp $ (LBL)";
#endif
/*
static int live_open_old(pcap_t *, const char *, int, int, char *);
static int live_open_new(pcap_t *, const char *, int, int, char *);
static int pcap_read_packet(pcap_t *, pcap_handler, u_char *);
+static void pcap_close_linux(pcap_t *handle);
/*
* Wrap some ioctl calls
*/
mtu = iface_get_mtu(handle->fd, device, ebuf);
if (mtu == -1) {
- if (handle->md.clear_promisc)
- /* 2.0.x kernel */
- pcap_close_linux(handle);
- close(handle->fd);
- if (handle->md.device != NULL)
- free(handle->md.device);
+ pcap_close_linux(handle);
free(handle);
return NULL;
}
if (!handle->buffer) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
- if (handle->md.clear_promisc)
- /* 2.0.x kernel */
- pcap_close_linux(handle);
- close(handle->fd);
- if (handle->md.device != NULL)
- free(handle->md.device);
+ pcap_close_linux(handle);
free(handle);
return NULL;
}
+ handle->close_op = pcap_close_linux;
+
return handle;
}
pcap_close(handle);
}
-void pcap_close_linux( pcap_t *handle )
+static void pcap_close_linux( pcap_t *handle )
{
struct pcap *p, *prevp;
struct ifreq ifr;
-#ifdef HAVE_DAG_API
- if (handle->md.is_dag) {
- /* close actions will be done in dag_platform_close() */
- return;
- }
-#endif /* HAVE_DAG_API */
-
if (handle->md.clear_promisc) {
/*
* We put the interface into promiscuous mode; take
if (handle->md.device != NULL)
free(handle->md.device);
handle->md.device = NULL;
+ if (handle->buffer != NULL)
+ free(handle->buffer);
+ if (handle->fd >= 0)
+ close(handle->fd);
}
/*
live_open_old(pcap_t *handle, const char *device, int promisc,
int to_ms, char *ebuf)
{
- int sock_fd = -1, arptype;
+ int arptype;
struct ifreq ifr;
do {
/* Open the socket */
- sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
- if (sock_fd == -1) {
+ handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
+ if (handle->fd == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
break;
PCAP_ERRBUF_SIZE);
break;
}
- if (iface_bind_old(sock_fd, device, ebuf) == -1)
+ if (iface_bind_old(handle->fd, device, ebuf) == -1)
break;
/*
* Try to get the link-layer type.
*/
- arptype = iface_get_arptype(sock_fd, device, ebuf);
+ arptype = iface_get_arptype(handle->fd, device, ebuf);
if (arptype == -1)
break;
if (promisc) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
+ if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"ioctl: %s", pcap_strerror(errno));
break;
}
ifr.ifr_flags |= IFF_PROMISC;
- if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
+ if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"ioctl: %s",
pcap_strerror(errno));
}
}
- /* Save the socket FD in the pcap structure */
-
- handle->fd = sock_fd;
-
/*
* Default value for offset to align link-layer payload
* on a 4-byte boundary.
} while (0);
- if (handle->md.clear_promisc)
- pcap_close_linux(handle);
- if (sock_fd != -1)
- close(sock_fd);
+ pcap_close_linux(handle);
return 0;
}
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.44 2002-12-22 02:36:49 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.45 2003-07-25 03:25:46 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return (0);
}
+static void
+pcap_close_nit(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
+
+ p->close_op = pcap_close_nit;
+
return (p);
bad:
if (fd >= 0)
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.73 2003-05-02 08:35:42 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.74 2003-07-25 03:25:47 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return (0);
}
+static void
+pcap_close_pf(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
goto bad;
}
}
+
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
+ if (p->buffer == NULL) {
+ strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ goto bad;
+ }
+
+ p->close_op = pcap_close_pf;
return (p);
bad:
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.60 2002-12-22 02:36:50 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.61 2003-07-25 03:25:47 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return (0);
}
+static void
+pcap_close_snit(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
+
+ p->close_op = pcap_close_snit;
+
return (p);
bad:
if (fd >= 0)
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.39 2002-12-22 02:36:50 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.40 2003-07-25 03:25:47 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return (0);
}
+static void
+pcap_close_snoop(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->fd >= 0)
+ close(p->fd);
+}
+
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
goto bad;
}
+ p->close_op = pcap_close_snoop;
+
return (p);
bad:
(void)close(fd);
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.8 2003-05-15 14:30:30 risso Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.9 2003-07-25 03:25:47 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
}
+static void
+pcap_close_win32(pcap_t *p)
+{
+ if (p->buffer != NULL)
+ free(p->buffer);
+ if (p->adapter != NULL) {
+ PacketCloseAdapter(p->adapter);
+ p->adapter = NULL;
+ }
+}
+
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
PacketSetReadTimeout(p->adapter, to_ms);
+ p->close_op = pcap_close_win32;
+
return (p);
bad:
if (p->adapter)
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.56 2003-07-23 05:29:22 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.57 2003-07-25 03:25:48 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
}
+static void
+pcap_close_dead(pcap_t *p)
+{
+ /* Nothing to do. */
+}
+
pcap_t *
pcap_open_dead(int linktype, int snaplen)
{
if (p == NULL)
return NULL;
memset (p, 0, sizeof(*p));
-#ifndef WIN32
- p->fd = -1;
-#else
- p->adapter = NULL;
-#endif /* WIN32 */
p->snapshot = snaplen;
p->linktype = linktype;
+ p->close_op = pcap_close_dead;
return p;
}
void
pcap_close(pcap_t *p)
{
- /*XXX*/
-#ifndef WIN32
- if (p->fd >= 0) {
-#ifdef linux
- pcap_close_linux(p);
-#endif
-#ifdef HAVE_DAG_API
- dag_platform_close(p);
-#endif
- close(p->fd);
- }
-#else /* WIN32 */
- if (p->adapter != NULL) {
- PacketCloseAdapter(p->adapter);
- p->adapter = NULL;
- }
-#endif /* WIN32 */
- if (p->sf.rfile != NULL) {
- if (p->sf.rfile != stdin)
- (void)fclose(p->sf.rfile);
- if (p->sf.base != NULL)
- free(p->sf.base);
- } else if (p->buffer != NULL)
- free(p->buffer);
+ p->close_op(p);
if (p->dlt_list != NULL)
free(p->dlt_list);
-
pcap_freecode(&p->fcode);
free(p);
}
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.81 2003-06-27 07:57:10 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.82 2003-07-25 03:25:48 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
hp->linktype = SWAPLONG(hp->linktype);
}
+static void
+sf_close(pcap_t *p)
+{
+ if (p->sf.rfile != stdin)
+ (void)fclose(p->sf.rfile);
+ if (p->sf.base != NULL)
+ free(p->sf.base);
+}
+
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
}
memset((char *)p, 0, sizeof(*p));
- /*
- * Set this field so we don't close stdin in pcap_close!
- */
-#ifndef WIN32
- p->fd = -1;
-#else
- p->adapter = NULL;
-#endif
if (fname[0] == '-' && fname[1] == '\0')
fp = stdin;
pcap_fddipad = 0;
#endif
+ p->close_op = sf_close;
+
return (p);
bad:
if(fp)