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. */
#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. */
#undef HAVE_MEMORY_H
@ -68,6 +71,9 @@
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#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. */
#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 Copyright (c) 1994, 1995, 1996, 1997
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
AC_REVISION($Revision: 1.148 $)
AC_REVISION($Revision: 1.149 $)
AC_PREREQ(2.50)
AC_INIT(pcap.c)
@ -448,9 +448,23 @@ linux)
if test $ac_cv_linux_vers -lt 2 ; then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
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
;;
bpf)
#
# Check whether we have the *BSD-style ioctls.
#
AC_CHECK_HEADERS(net/if_media.h)
;;
dag)
V_DEFS="$V_DEFS -DDAG_ONLY"
;;

View File

@ -12,7 +12,7 @@
*/
#ifndef lint
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
#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.
*/
int
pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
pcap_process_mactype(pcap_t *p, u_int mactype)
{
int retv = 0;
@ -247,7 +247,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
#endif
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
mactype);
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.
*/
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;
@ -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. */
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;
}
ss = snaplen;
if (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;
}
@ -286,7 +286,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout * 1000) % 1000000;
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;
}
}
@ -295,7 +295,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
chunksize = CHUNKSIZE;
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
!= 0) {
pcap_stream_err("SBIOCSCHUNKP", errno, ebuf);
pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf);
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.
*/
int
pcap_alloc_databuf(pcap_t *p, char *ebuf)
pcap_alloc_databuf(pcap_t *p)
{
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
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
@ -14,11 +14,11 @@ extern "C" {
*/
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_mactype(pcap_t *, u_int, char *);
int pcap_process_mactype(pcap_t *, u_int);
#ifdef HAVE_SYS_BUFMOD_H
int pcap_conf_bufmod(pcap_t *, int, int, char *);
int pcap_conf_bufmod(pcap_t *, int, int);
#endif
int pcap_alloc_databuf(pcap_t *, char *);
int pcap_alloc_databuf(pcap_t *);
int strioctl(int, int, int, char *);
#ifdef __cplusplus

1253
pcap-bpf.c

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
*/
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -64,6 +64,7 @@ static const char rcsid[] _U_ =
#define BT_CTRL_SIZE 128
/* forward declaration */
static int bt_activate(pcap_t *);
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_setfilter_linux(pcap_t *, struct bpf_program *);
@ -135,35 +136,37 @@ done:
}
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;
int opt;
pcap_t *handle;
int dev_id;
struct hci_filter flt;
/* 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,
"Can't get Bluetooth bus index from %s", bus);
return NULL;
}
/* 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;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device index from %s",
handle->opt.source);
return -1;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->bufsize = snaplen+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->offset = BT_CTRL_SIZE;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
@ -181,34 +184,30 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
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));
free(handle);
return NULL;
return -1;
}
handle->buffer = malloc(handle->bufsize);
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_close(handle);
return NULL;
goto close_fail;
}
opt = 1;
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));
pcap_close(handle);
return NULL;
goto close_fail;
}
opt = 1;
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));
pcap_close(handle);
return NULL;
goto close_fail;
}
/* Setup filter, do not call hci function to avoid dependence on
@ -217,10 +216,9 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
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));
pcap_close(handle);
return NULL;
goto close_fail;
}
@ -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_dev = handle->md.ifindex;
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));
pcap_close(handle);
return NULL;
goto close_fail;
}
handle->selectable_fd = handle->fd;
return 0;
return handle;
close_fail:
close(handle->fd);
return -1;
}
static int

View File

@ -30,11 +30,11 @@
* Bluetooth sniffing API implementation for Linux platform
* 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
*/
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
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
#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. */
/* 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
#endif /* DAG_ONLY */
@ -564,21 +564,20 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
* not supported in hardware.
*
* 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).
*/
pcap_t *
dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
static int dag_activate(pcap_t* handle)
{
#if 0
char conf[30]; /* dag configure string */
#endif
pcap_t *handle;
char *s;
int n;
daginf_t* daginf;
char * newDev = NULL;
char * device = handle->opt.source;
#ifdef HAVE_DAG_STREAMS_API
uint32_t mindata;
struct timeval maxwait;
@ -586,44 +585,35 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
#endif
if (device == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
return NULL;
}
/* 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;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
return -1;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
#ifdef HAVE_DAG_STREAMS_API
newDev = (char *)malloc(strlen(device) + 16);
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;
}
/* 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) {
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;
}
device = newDev;
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;
}
#else
if (strncmp(device, "/dev/", 5) != 0) {
newDev = (char *)malloc(strlen(device) + 5);
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;
}
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 */
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;
}
#ifdef HAVE_DAG_STREAMS_API
/* Open requested stream. Can fail if already locked or on error */
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;
}
@ -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,
&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;
}
@ -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,
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;
}
#else
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;
}
@ -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 */
/* This is a really bad idea, as different cards have different
* valid slen ranges. Should fix in Config API. */
if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
snaplen = MAX_DAG_SNAPLEN;
if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
handle->snapshot = MAX_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 */
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
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;
}
#endif
#ifdef HAVE_DAG_STREAMS_API
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;
}
#else
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;
}
#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;
} else {
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;
}
}
@ -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 = to_ms;
handle->md.dag_timeout = handle->md.timeout;
handle->linktype = -1;
if (dag_get_datalink(handle) < 0) {
strcpy(ebuf, handle->errbuf);
if (dag_get_datalink(handle) < 0)
goto failstop;
}
handle->bufsize = 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;
}
@ -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->md.stat.ps_drop = 0;
handle->md.stat.ps_recv = 0;
return handle;
return 0;
#ifdef HAVE_DAG_STREAMS_API
failstop:
if (handle != NULL) {
if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0)
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
}
faildetach:
if (handle != NULL) {
if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
}
#else
failstop:
if (handle != NULL) {
if (dag_stop(handle->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
}
#endif /* HAVE_DAG_STREAMS_API */
failclose:
if (handle != NULL) {
if (dag_close(handle->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
}
if (handle != NULL)
delete_pcap_dag(handle);
fail:
if (newDev != NULL) {
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 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

View File

@ -7,10 +7,10 @@
*
* 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);
#ifndef TYPE_AAL5

View File

@ -70,7 +70,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -321,12 +321,10 @@ pcap_close_dlpi(pcap_t *p)
close(p->send_fd);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_dlpi(pcap_t *p)
{
register char *cp;
register pcap_t *p;
int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
@ -345,12 +343,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char dname2[100];
#endif
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* 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->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.
*/
cp = strrchr(device, '/');
cp = strrchr(p->opt.source, '/');
if (cp == NULL)
strlcpy(dname, device, sizeof(dname));
strlcpy(dname, p->opt.source, sizeof(dname));
else
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;
* 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)
goto bad;
*cp = '\0';
@ -386,7 +385,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
*/
cp = "/dev/dlpi";
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));
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
* 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)
goto bad;
#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
* device name.
*/
if (*device == '/')
strlcpy(dname, device, sizeof(dname));
if (*p->opt.source == '/')
strlcpy(dname, p->opt.source, sizeof(dname));
else
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
* type name.
*/
cp = split_dname(dname, &ppa, ebuf);
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL)
goto bad;
@ -444,7 +443,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
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
* symptom of that inability.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", device);
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
goto bad;
@ -480,13 +479,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
}
#endif
p->snapshot = snaplen;
/*
** Attach if "style 2" provider
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
#ifdef HAVE_SOLARIS
@ -494,11 +491,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
isatm = 1;
#endif
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;
#ifdef DL_HP_RAWDLS
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;
}
#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
** types that use 802.2 LLC).
*/
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
dlbindreq(p->fd, 2, ebuf) < 0) ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
dlbindreq(p->fd, 2, p->errbuf) < 0) ||
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad;
#elif defined(DL_HP_RAWDLS)
/*
** HP-UX 10.0x and 10.1x.
*/
if (dl_dohpuxbind(p->fd, ebuf) < 0)
if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
goto bad;
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
** still receive?
*/
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad;
}
#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
** OS using DLPI.
**/
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad;
#endif /* AIX vs. HP-UX vs. other */
#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.
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s",
pcap_strerror(errno));
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
goto bad;
}
} else
#endif
if (promisc) {
if (p->opt.promisc) {
/*
** Enable promiscuous (not necessary on send FD)
*/
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0)
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
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)
*/
#if !defined(__hpux) && !defined(sinix)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf);
"WARNING: DL_PROMISC_MULTI failed (%s)\n",
p->errbuf);
#endif
}
/*
@ -608,17 +606,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef sinix
if (
#ifdef __hpux
!promisc &&
!p->opt.promisc &&
#endif
#ifdef HAVE_SOLARIS
!isatm &&
#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
(dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (promisc)
if (p->opt.promisc)
fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf);
"WARNING: DL_PROMISC_SAP failed (%s)\n", p->errbuf);
else
goto bad;
}
@ -629,7 +627,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** promiscuous options.
*/
#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;
/*
** 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
** still receive?
*/
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad;
}
#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
** when sending packets.
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad;
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;
#ifdef DLIOCRAW
@ -666,13 +664,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** header.
*/
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));
goto bad;
}
#endif
ss = snaplen;
ss = p->snapshot;
/*
** 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
/* 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;
#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.
*/
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));
goto bad;
}
/* Allocate data buffer. */
if (pcap_alloc_databuf(p, ebuf) != 0)
if (pcap_alloc_databuf(p) != 0)
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->close_op = pcap_close_dlpi;
return (p);
return (0);
bad:
if (p->fd >= 0)
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
return (PCAP_ERROR);
}
/*
@ -1649,3 +1641,16 @@ dlpi_kread(register int fd, register off_t addr,
return (cc);
}
#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
* 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>
@ -97,6 +97,7 @@ static volatile BOOL exc_occured = 0;
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,
u_char *data);
static void pcap_close_dos (pcap_t *p);
@ -142,31 +143,40 @@ static struct device *get_device (int fd)
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
* network packets.
*/
pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
int timeout_ms, char *errbuf)
static int pcap_activate_dos (pcap_t *pcap)
{
struct pcap *pcap;
int err = 0;
if (snaplen < ETH_MIN)
snaplen = ETH_MIN;
if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */
snaplen = ETH_MAX;
pcap = calloc (sizeof(*pcap), 1);
if (!pcap)
{
strcpy (errbuf, "Not enough memory (pcap)");
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on DOS.
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
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->inter_packet_wait = timeout_ms;
pcap->close_op = pcap_close_dos;
pcap->read_op = pcap_read_dos;
pcap->stats_op = pcap_stats_dos;
@ -177,24 +187,24 @@ pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
if (pcap->fd == 1) /* first time we're called */
{
if (!init_watt32(pcap, device_name, errbuf) ||
!first_init(device_name, errbuf, promisc))
if (!init_watt32(pcap, pcap->md.device, pcap->errbuf) ||
!first_init(pcap->md.device, pcap->errbuf, pcap->opt.promisc))
{
free (pcap);
return (NULL);
return (PCAP_ERROR);
}
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 "
"(`%s' vs. `%s')", active_dev->name, device_name);
"(`%s' vs. `%s')", active_dev->name, pcap->md.device);
free (pcap);
pcap = NULL;
err = PCAP_ERROR;
}
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;
int rx_len = 0;
if (p->inter_packet_wait > 0)
if (p->md.timeout > 0)
{
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;
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
* 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;
gettimeofday2 (&now, NULL);
@ -476,7 +486,7 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
{
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");
return (-1);
}
@ -587,7 +597,7 @@ void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
if (p)
{
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)
{

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.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
@ -96,6 +96,9 @@ typedef enum {
MAYBE_SWAPPED
} swapped_type_t;
/*
* Used when reading a savefile.
*/
struct pcap_sf {
FILE *rfile;
int swapped;
@ -106,6 +109,9 @@ struct pcap_sf {
u_char *base;
};
/*
* Used when doing a live capture.
*/
struct pcap_md {
struct pcap_stat stat;
/*XXX*/
@ -116,18 +122,17 @@ struct pcap_md {
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
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
int sock_packet; /* using Linux 2.0 compatible interface */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */
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() */
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
#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_STREAMS_API
@ -147,6 +152,19 @@ struct pcap_md {
#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
* Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
@ -160,11 +178,27 @@ struct pcap_md {
#define PCAP_FDDIPAD 3
#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 {
#ifdef WIN32
ADAPTER *adapter;
LPPACKET Packet;
int timeout;
int nonblock;
#else
int fd;
@ -180,6 +214,8 @@ struct pcap {
int linktype_ext; /* Extended information stored in the linktype field of a file */
int tzoff; /* timezone offset */
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 */
@ -188,12 +224,12 @@ struct pcap {
#endif
#ifdef MSDOS
int inter_packet_wait; /* offline: wait between packets */
void (*wait_proc)(void); /* call proc while waiting */
#endif
struct pcap_sf sf;
struct pcap_md md;
struct pcap_opt opt;
/*
* Read buffer.
@ -214,30 +250,27 @@ struct pcap {
/*
* Methods.
*/
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*inject_op)(pcap_t *, const void *, size_t);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
int (*setdirection_op)(pcap_t *, pcap_direction_t);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
int (*setnonblock_op)(pcap_t *, int, char *);
int (*stats_op)(pcap_t *, struct pcap_stat *);
#ifdef WIN32
/*
* 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);
activate_op_t activate_op;
can_set_rfmon_op_t can_set_rfmon_op;
read_op_t read_op;
inject_op_t inject_op;
setfilter_op_t setfilter_op;
setdirection_op_t setdirection_op;
set_datalink_op_t set_datalink_op;
getnonblock_op_t getnonblock_op;
setnonblock_op_t setnonblock_op;
stats_op_t stats_op;
#ifdef WIN32
/*
* These are, at least currently, specific to the Win32 NPF
* driver.
*/
int (*setmode_op)(pcap_t *, int);
int (*setmintocopy_op)(pcap_t *, int);
setbuff_op_t setbuff_op;
setmode_op_t setmode_op;
setmintocopy_op_t setmintocopy_op;
#endif
void (*close_op)(pcap_t *);
close_op_t close_op;
/*
* 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 *);
#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 *);
int pcap_not_initialized(pcap_t *);
int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".

View File

@ -26,7 +26,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -96,57 +96,54 @@ list_interfaces(const char *linkname, void *arg)
return (B_FALSE);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_libdlpi(pcap_t *p)
{
int retv;
pcap_t *p;
dlpi_handle_t dh;
dlpi_info_t dlinfo;
if ((p = (pcap_t *)malloc(sizeof(*p))) == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* 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->send_fd = -1;
/*
* Enable Solaris raw and passive DLPI extensions;
* dlpi_open() will not fail if the underlying link does not support
* 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) {
pcap_libdlpi_err(device, "dlpi_open", retv, ebuf);
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, p->errbuf);
goto bad;
}
p->dlpi_hd = dh;
p->snapshot = snaplen;
/* Bind with DLPI_ANY_SAP. */
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;
}
/* Enable promiscuous mode. */
if (promisc) {
if (p->opt.promisc) {
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_promisc(PHYSICAL)",
retv, ebuf);
pcap_libdlpi_err(p->opt.source,
"dlpi_promisc(PHYSICAL)", retv, p->errbuf);
goto bad;
}
} else {
/* Try to enable multicast. */
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(device, "dlpi_promisc(MULTI)",
retv, ebuf);
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
retv, p->errbuf);
goto bad;
}
}
@ -154,42 +151,42 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try to enable SAP promiscuity. */
if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) {
if (!promisc) {
pcap_libdlpi_err(device, "dlpi_promisc(SAP)",
retv, ebuf);
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
retv, p->errbuf);
goto bad;
}
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
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. */
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;
}
if (pcap_process_mactype(p, dlinfo.di_mactype, ebuf) != 0)
if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
goto bad;
p->fd = dlpi_fd(p->dlpi_hd);
/* 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;
/*
* Flush the read side.
*/
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));
goto bad;
}
/* Allocate data buffer. */
if (pcap_alloc_databuf(p, ebuf) != 0)
if (pcap_alloc_databuf(p) != 0)
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->close_op = pcap_close_libdlpi;
return (p);
return (0);
bad:
/* Get rid of any link-layer type list we allocated. */
if (p->dlt_list != NULL)
free(p->dlt_list);
pcap_close_libdlpi(p);
free(p);
return (NULL);
dlpi_close(p->dlpi_hd);
return (PCAP_ERROR);
}
/*
@ -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",
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
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
#ifdef HAVE_CONFIG_H
@ -237,51 +237,43 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
static void
pcap_close_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)
static int
pcap_activate_nit(pcap_t *p)
{
int fd;
struct sockaddr_nit snit;
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on SunOS 3.x or earlier (no
* 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.
*/
snaplen = 96;
p->snapshot = 96;
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
goto bad;
}
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))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
nit_setflags(p->fd, promisc, to_ms, ebuf);
nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf);
/*
* 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->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(ebuf, 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);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
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->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_nit;
p->close_op = pcap_close_nit;
p->close_op = pcap_close_common;
return (p);
return (0);
bad:
if (fd >= 0)
close(fd);
free(p);
return (PCAP_ERROR);
}
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

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -40,10 +40,9 @@ static const char rcsid[] _U_ =
static char nosup[] = "live packet capture not supported on this system";
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
pcap_activate(pcap_t *p)
{
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
(void)strlcpy(p->errbuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);
}

View File

@ -24,7 +24,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -291,23 +291,14 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
#define DLT_DOCSIS 143
#endif
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_pf(pcap_t *p)
{
pcap_t *p;
short enmode;
int backlog = -1; /* request the most */
struct enfilter Filter;
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
* 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
* 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)
p->fd = pfopen(device, O_RDONLY);
p->fd = pfopen(p->opt.source, O_RDONLY);
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",
device, pcap_strerror(errno));
p->opt.source, pcap_strerror(errno));
goto bad;
}
p->md.OrigMissed = -1;
enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
if (promisc)
if (p->opt.promisc)
enmode |= ENPROMISC;
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));
goto bad;
}
@ -352,13 +343,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
#endif
/* set the backlog */
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));
goto bad;
}
/* discover interface type */
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));
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
* doesn't specify a particular type of header.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u",
devparams.end_dev_type);
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type);
goto bad;
}
/* set truncation */
@ -450,32 +441,31 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->fddipad = PCAP_FDDIPAD;
/* packetfilter includes the padding in the snapshot */
snaplen += PCAP_FDDIPAD;
p->snapshot += PCAP_FDDIPAD;
} else
p->fddipad = 0;
#endif
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* accept all packets */
memset(&Filter, 0, sizeof(Filter));
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
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));
goto bad;
}
if (to_ms != 0) {
if (p->md.timeout != 0) {
struct timeval timeout;
timeout.tv_sec = to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) % 1000000;
timeout.tv_sec = p->md.timeout / 1000;
timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
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));
goto bad;
}
@ -484,7 +474,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
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->close_op = pcap_close_common;
return (p);
return (0);
bad:
if (p->fd >= 0)
close(p->fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (PCAP_ERROR);
}
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_pf;
return (p);
}
int

View File

@ -16,7 +16,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -50,8 +50,8 @@ static const char rcsid[] _U_ =
/* This code is required when compiling for a Septel device only. */
#include "pcap-septel.h"
/* Replace dag function names with pcap equivalent. */
#define septel_open_live pcap_open_live
/* Replace septel function names with pcap equivalent. */
#define septel_create pcap_create
#define septel_platform_finddevs pcap_platform_finddevs
#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 to_ms parameter is also ignored as it is
* not supported in hardware.
* The timeout is also ignored as it is not supported in hardware.
*
* See also pcap(3).
*/
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
pcap_t *handle;
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
return NULL;
}
static pcap_t *septel_activate(pcap_t* handle) {
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->linktype = DLT_MTP2;
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->close_op = septel_platform_close;
return handle;
fail:
if (handle != NULL) {
free(handle);
return 0;
}
pcap_t *septel_create(const char *device, char *ebuf) {
pcap_t *p;
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) {

View File

@ -8,8 +8,8 @@
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
* (+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;
}
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
pcap_t *handle;
static int pcap_activate_sita(pcap_t *handle) {
int fd;
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return NULL;
if (handle->opt.rfmon) {
/*
* No monitor mode on SITA devices (they're not Wi-Fi
* devices).
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/* 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->setfilter_op = pcap_setfilter_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->stats_op = pcap_stats_acn;
fd = acn_open_live(device, ebuf, &handle->linktype);
if (fd == -1) {
free(handle);
return NULL;
}
handle->md.clear_promisc = promisc;
fd = acn_open_live(handle->opt.source, handle->errbuf,
&handle->linktype);
if (fd == -1)
return PCAP_ERROR;
handle->md.clear_promisc = handle->md.promisc;
handle->fd = fd;
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);
if (!handle->buffer) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
pcap_close_acn(handle);
free(handle);
return NULL;
return PCAP_ERROR;
}
/*
@ -972,5 +964,16 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
*/
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
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
#ifdef HAVE_CONFIG_H
@ -260,30 +260,29 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_snit(pcap_t *p)
{
struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request struct */
int chunksize = CHUNKSIZE;
int fd;
static char dev[] = "/dev/nit";
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on SunOS 4.x (no Wi-Fi devices on
* 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.
*/
snaplen = 96;
p->snapshot = 96;
memset(p, 0, sizeof(*p));
/*
* Initially try a read/write open (to allow the inject
* 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)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
pcap_strerror(errno));
goto bad;
}
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
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));
goto bad;
}
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));
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_dp = (char *)&chunksize;
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));
goto bad;
}
/* 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';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
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));
goto bad;
}
/* set the snapshot length */
si.ic_cmd = NIOCSSNAP;
si.ic_len = sizeof(snaplen);
si.ic_dp = (char *)&snaplen;
si.ic_len = sizeof(p->snapshot);
si.ic_dp = (char *)&p->snapshot;
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));
goto bad;
}
p->snapshot = snaplen;
if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
goto bad;
(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->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
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->close_op = pcap_close_common;
return (p);
return (0);
bad:
if (fd >= 0)
close(fd);
free(p);
return (PCAP_ERROR);
}
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

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -194,9 +194,8 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
}
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_snoop(pcap_t *p)
{
int fd;
struct sockaddr_raw sr;
@ -204,34 +203,34 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
u_int v;
int ll_hdrlen;
int snooplen;
pcap_t *p;
struct ifreq ifr;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on Irix (no Wi-Fi devices on
* hardware supported by Irix).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
memset(p, 0, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_strerror(errno));
goto bad;
}
p->fd = fd;
memset(&sr, 0, sizeof(sr));
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))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
pcap_strerror(errno));
goto bad;
}
memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_strerror(errno));
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
*/
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit,
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", device, 2) == 0 ||
strncmp("qaa", device, 3) == 0 ||
strncmp("cip", device, 3) == 0 ||
strncmp("el", device, 2) == 0) {
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", p->opt.source, 2) == 0 ||
strncmp("qaa", p->opt.source, 3) == 0 ||
strncmp("cip", p->opt.source, 3) == 0 ||
strncmp("el", p->opt.source, 2) == 0) {
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(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_count = 2;
}
} else if (strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) {
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", p->opt.source, 3) == 0) {
p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */
ll_hdrlen = 13;
} else if (strncmp("ppp", device, 3) == 0) {
} else if (strncmp("ppp", p->opt.source, 3) == 0) {
p->linktype = DLT_RAW;
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;
ll_hdrlen = 24;
} else if (strncmp("pl", device, 2) == 0) {
} else if (strncmp("pl", p->opt.source, 2) == 0) {
p->linktype = DLT_RAW;
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;
ll_hdrlen = 4;
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type");
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
* 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_strerror(errno));
goto bad;
}
@ -338,8 +337,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef ifr_mtu
#define ifr_mtu ifr_metric
#endif
if (snaplen > ifr.ifr_mtu + ll_hdrlen)
snaplen = ifr.ifr_mtu + ll_hdrlen;
if (p->snapshot > ifr.ifr_mtu + ll_hdrlen)
p->snapshot = ifr.ifr_mtu + ll_hdrlen;
#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
* header bytes.
*/
snooplen = snaplen - ll_hdrlen;
snooplen = p->snapshot - ll_hdrlen;
if (snooplen < 0)
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));
goto bad;
}
p->snapshot = snaplen;
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_strerror(errno));
goto bad;
}
@ -366,7 +364,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
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->close_op = pcap_close_common;
return (p);
return (0);
bad:
(void)close(fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (PCAP_ERROR);
}
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_snoop;
return (p);
}
int

View File

@ -34,7 +34,7 @@
*/
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -117,6 +117,7 @@ struct mon_bin_mfetch {
#define MON_BIN_ERROR 0x8
/* forward declaration */
static int usb_activate(pcap_t *);
static int usb_stats_linux(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 *);
@ -184,24 +185,25 @@ int usb_mmap(pcap_t* handle)
}
pcap_t *
usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg)
usb_create(const char *device, char *ebuf)
{
char full_path[USB_LINE_LEN];
pcap_t *handle;
pcap_t *p;
/* 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;
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];
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->bufsize = snaplen;
handle->bufsize = handle->snapshot;
handle->offset = 0;
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;
/*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,
"Can't get USB bus index from %s", bus);
free(handle);
return NULL;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.source);
return -1;
}
/*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.
*/
handle->selectable_fd = handle->fd;
return handle;
return 0;
}
/* 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)
{
/* 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));
free(handle);
return NULL;
return -1;
}
handle->stats_op = usb_stats_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 */
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(errmsg, PCAP_ERRBUF_SIZE,
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
usb_close_linux(handle);
return NULL;
close(handle->fd);
return -1;
}
return handle;
return 0;
}
static inline int

View File

@ -30,11 +30,11 @@
* USB sniffing API implementation for Linux platform
* 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
*/
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
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
#include <pcap-int.h>
@ -430,39 +430,36 @@ pcap_close_win32(pcap_t *p)
}
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_win32(pcap_t *p)
{
register pcap_t *p;
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 */
wsockinit();
p = (pcap_t *)malloc(sizeof(*p));
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);
p->adapter = PacketOpenAdapter(p->opt.source);
if (p->adapter == NULL)
{
free(p);
/* Adapter detected but we are not able to open it. Return failure. */
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return NULL;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return PCAP_ERROR;
}
/*get network type*/
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;
}
@ -546,12 +543,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
}
/* Set promiscuous mode */
if (promisc)
if (p->opt.promisc)
{
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;
}
}
@ -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)
{
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;
}
}
@ -568,12 +565,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = PcapBufSize;
/* Store the timeout. Used by pcap_setnonblock() */
p->timeout= to_ms;
p->md.timeout= to_ms;
/* allocate Packet structure used during the capture */
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;
}
@ -582,11 +579,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/*
* 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);
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;
}
@ -597,14 +605,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* allocate the standard buffer in the driver */
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;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
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;
}
}
@ -623,7 +631,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
"SYSTEM\\CurrentControlSet\\Services\\DAG",
strstr(_strlwr((char*)device), "dag"));
strstr(_strlwr(p->opt.source), "dag"));
do
{
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->close_op = pcap_close_win32;
return (p);
return (0);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
if(p->Packet)
PacketFreePacket(p->Packet);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
return (PCAP_ERROR);
}
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
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
* really leaving non-blocking mode.)
*/
newtimeout = p->timeout;
newtimeout = p->md.timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,

323
pcap.c
View File

@ -33,7 +33,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -70,10 +70,192 @@ static const char rcsid[] _U_ =
#include <dagapi.h>
#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
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
return p->read_op(p, cnt, callback, user);
}
@ -702,22 +884,57 @@ pcap_win32strerror(void)
/*
* Not all systems have strerror().
* We also use this to generate error strings for PCAP_ERROR_ values.
*/
const char *
pcap_strerror(int errnum)
{
static char ebuf[128+1];
#ifndef HAVE_STRERROR
extern int sys_nerr;
extern const char *const sys_errlist[];
#endif
switch (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
extern int sys_nerr;
extern const char *const sys_errlist[];
static char ebuf[20];
if ((unsigned int)errnum < sys_nerr)
return ((char *)sys_errlist[errnum]);
#endif
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
#endif
}
int
@ -801,11 +1018,102 @@ pcap_setmintocopy_dead(pcap_t *p, int size)
}
#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
pcap_close_common(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->opt.source != NULL);
free(p->opt.source);
#if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0)
close(p->fd);
@ -836,6 +1144,7 @@ pcap_open_dead(int linktype, int snaplen)
p->setmintocopy_op = pcap_setmintocopy_dead;
#endif
p->close_op = pcap_close_dead;
p->activated = 1;
return p;
}

View File

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* 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
@ -226,8 +226,27 @@ struct pcap_addr {
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
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 *);
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_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);

View File

@ -30,7 +30,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -1310,6 +1310,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
p->setmintocopy_op = sf_setmintocopy;
#endif
p->close_op = sf_close;
p->activated = 1;
return (p);
bad: