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. */
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
#undef HAVE_LIMITS_H
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <linux/wireless.h> header file. */
|
||||||
|
#undef HAVE_LINUX_WIRELESS_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#undef HAVE_MEMORY_H
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
@ -68,6 +71,9 @@
|
||||||
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
|
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
|
||||||
#undef HAVE_NETINET_IF_ETHER_H
|
#undef HAVE_NETINET_IF_ETHER_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <net/if_media.h> header file. */
|
||||||
|
#undef HAVE_NET_IF_MEDIA_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <net/pfvar.h> header file. */
|
/* Define to 1 if you have the <net/pfvar.h> header file. */
|
||||||
#undef HAVE_NET_PFVAR_H
|
#undef HAVE_NET_PFVAR_H
|
||||||
|
|
||||||
|
|
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
|
||||||
dnl Copyright (c) 1994, 1995, 1996, 1997
|
dnl Copyright (c) 1994, 1995, 1996, 1997
|
||||||
dnl The Regents of the University of California. All rights reserved.
|
dnl The Regents of the University of California. All rights reserved.
|
||||||
|
@ -6,7 +6,7 @@ dnl
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
AC_REVISION($Revision: 1.148 $)
|
AC_REVISION($Revision: 1.149 $)
|
||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
AC_INIT(pcap.c)
|
AC_INIT(pcap.c)
|
||||||
|
|
||||||
|
@ -448,9 +448,23 @@ linux)
|
||||||
if test $ac_cv_linux_vers -lt 2 ; then
|
if test $ac_cv_linux_vers -lt 2 ; then
|
||||||
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
|
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
|
||||||
fi
|
fi
|
||||||
|
AC_CHECK_HEADERS(linux/wireless.h, [], [],
|
||||||
|
[
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
])
|
||||||
|
AC_CHECK_HEADERS()
|
||||||
AC_LBL_TPACKET_STATS
|
AC_LBL_TPACKET_STATS
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
bpf)
|
||||||
|
#
|
||||||
|
# Check whether we have the *BSD-style ioctls.
|
||||||
|
#
|
||||||
|
AC_CHECK_HEADERS(net/if_media.h)
|
||||||
|
;;
|
||||||
|
|
||||||
dag)
|
dag)
|
||||||
V_DEFS="$V_DEFS -DDAG_ONLY"
|
V_DEFS="$V_DEFS -DDAG_ONLY"
|
||||||
;;
|
;;
|
||||||
|
|
20
dlpisubs.c
20
dlpisubs.c
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.1 2008-03-13 18:13:57 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.2 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -197,7 +197,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
|
||||||
* Process the mac type. Returns -1 if no matching mac type found, otherwise 0.
|
* Process the mac type. Returns -1 if no matching mac type found, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
|
pcap_process_mactype(pcap_t *p, u_int mactype)
|
||||||
{
|
{
|
||||||
int retv = 0;
|
int retv = 0;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
|
||||||
mactype);
|
mactype);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype, char *ebuf)
|
||||||
* Push and configure the buffer module. Returns -1 for error, otherwise 0.
|
* Push and configure the buffer module. Returns -1 for error, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
|
pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout)
|
||||||
{
|
{
|
||||||
int retv = 0;
|
int retv = 0;
|
||||||
|
|
||||||
|
@ -268,14 +268,14 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
|
||||||
|
|
||||||
/* Non-standard call to get the data nicely buffered. */
|
/* Non-standard call to get the data nicely buffered. */
|
||||||
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
|
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
|
||||||
pcap_stream_err("I_PUSH bufmod", errno, ebuf);
|
pcap_stream_err("I_PUSH bufmod", errno, p->errbuf);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss = snaplen;
|
ss = snaplen;
|
||||||
if (ss > 0 &&
|
if (ss > 0 &&
|
||||||
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
|
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
|
||||||
pcap_stream_err("SBIOCSSNAP", errno, ebuf);
|
pcap_stream_err("SBIOCSSNAP", errno, p->errbuf);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
|
||||||
to.tv_sec = timeout / 1000;
|
to.tv_sec = timeout / 1000;
|
||||||
to.tv_usec = (timeout * 1000) % 1000000;
|
to.tv_usec = (timeout * 1000) % 1000000;
|
||||||
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
|
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
|
||||||
pcap_stream_err("SBIOCSTIME", errno, ebuf);
|
pcap_stream_err("SBIOCSTIME", errno, p->errbuf);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
|
||||||
chunksize = CHUNKSIZE;
|
chunksize = CHUNKSIZE;
|
||||||
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
|
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
pcap_stream_err("SBIOCSCHUNKP", errno, ebuf);
|
pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,12 +307,12 @@ pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout, char *ebuf)
|
||||||
* Allocate data buffer. Returns -1 if memory allocation fails, else 0.
|
* Allocate data buffer. Returns -1 if memory allocation fails, else 0.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pcap_alloc_databuf(pcap_t *p, char *ebuf)
|
pcap_alloc_databuf(pcap_t *p)
|
||||||
{
|
{
|
||||||
p->bufsize = PKTBUFSIZE;
|
p->bufsize = PKTBUFSIZE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
|
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/dlpisubs.h,v 1.1 2008-03-13 18:13:57 guy Exp $
|
* @(#) $Header: /tcpdump/master/libpcap/dlpisubs.h,v 1.2 2008-04-04 19:37:45 guy Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef dlpisubs_h
|
#ifndef dlpisubs_h
|
||||||
|
@ -14,11 +14,11 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
int pcap_stats_dlpi(pcap_t *, struct pcap_stat *);
|
int pcap_stats_dlpi(pcap_t *, struct pcap_stat *);
|
||||||
int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int);
|
int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int);
|
||||||
int pcap_process_mactype(pcap_t *, u_int, char *);
|
int pcap_process_mactype(pcap_t *, u_int);
|
||||||
#ifdef HAVE_SYS_BUFMOD_H
|
#ifdef HAVE_SYS_BUFMOD_H
|
||||||
int pcap_conf_bufmod(pcap_t *, int, int, char *);
|
int pcap_conf_bufmod(pcap_t *, int, int);
|
||||||
#endif
|
#endif
|
||||||
int pcap_alloc_databuf(pcap_t *, char *);
|
int pcap_alloc_databuf(pcap_t *);
|
||||||
int strioctl(int, int, int, char *);
|
int strioctl(int, int, int, char *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
1283
pcap-bpf.c
1283
pcap-bpf.c
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.10 2008-02-14 23:27:42 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.11 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -64,6 +64,7 @@ static const char rcsid[] _U_ =
|
||||||
#define BT_CTRL_SIZE 128
|
#define BT_CTRL_SIZE 128
|
||||||
|
|
||||||
/* forward declaration */
|
/* forward declaration */
|
||||||
|
static int bt_activate(pcap_t *);
|
||||||
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
||||||
static int bt_inject_linux(pcap_t *, const void *, size_t);
|
static int bt_inject_linux(pcap_t *, const void *, size_t);
|
||||||
static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
|
static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
|
||||||
|
@ -134,39 +135,41 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t*
|
pcap_t *
|
||||||
bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg)
|
bt_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = bt_activate;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bt_activate(pcap_t* handle)
|
||||||
{
|
{
|
||||||
struct sockaddr_hci addr;
|
struct sockaddr_hci addr;
|
||||||
int opt;
|
int opt;
|
||||||
pcap_t *handle;
|
|
||||||
int dev_id;
|
int dev_id;
|
||||||
struct hci_filter flt;
|
struct hci_filter flt;
|
||||||
|
|
||||||
/* get bt interface id */
|
/* get bt interface id */
|
||||||
if (sscanf(bus, BT_IFACE"%d", &dev_id) != 1)
|
if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
|
||||||
{
|
{
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE,
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get Bluetooth bus index from %s", bus);
|
"Can't get Bluetooth device index from %s",
|
||||||
return NULL;
|
handle->opt.source);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a handle for this session. */
|
|
||||||
handle = malloc(sizeof(*handle));
|
|
||||||
if (handle == NULL) {
|
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "malloc: %s",
|
|
||||||
pcap_strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
/* Initialize some components of the pcap structure. */
|
||||||
memset(handle, 0, sizeof(*handle));
|
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
|
||||||
handle->snapshot = snaplen;
|
|
||||||
handle->md.timeout = to_ms;
|
|
||||||
handle->bufsize = snaplen+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
|
|
||||||
handle->offset = BT_CTRL_SIZE;
|
handle->offset = BT_CTRL_SIZE;
|
||||||
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
|
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
|
||||||
|
|
||||||
handle->read_op = bt_read_linux;
|
handle->read_op = bt_read_linux;
|
||||||
handle->inject_op = bt_inject_linux;
|
handle->inject_op = bt_inject_linux;
|
||||||
handle->setfilter_op = bt_setfilter_linux;
|
handle->setfilter_op = bt_setfilter_linux;
|
||||||
|
@ -181,46 +184,41 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
|
||||||
/* Create HCI socket */
|
/* Create HCI socket */
|
||||||
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||||
if (handle->fd < 0) {
|
if (handle->fd < 0) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
free(handle);
|
return -1;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
pcap_close(handle);
|
goto close_fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
|
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
pcap_close(handle);
|
goto close_fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
pcap_close(handle);
|
goto close_fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup filter, do not call hci function to avoid dependence on
|
/* Setup filter, do not call hci function to avoid dependence on
|
||||||
* external libs */
|
* external libs */
|
||||||
memset(&flt, 0, sizeof(flt));
|
memset(&flt, 0, sizeof(flt));
|
||||||
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
|
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
|
||||||
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
|
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
pcap_close(handle);
|
goto close_fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,14 +226,16 @@ bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg
|
||||||
addr.hci_family = AF_BLUETOOTH;
|
addr.hci_family = AF_BLUETOOTH;
|
||||||
addr.hci_dev = handle->md.ifindex;
|
addr.hci_dev = handle->md.ifindex;
|
||||||
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
|
||||||
handle->md.ifindex, errno, strerror(errno));
|
handle->md.ifindex, errno, strerror(errno));
|
||||||
pcap_close(handle);
|
goto close_fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
handle->selectable_fd = handle->fd;
|
handle->selectable_fd = handle->fd;
|
||||||
|
return 0;
|
||||||
return handle;
|
|
||||||
|
close_fail:
|
||||||
|
close(handle->fd);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -30,11 +30,11 @@
|
||||||
* Bluetooth sniffing API implementation for Linux platform
|
* Bluetooth sniffing API implementation for Linux platform
|
||||||
* By Paolo Abeni <paolo.abeni@email.it>
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.h,v 1.4 2007-09-14 01:55:49 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.h,v 1.5 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes for Bluetooth-related functions
|
* Prototypes for Bluetooth-related functions
|
||||||
*/
|
*/
|
||||||
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
|
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
|
||||||
pcap_t* bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg);
|
pcap_t *bt_create(const char *device, char *ebuf);
|
||||||
|
|
120
pcap-dag.c
120
pcap-dag.c
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.36 2008-02-02 20:42:35 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.37 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -87,7 +87,7 @@ static const unsigned short endian_test_word = 0x0100;
|
||||||
/* This code is required when compiling for a DAG device only. */
|
/* This code is required when compiling for a DAG device only. */
|
||||||
|
|
||||||
/* Replace dag function names with pcap equivalent. */
|
/* Replace dag function names with pcap equivalent. */
|
||||||
#define dag_open_live pcap_open_live
|
#define dag_create pcap_create
|
||||||
#define dag_platform_finddevs pcap_platform_finddevs
|
#define dag_platform_finddevs pcap_platform_finddevs
|
||||||
#endif /* DAG_ONLY */
|
#endif /* DAG_ONLY */
|
||||||
|
|
||||||
|
@ -564,21 +564,20 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||||
* not supported in hardware.
|
* not supported in hardware.
|
||||||
*
|
*
|
||||||
* snaplen is now also ignored, until we get per-stream slen support. Set
|
* snaplen is now also ignored, until we get per-stream slen support. Set
|
||||||
* slen with approprite DAG tool BEFORE pcap_open_live().
|
* slen with approprite DAG tool BEFORE pcap_activate().
|
||||||
*
|
*
|
||||||
* See also pcap(3).
|
* See also pcap(3).
|
||||||
*/
|
*/
|
||||||
pcap_t *
|
static int dag_activate(pcap_t* handle)
|
||||||
dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
|
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
char conf[30]; /* dag configure string */
|
char conf[30]; /* dag configure string */
|
||||||
#endif
|
#endif
|
||||||
pcap_t *handle;
|
|
||||||
char *s;
|
char *s;
|
||||||
int n;
|
int n;
|
||||||
daginf_t* daginf;
|
daginf_t* daginf;
|
||||||
char * newDev = NULL;
|
char * newDev = NULL;
|
||||||
|
char * device = handle->opt.source;
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
uint32_t mindata;
|
uint32_t mindata;
|
||||||
struct timeval maxwait;
|
struct timeval maxwait;
|
||||||
|
@ -586,44 +585,35 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Allocate a handle for this session. */
|
|
||||||
|
|
||||||
handle = malloc(sizeof(*handle));
|
|
||||||
if (handle == NULL) {
|
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
/* Initialize some components of the pcap structure. */
|
||||||
|
|
||||||
memset(handle, 0, sizeof(*handle));
|
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
newDev = (char *)malloc(strlen(device) + 16);
|
newDev = (char *)malloc(strlen(device) + 16);
|
||||||
if (newDev == NULL) {
|
if (newDev == NULL) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse input name to get dag device and stream number if provided */
|
/* Parse input name to get dag device and stream number if provided */
|
||||||
if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
|
if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
device = newDev;
|
device = newDev;
|
||||||
|
|
||||||
if (handle->md.dag_stream%2) {
|
if (handle->md.dag_stream%2) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (strncmp(device, "/dev/", 5) != 0) {
|
if (strncmp(device, "/dev/", 5) != 0) {
|
||||||
newDev = (char *)malloc(strlen(device) + 5);
|
newDev = (char *)malloc(strlen(device) + 5);
|
||||||
if (newDev == NULL) {
|
if (newDev == NULL) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
strcpy(newDev, "/dev/");
|
strcpy(newDev, "/dev/");
|
||||||
|
@ -634,14 +624,14 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
|
|
||||||
/* setup device parameters */
|
/* setup device parameters */
|
||||||
if((handle->fd = dag_open((char *)device)) < 0) {
|
if((handle->fd = dag_open((char *)device)) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
/* Open requested stream. Can fail if already locked or on error */
|
/* Open requested stream. Can fail if already locked or on error */
|
||||||
if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
|
if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
|
||||||
goto failclose;
|
goto failclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +640,7 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
*/
|
*/
|
||||||
if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
|
if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
|
||||||
&mindata, &maxwait, &poll) < 0) {
|
&mindata, &maxwait, &poll) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
||||||
goto faildetach;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,13 +658,13 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
|
|
||||||
if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
|
if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
|
||||||
mindata, &maxwait, &poll) < 0) {
|
mindata, &maxwait, &poll) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
||||||
goto faildetach;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
|
if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
|
||||||
goto failclose;
|
goto failclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,28 +678,28 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
/* set the card snap length to the specified snaplen parameter */
|
/* set the card snap length to the specified snaplen parameter */
|
||||||
/* This is a really bad idea, as different cards have different
|
/* This is a really bad idea, as different cards have different
|
||||||
* valid slen ranges. Should fix in Config API. */
|
* valid slen ranges. Should fix in Config API. */
|
||||||
if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
|
if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
|
||||||
snaplen = MAX_DAG_SNAPLEN;
|
handle->snapshot = MAX_DAG_SNAPLEN;
|
||||||
} else if (snaplen < MIN_DAG_SNAPLEN) {
|
} else if (snaplen < MIN_DAG_SNAPLEN) {
|
||||||
snaplen = MIN_DAG_SNAPLEN;
|
handle->snapshot = MIN_DAG_SNAPLEN;
|
||||||
}
|
}
|
||||||
/* snap len has to be a multiple of 4 */
|
/* snap len has to be a multiple of 4 */
|
||||||
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
|
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
|
||||||
|
|
||||||
if(dag_configure(handle->fd, conf) < 0) {
|
if(dag_configure(handle->fd, conf) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
|
||||||
goto faildetach;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
|
if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
|
||||||
goto faildetach;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(dag_start(handle->fd) < 0) {
|
if(dag_start(handle->fd) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
|
||||||
goto failclose;
|
goto failclose;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#endif /* HAVE_DAG_STREAMS_API */
|
||||||
|
@ -745,7 +735,7 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
handle->md.dag_fcs_bits = n;
|
handle->md.dag_fcs_bits = n;
|
||||||
} else {
|
} else {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
|
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
|
||||||
goto failstop;
|
goto failstop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,19 +753,16 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->snapshot = snaplen;
|
handle->md.dag_timeout = handle->md.timeout;
|
||||||
handle->md.dag_timeout = to_ms;
|
|
||||||
|
|
||||||
handle->linktype = -1;
|
handle->linktype = -1;
|
||||||
if (dag_get_datalink(handle) < 0) {
|
if (dag_get_datalink(handle) < 0)
|
||||||
strcpy(ebuf, handle->errbuf);
|
|
||||||
goto failstop;
|
goto failstop;
|
||||||
}
|
|
||||||
|
|
||||||
handle->bufsize = 0;
|
handle->bufsize = 0;
|
||||||
|
|
||||||
if (new_pcap_dag(handle) < 0) {
|
if (new_pcap_dag(handle) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
|
||||||
goto failstop;
|
goto failstop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,51 +786,46 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
|
||||||
handle->close_op = dag_platform_close;
|
handle->close_op = dag_platform_close;
|
||||||
handle->md.stat.ps_drop = 0;
|
handle->md.stat.ps_drop = 0;
|
||||||
handle->md.stat.ps_recv = 0;
|
handle->md.stat.ps_recv = 0;
|
||||||
return handle;
|
return 0;
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
failstop:
|
failstop:
|
||||||
if (handle != NULL) {
|
if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0)
|
||||||
if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0)
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
faildetach:
|
faildetach:
|
||||||
if (handle != NULL) {
|
if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
|
||||||
if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
#else
|
||||||
}
|
|
||||||
#else
|
|
||||||
failstop:
|
failstop:
|
||||||
if (handle != NULL) {
|
if (dag_stop(handle->fd) < 0)
|
||||||
if (dag_stop(handle->fd) < 0)
|
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
|
||||||
}
|
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#endif /* HAVE_DAG_STREAMS_API */
|
||||||
|
|
||||||
failclose:
|
failclose:
|
||||||
if (handle != NULL) {
|
if (dag_close(handle->fd) < 0)
|
||||||
if (dag_close(handle->fd) < 0)
|
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
delete_pcap_dag(handle);
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
delete_pcap_dag(handle);
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (newDev != NULL) {
|
if (newDev != NULL) {
|
||||||
free((char *)newDev);
|
free((char *)newDev);
|
||||||
}
|
}
|
||||||
if (handle != NULL) {
|
|
||||||
/*
|
|
||||||
* Get rid of any link-layer type list we allocated.
|
|
||||||
*/
|
|
||||||
if (handle->dlt_list != NULL) {
|
|
||||||
free(handle->dlt_list);
|
|
||||||
}
|
|
||||||
free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return PCAP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_t *dag_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p->activate_op = dag_activate;
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
*
|
*
|
||||||
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.6 2007-11-09 00:55:53 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.7 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
|
pcap_t *dag_create(const char *, char *);
|
||||||
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
|
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
|
||||||
|
|
||||||
#ifndef TYPE_AAL5
|
#ifndef TYPE_AAL5
|
||||||
|
|
137
pcap-dlpi.c
137
pcap-dlpi.c
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.120 2008-03-13 18:13:57 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.121 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -321,12 +321,10 @@ pcap_close_dlpi(pcap_t *p)
|
||||||
close(p->send_fd);
|
close(p->send_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_dlpi(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
register char *cp;
|
register char *cp;
|
||||||
register pcap_t *p;
|
|
||||||
int ppa;
|
int ppa;
|
||||||
#ifdef HAVE_SOLARIS
|
#ifdef HAVE_SOLARIS
|
||||||
int isatm = 0;
|
int isatm = 0;
|
||||||
|
@ -345,12 +343,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
char dname2[100];
|
char dname2[100];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
if (p->opt.rfmon) {
|
||||||
if (p == NULL) {
|
/*
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
* No monitor mode on any platforms that support DLPI.
|
||||||
return (NULL);
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
}
|
}
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
p->fd = -1; /* indicate that it hasn't been opened yet */
|
p->fd = -1; /* indicate that it hasn't been opened yet */
|
||||||
p->send_fd = -1;
|
p->send_fd = -1;
|
||||||
|
|
||||||
|
@ -358,9 +357,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/*
|
/*
|
||||||
** Remove any "/dev/" on the front of the device.
|
** Remove any "/dev/" on the front of the device.
|
||||||
*/
|
*/
|
||||||
cp = strrchr(device, '/');
|
cp = strrchr(p->opt.source, '/');
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
strlcpy(dname, device, sizeof(dname));
|
strlcpy(dname, p->opt.source, sizeof(dname));
|
||||||
else
|
else
|
||||||
strlcpy(dname, cp + 1, sizeof(dname));
|
strlcpy(dname, cp + 1, sizeof(dname));
|
||||||
|
|
||||||
|
@ -368,7 +367,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* Split the device name into a device type name and a unit number;
|
* Split the device name into a device type name and a unit number;
|
||||||
* chop off the unit number, so "dname" is just a device type name.
|
* chop off the unit number, so "dname" is just a device type name.
|
||||||
*/
|
*/
|
||||||
cp = split_dname(dname, &ppa, ebuf);
|
cp = split_dname(dname, &ppa, p->errbuf);
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
goto bad;
|
goto bad;
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
@ -386,7 +385,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
*/
|
*/
|
||||||
cp = "/dev/dlpi";
|
cp = "/dev/dlpi";
|
||||||
if ((p->fd = open(cp, O_RDWR)) < 0) {
|
if ((p->fd = open(cp, O_RDWR)) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s: %s", cp, pcap_strerror(errno));
|
"%s: %s", cp, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -410,7 +409,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* Get a table of all PPAs for that device, and search that
|
* Get a table of all PPAs for that device, and search that
|
||||||
* table for the specified device type name and unit number.
|
* table for the specified device type name and unit number.
|
||||||
*/
|
*/
|
||||||
ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf);
|
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
|
||||||
if (ppa < 0)
|
if (ppa < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
#else
|
#else
|
||||||
|
@ -420,17 +419,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* otherwise, concatenate the device directory name and the
|
* otherwise, concatenate the device directory name and the
|
||||||
* device name.
|
* device name.
|
||||||
*/
|
*/
|
||||||
if (*device == '/')
|
if (*p->opt.source == '/')
|
||||||
strlcpy(dname, device, sizeof(dname));
|
strlcpy(dname, p->opt.source, sizeof(dname));
|
||||||
else
|
else
|
||||||
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||||
device);
|
p->opt.source);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the unit number, and a pointer to the end of the device
|
* Get the unit number, and a pointer to the end of the device
|
||||||
* type name.
|
* type name.
|
||||||
*/
|
*/
|
||||||
cp = split_dname(dname, &ppa, ebuf);
|
cp = split_dname(dname, &ppa, p->errbuf);
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
@ -444,7 +443,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/* Try device without unit number */
|
/* Try device without unit number */
|
||||||
if ((p->fd = open(dname, O_RDWR)) < 0) {
|
if ((p->fd = open(dname, O_RDWR)) < 0) {
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -467,10 +466,10 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* for the loopback interface is just a
|
* for the loopback interface is just a
|
||||||
* symptom of that inability.
|
* symptom of that inability.
|
||||||
*/
|
*/
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s: No DLPI device found", device);
|
"%s: No DLPI device found", device);
|
||||||
} else {
|
} else {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||||
dname2, pcap_strerror(errno));
|
dname2, pcap_strerror(errno));
|
||||||
}
|
}
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -480,13 +479,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p->snapshot = snaplen;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Attach if "style 2" provider
|
** Attach if "style 2" provider
|
||||||
*/
|
*/
|
||||||
if (dlinforeq(p->fd, ebuf) < 0 ||
|
if (dlinforeq(p->fd, p->errbuf) < 0 ||
|
||||||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
|
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
infop = &((union DL_primitives *)buf)->info_ack;
|
infop = &((union DL_primitives *)buf)->info_ack;
|
||||||
#ifdef HAVE_SOLARIS
|
#ifdef HAVE_SOLARIS
|
||||||
|
@ -494,11 +491,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
isatm = 1;
|
isatm = 1;
|
||||||
#endif
|
#endif
|
||||||
if (infop->dl_provider_style == DL_STYLE2) {
|
if (infop->dl_provider_style == DL_STYLE2) {
|
||||||
if (dl_doattach(p->fd, ppa, ebuf) < 0)
|
if (dl_doattach(p->fd, ppa, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
#ifdef DL_HP_RAWDLS
|
#ifdef DL_HP_RAWDLS
|
||||||
if (p->send_fd >= 0) {
|
if (p->send_fd >= 0) {
|
||||||
if (dl_doattach(p->send_fd, ppa, ebuf) < 0)
|
if (dl_doattach(p->send_fd, ppa, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -535,15 +532,15 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** assume the SAP value in a DLPI bind is an LLC SAP for network
|
** assume the SAP value in a DLPI bind is an LLC SAP for network
|
||||||
** types that use 802.2 LLC).
|
** types that use 802.2 LLC).
|
||||||
*/
|
*/
|
||||||
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
|
if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
|
||||||
dlbindreq(p->fd, 2, ebuf) < 0) ||
|
dlbindreq(p->fd, 2, p->errbuf) < 0) ||
|
||||||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
|
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
#elif defined(DL_HP_RAWDLS)
|
#elif defined(DL_HP_RAWDLS)
|
||||||
/*
|
/*
|
||||||
** HP-UX 10.0x and 10.1x.
|
** HP-UX 10.0x and 10.1x.
|
||||||
*/
|
*/
|
||||||
if (dl_dohpuxbind(p->fd, ebuf) < 0)
|
if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
if (p->send_fd >= 0) {
|
if (p->send_fd >= 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -551,7 +548,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** set it to -1, so that you can't send but can
|
** set it to -1, so that you can't send but can
|
||||||
** still receive?
|
** still receive?
|
||||||
*/
|
*/
|
||||||
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
|
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
#else /* neither AIX nor HP-UX */
|
#else /* neither AIX nor HP-UX */
|
||||||
|
@ -559,8 +556,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
|
** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
|
||||||
** OS using DLPI.
|
** OS using DLPI.
|
||||||
**/
|
**/
|
||||||
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
|
if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
|
||||||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
|
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
#endif /* AIX vs. HP-UX vs. other */
|
#endif /* AIX vs. HP-UX vs. other */
|
||||||
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
|
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
|
||||||
|
@ -574,18 +571,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** help, and may break things.
|
** help, and may break things.
|
||||||
*/
|
*/
|
||||||
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
|
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
pcap_strerror(errno));
|
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (promisc) {
|
if (p->opt.promisc) {
|
||||||
/*
|
/*
|
||||||
** Enable promiscuous (not necessary on send FD)
|
** Enable promiscuous (not necessary on send FD)
|
||||||
*/
|
*/
|
||||||
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
|
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
|
||||||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0)
|
dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -594,10 +591,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** HP-UX or SINIX) (Not necessary on send FD)
|
** HP-UX or SINIX) (Not necessary on send FD)
|
||||||
*/
|
*/
|
||||||
#if !defined(__hpux) && !defined(sinix)
|
#if !defined(__hpux) && !defined(sinix)
|
||||||
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
|
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
|
||||||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0)
|
dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf);
|
"WARNING: DL_PROMISC_MULTI failed (%s)\n",
|
||||||
|
p->errbuf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -608,17 +606,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
#ifndef sinix
|
#ifndef sinix
|
||||||
if (
|
if (
|
||||||
#ifdef __hpux
|
#ifdef __hpux
|
||||||
!promisc &&
|
!p->opt.promisc &&
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SOLARIS
|
#ifdef HAVE_SOLARIS
|
||||||
!isatm &&
|
!isatm &&
|
||||||
#endif
|
#endif
|
||||||
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
|
(dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
|
||||||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
|
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
|
||||||
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
|
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
|
||||||
if (promisc)
|
if (p->opt.promisc)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf);
|
"WARNING: DL_PROMISC_SAP failed (%s)\n", p->errbuf);
|
||||||
else
|
else
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -629,7 +627,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** promiscuous options.
|
** promiscuous options.
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
|
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
|
||||||
if (dl_dohpuxbind(p->fd, ebuf) < 0)
|
if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
/*
|
/*
|
||||||
** We don't set promiscuous mode on the send FD, but we'll defer
|
** We don't set promiscuous mode on the send FD, but we'll defer
|
||||||
|
@ -642,7 +640,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** set it to -1, so that you can't send but can
|
** set it to -1, so that you can't send but can
|
||||||
** still receive?
|
** still receive?
|
||||||
*/
|
*/
|
||||||
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
|
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -652,12 +650,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** XXX - get SAP length and address length as well, for use
|
** XXX - get SAP length and address length as well, for use
|
||||||
** when sending packets.
|
** when sending packets.
|
||||||
*/
|
*/
|
||||||
if (dlinforeq(p->fd, ebuf) < 0 ||
|
if (dlinforeq(p->fd, p->errbuf) < 0 ||
|
||||||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
|
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
infop = &((union DL_primitives *)buf)->info_ack;
|
infop = &((union DL_primitives *)buf)->info_ack;
|
||||||
if (pcap_process_mactype(p, infop->dl_mac_type, ebuf) != 0)
|
if (pcap_process_mactype(p, infop->dl_mac_type, p->errbuf) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
#ifdef DLIOCRAW
|
#ifdef DLIOCRAW
|
||||||
|
@ -666,13 +664,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** header.
|
** header.
|
||||||
*/
|
*/
|
||||||
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
|
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ss = snaplen;
|
ss = p->snapshot;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** There is a bug in bufmod(7). When dealing with messages of
|
** There is a bug in bufmod(7). When dealing with messages of
|
||||||
|
@ -695,7 +693,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
|
|
||||||
#ifdef HAVE_SYS_BUFMOD_H
|
#ifdef HAVE_SYS_BUFMOD_H
|
||||||
/* Push and configure bufmod. */
|
/* Push and configure bufmod. */
|
||||||
if (pcap_conf_bufmod(p, ss, to_ms, ebuf) != 0)
|
if (pcap_conf_bufmod(p, ss, p->md.timeout) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -703,13 +701,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
** As the last operation flush the read side.
|
** As the last operation flush the read side.
|
||||||
*/
|
*/
|
||||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate data buffer. */
|
/* Allocate data buffer. */
|
||||||
if (pcap_alloc_databuf(p, ebuf) != 0)
|
if (pcap_alloc_databuf(p) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -728,19 +726,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->stats_op = pcap_stats_dlpi;
|
p->stats_op = pcap_stats_dlpi;
|
||||||
p->close_op = pcap_close_dlpi;
|
p->close_op = pcap_close_dlpi;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (p->fd >= 0)
|
if (p->fd >= 0)
|
||||||
close(p->fd);
|
close(p->fd);
|
||||||
if (p->send_fd >= 0)
|
if (p->send_fd >= 0)
|
||||||
close(p->send_fd);
|
close(p->send_fd);
|
||||||
/*
|
return (PCAP_ERROR);
|
||||||
* Get rid of any link-layer type list we allocated.
|
|
||||||
*/
|
|
||||||
if (p->dlt_list != NULL)
|
|
||||||
free(p->dlt_list);
|
|
||||||
free(p);
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1649,3 +1641,16 @@ dlpi_kread(register int fd, register off_t addr,
|
||||||
return (cc);
|
return (cc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_dlpi;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
74
pcap-dos.c
74
pcap-dos.c
|
@ -5,7 +5,7 @@
|
||||||
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
|
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
|
||||||
* network drivers.
|
* network drivers.
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.3 2007-12-05 23:37:26 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -97,6 +97,7 @@ static volatile BOOL exc_occured = 0;
|
||||||
|
|
||||||
static struct device *handle_to_device [20];
|
static struct device *handle_to_device [20];
|
||||||
|
|
||||||
|
static void pcap_activate_dos (pcap_t *p);
|
||||||
static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
|
static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
|
||||||
u_char *data);
|
u_char *data);
|
||||||
static void pcap_close_dos (pcap_t *p);
|
static void pcap_close_dos (pcap_t *p);
|
||||||
|
@ -142,59 +143,68 @@ static struct device *get_device (int fd)
|
||||||
return handle_to_device [fd-1];
|
return handle_to_device [fd-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcap_t *pcap_create (const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_dos;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open MAC-driver with name 'device_name' for live capture of
|
* Open MAC-driver with name 'device_name' for live capture of
|
||||||
* network packets.
|
* network packets.
|
||||||
*/
|
*/
|
||||||
pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
|
static int pcap_activate_dos (pcap_t *pcap)
|
||||||
int timeout_ms, char *errbuf)
|
|
||||||
{
|
{
|
||||||
struct pcap *pcap;
|
int err = 0;
|
||||||
|
|
||||||
if (snaplen < ETH_MIN)
|
if (p->opt.rfmon) {
|
||||||
snaplen = ETH_MIN;
|
/*
|
||||||
|
* No monitor mode on DOS.
|
||||||
if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */
|
*/
|
||||||
snaplen = ETH_MAX;
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
|
|
||||||
pcap = calloc (sizeof(*pcap), 1);
|
|
||||||
if (!pcap)
|
|
||||||
{
|
|
||||||
strcpy (errbuf, "Not enough memory (pcap)");
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap->snapshot = max (ETH_MIN+8, snaplen);
|
if (pcap->snapshot < ETH_MIN+8)
|
||||||
|
pcap->snapshot = ETH_MIN+8;
|
||||||
|
|
||||||
|
if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */
|
||||||
|
pcap->snapshot = ETH_MAX;
|
||||||
|
|
||||||
pcap->linktype = DLT_EN10MB; /* !! */
|
pcap->linktype = DLT_EN10MB; /* !! */
|
||||||
pcap->inter_packet_wait = timeout_ms;
|
|
||||||
pcap->close_op = pcap_close_dos;
|
pcap->close_op = pcap_close_dos;
|
||||||
pcap->read_op = pcap_read_dos;
|
pcap->read_op = pcap_read_dos;
|
||||||
pcap->stats_op = pcap_stats_dos;
|
pcap->stats_op = pcap_stats_dos;
|
||||||
pcap->inject_op = pcap_sendpacket_dos;
|
pcap->inject_op = pcap_sendpacket_dos;
|
||||||
pcap->setfilter_op = pcap_setfilter_dos;
|
pcap->setfilter_op = pcap_setfilter_dos;
|
||||||
pcap->setdirection_op = NULL; /* Not implemented.*/
|
pcap->setdirection_op = NULL; /* Not implemented.*/
|
||||||
pcap->fd = ++ref_count;
|
pcap->fd = ++ref_count;
|
||||||
|
|
||||||
if (pcap->fd == 1) /* first time we're called */
|
if (pcap->fd == 1) /* first time we're called */
|
||||||
{
|
{
|
||||||
if (!init_watt32(pcap, device_name, errbuf) ||
|
if (!init_watt32(pcap, pcap->md.device, pcap->errbuf) ||
|
||||||
!first_init(device_name, errbuf, promisc))
|
!first_init(pcap->md.device, pcap->errbuf, pcap->opt.promisc))
|
||||||
{
|
{
|
||||||
free (pcap);
|
free (pcap);
|
||||||
return (NULL);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
atexit (close_driver);
|
atexit (close_driver);
|
||||||
}
|
}
|
||||||
else if (stricmp(active_dev->name,device_name))
|
else if (stricmp(active_dev->name,pcap->md.device))
|
||||||
{
|
{
|
||||||
snprintf (errbuf, PCAP_ERRBUF_SIZE,
|
snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Cannot use different devices simultaneously "
|
"Cannot use different devices simultaneously "
|
||||||
"(`%s' vs. `%s')", active_dev->name, device_name);
|
"(`%s' vs. `%s')", active_dev->name, pcap->md.device);
|
||||||
free (pcap);
|
free (pcap);
|
||||||
pcap = NULL;
|
err = PCAP_ERROR;
|
||||||
}
|
}
|
||||||
handle_to_device [pcap->fd-1] = active_dev;
|
handle_to_device [pcap->fd-1] = active_dev;
|
||||||
return (pcap);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -209,10 +219,10 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||||
BYTE *rx_buf;
|
BYTE *rx_buf;
|
||||||
int rx_len = 0;
|
int rx_len = 0;
|
||||||
|
|
||||||
if (p->inter_packet_wait > 0)
|
if (p->md.timeout > 0)
|
||||||
{
|
{
|
||||||
gettimeofday2 (&now, NULL);
|
gettimeofday2 (&now, NULL);
|
||||||
expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait;
|
expiry.tv_usec = now.tv_usec + 1000UL * p->md.timeout;
|
||||||
expiry.tv_sec = now.tv_sec;
|
expiry.tv_sec = now.tv_sec;
|
||||||
while (expiry.tv_usec >= 1000000L)
|
while (expiry.tv_usec >= 1000000L)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +294,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||||
/* If not to wait for a packet or pcap_close() called from
|
/* If not to wait for a packet or pcap_close() called from
|
||||||
* e.g. SIGINT handler, exit loop now.
|
* e.g. SIGINT handler, exit loop now.
|
||||||
*/
|
*/
|
||||||
if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0)
|
if (p->md.timeout <= 0 || (volatile int)p->fd <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gettimeofday2 (&now, NULL);
|
gettimeofday2 (&now, NULL);
|
||||||
|
@ -476,7 +486,7 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
|
||||||
{
|
{
|
||||||
if (!_watt_is_init)
|
if (!_watt_is_init)
|
||||||
{
|
{
|
||||||
strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be "
|
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
|
||||||
"called first");
|
"called first");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -587,7 +597,7 @@ void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
p->wait_proc = yield;
|
p->wait_proc = yield;
|
||||||
p->inter_packet_wait = wait;
|
p->md.timeout = wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +749,7 @@ static void exc_handler (int sig)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the pcap device for the first client calling pcap_open_live()
|
* Open the pcap device for the first client calling pcap_activate()
|
||||||
*/
|
*/
|
||||||
static int first_init (const char *name, char *ebuf, int promisc)
|
static int first_init (const char *name, char *ebuf, int promisc)
|
||||||
{
|
{
|
||||||
|
|
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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.88 2008-03-13 18:13:57 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.89 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef pcap_int_h
|
#ifndef pcap_int_h
|
||||||
|
@ -96,6 +96,9 @@ typedef enum {
|
||||||
MAYBE_SWAPPED
|
MAYBE_SWAPPED
|
||||||
} swapped_type_t;
|
} swapped_type_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used when reading a savefile.
|
||||||
|
*/
|
||||||
struct pcap_sf {
|
struct pcap_sf {
|
||||||
FILE *rfile;
|
FILE *rfile;
|
||||||
int swapped;
|
int swapped;
|
||||||
|
@ -106,6 +109,9 @@ struct pcap_sf {
|
||||||
u_char *base;
|
u_char *base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used when doing a live capture.
|
||||||
|
*/
|
||||||
struct pcap_md {
|
struct pcap_md {
|
||||||
struct pcap_stat stat;
|
struct pcap_stat stat;
|
||||||
/*XXX*/
|
/*XXX*/
|
||||||
|
@ -116,18 +122,17 @@ struct pcap_md {
|
||||||
long TotMissed; /* missed by i/f during this run */
|
long TotMissed; /* missed by i/f during this run */
|
||||||
long OrigMissed; /* missed by i/f before this run */
|
long OrigMissed; /* missed by i/f before this run */
|
||||||
char *device; /* device name */
|
char *device; /* device name */
|
||||||
|
int timeout; /* timeout for buffering */
|
||||||
|
int must_clear; /* stuff we must clear when we close */
|
||||||
|
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
int sock_packet; /* using Linux 2.0 compatible interface */
|
int sock_packet; /* using Linux 2.0 compatible interface */
|
||||||
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
|
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
|
||||||
int ifindex; /* interface index of device we're bound to */
|
int ifindex; /* interface index of device we're bound to */
|
||||||
int lo_ifindex; /* interface index of the loopback device */
|
int lo_ifindex; /* interface index of the loopback device */
|
||||||
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
|
|
||||||
u_int packets_read; /* count of packets read with recvfrom() */
|
u_int packets_read; /* count of packets read with recvfrom() */
|
||||||
|
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
|
||||||
#endif /* linux */
|
#endif /* linux */
|
||||||
#if defined(linux) || defined(SITA)
|
|
||||||
int timeout; /* timeout specified to pcap_open_live */
|
|
||||||
int clear_promisc; /* must clear promiscuous mode when we close */
|
|
||||||
#endif /* linux || SITA */
|
|
||||||
|
|
||||||
#ifdef HAVE_DAG_API
|
#ifdef HAVE_DAG_API
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
|
@ -147,6 +152,19 @@ struct pcap_md {
|
||||||
#endif /* HAVE_DAG_API */
|
#endif /* HAVE_DAG_API */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stuff to clear when we close.
|
||||||
|
*/
|
||||||
|
#define MUST_CLEAR_PROMISC 0x00000001 /* promiscuous mode */
|
||||||
|
#define MUST_CLEAR_RFMON 0x00000002 /* rfmon (monitor) mode */
|
||||||
|
|
||||||
|
struct pcap_opt {
|
||||||
|
int buffer_size;
|
||||||
|
char *source;
|
||||||
|
int promisc;
|
||||||
|
int rfmon;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
|
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
|
||||||
* Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
|
* Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
|
||||||
|
@ -160,11 +178,27 @@ struct pcap_md {
|
||||||
#define PCAP_FDDIPAD 3
|
#define PCAP_FDDIPAD 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef int (*activate_op_t)(pcap_t *);
|
||||||
|
typedef int (*can_set_rfmon_op_t)(pcap_t *);
|
||||||
|
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||||
|
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
|
||||||
|
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
|
||||||
|
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
|
||||||
|
typedef int (*set_datalink_op_t)(pcap_t *, int);
|
||||||
|
typedef int (*getnonblock_op_t)(pcap_t *, char *);
|
||||||
|
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
|
||||||
|
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef int (*setbuff_op_t)(pcap_t *, int);
|
||||||
|
typedef int (*setmode_op_t)(pcap_t *, int);
|
||||||
|
typedef int (*setmintocopy_op_t)(pcap_t *, int);
|
||||||
|
#endif
|
||||||
|
typedef void (*close_op_t)(pcap_t *);
|
||||||
|
|
||||||
struct pcap {
|
struct pcap {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ADAPTER *adapter;
|
ADAPTER *adapter;
|
||||||
LPPACKET Packet;
|
LPPACKET Packet;
|
||||||
int timeout;
|
|
||||||
int nonblock;
|
int nonblock;
|
||||||
#else
|
#else
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -180,6 +214,8 @@ struct pcap {
|
||||||
int linktype_ext; /* Extended information stored in the linktype field of a file */
|
int linktype_ext; /* Extended information stored in the linktype field of a file */
|
||||||
int tzoff; /* timezone offset */
|
int tzoff; /* timezone offset */
|
||||||
int offset; /* offset for proper alignment */
|
int offset; /* offset for proper alignment */
|
||||||
|
int activated; /* true if the capture is really started */
|
||||||
|
int oldstyle; /* if we're opening with pcap_open_live() */
|
||||||
|
|
||||||
int break_loop; /* flag set to force break from packet-reading loop */
|
int break_loop; /* flag set to force break from packet-reading loop */
|
||||||
|
|
||||||
|
@ -188,12 +224,12 @@ struct pcap {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MSDOS
|
#ifdef MSDOS
|
||||||
int inter_packet_wait; /* offline: wait between packets */
|
|
||||||
void (*wait_proc)(void); /* call proc while waiting */
|
void (*wait_proc)(void); /* call proc while waiting */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct pcap_sf sf;
|
struct pcap_sf sf;
|
||||||
struct pcap_md md;
|
struct pcap_md md;
|
||||||
|
struct pcap_opt opt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read buffer.
|
* Read buffer.
|
||||||
|
@ -214,30 +250,27 @@ struct pcap {
|
||||||
/*
|
/*
|
||||||
* Methods.
|
* Methods.
|
||||||
*/
|
*/
|
||||||
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
|
activate_op_t activate_op;
|
||||||
int (*inject_op)(pcap_t *, const void *, size_t);
|
can_set_rfmon_op_t can_set_rfmon_op;
|
||||||
int (*setfilter_op)(pcap_t *, struct bpf_program *);
|
read_op_t read_op;
|
||||||
int (*setdirection_op)(pcap_t *, pcap_direction_t);
|
inject_op_t inject_op;
|
||||||
int (*set_datalink_op)(pcap_t *, int);
|
setfilter_op_t setfilter_op;
|
||||||
int (*getnonblock_op)(pcap_t *, char *);
|
setdirection_op_t setdirection_op;
|
||||||
int (*setnonblock_op)(pcap_t *, int, char *);
|
set_datalink_op_t set_datalink_op;
|
||||||
int (*stats_op)(pcap_t *, struct pcap_stat *);
|
getnonblock_op_t getnonblock_op;
|
||||||
#ifdef WIN32
|
setnonblock_op_t setnonblock_op;
|
||||||
/*
|
stats_op_t stats_op;
|
||||||
* Win32-only; given the way the buffer size is set with BPF,
|
|
||||||
* to make this cross-platform we'll have to set the buffer
|
|
||||||
* size at open time.
|
|
||||||
*/
|
|
||||||
int (*setbuff_op)(pcap_t *, int);
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
/*
|
/*
|
||||||
* These are, at least currently, specific to the Win32 NPF
|
* These are, at least currently, specific to the Win32 NPF
|
||||||
* driver.
|
* driver.
|
||||||
*/
|
*/
|
||||||
int (*setmode_op)(pcap_t *, int);
|
setbuff_op_t setbuff_op;
|
||||||
int (*setmintocopy_op)(pcap_t *, int);
|
setmode_op_t setmode_op;
|
||||||
|
setmintocopy_op_t setmintocopy_op;
|
||||||
#endif
|
#endif
|
||||||
void (*close_op)(pcap_t *);
|
close_op_t close_op;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Placeholder for filter code if bpf not in kernel.
|
* Placeholder for filter code if bpf not in kernel.
|
||||||
|
@ -354,7 +387,13 @@ int pcap_getnonblock_fd(pcap_t *, char *);
|
||||||
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pcap_t *pcap_create_common(const char *, char *);
|
||||||
|
int pcap_do_addexit(pcap_t *);
|
||||||
|
void pcap_add_to_pcaps_to_close(pcap_t *);
|
||||||
|
void pcap_remove_from_pcaps_to_close(pcap_t *);
|
||||||
void pcap_close_common(pcap_t *);
|
void pcap_close_common(pcap_t *);
|
||||||
|
int pcap_not_initialized(pcap_t *);
|
||||||
|
int pcap_check_activated(pcap_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal interfaces for "pcap_findalldevs()".
|
* Internal interfaces for "pcap_findalldevs()".
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.3 2008-03-15 04:26:14 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -96,57 +96,54 @@ list_interfaces(const char *linkname, void *arg)
|
||||||
return (B_FALSE);
|
return (B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_libdlpi(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
int retv;
|
int retv;
|
||||||
pcap_t *p;
|
|
||||||
dlpi_handle_t dh;
|
dlpi_handle_t dh;
|
||||||
dlpi_info_t dlinfo;
|
dlpi_info_t dlinfo;
|
||||||
|
|
||||||
if ((p = (pcap_t *)malloc(sizeof(*p))) == NULL) {
|
if (p->opt.rfmon) {
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
/*
|
||||||
return (NULL);
|
* No monitor mode on any platforms that support DLPI.
|
||||||
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
}
|
}
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
p->fd = -1; /* indicate that it hasn't been opened yet */
|
p->fd = -1; /* indicate that it hasn't been opened yet */
|
||||||
p->send_fd = -1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable Solaris raw and passive DLPI extensions;
|
* Enable Solaris raw and passive DLPI extensions;
|
||||||
* dlpi_open() will not fail if the underlying link does not support
|
* dlpi_open() will not fail if the underlying link does not support
|
||||||
* passive mode. See dlpi(7P) for details.
|
* passive mode. See dlpi(7P) for details.
|
||||||
*/
|
*/
|
||||||
retv = dlpi_open(device, &dh, DLPI_RAW|DLPI_PASSIVE);
|
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
|
||||||
if (retv != DLPI_SUCCESS) {
|
if (retv != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(device, "dlpi_open", retv, ebuf);
|
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->dlpi_hd = dh;
|
p->dlpi_hd = dh;
|
||||||
|
|
||||||
p->snapshot = snaplen;
|
|
||||||
|
|
||||||
/* Bind with DLPI_ANY_SAP. */
|
/* Bind with DLPI_ANY_SAP. */
|
||||||
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(device, "dlpi_bind", retv, ebuf);
|
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable promiscuous mode. */
|
/* Enable promiscuous mode. */
|
||||||
if (promisc) {
|
if (p->opt.promisc) {
|
||||||
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
|
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
|
||||||
if (retv != DLPI_SUCCESS) {
|
if (retv != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(device, "dlpi_promisc(PHYSICAL)",
|
pcap_libdlpi_err(p->opt.source,
|
||||||
retv, ebuf);
|
"dlpi_promisc(PHYSICAL)", retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Try to enable multicast. */
|
/* Try to enable multicast. */
|
||||||
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
|
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
|
||||||
if (retv != DLPI_SUCCESS) {
|
if (retv != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(device, "dlpi_promisc(MULTI)",
|
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
|
||||||
retv, ebuf);
|
retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,42 +151,42 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/* Try to enable SAP promiscuity. */
|
/* Try to enable SAP promiscuity. */
|
||||||
if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) {
|
||||||
if (!promisc) {
|
if (!promisc) {
|
||||||
pcap_libdlpi_err(device, "dlpi_promisc(SAP)",
|
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
|
||||||
retv, ebuf);
|
retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
|
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
|
||||||
fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
|
fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
|
||||||
" %s:(%s)\n", device, dlpi_strerror(retv));
|
" %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine link type. */
|
/* Determine link type. */
|
||||||
if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(device, "dlpi_info", retv, ebuf);
|
pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcap_process_mactype(p, dlinfo.di_mactype, ebuf) != 0)
|
if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
p->fd = dlpi_fd(p->dlpi_hd);
|
p->fd = dlpi_fd(p->dlpi_hd);
|
||||||
|
|
||||||
/* Push and configure bufmod. */
|
/* Push and configure bufmod. */
|
||||||
if (pcap_conf_bufmod(p, snaplen, to_ms, ebuf) != 0)
|
if (pcap_conf_bufmod(p, snaplen, p->md.timeout) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush the read side.
|
* Flush the read side.
|
||||||
*/
|
*/
|
||||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate data buffer. */
|
/* Allocate data buffer. */
|
||||||
if (pcap_alloc_databuf(p, ebuf) != 0)
|
if (pcap_alloc_databuf(p) != 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -208,14 +205,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->stats_op = pcap_stats_dlpi;
|
p->stats_op = pcap_stats_dlpi;
|
||||||
p->close_op = pcap_close_libdlpi;
|
p->close_op = pcap_close_libdlpi;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
/* Get rid of any link-layer type list we allocated. */
|
/* Get rid of any link-layer type list we allocated. */
|
||||||
if (p->dlt_list != NULL)
|
if (p->dlt_list != NULL)
|
||||||
free(p->dlt_list);
|
free(p->dlt_list);
|
||||||
pcap_close_libdlpi(p);
|
dlpi_close(p->dlpi_hd);
|
||||||
free(p);
|
return (PCAP_ERROR);
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -352,3 +348,16 @@ pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
|
||||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
|
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
|
||||||
func, linkname, dlpi_strerror(err));
|
func, linkname, dlpi_strerror(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_libdlpi;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
1762
pcap-linux.c
1762
pcap-linux.c
File diff suppressed because it is too large
Load Diff
72
pcap-nit.c
72
pcap-nit.c
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.60 2008-02-02 20:58:18 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.61 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -237,51 +237,43 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
pcap_close_nit(pcap_t *p)
|
pcap_activate_nit(pcap_t *p)
|
||||||
{
|
|
||||||
pcap_close_common(p);
|
|
||||||
if (p->device != NULL)
|
|
||||||
free(p->device);
|
|
||||||
}
|
|
||||||
|
|
||||||
pcap_t *
|
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_nit snit;
|
struct sockaddr_nit snit;
|
||||||
register pcap_t *p;
|
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
if (p->opt.rfmon) {
|
||||||
if (p == NULL) {
|
/*
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
* No monitor mode on SunOS 3.x or earlier (no
|
||||||
return (NULL);
|
* Wi-Fi *devices* for the hardware that supported
|
||||||
|
* them!).
|
||||||
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snaplen < 96)
|
if (p->snapshot < 96)
|
||||||
/*
|
/*
|
||||||
* NIT requires a snapshot length of at least 96.
|
* NIT requires a snapshot length of at least 96.
|
||||||
*/
|
*/
|
||||||
snaplen = 96;
|
p->snapshot = 96;
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
|
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"socket: %s", pcap_strerror(errno));
|
"socket: %s", pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
snit.snit_family = AF_NIT;
|
snit.snit_family = AF_NIT;
|
||||||
(void)strncpy(snit.snit_ifname, device, NITIFSIZ);
|
(void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ);
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
|
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
|
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->snapshot = snaplen;
|
nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf);
|
||||||
nit_setflags(p->fd, promisc, to_ms, ebuf);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NIT supports only ethernets.
|
* NIT supports only ethernets.
|
||||||
|
@ -291,17 +283,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = (u_char *)malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need the device name in order to send packets.
|
|
||||||
*/
|
|
||||||
p->device = strdup(device);
|
|
||||||
if (p->device == NULL) {
|
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
|
||||||
free(p->buffer);
|
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,14 +320,26 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->getnonblock_op = pcap_getnonblock_fd;
|
p->getnonblock_op = pcap_getnonblock_fd;
|
||||||
p->setnonblock_op = pcap_setnonblock_fd;
|
p->setnonblock_op = pcap_setnonblock_fd;
|
||||||
p->stats_op = pcap_stats_nit;
|
p->stats_op = pcap_stats_nit;
|
||||||
p->close_op = pcap_close_nit;
|
p->close_op = pcap_close_common;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
free(p);
|
return (PCAP_ERROR);
|
||||||
return (NULL);
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_nit;
|
||||||
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.21 2003-11-15 23:24:03 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.22 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -40,10 +40,9 @@ static const char rcsid[] _U_ =
|
||||||
static char nosup[] = "live packet capture not supported on this system";
|
static char nosup[] = "live packet capture not supported on this system";
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
(void)strlcpy(p->errbuf, nosup, PCAP_ERRBUF_SIZE);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
77
pcap-pf.c
77
pcap-pf.c
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.95 2007-12-05 23:37:26 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.96 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -291,23 +291,14 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
|
||||||
#define DLT_DOCSIS 143
|
#define DLT_DOCSIS 143
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_pf(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
|
||||||
short enmode;
|
short enmode;
|
||||||
int backlog = -1; /* request the most */
|
int backlog = -1; /* request the most */
|
||||||
struct enfilter Filter;
|
struct enfilter Filter;
|
||||||
struct endevp devparams;
|
struct endevp devparams;
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
|
||||||
if (p == NULL) {
|
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
|
||||||
"pcap_open_live: %s", pcap_strerror(errno));
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
/*
|
/*
|
||||||
* Initially try a read/write open (to allow the inject
|
* Initially try a read/write open (to allow the inject
|
||||||
* method to work). If that fails due to permission
|
* method to work). If that fails due to permission
|
||||||
|
@ -327,21 +318,21 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* "const char *" as its first argument. That appears to be
|
* "const char *" as its first argument. That appears to be
|
||||||
* the case, at least on Digital UNIX 4.0.
|
* the case, at least on Digital UNIX 4.0.
|
||||||
*/
|
*/
|
||||||
p->fd = pfopen(device, O_RDWR);
|
p->fd = pfopen(p->opt.source, O_RDWR);
|
||||||
if (p->fd == -1 && errno == EACCES)
|
if (p->fd == -1 && errno == EACCES)
|
||||||
p->fd = pfopen(device, O_RDONLY);
|
p->fd = pfopen(p->opt.source, O_RDONLY);
|
||||||
if (p->fd < 0) {
|
if (p->fd < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
|
||||||
your system may not be properly configured; see the packetfilter(4) man page\n",
|
your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
device, pcap_strerror(errno));
|
p->opt.source, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->md.OrigMissed = -1;
|
p->md.OrigMissed = -1;
|
||||||
enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
|
enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
|
||||||
if (promisc)
|
if (p->opt.promisc)
|
||||||
enmode |= ENPROMISC;
|
enmode |= ENPROMISC;
|
||||||
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
|
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -352,13 +343,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
#endif
|
#endif
|
||||||
/* set the backlog */
|
/* set the backlog */
|
||||||
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
|
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
/* discover interface type */
|
/* discover interface type */
|
||||||
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
|
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -440,8 +431,8 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
* framing", there's not much we can do, as that
|
* framing", there's not much we can do, as that
|
||||||
* doesn't specify a particular type of header.
|
* doesn't specify a particular type of header.
|
||||||
*/
|
*/
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
devparams.end_dev_type);
|
"unknown data-link type %u", devparams.end_dev_type);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
/* set truncation */
|
/* set truncation */
|
||||||
|
@ -450,32 +441,31 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
p->fddipad = PCAP_FDDIPAD;
|
p->fddipad = PCAP_FDDIPAD;
|
||||||
|
|
||||||
/* packetfilter includes the padding in the snapshot */
|
/* packetfilter includes the padding in the snapshot */
|
||||||
snaplen += PCAP_FDDIPAD;
|
p->snapshot += PCAP_FDDIPAD;
|
||||||
} else
|
} else
|
||||||
p->fddipad = 0;
|
p->fddipad = 0;
|
||||||
#endif
|
#endif
|
||||||
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
|
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->snapshot = snaplen;
|
|
||||||
/* accept all packets */
|
/* accept all packets */
|
||||||
memset(&Filter, 0, sizeof(Filter));
|
memset(&Filter, 0, sizeof(Filter));
|
||||||
Filter.enf_Priority = 37; /* anything > 2 */
|
Filter.enf_Priority = 37; /* anything > 2 */
|
||||||
Filter.enf_FilterLen = 0; /* means "always true" */
|
Filter.enf_FilterLen = 0; /* means "always true" */
|
||||||
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
|
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_ms != 0) {
|
if (p->md.timeout != 0) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = to_ms / 1000;
|
timeout.tv_sec = p->md.timeout / 1000;
|
||||||
timeout.tv_usec = (to_ms * 1000) % 1000000;
|
timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
|
||||||
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
|
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -484,7 +474,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
|
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,17 +493,24 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
p->stats_op = pcap_stats_pf;
|
p->stats_op = pcap_stats_pf;
|
||||||
p->close_op = pcap_close_common;
|
p->close_op = pcap_close_common;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (p->fd >= 0)
|
if (p->fd >= 0)
|
||||||
close(p->fd);
|
close(p->fd);
|
||||||
/*
|
return (PCAP_ERROR);
|
||||||
* Get rid of any link-layer type list we allocated.
|
}
|
||||||
*/
|
|
||||||
if (p->dlt_list != NULL)
|
pcap_t *
|
||||||
free(p->dlt_list);
|
pcap_create(const char *device, char *ebuf)
|
||||||
free(p);
|
{
|
||||||
return (NULL);
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_pf;
|
||||||
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.2 2005-06-21 01:03:03 guy Exp $";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.3 2008-04-04 19:37:45 guy Exp $";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -50,8 +50,8 @@ static const char rcsid[] _U_ =
|
||||||
/* This code is required when compiling for a Septel device only. */
|
/* This code is required when compiling for a Septel device only. */
|
||||||
#include "pcap-septel.h"
|
#include "pcap-septel.h"
|
||||||
|
|
||||||
/* Replace dag function names with pcap equivalent. */
|
/* Replace septel function names with pcap equivalent. */
|
||||||
#define septel_open_live pcap_open_live
|
#define septel_create pcap_create
|
||||||
#define septel_platform_finddevs pcap_platform_finddevs
|
#define septel_platform_finddevs pcap_platform_finddevs
|
||||||
#endif /* SEPTEL_ONLY */
|
#endif /* SEPTEL_ONLY */
|
||||||
|
|
||||||
|
@ -199,28 +199,14 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a handle for a live capture from the given Septel device. Always pass a NULL device
|
* Activate a handle for a live capture from the given Septel device. Always pass a NULL device
|
||||||
* The promisc flag is ignored because Septel cards have built-in tracing.
|
* The promisc flag is ignored because Septel cards have built-in tracing.
|
||||||
* The to_ms parameter is also ignored as it is
|
* The timeout is also ignored as it is not supported in hardware.
|
||||||
* not supported in hardware.
|
|
||||||
*
|
*
|
||||||
* See also pcap(3).
|
* See also pcap(3).
|
||||||
*/
|
*/
|
||||||
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
|
static pcap_t *septel_activate(pcap_t* handle) {
|
||||||
pcap_t *handle;
|
/* Initialize some components of the pcap structure. */
|
||||||
|
|
||||||
handle = malloc(sizeof(*handle));
|
|
||||||
if (handle == NULL) {
|
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
|
||||||
|
|
||||||
memset(handle, 0, sizeof(*handle));
|
|
||||||
|
|
||||||
handle->snapshot = snaplen;
|
|
||||||
|
|
||||||
handle->linktype = DLT_MTP2;
|
handle->linktype = DLT_MTP2;
|
||||||
|
|
||||||
handle->bufsize = 0;
|
handle->bufsize = 0;
|
||||||
|
@ -239,14 +225,18 @@ pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms
|
||||||
handle->stats_op = septel_stats;
|
handle->stats_op = septel_stats;
|
||||||
handle->close_op = septel_platform_close;
|
handle->close_op = septel_platform_close;
|
||||||
|
|
||||||
return handle;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
pcap_t *septel_create(const char *device, char *ebuf) {
|
||||||
if (handle != NULL) {
|
pcap_t *p;
|
||||||
free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p->activate_op = septel_activate;
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
|
static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
||||||
* (+961 3 485343);
|
* (+961 3 485343);
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1 2005-06-20 21:27:10 guy Exp $
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.2 2008-04-04 19:37:45 guy Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
|
pcap_t *septel_create(const char *device, char *ebuf);
|
||||||
|
|
||||||
|
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
|
static int pcap_activate_sita(pcap_t *handle) {
|
||||||
pcap_t *handle;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* Allocate a handle for this session. */
|
if (handle->opt.rfmon) {
|
||||||
|
/*
|
||||||
handle = malloc(sizeof(*handle));
|
* No monitor mode on SITA devices (they're not Wi-Fi
|
||||||
if (handle == NULL) {
|
* devices).
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
*/
|
||||||
pcap_strerror(errno));
|
return PCAP_ERROR_RFMON_NOTSUP;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
/* Initialize some components of the pcap structure. */
|
||||||
|
|
||||||
memset(handle, 0, sizeof(*handle));
|
|
||||||
handle->snapshot = snaplen;
|
|
||||||
handle->md.timeout = to_ms;
|
|
||||||
|
|
||||||
handle->inject_op = pcap_inject_acn;
|
handle->inject_op = pcap_inject_acn;
|
||||||
handle->setfilter_op = pcap_setfilter_acn;
|
handle->setfilter_op = pcap_setfilter_acn;
|
||||||
handle->setdirection_op = pcap_setdirection_acn;
|
handle->setdirection_op = pcap_setdirection_acn;
|
||||||
|
@ -946,12 +940,11 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
handle->read_op = pcap_read_acn;
|
handle->read_op = pcap_read_acn;
|
||||||
handle->stats_op = pcap_stats_acn;
|
handle->stats_op = pcap_stats_acn;
|
||||||
|
|
||||||
fd = acn_open_live(device, ebuf, &handle->linktype);
|
fd = acn_open_live(handle->opt.source, handle->errbuf,
|
||||||
if (fd == -1) {
|
&handle->linktype);
|
||||||
free(handle);
|
if (fd == -1)
|
||||||
return NULL;
|
return PCAP_ERROR;
|
||||||
}
|
handle->md.clear_promisc = handle->md.promisc;
|
||||||
handle->md.clear_promisc = promisc;
|
|
||||||
handle->fd = fd;
|
handle->fd = fd;
|
||||||
handle->bufsize = handle->snapshot;
|
handle->bufsize = handle->snapshot;
|
||||||
|
|
||||||
|
@ -959,11 +952,10 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize + handle->offset);
|
handle->buffer = malloc(handle->bufsize + handle->offset);
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
pcap_close_acn(handle);
|
pcap_close_acn(handle);
|
||||||
free(handle);
|
return PCAP_ERROR;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -972,5 +964,16 @@ pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
*/
|
*/
|
||||||
handle->selectable_fd = handle->fd;
|
handle->selectable_fd = handle->fd;
|
||||||
|
|
||||||
return handle;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_t *pcap_create(const char *device, char *ebuf) {
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_sita;
|
||||||
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
64
pcap-snit.c
64
pcap-snit.c
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.75 2008-02-02 20:58:18 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.76 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -260,30 +260,29 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_snit(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
struct strioctl si; /* struct for ioctl() */
|
struct strioctl si; /* struct for ioctl() */
|
||||||
struct ifreq ifr; /* interface request struct */
|
struct ifreq ifr; /* interface request struct */
|
||||||
int chunksize = CHUNKSIZE;
|
int chunksize = CHUNKSIZE;
|
||||||
int fd;
|
int fd;
|
||||||
static char dev[] = "/dev/nit";
|
static char dev[] = "/dev/nit";
|
||||||
register pcap_t *p;
|
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
if (p->opt.rfmon) {
|
||||||
if (p == NULL) {
|
/*
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
* No monitor mode on SunOS 4.x (no Wi-Fi devices on
|
||||||
return (NULL);
|
* hardware supported by SunOS 4.x).
|
||||||
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snaplen < 96)
|
if (p->snapshot < 96)
|
||||||
/*
|
/*
|
||||||
* NIT requires a snapshot length of at least 96.
|
* NIT requires a snapshot length of at least 96.
|
||||||
*/
|
*/
|
||||||
snaplen = 96;
|
p->snapshot = 96;
|
||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
/*
|
/*
|
||||||
* Initially try a read/write open (to allow the inject
|
* Initially try a read/write open (to allow the inject
|
||||||
* method to work). If that fails due to permission
|
* method to work). If that fails due to permission
|
||||||
|
@ -302,19 +301,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
if (fd < 0 && errno == EACCES)
|
if (fd < 0 && errno == EACCES)
|
||||||
p->fd = fd = open(dev, O_RDONLY);
|
p->fd = fd = open(dev, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
|
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
|
||||||
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
|
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
|
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -324,34 +323,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
si.ic_len = sizeof(chunksize);
|
si.ic_len = sizeof(chunksize);
|
||||||
si.ic_dp = (char *)&chunksize;
|
si.ic_dp = (char *)&chunksize;
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* request the interface */
|
/* request the interface */
|
||||||
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
|
||||||
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
||||||
si.ic_cmd = NIOCBIND;
|
si.ic_cmd = NIOCBIND;
|
||||||
si.ic_len = sizeof(ifr);
|
si.ic_len = sizeof(ifr);
|
||||||
si.ic_dp = (char *)𝔦
|
si.ic_dp = (char *)𝔦
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
|
||||||
ifr.ifr_name, pcap_strerror(errno));
|
ifr.ifr_name, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the snapshot length */
|
/* set the snapshot length */
|
||||||
si.ic_cmd = NIOCSSNAP;
|
si.ic_cmd = NIOCSSNAP;
|
||||||
si.ic_len = sizeof(snaplen);
|
si.ic_len = sizeof(p->snapshot);
|
||||||
si.ic_dp = (char *)&snaplen;
|
si.ic_dp = (char *)&p->snapshot;
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->snapshot = snaplen;
|
if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
|
||||||
if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
|
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
|
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
|
||||||
|
@ -363,7 +361,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = (u_char *)malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,12 +401,24 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->stats_op = pcap_stats_snit;
|
p->stats_op = pcap_stats_snit;
|
||||||
p->close_op = pcap_close_common;
|
p->close_op = pcap_close_common;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
free(p);
|
return (PCAP_ERROR);
|
||||||
return (NULL);
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_snit;
|
||||||
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
111
pcap-snoop.c
111
pcap-snoop.c
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.55 2005-05-03 18:54:00 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.56 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -194,9 +194,8 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX can't disable promiscuous */
|
/* XXX can't disable promiscuous */
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_snoop(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_raw sr;
|
struct sockaddr_raw sr;
|
||||||
|
@ -204,34 +203,34 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
u_int v;
|
u_int v;
|
||||||
int ll_hdrlen;
|
int ll_hdrlen;
|
||||||
int snooplen;
|
int snooplen;
|
||||||
pcap_t *p;
|
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
if (p->opt.rfmon) {
|
||||||
if (p == NULL) {
|
/*
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
* No monitor mode on Irix (no Wi-Fi devices on
|
||||||
pcap_strerror(errno));
|
* hardware supported by Irix).
|
||||||
return (NULL);
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
}
|
}
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
|
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->fd = fd;
|
p->fd = fd;
|
||||||
memset(&sr, 0, sizeof(sr));
|
memset(&sr, 0, sizeof(sr));
|
||||||
sr.sr_family = AF_RAW;
|
sr.sr_family = AF_RAW;
|
||||||
(void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
|
(void)strncpy(sr.sr_ifname, p->opt.source, sizeof(sr.sr_ifname));
|
||||||
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
|
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
memset(&sf, 0, sizeof(sf));
|
memset(&sf, 0, sizeof(sf));
|
||||||
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
|
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -240,19 +239,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/*
|
/*
|
||||||
* XXX hack - map device name to link layer type
|
* XXX hack - map device name to link layer type
|
||||||
*/
|
*/
|
||||||
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */
|
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
|
||||||
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
||||||
O2 10/100 */
|
O2 10/100 */
|
||||||
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */
|
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
|
||||||
strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
||||||
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */
|
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
|
||||||
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */
|
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
|
||||||
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
||||||
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */
|
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
|
||||||
strncmp("fa", device, 2) == 0 ||
|
strncmp("fa", p->opt.source, 2) == 0 ||
|
||||||
strncmp("qaa", device, 3) == 0 ||
|
strncmp("qaa", p->opt.source, 3) == 0 ||
|
||||||
strncmp("cip", device, 3) == 0 ||
|
strncmp("cip", p->opt.source, 3) == 0 ||
|
||||||
strncmp("el", device, 2) == 0) {
|
strncmp("el", p->opt.source, 2) == 0) {
|
||||||
p->linktype = DLT_EN10MB;
|
p->linktype = DLT_EN10MB;
|
||||||
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
||||||
ll_hdrlen = sizeof(struct ether_header);
|
ll_hdrlen = sizeof(struct ether_header);
|
||||||
|
@ -285,26 +284,26 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->dlt_list[1] = DLT_DOCSIS;
|
p->dlt_list[1] = DLT_DOCSIS;
|
||||||
p->dlt_count = 2;
|
p->dlt_count = 2;
|
||||||
}
|
}
|
||||||
} else if (strncmp("ipg", device, 3) == 0 ||
|
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
|
||||||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
|
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
|
||||||
strncmp("xpi", device, 3) == 0) {
|
strncmp("xpi", p->opt.source, 3) == 0) {
|
||||||
p->linktype = DLT_FDDI;
|
p->linktype = DLT_FDDI;
|
||||||
p->offset = 3; /* XXX yeah? */
|
p->offset = 3; /* XXX yeah? */
|
||||||
ll_hdrlen = 13;
|
ll_hdrlen = 13;
|
||||||
} else if (strncmp("ppp", device, 3) == 0) {
|
} else if (strncmp("ppp", p->opt.source, 3) == 0) {
|
||||||
p->linktype = DLT_RAW;
|
p->linktype = DLT_RAW;
|
||||||
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
|
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
|
||||||
} else if (strncmp("qfa", device, 3) == 0) {
|
} else if (strncmp("qfa", p->opt.source, 3) == 0) {
|
||||||
p->linktype = DLT_IP_OVER_FC;
|
p->linktype = DLT_IP_OVER_FC;
|
||||||
ll_hdrlen = 24;
|
ll_hdrlen = 24;
|
||||||
} else if (strncmp("pl", device, 2) == 0) {
|
} else if (strncmp("pl", p->opt.source, 2) == 0) {
|
||||||
p->linktype = DLT_RAW;
|
p->linktype = DLT_RAW;
|
||||||
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
|
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
|
||||||
} else if (strncmp("lo", device, 2) == 0) {
|
} else if (strncmp("lo", p->opt.source, 2) == 0) {
|
||||||
p->linktype = DLT_NULL;
|
p->linktype = DLT_NULL;
|
||||||
ll_hdrlen = 4;
|
ll_hdrlen = 4;
|
||||||
} else {
|
} else {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"snoop: unknown physical layer type");
|
"snoop: unknown physical layer type");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -315,9 +314,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* the MTU first and, if that succeeds, trim the snap length
|
* the MTU first and, if that succeeds, trim the snap length
|
||||||
* to be no greater than the MTU.
|
* to be no greater than the MTU.
|
||||||
*/
|
*/
|
||||||
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
(void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
|
||||||
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
|
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -338,8 +337,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
#ifndef ifr_mtu
|
#ifndef ifr_mtu
|
||||||
#define ifr_mtu ifr_metric
|
#define ifr_mtu ifr_metric
|
||||||
#endif
|
#endif
|
||||||
if (snaplen > ifr.ifr_mtu + ll_hdrlen)
|
if (p->snapshot > ifr.ifr_mtu + ll_hdrlen)
|
||||||
snaplen = ifr.ifr_mtu + ll_hdrlen;
|
p->snapshot = ifr.ifr_mtu + ll_hdrlen;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -347,18 +346,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
* payload bytes to capture - it doesn't count link-layer
|
* payload bytes to capture - it doesn't count link-layer
|
||||||
* header bytes.
|
* header bytes.
|
||||||
*/
|
*/
|
||||||
snooplen = snaplen - ll_hdrlen;
|
snooplen = p->snapshot - ll_hdrlen;
|
||||||
if (snooplen < 0)
|
if (snooplen < 0)
|
||||||
snooplen = 0;
|
snooplen = 0;
|
||||||
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
|
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->snapshot = snaplen;
|
|
||||||
v = 1;
|
v = 1;
|
||||||
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
|
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +364,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->bufsize = 4096; /* XXX */
|
p->bufsize = 4096; /* XXX */
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = (u_char *)malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -386,16 +384,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->stats_op = pcap_stats_snoop;
|
p->stats_op = pcap_stats_snoop;
|
||||||
p->close_op = pcap_close_common;
|
p->close_op = pcap_close_common;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
/*
|
return (PCAP_ERROR);
|
||||||
* Get rid of any link-layer type list we allocated.
|
}
|
||||||
*/
|
|
||||||
if (p->dlt_list != NULL)
|
pcap_t *
|
||||||
free(p->dlt_list);
|
pcap_create(const char *device, char *ebuf)
|
||||||
free(p);
|
{
|
||||||
return (NULL);
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_snoop;
|
||||||
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.21 2008-02-02 20:50:31 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.22 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -117,6 +117,7 @@ struct mon_bin_mfetch {
|
||||||
#define MON_BIN_ERROR 0x8
|
#define MON_BIN_ERROR 0x8
|
||||||
|
|
||||||
/* forward declaration */
|
/* forward declaration */
|
||||||
|
static int usb_activate(pcap_t *);
|
||||||
static int usb_stats_linux(pcap_t *, struct pcap_stat *);
|
static int usb_stats_linux(pcap_t *, struct pcap_stat *);
|
||||||
static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
|
static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
|
||||||
static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
|
||||||
|
@ -183,25 +184,26 @@ int usb_mmap(pcap_t* handle)
|
||||||
return handle->buffer != MAP_FAILED;
|
return handle->buffer != MAP_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t*
|
pcap_t *
|
||||||
usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg)
|
usb_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = usb_activate;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
usb_activate(pcap_t* handle)
|
||||||
{
|
{
|
||||||
char full_path[USB_LINE_LEN];
|
char full_path[USB_LINE_LEN];
|
||||||
pcap_t *handle;
|
|
||||||
|
|
||||||
/* Allocate a handle for this session. */
|
|
||||||
handle = malloc(sizeof(*handle));
|
|
||||||
if (handle == NULL) {
|
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE, "malloc: %s",
|
|
||||||
pcap_strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
/* Initialize some components of the pcap structure. */
|
||||||
memset(handle, 0, sizeof(*handle));
|
handle->bufsize = handle->snapshot;
|
||||||
handle->snapshot = snaplen;
|
|
||||||
handle->md.timeout = to_ms;
|
|
||||||
handle->bufsize = snaplen;
|
|
||||||
handle->offset = 0;
|
handle->offset = 0;
|
||||||
handle->linktype = DLT_USB_LINUX;
|
handle->linktype = DLT_USB_LINUX;
|
||||||
|
|
||||||
|
@ -214,12 +216,11 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
|
||||||
handle->close_op = usb_close_linux;
|
handle->close_op = usb_close_linux;
|
||||||
|
|
||||||
/*get usb bus index from device name */
|
/*get usb bus index from device name */
|
||||||
if (sscanf(bus, USB_IFACE"%d", &handle->md.ifindex) != 1)
|
if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1)
|
||||||
{
|
{
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE,
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get USB bus index from %s", bus);
|
"Can't get USB bus index from %s", handle->opt.source);
|
||||||
free(handle);
|
return -1;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*now select the read method: try to open binary interface */
|
/*now select the read method: try to open binary interface */
|
||||||
|
@ -238,7 +239,7 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
|
||||||
* "poll()" work on it.
|
* "poll()" work on it.
|
||||||
*/
|
*/
|
||||||
handle->selectable_fd = handle->fd;
|
handle->selectable_fd = handle->fd;
|
||||||
return handle;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can't mmap, use plain binary interface access */
|
/* can't mmap, use plain binary interface access */
|
||||||
|
@ -252,10 +253,9 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
|
||||||
if (handle->fd < 0)
|
if (handle->fd < 0)
|
||||||
{
|
{
|
||||||
/* no more fallback, give it up*/
|
/* no more fallback, give it up*/
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE,
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't open USB bus file %s: %s", full_path, strerror(errno));
|
"Can't open USB bus file %s: %s", full_path, strerror(errno));
|
||||||
free(handle);
|
return -1;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
handle->stats_op = usb_stats_linux;
|
handle->stats_op = usb_stats_linux;
|
||||||
handle->read_op = usb_read_linux;
|
handle->read_op = usb_read_linux;
|
||||||
|
@ -271,12 +271,12 @@ usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errms
|
||||||
* buffer */
|
* buffer */
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
snprintf(errmsg, PCAP_ERRBUF_SIZE,
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
usb_close_linux(handle);
|
close(handle->fd);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
return handle;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
|
|
@ -30,11 +30,11 @@
|
||||||
* USB sniffing API implementation for Linux platform
|
* USB sniffing API implementation for Linux platform
|
||||||
* By Paolo Abeni <paolo.abeni@email.it>
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.h,v 1.4 2007-09-14 01:55:49 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.h,v 1.5 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes for USB-related functions
|
* Prototypes for USB-related functions
|
||||||
*/
|
*/
|
||||||
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
|
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
|
||||||
pcap_t* usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg);
|
pcap_t *usb_create(const char *device, char *ebuf);
|
||||||
|
|
92
pcap-win32.c
92
pcap-win32.c
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.36 2007-11-13 21:55:51 gianluca Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.37 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <pcap-int.h>
|
#include <pcap-int.h>
|
||||||
|
@ -430,39 +430,36 @@ pcap_close_win32(pcap_t *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
static int
|
||||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
pcap_activate_win32(pcap_t *p)
|
||||||
char *ebuf)
|
|
||||||
{
|
{
|
||||||
register pcap_t *p;
|
|
||||||
NetType type;
|
NetType type;
|
||||||
|
|
||||||
|
if (p->opt.rfmon) {
|
||||||
|
/*
|
||||||
|
* No monitor mode on Windows. It could be done on
|
||||||
|
* Vista with drivers that support the native 802.11
|
||||||
|
* mechanism and monitor mode.
|
||||||
|
*/
|
||||||
|
return (PCAP_ERROR_RFMON_NOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
/* Init WinSock */
|
/* Init WinSock */
|
||||||
wsockinit();
|
wsockinit();
|
||||||
|
|
||||||
p = (pcap_t *)malloc(sizeof(*p));
|
p->adapter = PacketOpenAdapter(p->opt.source);
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
p->adapter=NULL;
|
|
||||||
|
|
||||||
p->adapter = PacketOpenAdapter((char*)device);
|
|
||||||
|
|
||||||
if (p->adapter == NULL)
|
if (p->adapter == NULL)
|
||||||
{
|
{
|
||||||
free(p);
|
|
||||||
/* Adapter detected but we are not able to open it. Return failure. */
|
/* Adapter detected but we are not able to open it. Return failure. */
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
|
||||||
return NULL;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*get network type*/
|
/*get network type*/
|
||||||
if(PacketGetNetType (p->adapter,&type) == FALSE)
|
if(PacketGetNetType (p->adapter,&type) == FALSE)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,12 +543,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set promiscuous mode */
|
/* Set promiscuous mode */
|
||||||
if (promisc)
|
if (p->opt.promisc)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
|
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,7 +556,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
{
|
{
|
||||||
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
|
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,12 +565,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->bufsize = PcapBufSize;
|
p->bufsize = PcapBufSize;
|
||||||
|
|
||||||
/* Store the timeout. Used by pcap_setnonblock() */
|
/* Store the timeout. Used by pcap_setnonblock() */
|
||||||
p->timeout= to_ms;
|
p->md.timeout= to_ms;
|
||||||
|
|
||||||
/* allocate Packet structure used during the capture */
|
/* allocate Packet structure used during the capture */
|
||||||
if((p->Packet = PacketAllocatePacket())==NULL)
|
if((p->Packet = PacketAllocatePacket())==NULL)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,11 +579,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/*
|
/*
|
||||||
* Traditional Adapter
|
* Traditional Adapter
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* If the buffer size wasn't explicitly set, default to
|
||||||
|
* SIZE_BUF.
|
||||||
|
*/
|
||||||
|
if (p->opt.buffer_size == 0)
|
||||||
|
p->opt.buffer_size = SIZE_BUF;
|
||||||
|
if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
|
||||||
|
{
|
||||||
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
p->buffer = (u_char *)malloc(PcapBufSize);
|
p->buffer = (u_char *)malloc(PcapBufSize);
|
||||||
if (p->buffer == NULL)
|
if (p->buffer == NULL)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,14 +605,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
/* allocate the standard buffer in the driver */
|
/* allocate the standard buffer in the driver */
|
||||||
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
|
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tell the driver to copy the buffer only if it contains at least 16K */
|
/* tell the driver to copy the buffer only if it contains at least 16K */
|
||||||
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
|
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
|
||||||
{
|
{
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,7 +631,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
|
|
||||||
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
|
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
|
||||||
"SYSTEM\\CurrentControlSet\\Services\\DAG",
|
"SYSTEM\\CurrentControlSet\\Services\\DAG",
|
||||||
strstr(_strlwr((char*)device), "dag"));
|
strstr(_strlwr(p->opt.source), "dag"));
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
|
||||||
|
@ -687,23 +695,31 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||||
p->setmintocopy_op = pcap_setmintocopy_win32;
|
p->setmintocopy_op = pcap_setmintocopy_win32;
|
||||||
p->close_op = pcap_close_win32;
|
p->close_op = pcap_close_win32;
|
||||||
|
|
||||||
return (p);
|
return (0);
|
||||||
bad:
|
bad:
|
||||||
if (p->adapter)
|
if (p->adapter)
|
||||||
PacketCloseAdapter(p->adapter);
|
PacketCloseAdapter(p->adapter);
|
||||||
if (p->buffer != NULL)
|
if (p->buffer != NULL) {
|
||||||
free(p->buffer);
|
free(p->buffer);
|
||||||
|
p->buffer = NULL;
|
||||||
|
}
|
||||||
if(p->Packet)
|
if(p->Packet)
|
||||||
PacketFreePacket(p->Packet);
|
PacketFreePacket(p->Packet);
|
||||||
/*
|
return (PCAP_ERROR);
|
||||||
* Get rid of any link-layer type list we allocated.
|
|
||||||
*/
|
|
||||||
if (p->dlt_list != NULL)
|
|
||||||
free(p->dlt_list);
|
|
||||||
free(p);
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create(const char *device, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create_common(device, ebuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
p->activate_op = pcap_activate_win32;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
|
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
|
||||||
|
@ -780,7 +796,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
|
||||||
* (Note that this may be -1, in which case we're not
|
* (Note that this may be -1, in which case we're not
|
||||||
* really leaving non-blocking mode.)
|
* really leaving non-blocking mode.)
|
||||||
*/
|
*/
|
||||||
newtimeout = p->timeout;
|
newtimeout = p->md.timeout;
|
||||||
}
|
}
|
||||||
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
|
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
|
|
327
pcap.c
327
pcap.c
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.114 2007-11-06 16:20:53 gianluca Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.115 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -70,10 +70,192 @@ static const char rcsid[] _U_ =
|
||||||
#include <dagapi.h>
|
#include <dagapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_not_initialized(pcap_t *pcap)
|
||||||
|
{
|
||||||
|
/* this means 'not initialized' */
|
||||||
|
return PCAP_ERROR_NOT_ACTIVATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
|
||||||
|
* a PCAP_ERROR value on an error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pcap_can_set_rfmon(pcap_t *p)
|
||||||
|
{
|
||||||
|
return (p->can_set_rfmon_op(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For systems where rfmon mode is never supported.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
pcap_cant_set_rfmon(pcap_t *p _U_)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_create_common(const char *source, char *ebuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = malloc(sizeof(*p));
|
||||||
|
if (p == NULL) {
|
||||||
|
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||||
|
pcap_strerror(errno));
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memset(p, 0, sizeof(*p));
|
||||||
|
|
||||||
|
p->opt.source = strdup(source);
|
||||||
|
if (p->opt.source == NULL) {
|
||||||
|
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||||
|
pcap_strerror(errno));
|
||||||
|
free(p);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default to "can't set rfmon mode"; if it's supported by
|
||||||
|
* a platform, it can set the op to its routine to check
|
||||||
|
* whether a particular device supports it.
|
||||||
|
*/
|
||||||
|
p->can_set_rfmon_op = pcap_cant_set_rfmon;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some operations can be performed only on activated pcap_t's;
|
||||||
|
* have those operations handled by a "not supported" handler
|
||||||
|
* until the pcap_t is activated.
|
||||||
|
*/
|
||||||
|
p->read_op = (read_op_t)pcap_not_initialized;
|
||||||
|
p->inject_op = (inject_op_t)pcap_not_initialized;
|
||||||
|
p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
|
||||||
|
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
|
||||||
|
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
|
||||||
|
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
|
||||||
|
p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
|
||||||
|
p->stats_op = (stats_op_t)pcap_not_initialized;
|
||||||
|
#ifdef WIN32
|
||||||
|
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
|
||||||
|
p->setmode_op = (setmode_op_t)pcap_not_initialized;
|
||||||
|
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
|
||||||
|
#endif
|
||||||
|
p->close_op = (close_op_t)pcap_close_common;
|
||||||
|
|
||||||
|
/* put in some defaults*/
|
||||||
|
pcap_set_timeout(p, 0);
|
||||||
|
pcap_set_snaplen(p, 65535); /* max packet size */
|
||||||
|
p->opt.promisc = 0;
|
||||||
|
p->opt.buffer_size = 0;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_check_activated(pcap_t *p)
|
||||||
|
{
|
||||||
|
if (p->activated) {
|
||||||
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
|
||||||
|
" operation on activated capture");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_set_snaplen(pcap_t *p, int snaplen)
|
||||||
|
{
|
||||||
|
if (pcap_check_activated(p))
|
||||||
|
return PCAP_ERROR_ACTIVATED;
|
||||||
|
p->snapshot = snaplen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_set_promisc(pcap_t *p, int promisc)
|
||||||
|
{
|
||||||
|
if (pcap_check_activated(p))
|
||||||
|
return PCAP_ERROR_ACTIVATED;
|
||||||
|
p->opt.promisc = promisc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_set_rfmon(pcap_t *p, int rfmon)
|
||||||
|
{
|
||||||
|
if (pcap_check_activated(p))
|
||||||
|
return PCAP_ERROR_ACTIVATED;
|
||||||
|
p->opt.rfmon = rfmon;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_set_timeout(pcap_t *p, int timeout_ms)
|
||||||
|
{
|
||||||
|
if (pcap_check_activated(p))
|
||||||
|
return PCAP_ERROR_ACTIVATED;
|
||||||
|
p->md.timeout = timeout_ms;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_set_buffer_size(pcap_t *p, int buffer_size)
|
||||||
|
{
|
||||||
|
if (pcap_check_activated(p))
|
||||||
|
return PCAP_ERROR_ACTIVATED;
|
||||||
|
p->opt.buffer_size = buffer_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_activate(pcap_t *p)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = p->activate_op(p);
|
||||||
|
if (err == 0)
|
||||||
|
p->activated = 1;
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_t *
|
||||||
|
pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
|
||||||
|
{
|
||||||
|
pcap_t *p;
|
||||||
|
|
||||||
|
p = pcap_create(source, errbuf);
|
||||||
|
if (p == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if (pcap_set_snaplen(p, snaplen))
|
||||||
|
goto fail;
|
||||||
|
if (pcap_set_promisc(p, promisc))
|
||||||
|
goto fail;
|
||||||
|
if (pcap_set_timeout(p, to_ms))
|
||||||
|
goto fail;
|
||||||
|
/*
|
||||||
|
* Mark this as opened with pcap_open_live(), so that, for
|
||||||
|
* example, we show the full list of DLT_ values, rather
|
||||||
|
* than just the ones that are compatible with capturing
|
||||||
|
* when not in monitor mode. That allows existing applications
|
||||||
|
* to work the way they used to work, but allows new applications
|
||||||
|
* that know about the new open API to, for example, find out the
|
||||||
|
* DLT_ values that they can select without changing whether
|
||||||
|
* the adapter is in monitor mode or not.
|
||||||
|
*/
|
||||||
|
p->oldstyle = 1;
|
||||||
|
if (pcap_activate(p))
|
||||||
|
goto fail;
|
||||||
|
return (p);
|
||||||
|
fail:
|
||||||
|
strncpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||||
|
pcap_close(p);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
{
|
{
|
||||||
|
|
||||||
return p->read_op(p, cnt, callback, user);
|
return p->read_op(p, cnt, callback, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,22 +884,57 @@ pcap_win32strerror(void)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not all systems have strerror().
|
* Not all systems have strerror().
|
||||||
|
* We also use this to generate error strings for PCAP_ERROR_ values.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
pcap_strerror(int errnum)
|
pcap_strerror(int errnum)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STRERROR
|
static char ebuf[128+1];
|
||||||
return (strerror(errnum));
|
#ifndef HAVE_STRERROR
|
||||||
#else
|
|
||||||
extern int sys_nerr;
|
extern int sys_nerr;
|
||||||
extern const char *const sys_errlist[];
|
extern const char *const sys_errlist[];
|
||||||
static char ebuf[20];
|
#endif
|
||||||
|
|
||||||
if ((unsigned int)errnum < sys_nerr)
|
switch (errnum) {
|
||||||
return ((char *)sys_errlist[errnum]);
|
|
||||||
|
case PCAP_ERROR:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "Generic error");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_BREAK:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "Loop terminated by pcap_breakloop");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_NOT_ACTIVATED:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "The pcap_t has not been activated");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_ACTIVATED:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "The setting can't be changed after the pcap_t is activated");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_NO_SUCH_DEVICE:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "No such device exists");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_RFMON_NOTSUP:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "That device doesn't support monitor mode");
|
||||||
|
return(ebuf);
|
||||||
|
|
||||||
|
case PCAP_ERROR_NOT_RFMON:
|
||||||
|
(void)snprintf(ebuf, sizeof ebuf, "That operation is supported only in monitor mode");
|
||||||
|
return(ebuf);
|
||||||
|
}
|
||||||
|
if (errnum >= 0) {
|
||||||
|
#ifdef HAVE_STRERROR
|
||||||
|
return (strerror(errnum));
|
||||||
|
#else
|
||||||
|
if ((unsigned int)errnum < sys_nerr)
|
||||||
|
return ((char *)sys_errlist[errnum]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
|
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
|
||||||
return(ebuf);
|
return(ebuf);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -801,11 +1018,102 @@ pcap_setmintocopy_dead(pcap_t *p, int size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On some platforms, we need to clean up promiscuous or monitor mode
|
||||||
|
* when we close a device - and we want that to happen even if the
|
||||||
|
* application just exits without explicitl closing devices.
|
||||||
|
* On those platforms, we need to register a "close all the pcaps"
|
||||||
|
* routine to be called when we exit, and need to maintain a list of
|
||||||
|
* pcaps that need to be closed to clean up modes.
|
||||||
|
*
|
||||||
|
* XXX - not thread-safe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of pcaps on which we've done something that needs to be
|
||||||
|
* cleaned up.
|
||||||
|
* If there are any such pcaps, we arrange to call "pcap_close_all()"
|
||||||
|
* when we exit, and have it close all of them.
|
||||||
|
*/
|
||||||
|
static struct pcap *pcaps_to_close;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TRUE if we've already called "atexit()" to cause "pcap_close_all()" to
|
||||||
|
* be called on exit.
|
||||||
|
*/
|
||||||
|
static int did_atexit;
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcap_close_all(void)
|
||||||
|
{
|
||||||
|
struct pcap *handle;
|
||||||
|
|
||||||
|
while ((handle = pcaps_to_close) != NULL)
|
||||||
|
pcap_close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcap_do_addexit(pcap_t *p)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we haven't already done so, arrange to have
|
||||||
|
* "pcap_close_all()" called when we exit.
|
||||||
|
*/
|
||||||
|
if (!did_atexit) {
|
||||||
|
if (atexit(pcap_close_all) == -1) {
|
||||||
|
/*
|
||||||
|
* "atexit()" failed; let our caller know.
|
||||||
|
*/
|
||||||
|
strncpy(p->errbuf, "atexit failed",
|
||||||
|
PCAP_ERRBUF_SIZE);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
did_atexit = 1;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pcap_add_to_pcaps_to_close(pcap_t *p)
|
||||||
|
{
|
||||||
|
p->md.next = pcaps_to_close;
|
||||||
|
pcaps_to_close = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pcap_remove_from_pcaps_to_close(pcap_t *p)
|
||||||
|
{
|
||||||
|
pcap_t *pc, *prevpc;
|
||||||
|
|
||||||
|
for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
|
||||||
|
prevpc = pc, pc = pc->md.next) {
|
||||||
|
if (pc == p) {
|
||||||
|
/*
|
||||||
|
* Found it. Remove it from the list.
|
||||||
|
*/
|
||||||
|
if (prevpc == NULL) {
|
||||||
|
/*
|
||||||
|
* It was at the head of the list.
|
||||||
|
*/
|
||||||
|
pcaps_to_close = pc->md.next;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* It was in the middle of the list.
|
||||||
|
*/
|
||||||
|
prevpc->md.next = pc->md.next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pcap_close_common(pcap_t *p)
|
pcap_close_common(pcap_t *p)
|
||||||
{
|
{
|
||||||
if (p->buffer != NULL)
|
if (p->buffer != NULL)
|
||||||
free(p->buffer);
|
free(p->buffer);
|
||||||
|
if (p->opt.source != NULL);
|
||||||
|
free(p->opt.source);
|
||||||
#if !defined(WIN32) && !defined(MSDOS)
|
#if !defined(WIN32) && !defined(MSDOS)
|
||||||
if (p->fd >= 0)
|
if (p->fd >= 0)
|
||||||
close(p->fd);
|
close(p->fd);
|
||||||
|
@ -836,6 +1144,7 @@ pcap_open_dead(int linktype, int snaplen)
|
||||||
p->setmintocopy_op = pcap_setmintocopy_dead;
|
p->setmintocopy_op = pcap_setmintocopy_dead;
|
||||||
#endif
|
#endif
|
||||||
p->close_op = pcap_close_dead;
|
p->close_op = pcap_close_dead;
|
||||||
|
p->activated = 1;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.5 2008-01-02 04:16:46 guy Exp $ (LBL)
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.6 2008-04-04 19:37:45 guy Exp $ (LBL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lib_pcap_pcap_h
|
#ifndef lib_pcap_pcap_h
|
||||||
|
@ -226,8 +226,27 @@ struct pcap_addr {
|
||||||
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||||
const u_char *);
|
const u_char *);
|
||||||
|
|
||||||
|
/* list of known error code for pcap API */
|
||||||
|
#define PCAP_ERROR -1 /* generic error code */
|
||||||
|
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
|
||||||
|
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
|
||||||
|
#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
|
||||||
|
#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
|
||||||
|
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
|
||||||
|
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
|
||||||
|
|
||||||
char *pcap_lookupdev(char *);
|
char *pcap_lookupdev(char *);
|
||||||
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||||
|
|
||||||
|
pcap_t *pcap_create(const char *, char *);
|
||||||
|
int pcap_set_snaplen(pcap_t *, int);
|
||||||
|
int pcap_set_promisc(pcap_t *, int);
|
||||||
|
int pcap_can_set_rfmon(pcap_t *);
|
||||||
|
int pcap_set_rfmon(pcap_t *, int);
|
||||||
|
int pcap_set_timeout(pcap_t *, int);
|
||||||
|
int pcap_set_buffer_size(pcap_t *, int);
|
||||||
|
int pcap_activate(pcap_t *);
|
||||||
|
|
||||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||||
pcap_t *pcap_open_dead(int, int);
|
pcap_t *pcap_open_dead(int, int);
|
||||||
pcap_t *pcap_open_offline(const char *, char *);
|
pcap_t *pcap_open_offline(const char *, char *);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
static const char rcsid[] _U_ =
|
||||||
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.172 2008-02-18 20:21:00 guy Exp $ (LBL)";
|
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.173 2008-04-04 19:37:45 guy Exp $ (LBL)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -1310,6 +1310,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
|
||||||
p->setmintocopy_op = sf_setmintocopy;
|
p->setmintocopy_op = sf_setmintocopy;
|
||||||
#endif
|
#endif
|
||||||
p->close_op = sf_close;
|
p->close_op = sf_close;
|
||||||
|
p->activated = 1;
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
bad:
|
bad:
|
||||||
|
|
Reference in New Issue