aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-usb.c14
-rw-r--r--epan/dissectors/packet-usb.h2
2 files changed, 15 insertions, 1 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index 696ec682a1..8ddc784e40 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -155,6 +155,7 @@ static gboolean try_heuristics = TRUE;
static dissector_table_t usb_bulk_dissector_table;
static dissector_table_t usb_control_dissector_table;
+static dissector_table_t usb_descriptor_dissector_table;
static heur_dissector_list_t heur_bulk_subdissector_list;
static heur_dissector_list_t heur_control_subdissector_list;
@@ -744,6 +745,7 @@ get_usb_conv_info(conversation_t *conversation)
/* no not yet so create some */
usb_conv_info = se_alloc0(sizeof(usb_conv_info_t));
usb_conv_info->interfaceClass=IF_CLASS_UNKNOWN;
+ usb_conv_info->interfaceSubclass = IF_SUBCLASS_UNKNOWN;
usb_conv_info->transactions=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "usb transactions");
conversation_add_proto_data(conversation, proto_usb, usb_conv_info);
@@ -1064,6 +1066,8 @@ dissect_usb_interface_descriptor(packet_info *pinfo, proto_tree *parent_tree, tv
/* bInterfaceSubClass */
proto_tree_add_item(tree, hf_usb_bInterfaceSubClass, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ /* save the subclass so we can access it later in class-specific descriptors */
+ usb_conv_info->interfaceSubclass = tvb_get_guint8(tvb, offset);
offset++;
/* bInterfaceProtocol */
@@ -1322,6 +1326,7 @@ dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_
/* decode any additional interface and endpoint descriptors */
while(len>(old_offset-offset)){
guint8 next_type;
+ tvbuff_t *next_tvb = NULL;
if(tvb_length_remaining(tvb, offset)<2){
break;
@@ -1335,7 +1340,12 @@ dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_
offset=dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
break;
default:
- offset=dissect_usb_unknown_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+ if (dissector_try_uint(usb_descriptor_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent_tree)){
+ offset += tvb_get_guint8(next_tvb, 0);
+ } else {
+ offset=dissect_usb_unknown_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info, usb_conv_info);
+ }
break;
/* was: return offset; */
}
@@ -2763,6 +2773,8 @@ proto_register_usb(void)
usb_control_dissector_table = register_dissector_table("usb.control",
"USB control endpoint", FT_UINT8, BASE_DEC);
register_heur_dissector_list("usb.control", &heur_control_subdissector_list);
+ usb_descriptor_dissector_table = register_dissector_table("usb.descriptor",
+ "USB descriptor", FT_UINT8, BASE_DEC);
usb_module = prefs_register_protocol(proto_usb, NULL);
prefs_register_bool_preference(usb_module, "try_heuristics",
diff --git a/epan/dissectors/packet-usb.h b/epan/dissectors/packet-usb.h
index ef7a1cb2b4..48ec7e01d1 100644
--- a/epan/dissectors/packet-usb.h
+++ b/epan/dissectors/packet-usb.h
@@ -60,6 +60,7 @@ typedef struct _usb_trans_info_t {
/* there is one such structure for each device/endpoint conversation */
struct _usb_conv_info_t {
guint16 interfaceClass; /* class for this conversation */
+ guint16 interfaceSubclass; /* Most recent interface descriptor subclass */
emem_tree_t *transactions;
usb_trans_info_t *usb_trans_info; /* pointer to the current transaction */
void *class_data; /* private class/id decode data */
@@ -120,6 +121,7 @@ typedef struct _usb_tap_data_t {
#define IF_CLASS_APPLICATION_SPECIFIC 0xfe
#define IF_CLASS_VENDOR_SPECIFIC 0xff
+#define IF_SUBCLASS_UNKNOWN 0xffff
/* bmRequestType values */
#define USB_DIR_OUT 0 /* to device */