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:
parent
19d1a629c7
commit
d9b420231a
|
@ -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
|
||||
|
||||
|
|
18
configure.in
18
configure.in
|
@ -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"
|
||||
;;
|
||||
|
|
20
dlpisubs.c
20
dlpisubs.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
1253
pcap-bpf.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
94
pcap-dag.c
94
pcap-dag.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
137
pcap-dlpi.c
137
pcap-dlpi.c
|
@ -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);
|
||||
}
|
||||
|
|
72
pcap-dos.c
72
pcap-dos.c
|
@ -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)
|
||||
{
|
||||
|
|
91
pcap-int.h
91
pcap-int.h
|
@ -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()".
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
1236
pcap-linux.c
1236
pcap-linux.c
File diff suppressed because it is too large
Load Diff
70
pcap-nit.c
70
pcap-nit.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
75
pcap-pf.c
75
pcap-pf.c
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
49
pcap-sita.c
49
pcap-sita.c
|
@ -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);
|
||||
}
|
||||
|
|
62
pcap-snit.c
62
pcap-snit.c
|
@ -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 *)𝔦
|
||||
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
|
||||
|
|
107
pcap-snoop.c
107
pcap-snoop.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
92
pcap-win32.c
92
pcap-win32.c
|
@ -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
323
pcap.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
21
pcap/pcap.h
21
pcap/pcap.h
|
@ -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 *);
|
||||
|
|
|
@ -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:
|
||||
|
|
Reference in New Issue