]> The Tcpdump Group git mirrors - tcpdump/commitdiff
From Bert Vermeulen: add a USB printer, and fix the error message
authorGuy Harris <[email protected]>
Sat, 4 Apr 2009 19:30:27 +0000 (12:30 -0700)
committerGuy Harris <[email protected]>
Sat, 4 Apr 2009 19:30:27 +0000 (12:30 -0700)
printed when trying to print packets for a DLT_ for which we don't have
a printer to indicate that you can still save to a capture file in that
case.  (Slightly changed not to require DLT_USB_LINUX_MMAPPED to be
defined, for older libpcaps that only define DLT_USB_LINUX.)

CREDITS
INSTALL.txt
Makefile.in
config.h.in
configure
configure.in
interface.h
print-usb.c [new file with mode: 0644]
tcpdump.c

diff --git a/CREDITS b/CREDITS
index ed82f792917e32f2c69af1b829c6ce5ea60f1660..fa62fe3e45df80a0119cd3b3578df7eb487b3a01 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -27,6 +27,7 @@ Additional people who have contributed patches:
        Ben Byer                        <bushing at sourceforge dot net>
        Atsushi Onoe                    <onoe at netbsd dot org>
        Ben Smithurst                   <ben at scientia dot demon dot co dot uk>
+       Bert Vermeulen                  <bert at biot dot com>
        Bjoern A. Zeeb                  <bzeeb at Zabbadoz dot NeT>
        Brent L. Bates                  <blbates at vigyan dot com>
        Brian Ginsbach                  <ginsbach at cray dot com>
index 3f845c053a45d208c25fc70dcbe37389bdb1e9fc..a03e2c0001b312a4aed137dc4ea7b14390e1fd92 100644 (file)
@@ -221,6 +221,7 @@ print-tftp.c        - Trivial File Transfer Protocol printer routines
 print-timed.c  - BSD time daemon protocol printer routines
 print-token.c  - Token Ring printer routines
 print-udp.c    - UDP printer routines
+print-usb.c    - USB printer routines
 print-vjc.c    - PPP Van Jacobson compression (RFC1144) printer routines
 print-vrrp.c   - Virtual Router Redundancy Protocol
 print-wb.c     - White Board printer routines
index 0496a827b5771a9423a75c265c29539d00ab7633..be3d8c2172255cfd71d2bfca135ed21220b99a67 100644 (file)
@@ -88,7 +88,7 @@ CSRC =        addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c
        print-rx.c print-sctp.c print-sflow.c print-sip.c print-sl.c print-sll.c \
        print-slow.c print-snmp.c print-stp.c print-sunatm.c print-sunrpc.c \
        print-symantec.c print-syslog.c print-tcp.c print-telnet.c print-tftp.c \
-       print-timed.c print-token.c print-udld.c print-udp.c \
+       print-timed.c print-token.c print-udld.c print-udp.c print-usb.c \
        print-vjc.c print-vqp.c print-vrrp.c print-vtp.c \
        print-wb.c print-zephyr.c signature.h signature.c setsignal.c tcpdump.c util.c
 
index 085cc936b36e30247c77038102ba7c1a1f974b15..f2d1301495eb12af2002fbccad5e56d55ae105c5 100644 (file)
 /* Define to 1 if you have the `pcap_lib_version' function. */
 #undef HAVE_PCAP_LIB_VERSION
 
+/* Define to 1 if you have the <pcap/usb.h> header file. */
+#undef HAVE_PCAP_USB_H
+
 /* Define to 1 if you have the `pfopen' function. */
 #undef HAVE_PFOPEN
 
index 8bea34ed734966f456e5cc4b5607d0b02dd5c79a..b661289b676d6ab5fb82c349ae7098487e28a8da 100755 (executable)
--- a/configure
+++ b/configure
 
 done
 
+
+for ac_header in pcap/usb.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_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_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 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); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
 CPPFLAGS="$savedcppflags"
 
 
@@ -13348,6 +13488,16 @@ echo $ECHO_N "checking where SSLeay is located... $ECHO_C" >&6; }
                fi
                for dir in $dirs; do
 
+       #
+       # Find the last component of $libdir; it's not necessarily
+       # "lib" - it might be "lib64" on, for example, x86-64
+       # Linux systems.
+       #
+       # We assume the directory in which we're looking for
+       # libcrypto has a subdirectory with that as its name.
+       #
+       tmplib=`echo "$libdir" | sed 's,.*/,,'`
+
        #
        # XXX - is there a better way to check if a given library is
        # in a given directory than checking each of the possible
@@ -13358,10 +13508,10 @@ echo $ECHO_N "checking where SSLeay is located... $ECHO_C" >&6; }
        #
        # Or should we just look for "libcrypto.*"?
        #
-       if test -d "$dir/lib" -a \( -f "$dir/lib/libcrypto.a" -o \
-                                   -f "$dir/lib/libcrypto.so" -o \
-                                   -f "$dir/lib/libcrypto.sl" -o \
-                                   -f "$dir/lib/libcrypto.dylib" \); then
+       if test -d "$dir/$tmplib" -a \( -f "$dir/$tmplib/libcrypto.a" -o \
+                                   -f "$dir/$tmplib/libcrypto.so" -o \
+                                   -f "$dir/$tmplib/libcrypto.sl" -o \
+                                   -f "$dir/$tmplib/libcrypto.dylib" \); then
                ac_cv_ssleay_path="$dir"
        fi
 
@@ -13388,6 +13538,16 @@ echo "${ECHO_T}$ac_cv_ssleay_path" >&6; }
                { echo "$as_me:$LINENO: checking for SSLeay in $crypto_dir" >&5
 echo $ECHO_N "checking for SSLeay in $crypto_dir... $ECHO_C" >&6; }
 
+       #
+       # Find the last component of $libdir; it's not necessarily
+       # "lib" - it might be "lib64" on, for example, x86-64
+       # Linux systems.
+       #
+       # We assume the directory in which we're looking for
+       # libcrypto has a subdirectory with that as its name.
+       #
+       tmplib=`echo "$libdir" | sed 's,.*/,,'`
+
        #
        # XXX - is there a better way to check if a given library is
        # in a given directory than checking each of the possible
@@ -13398,10 +13558,10 @@ echo $ECHO_N "checking for SSLeay in $crypto_dir... $ECHO_C" >&6; }
        #
        # Or should we just look for "libcrypto.*"?
        #
-       if test -d "$crypto_dir/lib" -a \( -f "$crypto_dir/lib/libcrypto.a" -o \
-                                   -f "$crypto_dir/lib/libcrypto.so" -o \
-                                   -f "$crypto_dir/lib/libcrypto.sl" -o \
-                                   -f "$crypto_dir/lib/libcrypto.dylib" \); then
+       if test -d "$crypto_dir/$tmplib" -a \( -f "$crypto_dir/$tmplib/libcrypto.a" -o \
+                                   -f "$crypto_dir/$tmplib/libcrypto.so" -o \
+                                   -f "$crypto_dir/$tmplib/libcrypto.sl" -o \
+                                   -f "$crypto_dir/$tmplib/libcrypto.dylib" \); then
                ac_cv_ssleay_path="$crypto_dir"
        fi
 
index 6b617e373f5c4368a70ba68d0ed37229929ec53c..11f2c762baadcf16657c7dcc0f496369d98b0ffa 100644 (file)
@@ -849,6 +849,7 @@ fi
 savedcppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS $V_INCLS"
 AC_CHECK_HEADERS(pcap/bluetooth.h)
+AC_CHECK_HEADERS(pcap/usb.h)
 CPPFLAGS="$savedcppflags"
 
 AC_CHECK_HEADERS(sys/bitypes.h)
index b8e2001c4930906aaecd551d3216e45b295b7e04..688a2ac90dcf2d570daafc88715aa93c70eb62ff 100644 (file)
@@ -322,6 +322,7 @@ extern void bfd_print(const u_char *, u_int, u_int);
 extern void sip_print(const u_char *, u_int);
 extern void syslog_print(const u_char *, u_int);
 extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int usb_linux_print(const struct pcap_pkthdr *, const u_char *);
 
 #ifdef INET6
 extern void ip6_print(const u_char *, u_int);
diff --git a/print-usb.c b/print-usb.c
new file mode 100644 (file)
index 0000000..61f38ec
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2009 Bert Vermeulen <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by Paolo Abeni.''
+ * The name of author may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Support for USB packets
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+
+
+#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX)
+#include <pcap/usb.h>
+
+/* returns direction: 1=inbound 2=outbound -1=invalid */
+static int get_direction(int transfer_type, int event_type)
+{
+       int direction;
+
+       direction = -1;
+       switch(transfer_type){
+       case URB_BULK:
+       case URB_CONTROL:
+       case URB_ISOCHRONOUS:
+               switch(event_type)
+               {
+               case URB_SUBMIT:
+                       direction = 2;
+                       break;
+               case URB_COMPLETE:
+               case URB_ERROR:
+                       direction = 1;
+                       break;
+               default:
+                       direction = -1;
+               }
+               break;
+       case URB_INTERRUPT:
+               switch(event_type)
+               {
+               case URB_SUBMIT:
+                       direction = 1;
+                       break;
+               case URB_COMPLETE:
+               case URB_ERROR:
+                       direction = 2;
+                       break;
+               default:
+                       direction = -1;
+               }
+               break;
+        default:
+               direction = -1;
+       }
+
+       return direction;
+}
+
+
+u_int usb_linux_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+       const pcap_usb_header *uh;
+       int direction;
+
+       uh = (const pcap_usb_header *) p;
+       switch(uh->transfer_type)
+       {
+               case URB_ISOCHRONOUS:
+                       printf("ISOCHRONOUS");
+                       break;
+               case URB_INTERRUPT:
+                       printf("INTERRUPT");
+                       break;
+               case URB_CONTROL:
+                       printf("CONTROL");
+                       break;
+               case URB_BULK:
+                       printf("BULK");
+                       break;
+               default:
+                       printf(" ?");
+       }
+
+       switch(uh->event_type)
+       {
+               case URB_SUBMIT:
+                       printf(" SUBMIT");
+                       break;
+               case URB_COMPLETE:
+                       printf(" COMPLETE");
+                       break;
+               case URB_ERROR:
+                       printf(" ERROR");
+                       break;
+               default:
+                       printf(" ?");
+       }
+
+       direction = get_direction(uh->transfer_type, uh->event_type);
+       if(direction == 1)
+               printf(" from");
+       else if(direction == 2)
+               printf(" to");
+       printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f);
+
+       return(sizeof(pcap_usb_header));
+}
+
+#endif
+
index d524b0164d1bea3388c2c9f3dd66b7d4a304b7c3..18914d4b6638488f09b625f1b153eb9a36144084 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -275,6 +275,12 @@ static struct printer printers[] = {
 #endif
 #if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
        { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
+#endif
+#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX)
+       { usb_linux_print, DLT_USB_LINUX},
+#endif
+#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX_MMAPPED)
+       { usb_linux_print, DLT_USB_LINUX_MMAPPED},
 #endif
        { NULL,                 0 },
 };
@@ -1131,10 +1137,10 @@ main(int argc, char **argv)
                if (printinfo.printer == NULL) {
                        gndo->ndo_dltname = pcap_datalink_val_to_name(type);
                        if (gndo->ndo_dltname != NULL)
-                               error("unsupported data link type %s",
+                               error("packet printing is not supported for link type %s: use -w",
                                      gndo->ndo_dltname);
                        else
-                               error("unsupported data link type %d", type);
+                               error("packet printing is not supported for link type %d: use -w", type);
                }
                callback = print_packet;
                pcap_userdata = (u_char *)&printinfo;