dect
/
libpcap
Archived
13
0
Fork 0

From Paolo Abeni and me: split pcap_open_live() into a "get a pcap_t

handle" routine, an 'activate a pcap_t handle" routine, and some "set
the properties of the pcap_t handle" routines, so that, for example, the
buffer size can be set on a BPF device before the device is bound to an
interface.

Add additional routines to set monitor mode, and make at least an
initial attempt at supporting that on Linux, *BSD, and Mac OS X 10.4 and
10.5.  (Very much "initial" for Linux, which is a twisty little maze of
wireless drivers, many different.)

Have a "timeout" member of the pcap_md structure on all platforms, use
that on Windows instead of the "timeout" member of the pcap_t structure,
and get rid of the "timeout" member of that structure.
This commit is contained in:
guy 2008-04-04 19:37:44 +00:00
parent 19d1a629c7
commit d9b420231a
28 changed files with 3278 additions and 1345 deletions

View File

@ -59,6 +59,9 @@
/* Define to 1 if you have the <limits.h> header file. */ /* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H #undef HAVE_LIMITS_H
/* Define to 1 if you have the <linux/wireless.h> header file. */
#undef HAVE_LINUX_WIRELESS_H
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MEMORY_H
@ -68,6 +71,9 @@
/* Define to 1 if you have the <netinet/if_ether.h> header file. */ /* Define to 1 if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H #undef HAVE_NETINET_IF_ETHER_H
/* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H
/* Define to 1 if you have the <net/pfvar.h> header file. */ /* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H #undef HAVE_NET_PFVAR_H

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.148 2008-03-14 09:12:49 guy Exp $ (LBL) dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.149 2008-04-04 19:37:44 guy Exp $ (LBL)
dnl dnl
dnl Copyright (c) 1994, 1995, 1996, 1997 dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved. dnl The Regents of the University of California. All rights reserved.
@ -6,7 +6,7 @@ dnl
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl dnl
AC_REVISION($Revision: 1.148 $) AC_REVISION($Revision: 1.149 $)
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(pcap.c) AC_INIT(pcap.c)
@ -448,9 +448,23 @@ linux)
if test $ac_cv_linux_vers -lt 2 ; then if test $ac_cv_linux_vers -lt 2 ; then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info) AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
fi fi
AC_CHECK_HEADERS(linux/wireless.h, [], [],
[
#include <sys/socket.h>
#include <net/if.h>
#include <linux/types.h>
])
AC_CHECK_HEADERS()
AC_LBL_TPACKET_STATS AC_LBL_TPACKET_STATS
;; ;;
bpf)
#
# Check whether we have the *BSD-style ioctls.
#
AC_CHECK_HEADERS(net/if_media.h)
;;
dag) dag)
V_DEFS="$V_DEFS -DDAG_ONLY" V_DEFS="$V_DEFS -DDAG_ONLY"
;; ;;

View File

@ -12,7 +12,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.1 2008-03-13 18:13:57 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.2 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -197,7 +197,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
* Process the mac type. Returns -1 if no matching mac type found, otherwise 0. * Process the mac type. Returns -1 if no matching mac type found, otherwise 0.
*/ */
int int
pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf) pcap_process_mactype(pcap_t *p, u_int mactype)
{ {
int retv = 0; int retv = 0;
@ -247,7 +247,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
#endif #endif
default: default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mactype %u", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
mactype); mactype);
retv = -1; retv = -1;
} }
@ -260,7 +260,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
* Push and configure the buffer module. Returns -1 for error, otherwise 0. * Push and configure the buffer module. Returns -1 for error, otherwise 0.
*/ */
int int
pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf) pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout)
{ {
int retv = 0; int retv = 0;
@ -268,14 +268,14 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
/* Non-standard call to get the data nicely buffered. */ /* Non-standard call to get the data nicely buffered. */
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
pcap_stream_err("I_PUSH bufmod", errno, ebuf); pcap_stream_err("I_PUSH bufmod", errno, p->errbuf);
retv = -1; retv = -1;
} }
ss = snaplen; ss = snaplen;
if (ss > 0 && if (ss > 0 &&
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
pcap_stream_err("SBIOCSSNAP", errno, ebuf); pcap_stream_err("SBIOCSSNAP", errno, p->errbuf);
retv = -1; retv = -1;
} }
@ -286,7 +286,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
to.tv_sec = timeout / 1000; to.tv_sec = timeout / 1000;
to.tv_usec = (timeout * 1000) % 1000000; to.tv_usec = (timeout * 1000) % 1000000;
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
pcap_stream_err("SBIOCSTIME", errno, ebuf); pcap_stream_err("SBIOCSTIME", errno, p->errbuf);
retv = -1; retv = -1;
} }
} }
@ -295,7 +295,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
chunksize = CHUNKSIZE; chunksize = CHUNKSIZE;
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize) if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
!= 0) { != 0) {
pcap_stream_err("SBIOCSCHUNKP", errno, ebuf); pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf);
retv = -1; retv = -1;
} }
@ -307,12 +307,12 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
* Allocate data buffer. Returns -1 if memory allocation fails, else 0. * Allocate data buffer. Returns -1 if memory allocation fails, else 0.
*/ */
int int
pcap_alloc_databuf(pcap_t *p, char *ebuf) pcap_alloc_databuf(pcap_t *p)
{ {
p->bufsize = PKTBUFSIZE; p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset); p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) { if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }

View File

@ -1,5 +1,5 @@
/* /*
* @(#) $Header: /tcpdump/master/libpcap/dlpisubs.h,v 1.1 2008-03-13 18:13:57 guy Exp $ * @(#) $Header: /tcpdump/master/libpcap/dlpisubs.h,v 1.2 2008-04-04 19:37:45 guy Exp $
*/ */
#ifndef dlpisubs_h #ifndef dlpisubs_h
@ -14,11 +14,11 @@ extern "C" {
*/ */
int pcap_stats_dlpi(pcap_t *, struct pcap_stat *); int pcap_stats_dlpi(pcap_t *, struct pcap_stat *);
int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int); int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int);
int pcap_process_mactype(pcap_t *, u_int, char *); int pcap_process_mactype(pcap_t *, u_int);
#ifdef HAVE_SYS_BUFMOD_H #ifdef HAVE_SYS_BUFMOD_H
int pcap_conf_bufmod(pcap_t *, int, int, char *); int pcap_conf_bufmod(pcap_t *, int, int);
#endif #endif
int pcap_alloc_databuf(pcap_t *, char *); int pcap_alloc_databuf(pcap_t *);
int strioctl(int, int, int, char *); int strioctl(int, int, int, char *);
#ifdef __cplusplus #ifdef __cplusplus

1283
pcap-bpf.c

File diff suppressed because it is too large Load Diff

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.10 2008-02-14 23:27:42 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.11 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -64,6 +64,7 @@ static const char rcsid[] _U_ =
#define BT_CTRL_SIZE 128 #define BT_CTRL_SIZE 128
/* forward declaration */ /* forward declaration */
static int bt_activate(pcap_t *);
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *); static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int bt_inject_linux(pcap_t *, const void *, size_t); static int bt_inject_linux(pcap_t *, const void *, size_t);
static int bt_setfilter_linux(pcap_t *, struct bpf_program *); static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
@ -134,39 +135,41 @@ done:
return ret; return ret;
} }
pcap_t* pcap_t *
bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg) bt_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = bt_activate;
return (p);
}
static int
bt_activate(pcap_t* handle)
{ {
struct sockaddr_hci addr; struct sockaddr_hci addr;
int opt; int opt;
pcap_t *handle;
int dev_id; int dev_id;
struct hci_filter flt; struct hci_filter flt;
/* get bt interface id */ /* get bt interface id */
if (sscanf(bus, BT_IFACE"%d", &dev_id) != 1) if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
{ {
snprintf(errmsg, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth bus index from %s", bus); "Can't get Bluetooth device index from %s",
return NULL; handle->opt.source);
return -1;
} }
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */ /* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle)); handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->bufsize = snaplen+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->offset = BT_CTRL_SIZE; handle->offset = BT_CTRL_SIZE;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR; handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
handle->read_op = bt_read_linux; handle->read_op = bt_read_linux;
handle->inject_op = bt_inject_linux; handle->inject_op = bt_inject_linux;
handle->setfilter_op = bt_setfilter_linux; handle->setfilter_op = bt_setfilter_linux;
@ -181,46 +184,41 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
/* Create HCI socket */ /* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) { if (handle->fd < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
errno, strerror(errno)); errno, strerror(errno));
free(handle); return -1;
return NULL;
} }
handle->buffer = malloc(handle->bufsize); handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) { if (!handle->buffer) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno)); pcap_strerror(errno));
pcap_close(handle); goto close_fail;
return NULL;
} }
opt = 1; opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
errno, strerror(errno)); errno, strerror(errno));
pcap_close(handle); goto close_fail;
return NULL;
} }
opt = 1; opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
errno, strerror(errno)); errno, strerror(errno));
pcap_close(handle); goto close_fail;
return NULL;
} }
/* Setup filter, do not call hci function to avoid dependence on /* Setup filter, do not call hci function to avoid dependence on
* external libs */ * external libs */
memset(&flt, 0, sizeof(flt)); memset(&flt, 0, sizeof(flt));
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask)); memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask)); memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
errno, strerror(errno)); errno, strerror(errno));
pcap_close(handle); goto close_fail;
return NULL;
} }
@ -228,14 +226,16 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
addr.hci_family = AF_BLUETOOTH; addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handle->md.ifindex; addr.hci_dev = handle->md.ifindex;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s", snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
handle->md.ifindex, errno, strerror(errno)); handle->md.ifindex, errno, strerror(errno));
pcap_close(handle); goto close_fail;
return NULL;
} }
handle->selectable_fd = handle->fd; handle->selectable_fd = handle->fd;
return 0;
return handle;
close_fail:
close(handle->fd);
return -1;
} }
static int static int

View File

@ -30,11 +30,11 @@
* Bluetooth sniffing API implementation for Linux platform * Bluetooth sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it> * By Paolo Abeni <paolo.abeni@email.it>
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.h,v 1.4 2007-09-14 01:55:49 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.h,v 1.5 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
/* /*
* Prototypes for Bluetooth-related functions * Prototypes for Bluetooth-related functions
*/ */
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str); int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t* bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg); pcap_t *bt_create(const char *device, char *ebuf);

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.36 2008-02-02 20:42:35 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.37 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -87,7 +87,7 @@ static const unsigned short endian_test_word = 0x0100;
/* This code is required when compiling for a DAG device only. */ /* This code is required when compiling for a DAG device only. */
/* Replace dag function names with pcap equivalent. */ /* Replace dag function names with pcap equivalent. */
#define dag_open_live pcap_open_live #define dag_create pcap_create
#define dag_platform_finddevs pcap_platform_finddevs #define dag_platform_finddevs pcap_platform_finddevs
#endif /* DAG_ONLY */ #endif /* DAG_ONLY */
@ -564,21 +564,20 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
* not supported in hardware. * not supported in hardware.
* *
* snaplen is now also ignored, until we get per-stream slen support. Set * snaplen is now also ignored, until we get per-stream slen support. Set
* slen with approprite DAG tool BEFORE pcap_open_live(). * slen with approprite DAG tool BEFORE pcap_activate().
* *
* See also pcap(3). * See also pcap(3).
*/ */
pcap_t * static int dag_activate(pcap_t* handle)
dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{ {
#if 0 #if 0
char conf[30]; /* dag configure string */ char conf[30]; /* dag configure string */
#endif #endif
pcap_t *handle;
char *s; char *s;
int n; int n;
daginf_t* daginf; daginf_t* daginf;
char * newDev = NULL; char * newDev = NULL;
char * device = handle->opt.source;
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
uint32_t mindata; uint32_t mindata;
struct timeval maxwait; struct timeval maxwait;
@ -586,44 +585,35 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
#endif #endif
if (device == NULL) { if (device == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
return NULL; return -1;
} }
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */ /* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
newDev = (char *)malloc(strlen(device) + 16); newDev = (char *)malloc(strlen(device) + 16);
if (newDev == NULL) { if (newDev == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
goto fail; goto fail;
} }
/* Parse input name to get dag device and stream number if provided */ /* Parse input name to get dag device and stream number if provided */
if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) { if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
goto fail; goto fail;
} }
device = newDev; device = newDev;
if (handle->md.dag_stream%2) { if (handle->md.dag_stream%2) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n"); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
goto fail; goto fail;
} }
#else #else
if (strncmp(device, "/dev/", 5) != 0) { if (strncmp(device, "/dev/", 5) != 0) {
newDev = (char *)malloc(strlen(device) + 5); newDev = (char *)malloc(strlen(device) + 5);
if (newDev == NULL) { if (newDev == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
goto fail; goto fail;
} }
strcpy(newDev, "/dev/"); strcpy(newDev, "/dev/");
@ -634,14 +624,14 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
/* setup device parameters */ /* setup device parameters */
if((handle->fd = dag_open((char *)device)) < 0) { if((handle->fd = dag_open((char *)device)) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
goto fail; goto fail;
} }
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
/* Open requested stream. Can fail if already locked or on error */ /* Open requested stream. Can fail if already locked or on error */
if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) { if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
goto failclose; goto failclose;
} }
@ -650,7 +640,7 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
*/ */
if (dag_get_stream_poll(handle->fd, handle->md.dag_stream, if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
&mindata, &maxwait, &poll) < 0) { &mindata, &maxwait, &poll) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
goto faildetach; goto faildetach;
} }
@ -668,13 +658,13 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
if (dag_set_stream_poll(handle->fd, handle->md.dag_stream, if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
mindata, &maxwait, &poll) < 0) { mindata, &maxwait, &poll) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
goto faildetach; goto faildetach;
} }
#else #else
if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) { if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
goto failclose; goto failclose;
} }
@ -688,28 +678,28 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
/* set the card snap length to the specified snaplen parameter */ /* set the card snap length to the specified snaplen parameter */
/* This is a really bad idea, as different cards have different /* This is a really bad idea, as different cards have different
* valid slen ranges. Should fix in Config API. */ * valid slen ranges. Should fix in Config API. */
if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) { if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
snaplen = MAX_DAG_SNAPLEN; handle->snapshot = MAX_DAG_SNAPLEN;
} else if (snaplen < MIN_DAG_SNAPLEN) { } else if (snaplen < MIN_DAG_SNAPLEN) {
snaplen = MIN_DAG_SNAPLEN; handle->snapshot = MIN_DAG_SNAPLEN;
} }
/* snap len has to be a multiple of 4 */ /* snap len has to be a multiple of 4 */
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3); snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
if(dag_configure(handle->fd, conf) < 0) { if(dag_configure(handle->fd, conf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
goto faildetach; goto faildetach;
} }
#endif #endif
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) { if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
goto faildetach; goto faildetach;
} }
#else #else
if(dag_start(handle->fd) < 0) { if(dag_start(handle->fd) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
goto failclose; goto failclose;
} }
#endif /* HAVE_DAG_STREAMS_API */ #endif /* HAVE_DAG_STREAMS_API */
@ -745,7 +735,7 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
handle->md.dag_fcs_bits = n; handle->md.dag_fcs_bits = n;
} else { } else {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n); "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
goto failstop; goto failstop;
} }
} }
@ -763,19 +753,16 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
} }
} }
handle->snapshot = snaplen; handle->md.dag_timeout = handle->md.timeout;
handle->md.dag_timeout = to_ms;
handle->linktype = -1; handle->linktype = -1;
if (dag_get_datalink(handle) < 0) { if (dag_get_datalink(handle) < 0)
strcpy(ebuf, handle->errbuf);
goto failstop; goto failstop;
}
handle->bufsize = 0; handle->bufsize = 0;
if (new_pcap_dag(handle) < 0) { if (new_pcap_dag(handle) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno)); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
goto failstop; goto failstop;
} }
@ -799,51 +786,46 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
handle->close_op = dag_platform_close; handle->close_op = dag_platform_close;
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 handle; return 0;
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
failstop: failstop:
if (handle != NULL) { if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0)
if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0) fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
} }
faildetach: faildetach:
if (handle != NULL) { if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0) fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno)); #else
}
#else
failstop: failstop:
if (handle != NULL) { if (dag_stop(handle->fd) < 0)
if (dag_stop(handle->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 */
failclose: failclose:
if (handle != NULL) { if (dag_close(handle->fd) < 0)
if (dag_close(handle->fd) < 0) fprintf(stderr,"dag_close: %s\n", strerror(errno));
fprintf(stderr,"dag_close: %s\n", strerror(errno)); delete_pcap_dag(handle);
}
if (handle != NULL)
delete_pcap_dag(handle);
fail: fail:
if (newDev != NULL) { if (newDev != NULL) {
free((char *)newDev); free((char *)newDev);
} }
if (handle != NULL) {
/*
* Get rid of any link-layer type list we allocated.
*/
if (handle->dlt_list != NULL) {
free(handle->dlt_list);
}
free(handle);
}
return NULL; return PCAP_ERROR;
}
pcap_t *dag_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
p->activate_op = dag_activate;
return p;
} }
static int static int

View File

@ -7,10 +7,10 @@
* *
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.6 2007-11-09 00:55:53 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.7 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); pcap_t *dag_create(const char *, char *);
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf); int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
#ifndef TYPE_AAL5 #ifndef TYPE_AAL5

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.120 2008-03-13 18:13:57 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.121 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -321,12 +321,10 @@ pcap_close_dlpi(pcap_t *p)
close(p->send_fd); close(p->send_fd);
} }
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_dlpi(pcap_t *p)
char *ebuf)
{ {
register char *cp; register char *cp;
register pcap_t *p;
int ppa; int ppa;
#ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS
int isatm = 0; int isatm = 0;
@ -345,12 +343,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char dname2[100]; char dname2[100];
#endif #endif
p = (pcap_t *)malloc(sizeof(*p)); if (p->opt.rfmon) {
if (p == NULL) { /*
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); * No monitor mode on any platforms that support DLPI.
return (NULL); */
return (PCAP_ERROR_RFMON_NOTSUP);
} }
memset(p, 0, sizeof(*p));
p->fd = -1; /* indicate that it hasn't been opened yet */ p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1; p->send_fd = -1;
@ -358,9 +357,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* /*
** Remove any "/dev/" on the front of the device. ** Remove any "/dev/" on the front of the device.
*/ */
cp = strrchr(device, '/'); cp = strrchr(p->opt.source, '/');
if (cp == NULL) if (cp == NULL)
strlcpy(dname, device, sizeof(dname)); strlcpy(dname, p->opt.source, sizeof(dname));
else else
strlcpy(dname, cp + 1, sizeof(dname)); strlcpy(dname, cp + 1, sizeof(dname));
@ -368,7 +367,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* Split the device name into a device type name and a unit number; * Split the device name into a device type name and a unit number;
* chop off the unit number, so "dname" is just a device type name. * chop off the unit number, so "dname" is just a device type name.
*/ */
cp = split_dname(dname, &ppa, ebuf); cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) if (cp == NULL)
goto bad; goto bad;
*cp = '\0'; *cp = '\0';
@ -386,7 +385,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
*/ */
cp = "/dev/dlpi"; cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) { if ((p->fd = open(cp, O_RDWR)) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno)); "%s: %s", cp, pcap_strerror(errno));
goto bad; goto bad;
} }
@ -410,7 +409,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* Get a table of all PPAs for that device, and search that * Get a table of all PPAs for that device, and search that
* table for the specified device type name and unit number. * table for the specified device type name and unit number.
*/ */
ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) if (ppa < 0)
goto bad; goto bad;
#else #else
@ -420,17 +419,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* otherwise, concatenate the device directory name and the * otherwise, concatenate the device directory name and the
* device name. * device name.
*/ */
if (*device == '/') if (*p->opt.source == '/')
strlcpy(dname, device, sizeof(dname)); strlcpy(dname, p->opt.source, sizeof(dname));
else else
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
device); p->opt.source);
/* /*
* Get the unit number, and a pointer to the end of the device * Get the unit number, and a pointer to the end of the device
* type name. * type name.
*/ */
cp = split_dname(dname, &ppa, ebuf); cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) if (cp == NULL)
goto bad; goto bad;
@ -444,7 +443,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try device without unit number */ /* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) { if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) { if (errno != ENOENT) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -467,10 +466,10 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* for the loopback interface is just a * for the loopback interface is just a
* symptom of that inability. * symptom of that inability.
*/ */
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", device); "%s: No DLPI device found", device);
} else { } else {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno)); dname2, pcap_strerror(errno));
} }
goto bad; goto bad;
@ -480,13 +479,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
} }
#endif #endif
p->snapshot = snaplen;
/* /*
** Attach if "style 2" provider ** Attach if "style 2" provider
*/ */
if (dlinforeq(p->fd, ebuf) < 0 || if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0) dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad; goto bad;
infop = &((union DL_primitives *)buf)->info_ack; infop = &((union DL_primitives *)buf)->info_ack;
#ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS
@ -494,11 +491,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
isatm = 1; isatm = 1;
#endif #endif
if (infop->dl_provider_style == DL_STYLE2) { if (infop->dl_provider_style == DL_STYLE2) {
if (dl_doattach(p->fd, ppa, ebuf) < 0) if (dl_doattach(p->fd, ppa, p->errbuf) < 0)
goto bad; goto bad;
#ifdef DL_HP_RAWDLS #ifdef DL_HP_RAWDLS
if (p->send_fd >= 0) { if (p->send_fd >= 0) {
if (dl_doattach(p->send_fd, ppa, ebuf) < 0) if (dl_doattach(p->send_fd, ppa, p->errbuf) < 0)
goto bad; goto bad;
} }
#endif #endif
@ -535,15 +532,15 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** assume the SAP value in a DLPI bind is an LLC SAP for network ** assume the SAP value in a DLPI bind is an LLC SAP for network
** types that use 802.2 LLC). ** types that use 802.2 LLC).
*/ */
if ((dlbindreq(p->fd, 1537, ebuf) < 0 && if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
dlbindreq(p->fd, 2, ebuf) < 0) || dlbindreq(p->fd, 2, p->errbuf) < 0) ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0) dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad; goto bad;
#elif defined(DL_HP_RAWDLS) #elif defined(DL_HP_RAWDLS)
/* /*
** HP-UX 10.0x and 10.1x. ** HP-UX 10.0x and 10.1x.
*/ */
if (dl_dohpuxbind(p->fd, ebuf) < 0) if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
goto bad; goto bad;
if (p->send_fd >= 0) { if (p->send_fd >= 0) {
/* /*
@ -551,7 +548,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** set it to -1, so that you can't send but can ** set it to -1, so that you can't send but can
** still receive? ** still receive?
*/ */
if (dl_dohpuxbind(p->send_fd, ebuf) < 0) if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad; goto bad;
} }
#else /* neither AIX nor HP-UX */ #else /* neither AIX nor HP-UX */
@ -559,8 +556,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other ** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
** OS using DLPI. ** OS using DLPI.
**/ **/
if (dlbindreq(p->fd, 0, ebuf) < 0 || if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0) dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad; goto bad;
#endif /* AIX vs. HP-UX vs. other */ #endif /* AIX vs. HP-UX vs. other */
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */ #endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
@ -574,18 +571,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** help, and may break things. ** help, and may break things.
*/ */
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) { if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_strerror(errno)); "A_PROMISCON_REQ: %s", pcap_strerror(errno));
goto bad; goto bad;
} }
} else } else
#endif #endif
if (promisc) { if (p->opt.promisc) {
/* /*
** Enable promiscuous (not necessary on send FD) ** Enable promiscuous (not necessary on send FD)
*/ */
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 || if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0) dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
goto bad; goto bad;
/* /*
@ -594,10 +591,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** HP-UX or SINIX) (Not necessary on send FD) ** HP-UX or SINIX) (Not necessary on send FD)
*/ */
#if !defined(__hpux) && !defined(sinix) #if !defined(__hpux) && !defined(sinix)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 || if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0) dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
fprintf(stderr, fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf); "WARNING: DL_PROMISC_MULTI failed (%s)\n",
p->errbuf);
#endif #endif
} }
/* /*
@ -608,17 +606,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef sinix #ifndef sinix
if ( if (
#ifdef __hpux #ifdef __hpux
!promisc && !p->opt.promisc &&
#endif #endif
#ifdef HAVE_SOLARIS #ifdef HAVE_SOLARIS
!isatm && !isatm &&
#endif #endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 || (dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) { dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */ /* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (promisc) if (p->opt.promisc)
fprintf(stderr, fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf); "WARNING: DL_PROMISC_SAP failed (%s)\n", p->errbuf);
else else
goto bad; goto bad;
} }
@ -629,7 +627,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** promiscuous options. ** promiscuous options.
*/ */
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER) #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
if (dl_dohpuxbind(p->fd, ebuf) < 0) if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
goto bad; goto bad;
/* /*
** We don't set promiscuous mode on the send FD, but we'll defer ** We don't set promiscuous mode on the send FD, but we'll defer
@ -642,7 +640,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** set it to -1, so that you can't send but can ** set it to -1, so that you can't send but can
** still receive? ** still receive?
*/ */
if (dl_dohpuxbind(p->send_fd, ebuf) < 0) if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad; goto bad;
} }
#endif #endif
@ -652,12 +650,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** XXX - get SAP length and address length as well, for use ** XXX - get SAP length and address length as well, for use
** when sending packets. ** when sending packets.
*/ */
if (dlinforeq(p->fd, ebuf) < 0 || if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0) dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad; goto bad;
infop = &((union DL_primitives *)buf)->info_ack; infop = &((union DL_primitives *)buf)->info_ack;
if (pcap_process_mactype(p, infop->dl_mac_type, ebuf) != 0) if (pcap_process_mactype(p, infop->dl_mac_type, p->errbuf) != 0)
goto bad; goto bad;
#ifdef DLIOCRAW #ifdef DLIOCRAW
@ -666,13 +664,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** header. ** header.
*/ */
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
#endif #endif
ss = snaplen; ss = p->snapshot;
/* /*
** There is a bug in bufmod(7). When dealing with messages of ** There is a bug in bufmod(7). When dealing with messages of
@ -695,7 +693,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifdef HAVE_SYS_BUFMOD_H #ifdef HAVE_SYS_BUFMOD_H
/* Push and configure bufmod. */ /* Push and configure bufmod. */
if (pcap_conf_bufmod(p, ss, to_ms, ebuf) != 0) if (pcap_conf_bufmod(p, ss, p->md.timeout) != 0)
goto bad; goto bad;
#endif #endif
@ -703,13 +701,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** As the last operation flush the read side. ** As the last operation flush the read side.
*/ */
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
/* Allocate data buffer. */ /* Allocate data buffer. */
if (pcap_alloc_databuf(p, ebuf) != 0) if (pcap_alloc_databuf(p) != 0)
goto bad; goto bad;
/* /*
@ -728,19 +726,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->stats_op = pcap_stats_dlpi; p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi; p->close_op = pcap_close_dlpi;
return (p); return (0);
bad: bad:
if (p->fd >= 0) if (p->fd >= 0)
close(p->fd); close(p->fd);
if (p->send_fd >= 0) if (p->send_fd >= 0)
close(p->send_fd); close(p->send_fd);
/* return (PCAP_ERROR);
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
} }
/* /*
@ -1649,3 +1641,16 @@ dlpi_kread(register int fd, register off_t addr,
return (cc); return (cc);
} }
#endif #endif
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_dlpi;
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.3 2007-12-05 23:37:26 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
#include <stdio.h> #include <stdio.h>
@ -97,6 +97,7 @@ static volatile BOOL exc_occured = 0;
static struct device *handle_to_device [20]; static struct device *handle_to_device [20];
static void pcap_activate_dos (pcap_t *p);
static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
u_char *data); u_char *data);
static void pcap_close_dos (pcap_t *p); static void pcap_close_dos (pcap_t *p);
@ -142,59 +143,68 @@ static struct device *get_device (int fd)
return handle_to_device [fd-1]; return handle_to_device [fd-1];
} }
pcap_t *pcap_create (const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_dos;
return (p);
}
/* /*
* Open MAC-driver with name 'device_name' for live capture of * Open MAC-driver with name 'device_name' for live capture of
* network packets. * network packets.
*/ */
pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc, static int pcap_activate_dos (pcap_t *pcap)
int timeout_ms, char *errbuf)
{ {
struct pcap *pcap; int err = 0;
if (snaplen < ETH_MIN) if (p->opt.rfmon) {
snaplen = ETH_MIN; /*
* No monitor mode on DOS.
if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */ */
snaplen = ETH_MAX; return (PCAP_ERROR_RFMON_NOTSUP);
pcap = calloc (sizeof(*pcap), 1);
if (!pcap)
{
strcpy (errbuf, "Not enough memory (pcap)");
return (NULL);
} }
pcap->snapshot = max (ETH_MIN+8, snaplen); if (pcap->snapshot < ETH_MIN+8)
pcap->snapshot = ETH_MIN+8;
if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */
pcap->snapshot = ETH_MAX;
pcap->linktype = DLT_EN10MB; /* !! */ pcap->linktype = DLT_EN10MB; /* !! */
pcap->inter_packet_wait = timeout_ms;
pcap->close_op = pcap_close_dos; pcap->close_op = pcap_close_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;
pcap->setfilter_op = pcap_setfilter_dos; pcap->setfilter_op = pcap_setfilter_dos;
pcap->setdirection_op = NULL; /* Not implemented.*/ pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count; pcap->fd = ++ref_count;
if (pcap->fd == 1) /* first time we're called */ if (pcap->fd == 1) /* first time we're called */
{ {
if (!init_watt32(pcap, device_name, errbuf) || if (!init_watt32(pcap, pcap->md.device, pcap->errbuf) ||
!first_init(device_name, errbuf, promisc)) !first_init(pcap->md.device, pcap->errbuf, pcap->opt.promisc))
{ {
free (pcap); free (pcap);
return (NULL); return (PCAP_ERROR);
} }
atexit (close_driver); atexit (close_driver);
} }
else if (stricmp(active_dev->name,device_name)) else if (stricmp(active_dev->name,pcap->md.device))
{ {
snprintf (errbuf, PCAP_ERRBUF_SIZE, snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously " "Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, device_name); "(`%s' vs. `%s')", active_dev->name, pcap->md.device);
free (pcap); free (pcap);
pcap = NULL; err = PCAP_ERROR;
} }
handle_to_device [pcap->fd-1] = active_dev; handle_to_device [pcap->fd-1] = active_dev;
return (pcap); return (err);
} }
/* /*
@ -209,10 +219,10 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
BYTE *rx_buf; BYTE *rx_buf;
int rx_len = 0; int rx_len = 0;
if (p->inter_packet_wait > 0) if (p->md.timeout > 0)
{ {
gettimeofday2 (&now, NULL); gettimeofday2 (&now, NULL);
expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait; expiry.tv_usec = now.tv_usec + 1000UL * p->md.timeout;
expiry.tv_sec = now.tv_sec; expiry.tv_sec = now.tv_sec;
while (expiry.tv_usec >= 1000000L) while (expiry.tv_usec >= 1000000L)
{ {
@ -284,7 +294,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
/* If not to wait for a packet or pcap_close() called from /* If not to wait for a packet or pcap_close() called from
* e.g. SIGINT handler, exit loop now. * e.g. SIGINT handler, exit loop now.
*/ */
if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0) if (p->md.timeout <= 0 || (volatile int)p->fd <= 0)
break; break;
gettimeofday2 (&now, NULL); gettimeofday2 (&now, NULL);
@ -476,7 +486,7 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
{ {
if (!_watt_is_init) if (!_watt_is_init)
{ {
strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be " strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
"called first"); "called first");
return (-1); return (-1);
} }
@ -587,7 +597,7 @@ void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
if (p) if (p)
{ {
p->wait_proc = yield; p->wait_proc = yield;
p->inter_packet_wait = wait; p->md.timeout = wait;
} }
} }
@ -739,7 +749,7 @@ static void exc_handler (int sig)
/* /*
* Open the pcap device for the first client calling pcap_open_live() * Open the pcap device for the first client calling pcap_activate()
*/ */
static int first_init (const char *name, char *ebuf, int promisc) static int first_init (const char *name, char *ebuf, int promisc)
{ {

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.88 2008-03-13 18:13:57 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.89 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
#ifndef pcap_int_h #ifndef pcap_int_h
@ -96,6 +96,9 @@ typedef enum {
MAYBE_SWAPPED MAYBE_SWAPPED
} swapped_type_t; } swapped_type_t;
/*
* Used when reading a savefile.
*/
struct pcap_sf { struct pcap_sf {
FILE *rfile; FILE *rfile;
int swapped; int swapped;
@ -106,6 +109,9 @@ struct pcap_sf {
u_char *base; u_char *base;
}; };
/*
* Used when doing a live capture.
*/
struct pcap_md { struct pcap_md {
struct pcap_stat stat; struct pcap_stat stat;
/*XXX*/ /*XXX*/
@ -116,18 +122,17 @@ struct pcap_md {
long TotMissed; /* missed by i/f during this run */ long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */ long OrigMissed; /* missed by i/f before this run */
char *device; /* device name */ char *device; /* device name */
int timeout; /* timeout for buffering */
int must_clear; /* stuff we must clear when we close */
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
#ifdef linux #ifdef linux
int sock_packet; /* using Linux 2.0 compatible interface */ int sock_packet; /* using Linux 2.0 compatible interface */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */ int ifindex; /* interface index of device we're bound to */
int lo_ifindex; /* interface index of the loopback device */ int lo_ifindex; /* interface index of the loopback device */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
u_int packets_read; /* count of packets read with recvfrom() */ u_int packets_read; /* count of packets read with recvfrom() */
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
#endif /* linux */ #endif /* linux */
#if defined(linux) || defined(SITA)
int timeout; /* timeout specified to pcap_open_live */
int clear_promisc; /* must clear promiscuous mode when we close */
#endif /* linux || SITA */
#ifdef HAVE_DAG_API #ifdef HAVE_DAG_API
#ifdef HAVE_DAG_STREAMS_API #ifdef HAVE_DAG_STREAMS_API
@ -147,6 +152,19 @@ struct pcap_md {
#endif /* HAVE_DAG_API */ #endif /* HAVE_DAG_API */
}; };
/*
* Stuff to clear when we close.
*/
#define MUST_CLEAR_PROMISC 0x00000001 /* promiscuous mode */
#define MUST_CLEAR_RFMON 0x00000002 /* rfmon (monitor) mode */
struct pcap_opt {
int buffer_size;
char *source;
int promisc;
int rfmon;
};
/* /*
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
* Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything * Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
@ -160,11 +178,27 @@ struct pcap_md {
#define PCAP_FDDIPAD 3 #define PCAP_FDDIPAD 3
#endif #endif
typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
typedef int (*getnonblock_op_t)(pcap_t *, char *);
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef WIN32
typedef int (*setbuff_op_t)(pcap_t *, int);
typedef int (*setmode_op_t)(pcap_t *, int);
typedef int (*setmintocopy_op_t)(pcap_t *, int);
#endif
typedef void (*close_op_t)(pcap_t *);
struct pcap { struct pcap {
#ifdef WIN32 #ifdef WIN32
ADAPTER *adapter; ADAPTER *adapter;
LPPACKET Packet; LPPACKET Packet;
int timeout;
int nonblock; int nonblock;
#else #else
int fd; int fd;
@ -180,6 +214,8 @@ struct pcap {
int linktype_ext; /* Extended information stored in the linktype field of a file */ int linktype_ext; /* Extended information stored in the linktype field of a file */
int tzoff; /* timezone offset */ int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */ int offset; /* offset for proper alignment */
int activated; /* true if the capture is really started */
int oldstyle; /* if we're opening with pcap_open_live() */
int break_loop; /* flag set to force break from packet-reading loop */ int break_loop; /* flag set to force break from packet-reading loop */
@ -188,12 +224,12 @@ struct pcap {
#endif #endif
#ifdef MSDOS #ifdef MSDOS
int inter_packet_wait; /* offline: wait between packets */
void (*wait_proc)(void); /* call proc while waiting */ void (*wait_proc)(void); /* call proc while waiting */
#endif #endif
struct pcap_sf sf; struct pcap_sf sf;
struct pcap_md md; struct pcap_md md;
struct pcap_opt opt;
/* /*
* Read buffer. * Read buffer.
@ -214,30 +250,27 @@ struct pcap {
/* /*
* Methods. * Methods.
*/ */
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *); activate_op_t activate_op;
int (*inject_op)(pcap_t *, const void *, size_t); can_set_rfmon_op_t can_set_rfmon_op;
int (*setfilter_op)(pcap_t *, struct bpf_program *); read_op_t read_op;
int (*setdirection_op)(pcap_t *, pcap_direction_t); inject_op_t inject_op;
int (*set_datalink_op)(pcap_t *, int); setfilter_op_t setfilter_op;
int (*getnonblock_op)(pcap_t *, char *); setdirection_op_t setdirection_op;
int (*setnonblock_op)(pcap_t *, int, char *); set_datalink_op_t set_datalink_op;
int (*stats_op)(pcap_t *, struct pcap_stat *); getnonblock_op_t getnonblock_op;
#ifdef WIN32 setnonblock_op_t setnonblock_op;
/* stats_op_t stats_op;
* Win32-only; given the way the buffer size is set with BPF,
* to make this cross-platform we'll have to set the buffer
* size at open time.
*/
int (*setbuff_op)(pcap_t *, int);
#ifdef WIN32
/* /*
* These are, at least currently, specific to the Win32 NPF * These are, at least currently, specific to the Win32 NPF
* driver. * driver.
*/ */
int (*setmode_op)(pcap_t *, int); setbuff_op_t setbuff_op;
int (*setmintocopy_op)(pcap_t *, int); setmode_op_t setmode_op;
setmintocopy_op_t setmintocopy_op;
#endif #endif
void (*close_op)(pcap_t *); close_op_t close_op;
/* /*
* Placeholder for filter code if bpf not in kernel. * Placeholder for filter code if bpf not in kernel.
@ -354,7 +387,13 @@ int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *); int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif #endif
pcap_t *pcap_create_common(const char *, char *);
int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *);
void pcap_remove_from_pcaps_to_close(pcap_t *);
void pcap_close_common(pcap_t *); void pcap_close_common(pcap_t *);
int pcap_not_initialized(pcap_t *);
int pcap_check_activated(pcap_t *);
/* /*
* Internal interfaces for "pcap_findalldevs()". * Internal interfaces for "pcap_findalldevs()".

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.3 2008-03-15 04:26:14 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -96,57 +96,54 @@ list_interfaces(const char *linkname, void *arg)
return (B_FALSE); return (B_FALSE);
} }
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_libdlpi(pcap_t *p)
char *ebuf)
{ {
int retv; int retv;
pcap_t *p;
dlpi_handle_t dh; dlpi_handle_t dh;
dlpi_info_t dlinfo; dlpi_info_t dlinfo;
if ((p = (pcap_t *)malloc(sizeof(*p))) == NULL) { if (p->opt.rfmon) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); /*
return (NULL); * No monitor mode on any platforms that support DLPI.
*/
return (PCAP_ERROR_RFMON_NOTSUP);
} }
memset(p, 0, sizeof(*p));
p->fd = -1; /* indicate that it hasn't been opened yet */ p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
/* /*
* 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
* passive mode. See dlpi(7P) for details. * passive mode. See dlpi(7P) for details.
*/ */
retv = dlpi_open(device, &dh, DLPI_RAW|DLPI_PASSIVE); retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
if (retv != DLPI_SUCCESS) { if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_open", retv, ebuf); pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, p->errbuf);
goto bad; goto bad;
} }
p->dlpi_hd = dh; p->dlpi_hd = dh;
p->snapshot = snaplen;
/* Bind with DLPI_ANY_SAP. */ /* Bind with DLPI_ANY_SAP. */
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) { if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_bind", retv, ebuf); pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
goto bad; goto bad;
} }
/* Enable promiscuous mode. */ /* Enable promiscuous mode. */
if (promisc) { if (p->opt.promisc) {
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS); retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
if (retv != DLPI_SUCCESS) { if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_promisc(PHYSICAL)", pcap_libdlpi_err(p->opt.source,
retv, ebuf); "dlpi_promisc(PHYSICAL)", retv, p->errbuf);
goto bad; goto bad;
} }
} else { } else {
/* Try to enable multicast. */ /* Try to enable multicast. */
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI); retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
if (retv != DLPI_SUCCESS) { if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_promisc(MULTI)", pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
retv, ebuf); retv, p->errbuf);
goto bad; goto bad;
} }
} }
@ -154,42 +151,42 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try to enable SAP promiscuity. */ /* Try to enable SAP promiscuity. */
if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) { if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) {
if (!promisc) { if (!promisc) {
pcap_libdlpi_err(device, "dlpi_promisc(SAP)", pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
retv, ebuf); retv, p->errbuf);
goto bad; goto bad;
} }
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */ /* Not fatal, since the DL_PROMISC_PHYS mode worked. */
fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on" fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
" %s:(%s)\n", device, dlpi_strerror(retv)); " %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
} }
/* Determine link type. */ /* Determine link type. */
if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) { if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_info", retv, ebuf); pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
goto bad; goto bad;
} }
if (pcap_process_mactype(p, dlinfo.di_mactype, ebuf) != 0) if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
goto bad; goto bad;
p->fd = dlpi_fd(p->dlpi_hd); p->fd = dlpi_fd(p->dlpi_hd);
/* Push and configure bufmod. */ /* Push and configure bufmod. */
if (pcap_conf_bufmod(p, snaplen, to_ms, ebuf) != 0) if (pcap_conf_bufmod(p, snaplen, p->md.timeout) != 0)
goto bad; goto bad;
/* /*
* Flush the read side. * Flush the read side.
*/ */
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
/* Allocate data buffer. */ /* Allocate data buffer. */
if (pcap_alloc_databuf(p, ebuf) != 0) if (pcap_alloc_databuf(p) != 0)
goto bad; goto bad;
/* /*
@ -208,14 +205,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->stats_op = pcap_stats_dlpi; p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_libdlpi; p->close_op = pcap_close_libdlpi;
return (p); return (0);
bad: bad:
/* Get rid of any link-layer type list we allocated. */ /* Get rid of any link-layer type list we allocated. */
if (p->dlt_list != NULL) if (p->dlt_list != NULL)
free(p->dlt_list); free(p->dlt_list);
pcap_close_libdlpi(p); dlpi_close(p->dlpi_hd);
free(p); return (PCAP_ERROR);
return (NULL);
} }
/* /*
@ -352,3 +348,16 @@ pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s", snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
func, linkname, dlpi_strerror(err)); func, linkname, dlpi_strerror(err));
} }
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_libdlpi;
return (p);
}

File diff suppressed because it is too large Load Diff

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.60 2008-02-02 20:58:18 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.61 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -237,51 +237,43 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0); return (0);
} }
static void static int
pcap_close_nit(pcap_t *p) pcap_activate_nit(pcap_t *p)
{
pcap_close_common(p);
if (p->device != NULL)
free(p->device);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{ {
int fd; int fd;
struct sockaddr_nit snit; struct sockaddr_nit snit;
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p)); if (p->opt.rfmon) {
if (p == NULL) { /*
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); * No monitor mode on SunOS 3.x or earlier (no
return (NULL); * Wi-Fi *devices* for the hardware that supported
* them!).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
} }
if (snaplen < 96) if (p->snapshot < 96)
/* /*
* NIT requires a snapshot length of at least 96. * NIT requires a snapshot length of at least 96.
*/ */
snaplen = 96; p->snapshot = 96;
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) { if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno)); "socket: %s", pcap_strerror(errno));
goto bad; goto bad;
} }
snit.snit_family = AF_NIT; snit.snit_family = AF_NIT;
(void)strncpy(snit.snit_ifname, device, NITIFSIZ); (void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
goto bad; goto bad;
} }
p->snapshot = snaplen; nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf);
nit_setflags(p->fd, promisc, to_ms, ebuf);
/* /*
* NIT supports only ethernets. * NIT supports only ethernets.
@ -291,17 +283,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = BUFSPACE; p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize); p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) { if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* We need the device name in order to send packets.
*/
p->device = strdup(device);
if (p->device == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
free(p->buffer);
goto bad; goto bad;
} }
@ -338,14 +320,26 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
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_nit; p->close_op = pcap_close_common;
return (p); return (0);
bad: bad:
if (fd >= 0) if (fd >= 0)
close(fd); close(fd);
free(p); return (PCAP_ERROR);
return (NULL); }
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_nit;
return (p);
} }
int int

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-null.c,v 1.21 2003-11-15 23:24:03 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.22 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -40,10 +40,9 @@ static const char rcsid[] _U_ =
static char nosup[] = "live packet capture not supported on this system"; static char nosup[] = "live packet capture not supported on this system";
pcap_t * pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate(pcap_t *p)
char *ebuf)
{ {
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE); (void)strlcpy(p->errbuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL); return (NULL);
} }

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.95 2007-12-05 23:37:26 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.96 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -291,23 +291,14 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
#define DLT_DOCSIS 143 #define DLT_DOCSIS 143
#endif #endif
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_pf(pcap_t *p)
char *ebuf)
{ {
pcap_t *p;
short enmode; short enmode;
int backlog = -1; /* request the most */ int backlog = -1; /* request the most */
struct enfilter Filter; struct enfilter Filter;
struct endevp devparams; struct endevp devparams;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"pcap_open_live: %s", pcap_strerror(errno));
return (0);
}
memset(p, 0, sizeof(*p));
/* /*
* Initially try a read/write open (to allow the inject * Initially try a read/write open (to allow the inject
* method to work). If that fails due to permission * method to work). If that fails due to permission
@ -327,21 +318,21 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* "const char *" as its first argument. That appears to be * "const char *" as its first argument. That appears to be
* the case, at least on Digital UNIX 4.0. * the case, at least on Digital UNIX 4.0.
*/ */
p->fd = pfopen(device, O_RDWR); p->fd = pfopen(p->opt.source, O_RDWR);
if (p->fd == -1 && errno == EACCES) if (p->fd == -1 && errno == EACCES)
p->fd = pfopen(device, O_RDONLY); p->fd = pfopen(p->opt.source, O_RDONLY);
if (p->fd < 0) { if (p->fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
your system may not be properly configured; see the packetfilter(4) man page\n", your system may not be properly configured; see the packetfilter(4) man page\n",
device, pcap_strerror(errno)); p->opt.source, pcap_strerror(errno));
goto bad; goto bad;
} }
p->md.OrigMissed = -1; p->md.OrigMissed = -1;
enmode = ENTSTAMP|ENBATCH|ENNONEXCL; enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
if (promisc) if (p->opt.promisc)
enmode |= ENPROMISC; enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -352,13 +343,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
#endif #endif
/* set the backlog */ /* set the backlog */
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
/* discover interface type */ /* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -440,8 +431,8 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
* framing", there's not much we can do, as that * framing", there's not much we can do, as that
* doesn't specify a particular type of header. * doesn't specify a particular type of header.
*/ */
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u", snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
devparams.end_dev_type); "unknown data-link type %u", devparams.end_dev_type);
goto bad; goto bad;
} }
/* set truncation */ /* set truncation */
@ -450,32 +441,31 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->fddipad = PCAP_FDDIPAD; p->fddipad = PCAP_FDDIPAD;
/* packetfilter includes the padding in the snapshot */ /* packetfilter includes the padding in the snapshot */
snaplen += PCAP_FDDIPAD; p->snapshot += PCAP_FDDIPAD;
} else } else
p->fddipad = 0; p->fddipad = 0;
#endif #endif
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
p->snapshot = snaplen;
/* accept all packets */ /* accept all packets */
memset(&Filter, 0, sizeof(Filter)); memset(&Filter, 0, sizeof(Filter));
Filter.enf_Priority = 37; /* anything > 2 */ Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */ Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
if (to_ms != 0) { if (p->md.timeout != 0) {
struct timeval timeout; struct timeval timeout;
timeout.tv_sec = to_ms / 1000; timeout.tv_sec = p->md.timeout / 1000;
timeout.tv_usec = (to_ms * 1000) % 1000000; timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -484,7 +474,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->bufsize = BUFSPACE; p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset); p->buffer = (u_char*)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) { if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad; goto bad;
} }
@ -503,17 +493,24 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->stats_op = pcap_stats_pf; p->stats_op = pcap_stats_pf;
p->close_op = pcap_close_common; p->close_op = pcap_close_common;
return (p); return (0);
bad: bad:
if (p->fd >= 0) if (p->fd >= 0)
close(p->fd); close(p->fd);
/* return (PCAP_ERROR);
* Get rid of any link-layer type list we allocated. }
*/
if (p->dlt_list != NULL) pcap_t *
free(p->dlt_list); pcap_create(const char *device, char *ebuf)
free(p); {
return (NULL); pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_pf;
return (p);
} }
int int

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.2 2005-06-21 01:03:03 guy Exp $"; "@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.3 2008-04-04 19:37:45 guy Exp $";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -50,8 +50,8 @@ static const char rcsid[] _U_ =
/* This code is required when compiling for a Septel device only. */ /* This code is required when compiling for a Septel device only. */
#include "pcap-septel.h" #include "pcap-septel.h"
/* Replace dag function names with pcap equivalent. */ /* Replace septel function names with pcap equivalent. */
#define septel_open_live pcap_open_live #define septel_create pcap_create
#define septel_platform_finddevs pcap_platform_finddevs #define septel_platform_finddevs pcap_platform_finddevs
#endif /* SEPTEL_ONLY */ #endif /* SEPTEL_ONLY */
@ -199,28 +199,14 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
} }
/* /*
* Get a handle for a live capture from the given Septel device. Always pass a NULL device * Activate a handle for a live capture from the given Septel device. Always pass a NULL device
* The promisc flag is ignored because Septel cards have built-in tracing. * The promisc flag is ignored because Septel cards have built-in tracing.
* The to_ms parameter is also ignored as it is * The timeout is also ignored as it is not supported in hardware.
* not supported in hardware.
* *
* See also pcap(3). * See also pcap(3).
*/ */
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) { static pcap_t *septel_activate(pcap_t* handle) {
pcap_t *handle; /* Initialize some components of the pcap structure. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->linktype = DLT_MTP2; handle->linktype = DLT_MTP2;
handle->bufsize = 0; handle->bufsize = 0;
@ -239,14 +225,18 @@ pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms
handle->stats_op = septel_stats; handle->stats_op = septel_stats;
handle->close_op = septel_platform_close; handle->close_op = septel_platform_close;
return handle; return 0;
}
fail: pcap_t *septel_create(const char *device, char *ebuf) {
if (handle != NULL) { pcap_t *p;
free(handle);
}
return NULL; p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
p->activate_op = septel_activate;
return p;
} }
static int septel_stats(pcap_t *p, struct pcap_stat *ps) { static int septel_stats(pcap_t *p, struct pcap_stat *ps) {

View File

@ -8,8 +8,8 @@
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
* (+961 3 485343); * (+961 3 485343);
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1 2005-06-20 21:27:10 guy Exp $ * @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.2 2008-04-04 19:37:45 guy Exp $
*/ */
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); pcap_t *septel_create(const char *device, char *ebuf);

View File

@ -917,25 +917,19 @@ static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback,
return 1; return 1;
} }
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) { static int pcap_activate_sita(pcap_t *handle) {
pcap_t *handle;
int fd; int fd;
/* Allocate a handle for this session. */ if (handle->opt.rfmon) {
/*
handle = malloc(sizeof(*handle)); * No monitor mode on SITA devices (they're not Wi-Fi
if (handle == NULL) { * devices).
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", */
pcap_strerror(errno)); return PCAP_ERROR_RFMON_NOTSUP;
return NULL;
} }
/* Initialize some components of the pcap structure. */ /* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->inject_op = pcap_inject_acn; handle->inject_op = pcap_inject_acn;
handle->setfilter_op = pcap_setfilter_acn; handle->setfilter_op = pcap_setfilter_acn;
handle->setdirection_op = pcap_setdirection_acn; handle->setdirection_op = pcap_setdirection_acn;
@ -946,12 +940,11 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
handle->read_op = pcap_read_acn; handle->read_op = pcap_read_acn;
handle->stats_op = pcap_stats_acn; handle->stats_op = pcap_stats_acn;
fd = acn_open_live(device, ebuf, &handle->linktype); fd = acn_open_live(handle->opt.source, handle->errbuf,
if (fd == -1) { &handle->linktype);
free(handle); if (fd == -1)
return NULL; return PCAP_ERROR;
} handle->md.clear_promisc = handle->md.promisc;
handle->md.clear_promisc = promisc;
handle->fd = fd; handle->fd = fd;
handle->bufsize = handle->snapshot; handle->bufsize = handle->snapshot;
@ -959,11 +952,10 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
handle->buffer = malloc(handle->bufsize + handle->offset); handle->buffer = malloc(handle->bufsize + handle->offset);
if (!handle->buffer) { if (!handle->buffer) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno)); "malloc: %s", pcap_strerror(errno));
pcap_close_acn(handle); pcap_close_acn(handle);
free(handle); return PCAP_ERROR;
return NULL;
} }
/* /*
@ -972,5 +964,16 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
*/ */
handle->selectable_fd = handle->fd; handle->selectable_fd = handle->fd;
return handle; return 0;
}
pcap_t *pcap_create(const char *device, char *ebuf) {
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_sita;
return (p);
} }

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.75 2008-02-02 20:58:18 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.76 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -260,30 +260,29 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0); return (0);
} }
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_snit(pcap_t *p)
char *ebuf)
{ {
struct strioctl si; /* struct for ioctl() */ struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request struct */ struct ifreq ifr; /* interface request struct */
int chunksize = CHUNKSIZE; int chunksize = CHUNKSIZE;
int fd; int fd;
static char dev[] = "/dev/nit"; static char dev[] = "/dev/nit";
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p)); if (p->opt.rfmon) {
if (p == NULL) { /*
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); * No monitor mode on SunOS 4.x (no Wi-Fi devices on
return (NULL); * hardware supported by SunOS 4.x).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
} }
if (snaplen < 96) if (p->snapshot < 96)
/* /*
* NIT requires a snapshot length of at least 96. * NIT requires a snapshot length of at least 96.
*/ */
snaplen = 96; p->snapshot = 96;
memset(p, 0, sizeof(*p));
/* /*
* Initially try a read/write open (to allow the inject * Initially try a read/write open (to allow the inject
* method to work). If that fails due to permission * method to work). If that fails due to permission
@ -302,19 +301,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
if (fd < 0 && errno == EACCES) if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY); p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) { if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev, snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
/* arrange to get discrete messages from the STREAM and use NIT_BUF */ /* arrange to get discrete messages from the STREAM and use NIT_BUF */
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) { if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
if (ioctl(fd, I_PUSH, "nbuf") < 0) { if (ioctl(fd, I_PUSH, "nbuf") < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -324,34 +323,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
si.ic_len = sizeof(chunksize); si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize; si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) < 0) { if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
/* request the interface */ /* request the interface */
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
si.ic_cmd = NIOCBIND; si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr); si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr; si.ic_dp = (char *)&ifr;
if (ioctl(fd, I_STR, (char *)&si) < 0) { if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
ifr.ifr_name, pcap_strerror(errno)); ifr.ifr_name, pcap_strerror(errno));
goto bad; goto bad;
} }
/* set the snapshot length */ /* set the snapshot length */
si.ic_cmd = NIOCSSNAP; si.ic_cmd = NIOCSSNAP;
si.ic_len = sizeof(snaplen); si.ic_len = sizeof(p->snapshot);
si.ic_dp = (char *)&snaplen; si.ic_dp = (char *)&p->snapshot;
if (ioctl(fd, I_STR, (char *)&si) < 0) { if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
p->snapshot = snaplen; if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
goto bad; goto bad;
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR); (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
@ -363,7 +361,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = BUFSPACE; p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize); p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) { if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad; goto bad;
} }
@ -403,12 +401,24 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->stats_op = pcap_stats_snit; p->stats_op = pcap_stats_snit;
p->close_op = pcap_close_common; p->close_op = pcap_close_common;
return (p); return (0);
bad: bad:
if (fd >= 0) if (fd >= 0)
close(fd); close(fd);
free(p); return (PCAP_ERROR);
return (NULL); }
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_snit;
return (p);
} }
int int

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.55 2005-05-03 18:54:00 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.56 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -194,9 +194,8 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
} }
/* XXX can't disable promiscuous */ /* XXX can't disable promiscuous */
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_snoop(pcap_t *p)
char *ebuf)
{ {
int fd; int fd;
struct sockaddr_raw sr; struct sockaddr_raw sr;
@ -204,34 +203,34 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
u_int v; u_int v;
int ll_hdrlen; int ll_hdrlen;
int snooplen; int snooplen;
pcap_t *p;
struct ifreq ifr; struct ifreq ifr;
p = (pcap_t *)malloc(sizeof(*p)); if (p->opt.rfmon) {
if (p == NULL) { /*
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", * No monitor mode on Irix (no Wi-Fi devices on
pcap_strerror(errno)); * hardware supported by Irix).
return (NULL); */
return (PCAP_ERROR_RFMON_NOTSUP);
} }
memset(p, 0, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) { if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
p->fd = fd; p->fd = fd;
memset(&sr, 0, sizeof(sr)); memset(&sr, 0, sizeof(sr));
sr.sr_family = AF_RAW; sr.sr_family = AF_RAW;
(void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); (void)strncpy(sr.sr_ifname, p->opt.source, sizeof(sr.sr_ifname));
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
memset(&sf, 0, sizeof(sf)); memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -240,19 +239,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* /*
* XXX hack - map device name to link layer type * XXX hack - map device name to link layer type
*/ */
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */ O2 10/100 */
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", device, 2) == 0 || strncmp("fa", p->opt.source, 2) == 0 ||
strncmp("qaa", device, 3) == 0 || strncmp("qaa", p->opt.source, 3) == 0 ||
strncmp("cip", device, 3) == 0 || strncmp("cip", p->opt.source, 3) == 0 ||
strncmp("el", device, 2) == 0) { strncmp("el", p->opt.source, 2) == 0) {
p->linktype = DLT_EN10MB; p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header)); p->offset = RAW_HDRPAD(sizeof(struct ether_header));
ll_hdrlen = sizeof(struct ether_header); ll_hdrlen = sizeof(struct ether_header);
@ -285,26 +284,26 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->dlt_list[1] = DLT_DOCSIS; p->dlt_list[1] = DLT_DOCSIS;
p->dlt_count = 2; p->dlt_count = 2;
} }
} else if (strncmp("ipg", device, 3) == 0 || } else if (strncmp("ipg", p->opt.source, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) { strncmp("xpi", p->opt.source, 3) == 0) {
p->linktype = DLT_FDDI; p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */ p->offset = 3; /* XXX yeah? */
ll_hdrlen = 13; ll_hdrlen = 13;
} else if (strncmp("ppp", device, 3) == 0) { } else if (strncmp("ppp", p->opt.source, 3) == 0) {
p->linktype = DLT_RAW; p->linktype = DLT_RAW;
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
} else if (strncmp("qfa", device, 3) == 0) { } else if (strncmp("qfa", p->opt.source, 3) == 0) {
p->linktype = DLT_IP_OVER_FC; p->linktype = DLT_IP_OVER_FC;
ll_hdrlen = 24; ll_hdrlen = 24;
} else if (strncmp("pl", device, 2) == 0) { } else if (strncmp("pl", p->opt.source, 2) == 0) {
p->linktype = DLT_RAW; p->linktype = DLT_RAW;
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */ ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
} else if (strncmp("lo", device, 2) == 0) { } else if (strncmp("lo", p->opt.source, 2) == 0) {
p->linktype = DLT_NULL; p->linktype = DLT_NULL;
ll_hdrlen = 4; ll_hdrlen = 4;
} else { } else {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type"); "snoop: unknown physical layer type");
goto bad; goto bad;
} }
@ -315,9 +314,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* the MTU first and, if that succeeds, trim the snap length * the MTU first and, if that succeeds, trim the snap length
* to be no greater than the MTU. * to be no greater than the MTU.
*/ */
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); (void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -338,8 +337,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef ifr_mtu #ifndef ifr_mtu
#define ifr_mtu ifr_metric #define ifr_mtu ifr_metric
#endif #endif
if (snaplen > ifr.ifr_mtu + ll_hdrlen) if (p->snapshot > ifr.ifr_mtu + ll_hdrlen)
snaplen = ifr.ifr_mtu + ll_hdrlen; p->snapshot = ifr.ifr_mtu + ll_hdrlen;
#endif #endif
/* /*
@ -347,18 +346,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* payload bytes to capture - it doesn't count link-layer * payload bytes to capture - it doesn't count link-layer
* header bytes. * header bytes.
*/ */
snooplen = snaplen - ll_hdrlen; snooplen = p->snapshot - ll_hdrlen;
if (snooplen < 0) if (snooplen < 0)
snooplen = 0; snooplen = 0;
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
p->snapshot = snaplen;
v = 1; v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) { if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -366,7 +364,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = 4096; /* XXX */ p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize); p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) { if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno)); pcap_strerror(errno));
goto bad; goto bad;
} }
@ -386,16 +384,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->stats_op = pcap_stats_snoop; p->stats_op = pcap_stats_snoop;
p->close_op = pcap_close_common; p->close_op = pcap_close_common;
return (p); return (0);
bad: bad:
(void)close(fd); (void)close(fd);
/* return (PCAP_ERROR);
* Get rid of any link-layer type list we allocated. }
*/
if (p->dlt_list != NULL) pcap_t *
free(p->dlt_list); pcap_create(const char *device, char *ebuf)
free(p); {
return (NULL); pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_snoop;
return (p);
} }
int int

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.21 2008-02-02 20:50:31 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.22 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -117,6 +117,7 @@ struct mon_bin_mfetch {
#define MON_BIN_ERROR 0x8 #define MON_BIN_ERROR 0x8
/* forward declaration */ /* forward declaration */
static int usb_activate(pcap_t *);
static int usb_stats_linux(pcap_t *, struct pcap_stat *); static int usb_stats_linux(pcap_t *, struct pcap_stat *);
static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *); static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *); static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
@ -183,25 +184,26 @@ int usb_mmap(pcap_t* handle)
return handle->buffer != MAP_FAILED; return handle->buffer != MAP_FAILED;
} }
pcap_t* pcap_t *
usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg) usb_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = usb_activate;
return (p);
}
static int
usb_activate(pcap_t* handle)
{ {
char full_path[USB_LINE_LEN]; char full_path[USB_LINE_LEN];
pcap_t *handle;
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */ /* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle)); handle->bufsize = handle->snapshot;
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->bufsize = snaplen;
handle->offset = 0; handle->offset = 0;
handle->linktype = DLT_USB_LINUX; handle->linktype = DLT_USB_LINUX;
@ -214,12 +216,11 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
handle->close_op = usb_close_linux; handle->close_op = usb_close_linux;
/*get usb bus index from device name */ /*get usb bus index from device name */
if (sscanf(bus, USB_IFACE"%d", &handle->md.ifindex) != 1) if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1)
{ {
snprintf(errmsg, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", bus); "Can't get USB bus index from %s", handle->opt.source);
free(handle); return -1;
return NULL;
} }
/*now select the read method: try to open binary interface */ /*now select the read method: try to open binary interface */
@ -238,7 +239,7 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
* "poll()" work on it. * "poll()" work on it.
*/ */
handle->selectable_fd = handle->fd; handle->selectable_fd = handle->fd;
return handle; return 0;
} }
/* can't mmap, use plain binary interface access */ /* can't mmap, use plain binary interface access */
@ -252,10 +253,9 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
if (handle->fd < 0) if (handle->fd < 0)
{ {
/* no more fallback, give it up*/ /* no more fallback, give it up*/
snprintf(errmsg, 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));
free(handle); return -1;
return NULL;
} }
handle->stats_op = usb_stats_linux; handle->stats_op = usb_stats_linux;
handle->read_op = usb_read_linux; handle->read_op = usb_read_linux;
@ -271,12 +271,12 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
* buffer */ * buffer */
handle->buffer = malloc(handle->bufsize); handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) { if (!handle->buffer) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno)); "malloc: %s", pcap_strerror(errno));
usb_close_linux(handle); close(handle->fd);
return NULL; return -1;
} }
return handle; return 0;
} }
static inline int static inline int

View File

@ -30,11 +30,11 @@
* USB sniffing API implementation for Linux platform * USB sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it> * By Paolo Abeni <paolo.abeni@email.it>
* *
* @(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.h,v 1.4 2007-09-14 01:55:49 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.h,v 1.5 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
/* /*
* Prototypes for USB-related functions * Prototypes for USB-related functions
*/ */
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str); int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t* usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg); pcap_t *usb_create(const char *device, char *ebuf);

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.36 2007-11-13 21:55:51 gianluca Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.37 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#include <pcap-int.h> #include <pcap-int.h>
@ -430,39 +430,36 @@ pcap_close_win32(pcap_t *p)
} }
} }
pcap_t * static int
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, pcap_activate_win32(pcap_t *p)
char *ebuf)
{ {
register pcap_t *p;
NetType type; NetType type;
if (p->opt.rfmon) {
/*
* No monitor mode on Windows. It could be done on
* Vista with drivers that support the native 802.11
* mechanism and monitor mode.
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
/* Init WinSock */ /* Init WinSock */
wsockinit(); wsockinit();
p = (pcap_t *)malloc(sizeof(*p)); p->adapter = PacketOpenAdapter(p->opt.source);
if (p == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
p->adapter=NULL;
p->adapter = PacketOpenAdapter((char*)device);
if (p->adapter == NULL) if (p->adapter == NULL)
{ {
free(p);
/* Adapter detected but we are not able to open it. Return failure. */ /* Adapter detected but we are not able to open it. Return failure. */
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror()); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return NULL; return PCAP_ERROR;
} }
/*get network type*/ /*get network type*/
if(PacketGetNetType (p->adapter,&type) == FALSE) if(PacketGetNetType (p->adapter,&type) == FALSE)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror()); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
goto bad; goto bad;
} }
@ -546,12 +543,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
} }
/* Set promiscuous mode */ /* Set promiscuous mode */
if (promisc) if (p->opt.promisc)
{ {
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE) if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
goto bad; goto bad;
} }
} }
@ -559,7 +556,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
{ {
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE) if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
goto bad; goto bad;
} }
} }
@ -568,12 +565,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = PcapBufSize; p->bufsize = PcapBufSize;
/* Store the timeout. Used by pcap_setnonblock() */ /* Store the timeout. Used by pcap_setnonblock() */
p->timeout= to_ms; p->md.timeout= to_ms;
/* allocate Packet structure used during the capture */ /* allocate Packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL) if((p->Packet = PacketAllocatePacket())==NULL)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
goto bad; goto bad;
} }
@ -582,11 +579,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* /*
* Traditional Adapter * Traditional Adapter
*/ */
/*
* If the buffer size wasn't explicitly set, default to
* SIZE_BUF.
*/
if (p->opt.buffer_size == 0)
p->opt.buffer_size = SIZE_BUF;
if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
goto bad;
}
p->buffer = (u_char *)malloc(PcapBufSize); p->buffer = (u_char *)malloc(PcapBufSize);
if (p->buffer == NULL) if (p->buffer == NULL)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
goto bad; goto bad;
} }
@ -597,14 +605,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* allocate the standard buffer in the driver */ /* allocate the standard buffer in the driver */
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE) if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
goto bad; goto bad;
} }
/* tell the driver to copy the buffer only if it contains at least 16K */ /* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE) if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{ {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror()); snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
goto bad; goto bad;
} }
} }
@ -623,7 +631,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
"SYSTEM\\CurrentControlSet\\Services\\DAG", "SYSTEM\\CurrentControlSet\\Services\\DAG",
strstr(_strlwr((char*)device), "dag")); strstr(_strlwr(p->opt.source), "dag"));
do do
{ {
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey); status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
@ -687,23 +695,31 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->setmintocopy_op = pcap_setmintocopy_win32; p->setmintocopy_op = pcap_setmintocopy_win32;
p->close_op = pcap_close_win32; p->close_op = pcap_close_win32;
return (p); return (0);
bad: bad:
if (p->adapter) if (p->adapter)
PacketCloseAdapter(p->adapter); PacketCloseAdapter(p->adapter);
if (p->buffer != NULL) if (p->buffer != NULL) {
free(p->buffer); free(p->buffer);
p->buffer = NULL;
}
if(p->Packet) if(p->Packet)
PacketFreePacket(p->Packet); PacketFreePacket(p->Packet);
/* return (PCAP_ERROR);
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
} }
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_win32;
return (p);
}
static int static int
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp) pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
@ -780,7 +796,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
* (Note that this may be -1, in which case we're not * (Note that this may be -1, in which case we're not
* really leaving non-blocking mode.) * really leaving non-blocking mode.)
*/ */
newtimeout = p->timeout; newtimeout = p->md.timeout;
} }
if (!PacketSetReadTimeout(p->adapter, newtimeout)) { if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,

327
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.114 2007-11-06 16:20:53 gianluca Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.115 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -70,10 +70,192 @@ static const char rcsid[] _U_ =
#include <dagapi.h> #include <dagapi.h>
#endif #endif
int
pcap_not_initialized(pcap_t *pcap)
{
/* this means 'not initialized' */
return PCAP_ERROR_NOT_ACTIVATED;
}
/*
* Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
* a PCAP_ERROR value on an error.
*/
int
pcap_can_set_rfmon(pcap_t *p)
{
return (p->can_set_rfmon_op(p));
}
/*
* For systems where rfmon mode is never supported.
*/
static int
pcap_cant_set_rfmon(pcap_t *p _U_)
{
return (0);
}
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));
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.
*/
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->close_op = (close_op_t)pcap_close_common;
/* put in some defaults*/
pcap_set_timeout(p, 0);
pcap_set_snaplen(p, 65535); /* max packet size */
p->opt.promisc = 0;
p->opt.buffer_size = 0;
return (p);
}
int
pcap_check_activated(pcap_t *p)
{
if (p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
" operation on activated capture");
return -1;
}
return 0;
}
int
pcap_set_snaplen(pcap_t *p, int snaplen)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->snapshot = snaplen;
return 0;
}
int
pcap_set_promisc(pcap_t *p, int promisc)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.promisc = promisc;
return 0;
}
int
pcap_set_rfmon(pcap_t *p, int rfmon)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.rfmon = rfmon;
return 0;
}
int
pcap_set_timeout(pcap_t *p, int timeout_ms)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->md.timeout = timeout_ms;
return 0;
}
int
pcap_set_buffer_size(pcap_t *p, int buffer_size)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.buffer_size = buffer_size;
return 0;
}
int
pcap_activate(pcap_t *p)
{
int err;
err = p->activate_op(p);
if (err == 0)
p->activated = 1;
return (err);
}
pcap_t *
pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
{
pcap_t *p;
p = pcap_create(source, errbuf);
if (p == NULL)
return (NULL);
if (pcap_set_snaplen(p, snaplen))
goto fail;
if (pcap_set_promisc(p, promisc))
goto fail;
if (pcap_set_timeout(p, to_ms))
goto fail;
/*
* Mark this as opened with pcap_open_live(), so that, for
* example, we show the full list of DLT_ values, rather
* than just the ones that are compatible with capturing
* when not in monitor mode. That allows existing applications
* to work the way they used to work, but allows new applications
* that know about the new open API to, for example, find out the
* DLT_ values that they can select without changing whether
* the adapter is in monitor mode or not.
*/
p->oldstyle = 1;
if (pcap_activate(p))
goto fail;
return (p);
fail:
strncpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
pcap_close(p);
return (NULL);
}
int int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{ {
return p->read_op(p, cnt, callback, user); return p->read_op(p, cnt, callback, user);
} }
@ -702,22 +884,57 @@ pcap_win32strerror(void)
/* /*
* Not all systems have strerror(). * Not all systems have strerror().
* We also use this to generate error strings for PCAP_ERROR_ values.
*/ */
const char * const char *
pcap_strerror(int errnum) pcap_strerror(int errnum)
{ {
#ifdef HAVE_STRERROR static char ebuf[128+1];
return (strerror(errnum)); #ifndef HAVE_STRERROR
#else
extern int sys_nerr; extern int sys_nerr;
extern const char *const sys_errlist[]; extern const char *const sys_errlist[];
static char ebuf[20]; #endif
if ((unsigned int)errnum < sys_nerr) switch (errnum) {
return ((char *)sys_errlist[errnum]);
case PCAP_ERROR:
(void)snprintf(ebuf, sizeof ebuf, "Generic error");
return(ebuf);
case PCAP_ERROR_BREAK:
(void)snprintf(ebuf, sizeof ebuf, "Loop terminated by pcap_breakloop");
return(ebuf);
case PCAP_ERROR_NOT_ACTIVATED:
(void)snprintf(ebuf, sizeof ebuf, "The pcap_t has not been activated");
return(ebuf);
case PCAP_ERROR_ACTIVATED:
(void)snprintf(ebuf, sizeof ebuf, "The setting can't be changed after the pcap_t is activated");
return(ebuf);
case PCAP_ERROR_NO_SUCH_DEVICE:
(void)snprintf(ebuf, sizeof ebuf, "No such device exists");
return(ebuf);
case PCAP_ERROR_RFMON_NOTSUP:
(void)snprintf(ebuf, sizeof ebuf, "That device doesn't support monitor mode");
return(ebuf);
case PCAP_ERROR_NOT_RFMON:
(void)snprintf(ebuf, sizeof ebuf, "That operation is supported only in monitor mode");
return(ebuf);
}
if (errnum >= 0) {
#ifdef HAVE_STRERROR
return (strerror(errnum));
#else
if ((unsigned int)errnum < sys_nerr)
return ((char *)sys_errlist[errnum]);
#endif
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf); return(ebuf);
#endif
} }
int int
@ -801,11 +1018,102 @@ pcap_setmintocopy_dead(pcap_t *p, int size)
} }
#endif #endif
/*
* On some platforms, we need to clean up promiscuous or monitor mode
* when we close a device - and we want that to happen even if the
* application just exits without explicitl closing devices.
* On those platforms, we need to register a "close all the pcaps"
* routine to be called when we exit, and need to maintain a list of
* pcaps that need to be closed to clean up modes.
*
* XXX - not thread-safe.
*/
/*
* List of pcaps on which we've done something that needs to be
* cleaned up.
* If there are any such pcaps, we arrange to call "pcap_close_all()"
* when we exit, and have it close all of them.
*/
static struct pcap *pcaps_to_close;
/*
* TRUE if we've already called "atexit()" to cause "pcap_close_all()" to
* be called on exit.
*/
static int did_atexit;
static void
pcap_close_all(void)
{
struct pcap *handle;
while ((handle = pcaps_to_close) != NULL)
pcap_close(handle);
}
int
pcap_do_addexit(pcap_t *p)
{
/*
* If we haven't already done so, arrange to have
* "pcap_close_all()" called when we exit.
*/
if (!did_atexit) {
if (atexit(pcap_close_all) == -1) {
/*
* "atexit()" failed; let our caller know.
*/
strncpy(p->errbuf, "atexit failed",
PCAP_ERRBUF_SIZE);
return (0);
}
did_atexit = 1;
}
return (1);
}
void
pcap_add_to_pcaps_to_close(pcap_t *p)
{
p->md.next = pcaps_to_close;
pcaps_to_close = p;
}
void
pcap_remove_from_pcaps_to_close(pcap_t *p)
{
pcap_t *pc, *prevpc;
for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
prevpc = pc, pc = pc->md.next) {
if (pc == p) {
/*
* Found it. Remove it from the list.
*/
if (prevpc == NULL) {
/*
* It was at the head of the list.
*/
pcaps_to_close = pc->md.next;
} else {
/*
* It was in the middle of the list.
*/
prevpc->md.next = pc->md.next;
}
break;
}
}
}
void void
pcap_close_common(pcap_t *p) pcap_close_common(pcap_t *p)
{ {
if (p->buffer != NULL) if (p->buffer != NULL)
free(p->buffer); free(p->buffer);
if (p->opt.source != NULL);
free(p->opt.source);
#if !defined(WIN32) && !defined(MSDOS) #if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0) if (p->fd >= 0)
close(p->fd); close(p->fd);
@ -836,6 +1144,7 @@ pcap_open_dead(int linktype, int snaplen)
p->setmintocopy_op = pcap_setmintocopy_dead; p->setmintocopy_op = pcap_setmintocopy_dead;
#endif #endif
p->close_op = pcap_close_dead; p->close_op = pcap_close_dead;
p->activated = 1;
return p; return p;
} }

View File

@ -31,7 +31,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/pcap.h,v 1.5 2008-01-02 04:16:46 guy Exp $ (LBL) * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.6 2008-04-04 19:37:45 guy Exp $ (LBL)
*/ */
#ifndef lib_pcap_pcap_h #ifndef lib_pcap_pcap_h
@ -226,8 +226,27 @@ struct pcap_addr {
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *); const u_char *);
/* list of known error code for pcap API */
#define PCAP_ERROR -1 /* generic error code */
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
char *pcap_lookupdev(char *); char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_create(const char *, char *);
int pcap_set_snaplen(pcap_t *, int);
int pcap_set_promisc(pcap_t *, int);
int pcap_can_set_rfmon(pcap_t *);
int pcap_set_rfmon(pcap_t *, int);
int pcap_set_timeout(pcap_t *, int);
int pcap_set_buffer_size(pcap_t *, int);
int pcap_activate(pcap_t *);
pcap_t *pcap_open_live(const char *, int, int, int, char *); pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int); pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *); pcap_t *pcap_open_offline(const char *, char *);

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.172 2008-02-18 20:21:00 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.173 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -1310,6 +1310,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
p->setmintocopy_op = sf_setmintocopy; p->setmintocopy_op = sf_setmintocopy;
#endif #endif
p->close_op = sf_close; p->close_op = sf_close;
p->activated = 1;
return (p); return (p);
bad: bad: