From 87d0db882e422055e04f278c616064d858d6a2ca Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 23 Dec 2008 18:03:22 +0000 Subject: 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. --- pcap-usb-linux.c | 73 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'pcap-usb-linux.c') diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index 4ff62ed..b56d733 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -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); - - /* 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); + /* 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 (strncmp(name, "usb", 3) != 0) + continue; + + if (sscanf(&name[3], "%d", &n) == 0) + continue; + + ret = usb_dev_add(alldevsp, n, err_str); + } + + 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; } - 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; -- cgit v1.2.3