dect
/
libpcap
Archived
13
0
Fork 0

From Jon Smirl:

try scanning the sysfs USB directory first and, if that
	directory doesn't exist, try the procfs USB directory, to handle
	newer kernels where the relevant director is in sysfs;

	use the data length, not the URB length, as the amount of data
	in the packet (the URB length is the amount of space *available*
	for the data, not the actual amount of data).

For the memory-mapped interface, include the padding after the URB and
setup header in the packet lengths, and return a different link-layer
type so that code reading the packets knows that padding is there.
This commit is contained in:
guy 2008-12-23 18:03:22 +00:00
parent 8a49a4d47b
commit 87d0db882e
6 changed files with 96 additions and 35 deletions

View File

@ -21,7 +21,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.307 2008-12-21 19:28:56 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.308 2008-12-23 18:03:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -1507,6 +1507,16 @@ init_linktype(p)
off_nl = -1;
off_nl_nosnap = -1;
return;
case DLT_USB_LINUX_MMAP:
/*
* Currently, only raw "link[N:M]" filtering is supported.
*/
off_linktype = -1;
off_macpl = -1;
off_nl = -1;
off_nl_nosnap = -1;
return;
}
bpf_error("unknown data link type %d", linktype);
/* NOTREACHED */
@ -3360,6 +3370,7 @@ gen_linktype(proto)
case DLT_USB:
case DLT_USB_LINUX:
case DLT_USB_LINUX_MMAP:
bpf_error("USB link-layer type filtering not implemented");
case DLT_BLUETOOTH_HCI_H4:

View File

@ -34,7 +34,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.27 2008-11-24 18:49:57 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.28 2008-12-23 18:03:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -63,7 +63,8 @@ static const char rcsid[] _U_ =
#define USB_IFACE "usb"
#define USB_TEXT_DIR "/sys/kernel/debug/usbmon"
#define USB_BUS_DIR "/proc/bus/usb"
#define SYS_USB_BUS_DIR "/sys/bus/usb/devices"
#define PROC_USB_BUS_DIR "/proc/bus/usb"
#define USB_LINE_LEN 4096
#if __BYTE_ORDER == __LITTLE_ENDIAN
@ -142,27 +143,52 @@ usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
struct dirent* data;
int ret = 0;
DIR* dir;
int n;
char* name;
size_t len;
/* scan procfs usb bus directory */
dir = opendir(USB_BUS_DIR);
if (!dir) return 0;
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
int n;
char* name = data->d_name;
int len = strlen(name);
/* try scanning sysfs usb bus directory */
dir = opendir(SYS_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
if (strncmp(name, "usb", 3) != 0)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
if (sscanf(&name[3], "%d", &n) == 0)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
}
closedir(dir);
return ret;
}
closedir(dir);
return ret;
/* that didn't work; try scanning procfs usb bus directory */
dir = opendir(PROC_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
len = strlen(name);
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
}
closedir(dir);
return ret;
}
/* neither of them worked */
return 0;
}
static
@ -229,6 +255,7 @@ usb_activate(pcap_t* handle)
/* binary api is available, try to use fast mmap access */
if (usb_mmap(handle)) {
handle->linktype = DLT_USB_LINUX_MMAP;
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap;
handle->cleanup_op = usb_cleanup_linux_mmap;
@ -632,7 +659,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
clen = info.hdr->data_len;
info.hdr->data_len = clen;
pkth.caplen = clen + sizeof(pcap_usb_header);
pkth.len = info.hdr->urb_len + sizeof(pcap_usb_header);
pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
pkth.ts.tv_sec = info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec;
@ -705,8 +732,8 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
clen = hdr->data_len;
/* get packet info from header*/
pkth.caplen = clen + sizeof(pcap_usb_header);
pkth.len = hdr->urb_len + sizeof(pcap_usb_header);
pkth.caplen = clen + MMAPPED_USB_HEADER_SIZE;
pkth.len = hdr->data_len + MMAPPED_USB_HEADER_SIZE;
pkth.ts.tv_sec = hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec;

3
pcap.c
View File

@ -33,7 +33,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.126 2008-12-21 19:28:56 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.127 2008-12-23 18:03:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -624,6 +624,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
DLT_CHOICE(DLT_USB_LINUX_MMAP, "USB with padded Linux header"),
DLT_CHOICE_SENTINEL
};

View File

@ -37,7 +37,7 @@
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.30 2008-12-21 19:28:56 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.31 2008-12-23 18:03:22 guy Exp $ (LBL)
*/
/*
@ -844,6 +844,12 @@ struct bpf_version {
*/
#define DLT_MPLS 219
/*
* USB packets, beginning with a Linux USB header, with the USB header
* padded to 64 bytes; required for memory-mapped access.
*/
#define DLT_USB_LINUX_MMAP 220
/*
* DLT and savefile link type values are split into a class and

View File

@ -30,7 +30,7 @@
* Basic USB data struct
* By Paolo Abeni <paolo.abeni@email.it>
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007-09-22 02:06:08 guy Exp $
* @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.7 2008-12-23 18:03:22 guy Exp $
*/
#ifndef _PCAP_USB_STRUCTS_H__
@ -68,6 +68,8 @@ typedef struct _usb_setup {
/*
* Header prepended by linux kernel to each event.
* Appears at the front of each packet in DLT_USB_LINUX captures.
* Appears at the front of each packet, followed by padding to a multiple
* of 64 bytes, in DLT_USB_LINUX_MMAP captures.
*/
typedef struct _usb_header {
u_int64_t id;
@ -86,5 +88,9 @@ typedef struct _usb_header {
pcap_usb_setup setup;
} pcap_usb_header;
/*
* In DLT_USB_LINUX_MMAP captures, the header is padded to 64 bytes.
*/
#define MMAPPED_USB_HEADER_SIZE (sizeof (pcap_usb_header) + 63) & ~63)
#endif

View File

@ -30,7 +30,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.181 2008-12-21 19:28:56 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.182 2008-12-23 18:03:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -483,7 +483,7 @@ static const char rcsid[] _U_ =
* USB packets, beginning with a Linux USB header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
*/
#define LINKTYPE_USB_LINUX 189
#define LINKTYPE_USB_LINUX 189
/*
* Controller Area Network (CAN) v. 2.0B packets.
@ -670,6 +670,12 @@ static const char rcsid[] _U_ =
*/
#define LINKTYPE_MPLS 219
/*
* USB packets, beginning with a Linux USB header, with the USB header
* padded to 64 bytes; required for memory-mapped access.
*/
#define LINKTYPE_USB_LINUX_MMAP 220
static struct linktype_map {
int dlt;
@ -985,6 +991,9 @@ static struct linktype_map {
/* MPLS, with an MPLS label as the link-layer header */
{ DLT_MPLS, LINKTYPE_MPLS },
/* USB with padded Linux header */
{ DLT_USB_LINUX_MMAP, LINKTYPE_USB_LINUX_MMAP },
{ -1, -1 }
};
@ -1555,19 +1564,20 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
}
/*
* The DLT_USB_LINUX header is in host byte order when capturing
* (it's supplied directly from a memory-mapped buffer shared
* by the kernel).
* The DLT_USB_LINUX and DLT_USB_LINUX_MMAP headers are in host
* byte order when capturing (it's supplied directly from a
* memory-mapped buffer shared by the kernel).
*
* When reading a DLT_USB_LINUX capture file, we need to convert
* it from the capturing host's byte order to the reading host's
* byte order.
* When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAP capture file,
* we need to convert it from the capturing host's byte order to
* the reading host's byte order.
*/
if (p->sf.swapped && p->linktype == DLT_USB_LINUX) {
if (p->sf.swapped &&
(p->linktype == DLT_USB_LINUX || p->linktype == DLT_USB_LINUX_MMAP)) {
pcap_usb_header* uhdr = (pcap_usb_header*) buf;
/*
* The URB id is a totally opaque value; do we really need to
* converte it to the reading host's byte order???
* convert it to the reading host's byte order???
*/
if (hdr->caplen < 8)
return 0;