Wireshark-dev: [Wireshark-dev] [PATCH] usb dissector
From: Paolo Abeni <paolo.abeni@xxxxxxxx>
Date: Tue, 10 Oct 2006 17:26:03 +0200
hi list,

The attached patch add a basic usb dissector to take advantage of the
recently introduces libpcap ability to sniff from USB port.

This include the changes proposed by ronnie sahlberg, except for the
required pcap headers. 
This patch add also a test to the configure script to check out if
installed version of libpcap supports USB sniffing.

ciao,

Paolo

Index: acinclude.m4
===================================================================
--- acinclude.m4	(revision 19477)
+++ acinclude.m4	(working copy)
@@ -490,6 +490,8 @@
 	  AC_CHECK_FUNCS(pcap_get_selectable_fd)
 	fi
 	LIBS="$ac_save_LIBS"
+	AC_CHECK_HEADER(pcap/usb.h, 
+          [AC_DEFINE(HAVE_PCAP_USB, 1, Define if libpcap support USB port sniffig)],)
 ])
 
 #
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common	(revision 19477)
+++ epan/dissectors/Makefile.common	(working copy)
@@ -658,6 +658,7 @@
 	packet-uma.c	\
 	packet-udp.c	\
 	packet-ulp.c	\
+	packet-usb.c	\
 	packet-umts_fp.c	\
 	packet-umts_rrc.c	\
 	packet-umts_rrc_ies.c	\
Index: epan/dissectors/packet-usb.c
===================================================================
--- epan/dissectors/packet-usb.c	(revision 0)
+++ epan/dissectors/packet-usb.c	(revision 0)
@@ -0,0 +1,191 @@
+/* packet-usb.c
+ *
+ * $Id$
+ *
+ * usb basic dissector
+ * By Paolo Abeni <paolo.abeni@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+ 
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_PCAP_USB
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/etypes.h>
+#include <epan/addr_resolv.h>
+#include <pcap/bpf.h>
+#include <pcap/usb.h>
+
+/* protocols and header fields */
+static int proto_usb = -1;
+static int hf_usb_urb_type = -1;
+static int hf_usb_device_address = -1;
+static int hf_usb_endpoint_number = -1;
+static int hf_usb_request_type = -1;
+static int hf_usb_request = -1;
+static int hf_usb_value = -1;
+static int hf_usb_index = -1;
+static int hf_usb_length = -1;
+static int hf_usb_data = -1;
+
+static gint usb_hdr = -1;
+static gint usb_setup_hdr = -1;
+
+static const value_string usb_urb_type_vals[] = {
+    {URB_CONTROL_INPUT, "URB_CONTROL_INPUT"},
+    {URB_CONTROL_OUTPUT,"URB_CONTROL_OUTPUT"},
+    {URB_ISOCHRONOUS_INPUT,"URB_ISOCHRONOUS_INPUT"},
+    {URB_ISOCHRONOUS_OUTPUT,"URB_ISOCHRONOUS_OUTPUT"},
+    {URB_INTERRUPT_INPUT,"URB_INTERRUPT_INPUT"},
+    {URB_INTERRUPT_OUTPUT,"URB_INTERRUPT_OUTPUT"},
+    {URB_BULK_INPUT,"URB_BULK_INPUT"},
+    {URB_BULK_OUTPUT,"URB_BULK_OUTPUT"},
+    {URB_UNKNOWN, "URB_UNKNOWN"},
+    {0, NULL}
+};
+
+static void
+dissect_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
+{
+    int offset = 0;
+    int type;
+    gboolean setup;
+    proto_tree *tree = 0;
+    
+    if (check_col(pinfo->cinfo, COL_PROTOCOL))
+        col_set_str(pinfo->cinfo, COL_PROTOCOL, "USB");
+
+    /* add usb hdr*/    
+    if (parent) {
+      proto_item *ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0, 
+        sizeof(pcap_usb_header), "USB URB");
+
+      tree = proto_item_add_subtree(ti, usb_hdr);
+    }
+
+    
+    type = tvb_get_ntohl(tvb, offset);
+    proto_tree_add_item(tree, hf_usb_urb_type, tvb, offset, 4, FALSE);
+    offset += 4;
+    proto_tree_add_item(tree, hf_usb_device_address, tvb, offset, 4, FALSE);
+    offset += 4;
+    proto_tree_add_item(tree, hf_usb_endpoint_number, tvb, offset, 4, FALSE);
+    offset += 4;
+    
+    /* check for setup hdr presence */
+    setup = tvb_get_ntohl(tvb, offset);
+    offset += 4;
+    if (setup)
+    {
+        proto_item *ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 
+            offset, sizeof(pcap_usb_setup), "URB setup");
+        
+        proto_tree* setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
+        
+        proto_tree_add_item(setup_tree, hf_usb_request_type, tvb, offset, 4, FALSE);
+        offset += 4;
+        proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 4, FALSE);
+        offset += 4;
+        proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 4, FALSE);
+        offset += 4;
+        proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 4, FALSE);
+        offset += 4;
+        proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 4, FALSE);
+        offset += 4;
+    }
+    
+    proto_tree_add_item(tree, hf_usb_data, tvb,
+        offset, tvb_length_remaining(tvb, offset), FALSE);
+}
+
+#endif /* HAVE_PCAP_USB */
+
+void
+proto_register_usb(void)
+{
+#ifdef HAVE_PCAP_USB
+    static hf_register_info hf[] = {
+    
+        { &hf_usb_urb_type,
+        { "URB type", "usb.urb_type", FT_UINT32, BASE_DEC, 
+                VALS(usb_urb_type_vals), 0x0,
+                "URB type", HFILL }},
+
+        { &hf_usb_device_address,
+        { "Device", "usb.device_address", FT_UINT32, BASE_DEC, NULL, 0x0,
+                "USB device address", HFILL }},
+
+        { &hf_usb_endpoint_number,
+        { "Endpoint", "usb.endpoint_number", FT_UINT32, BASE_DEC, NULL, 0x0,
+                "usb endpoint number", HFILL }},
+
+        { &hf_usb_request_type,
+        { "Request Type", "usb.request_type", FT_UINT32, BASE_HEX, NULL, 0x0,
+                "", HFILL }},
+
+        { &hf_usb_request,
+        { "Request", "usb.request", FT_UINT32, BASE_HEX, NULL, 0x0,
+                "", HFILL }},
+
+        { &hf_usb_value,
+        { "value", "usb.value", FT_UINT32, BASE_HEX, NULL, 0x0,
+                "", HFILL }},
+
+        { &hf_usb_index,
+        { "Index", "usb.index", FT_UINT32, BASE_DEC, NULL, 0x0,
+                "", HFILL }},
+
+        { &hf_usb_length,
+        { "Length", "usb.length", FT_UINT32, BASE_DEC, NULL, 0x0,
+                "", HFILL }},
+                
+        { &hf_usb_data,
+        {"Application Data", "usb.data",
+            FT_BYTES, BASE_HEX, NULL, 0x0,
+            "Payload is application data", HFILL }}
+    
+    };
+    
+    static gint *usb_subtrees[] = {
+            &usb_hdr,
+            &usb_setup_hdr
+    };
+
+     
+    proto_usb = proto_register_protocol("USB", "USB", "usb");
+    proto_register_field_array(proto_usb, hf, array_length(hf));
+    proto_register_subtree_array(usb_subtrees, array_length(usb_subtrees));
+
+    
+    register_dissector("eth", dissect_usb, proto_usb);
+#endif /* HAVE_PCAP_USB */
+}
+
+void
+proto_reg_handoff_usb(void)
+{
+#ifdef HAVE_PCAP_USB
+    dissector_handle_t usb_handle;
+    usb_handle = create_dissector_handle(dissect_usb, proto_usb);
+
+    dissector_add("wtap_encap", WTAP_ENCAP_USB, usb_handle);
+#endif /* HAVE_PCAP_USB */   
+}
Index: wiretap/wtap.c
===================================================================
--- wiretap/wtap.c	(revision 19477)
+++ wiretap/wtap.c	(working copy)
@@ -363,6 +363,9 @@
 
 	/* WTAP_ENCAP_JUNIPER_VP */
 	{ "Juniper Voice PIC", "juniper-vp" },
+
+	/* WTAP_ENCAP_USB */
+	{ "Raw USB packets", "usb" },
 };
 
 /* Name that should be somewhat descriptive. */
Index: wiretap/wtap.h
===================================================================
--- wiretap/wtap.h	(revision 19477)
+++ wiretap/wtap.h	(working copy)
@@ -182,9 +182,10 @@
 #define WTAP_ENCAP_CATAPULT_DCT2000             89
 #define WTAP_ENCAP_BER                          90
 #define WTAP_ENCAP_JUNIPER_VP                   91
+#define WTAP_ENCAP_USB				92
 
 /* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES			92
+#define WTAP_NUM_ENCAP_TYPES			93
 
 /* File types that can be read by wiretap.
    We support writing some many of these file types, too, so we
Index: wiretap/libpcap.c
===================================================================
--- wiretap/libpcap.c	(revision 19477)
+++ wiretap/libpcap.c	(working copy)
@@ -410,6 +410,8 @@
         { 181,          WTAP_ENCAP_JUNIPER_CHDLC },
         /* VOIP Frames prepended with meta-information */
         { 183,          WTAP_ENCAP_JUNIPER_VP },
+	/* raw USB packets */
+	{ 186, 		WTAP_ENCAP_USB },
 
 
 	/*