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:
parent
8a49a4d47b
commit
87d0db882e
13
gencode.c
13
gencode.c
|
@ -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:
|
||||
|
|
|
@ -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
3
pcap.c
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
30
savefile.c
30
savefile.c
|
@ -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;
|
||||
|
|
Reference in New Issue