From: Guy Harris Date: Mon, 14 Mar 2022 06:45:24 +0000 (-0700) Subject: pcap-usb-linux: fix scan for usbmon devices. X-Git-Tag: libpcap-1.10.2~204 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/18cb2c66ee0cde6e3c720fdf753dfbbd8ce97bf4 pcap-usb-linux: fix scan for usbmon devices. The directory to scan is just /dev, which is wired into the udev source, at least in the systemd source tree. Just scan that directory, rather than using using udevinfo to find out the directory. (If there is ever a reason to look anywhere there than /dev for the usbmon devices - and, if so, there had better be a good reason, as stuffing special files anywhere other than /dev on any UN*X, including Linux, will break programs that use /dev/null or /dev/tty, among other well-known devices - then provide a mechanism that works at *run time*, so that it works even for cross-builds libpcap, and that works regardless of whether the machine on which the built version of libpcap has udev and whether it has udevinfo or udevadm or whatever.) (cherry picked from commit 52d9062fcd8d3ae8cef695f7a1c630f3dde5b968) --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 75fc26e5..3e77dfda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1497,7 +1497,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") if(NOT DISABLE_LINUX_USBMON) set(PCAP_SUPPORT_LINUX_USBMON TRUE) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-usb-linux.c) - set(LINUX_USB_MON_DEV /dev/usbmon) # # Do we have a version of available? # If so, we might need it for . diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index 1dc2491f..4ac85cc5 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -268,9 +268,6 @@ /* IPv6 */ #cmakedefine INET6 1 -/* path for device for USB sniffing */ -#cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@" - /* Define to 1 if netinet/ether.h declares `ether_hostton' */ #cmakedefine NETINET_ETHER_H_DECLARES_ETHER_HOSTTON 1 diff --git a/config.h.in b/config.h.in index 3eb90a8b..ab34376e 100644 --- a/config.h.in +++ b/config.h.in @@ -265,9 +265,6 @@ /* IPv6 */ #undef INET6 -/* path for device for USB sniffing */ -#undef LINUX_USB_MON_DEV - /* Define to 1 if netinet/ether.h declares `ether_hostton' */ #undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON diff --git a/configure b/configure index db8b9019..cb57fba6 100755 --- a/configure +++ b/configure @@ -11691,17 +11691,17 @@ $as_echo "#define PCAP_SUPPORT_LINUX_USBMON 1" >>confdefs.h MODULE_C_SRC="$MODULE_C_SRC pcap-usb-linux.c" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null` - if test $? -ne 0 ; then - ac_usb_dev_name="usbmon" - fi - -cat >>confdefs.h <<_ACEOF -#define LINUX_USB_MON_DEV "/dev/$ac_usb_dev_name" -_ACEOF - - { $as_echo "$as_me:${as_lineno-$LINENO}: Device for USB sniffing is /dev/$ac_usb_dev_name" >&5 -$as_echo "$as_me: Device for USB sniffing is /dev/$ac_usb_dev_name" >&6;} + # + # Note: if the directory for special files is *EVER* somewhere + # other than the UN*X standard of /dev (which will break any + # software that looks for /dev/null or /dev/tty, for example, + # so doing that is *REALLY* not a good idea), please provide + # some mechanism to determine that directory at *run time*, + # rather than *configure time*, so that it works when doinga + # a cross-build, and that works with *multiple* distributions, + # with our without udev, and with multiple versions of udev, + # with udevinfo or udevadm or any other mechanism to get the + # special files directory. # # Do we have a version of available? # If so, we might need it for . diff --git a/configure.ac b/configure.ac index 01b599d5..78851ec0 100644 --- a/configure.ac +++ b/configure.ac @@ -2377,12 +2377,17 @@ if test "xxx_only" != yes; then AC_DEFINE(PCAP_SUPPORT_LINUX_USBMON, 1, [target host supports Linux usbmon for USB sniffing]) MODULE_C_SRC="$MODULE_C_SRC pcap-usb-linux.c" AC_MSG_RESULT(yes) - ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null` - if test $? -ne 0 ; then - ac_usb_dev_name="usbmon" - fi - AC_DEFINE_UNQUOTED(LINUX_USB_MON_DEV, "/dev/$ac_usb_dev_name", [path for device for USB sniffing]) - AC_MSG_NOTICE(Device for USB sniffing is /dev/$ac_usb_dev_name) + # + # Note: if the directory for special files is *EVER* somewhere + # other than the UN*X standard of /dev (which will break any + # software that looks for /dev/null or /dev/tty, for example, + # so doing that is *REALLY* not a good idea), please provide + # some mechanism to determine that directory at *run time*, + # rather than *configure time*, so that it works when doinga + # a cross-build, and that works with *multiple* distributions, + # with our without udev, and with multiple versions of udev, + # with udevinfo or udevadm or any other mechanism to get the + # special files directory. # # Do we have a version of available? # If so, we might need it for . diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index 11382235..9b0d2359 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -73,6 +73,9 @@ #include "diag-control.h" #define USB_IFACE "usbmon" + +#define USBMON_DEV_PREFIX "usbmon" +#define USBMON_DEV_PREFIX_LEN (sizeof USBMON_DEV_PREFIX - 1) #define USB_LINE_LEN 4096 #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -175,9 +178,6 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str) int usb_findalldevs(pcap_if_list_t *devlistp, char *err_str) { - char usb_mon_dir[PATH_MAX]; - char *usb_mon_prefix; - size_t usb_mon_prefix_len; struct dirent* data; int ret = 0; DIR* dir; @@ -186,26 +186,10 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str) /* * We require 2.6.27 or later kernels, so we have binary-mode support. - * What do the device names look like? - * Split LINUX_USB_MON_DEV into a directory that we'll - * scan and a file name prefix that we'll check for. - */ - pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir); - usb_mon_prefix = strrchr(usb_mon_dir, '/'); - if (usb_mon_prefix == NULL) { - /* - * This "shouldn't happen". Just give up if it - * does. - */ - return 0; - } - *usb_mon_prefix++ = '\0'; - usb_mon_prefix_len = strlen(usb_mon_prefix); - - /* - * Open the directory and scan it. + * The devices are of the form /dev/usbmon{N}. + * Open /dev and scan it. */ - dir = opendir(usb_mon_dir); + dir = opendir("/dev"); if (dir != NULL) { while ((ret == 0) && ((data = readdir(dir)) != 0)) { name = data->d_name; @@ -213,13 +197,14 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str) /* * Is this a usbmon device? */ - if (strncmp(name, usb_mon_prefix, usb_mon_prefix_len) != 0) + if (strncmp(name, USBMON_DEV_PREFIX, + USBMON_DEV_PREFIX_LEN) != 0) continue; /* no */ /* * What's the device number? */ - if (sscanf(&name[usb_mon_prefix_len], "%d", &n) == 0) + if (sscanf(&name[USBMON_DEV_PREFIX_LEN], "%d", &n) == 0) continue; /* failed */ ret = usb_dev_add(devlistp, n, err_str); @@ -514,7 +499,8 @@ usb_activate(pcap_t* handle) * We require 2.6.27 or later kernels, so we have binary-mode support. * Try to open the binary interface. */ - snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); + snprintf(full_path, USB_LINE_LEN, "/dev/"USBMON_DEV_PREFIX"%d", + handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd < 0) {