From bbd8be8360053578da1a829b529204ae42c68ef1 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 4 Jul 2009 15:04:59 -0700 Subject: [PATCH] Older Linux kernels have different member names for "struct usbdevfs_ctrltransfer"; check for that and handle it. Don't declare variables in the middle of a block; some versions of GCC appear to warn about that. --- config.h.in | 3 +++ configure | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 20 +++++++++++++++ pcap-usb-linux.c | 21 ++++++++++++--- 4 files changed, 107 insertions(+), 3 deletions(-) diff --git a/config.h.in b/config.h.in index d523102..89fa639 100644 --- a/config.h.in +++ b/config.h.in @@ -154,6 +154,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* if struct usbdevfs_ctrltransfer has bRequestType */ +#undef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE + /* define if version.h is generated in the build procedure */ #undef HAVE_VERSION_H diff --git a/configure b/configure index b7f5ee4..405d76a 100755 --- a/configure +++ b/configure @@ -9481,6 +9481,72 @@ fi done + if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then + # + # OK, does it define bRequestType? Older versions of the kernel + # define fields with names like "requesttype, "request", and + # "value", rather than "bRequestType", "bRequest", and + # "wValue". + # + { echo "$as_me:$LINENO: checking if usbdevfs_ctrltransfer struct has bRequestType member" >&5 +echo $ECHO_N "checking if usbdevfs_ctrltransfer struct has bRequestType member... $ECHO_C" >&6; } + if test "${ac_cv_usbdevfs_ctrltransfer_has_bRequestType+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +int +main () +{ +u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&5 +echo "${ECHO_T}$ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&6; } + if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1 +_ACEOF + + fi + fi ;; *) { echo "$as_me:$LINENO: result: no" >&5 diff --git a/configure.in b/configure.in index 19ca84d..8732f6d 100644 --- a/configure.in +++ b/configure.in @@ -1117,6 +1117,26 @@ linux*) 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) AC_CHECK_HEADERS(linux/usbdevice_fs.h) + if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then + # + # OK, does it define bRequestType? Older versions of the kernel + # define fields with names like "requesttype, "request", and + # "value", rather than "bRequestType", "bRequest", and + # "wValue". + # + AC_MSG_CHECKING(if usbdevfs_ctrltransfer struct has bRequestType member) + AC_CACHE_VAL(ac_cv_usbdevfs_ctrltransfer_has_bRequestType, + AC_TRY_COMPILE([ +# include ], + [u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType)], + ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes, + ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no)) + AC_MSG_RESULT($ac_cv_usbdevfs_ctrltransfer_has_bRequestType) + if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then + AC_DEFINE(HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE,1, + [if struct usbdevfs_ctrltransfer has bRequestType]) + fi + fi ;; *) AC_MSG_RESULT(no) diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index 358865c..3d7cb2c 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -247,11 +247,23 @@ probe_devices(int bus) if (fd == -1) continue; + /* + * Sigh. Different kernels have different member names + * for this structure. + */ +#ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; ctrl.wValue = USB_DT_DEVICE << 8; ctrl.wIndex = 0; ctrl.wLength = sizeof(buf); +#else + ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; + ctrl.request = USB_REQ_GET_DESCRIPTOR; + ctrl.value = USB_DT_DEVICE << 8; + ctrl.index = 0; + ctrl.length = sizeof(buf); +#endif ctrl.data = buf; ctrl.timeout = CTRL_TIMEOUT; @@ -593,9 +605,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) char string[USB_LINE_LEN]; char token[USB_LINE_LEN]; char * ptr = string; - snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex); + int fd; - int fd = open(string, O_RDONLY, 0); + snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex); + fd = open(string, O_RDONLY, 0); if (fd < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, @@ -626,8 +639,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) * of execution" but the Corrigendum seems to contradict this. * Do not make any assumptions on the effect of %n conversions * on the return value and explicitly check for cnt assignmet*/ + int ntok; + cnt = -1; - int ntok = sscanf(ptr, "%s%n", token, &cnt); + ntok = sscanf(ptr, "%s%n", token, &cnt); if ((ntok < 1) || (cnt < 0)) break; consumed += cnt;