dissect a lot more of the descriptors so that we can finally see which endpoints are used for what purpose

svn path=/trunk/; revision=19557
This commit is contained in:
Ronnie Sahlberg 2006-10-16 14:43:35 +00:00
parent a32f396008
commit 2cb017d84f
1 changed files with 273 additions and 3 deletions

View File

@ -9,6 +9,7 @@
*
* usb basic dissector
* By Paolo Abeni <paolo.abeni@email.com>
* Ronnie Sahlberg 2006
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -74,6 +75,22 @@ static int hf_usb_iSerialNumber = -1;
static int hf_usb_bNumConfigurations = -1;
static int hf_usb_wLANGID = -1;
static int hf_usb_bString = -1;
static int hf_usb_bInterfaceNumber = -1;
static int hf_usb_bAlternateSetting = -1;
static int hf_usb_bNumEndpoints = -1;
static int hf_usb_bInterfaceClass = -1;
static int hf_usb_bInterfaceSubClass = -1;
static int hf_usb_bInterfaceProtocol = -1;
static int hf_usb_iInterface = -1;
static int hf_usb_bEndpointAddress = -1;
static int hf_usb_bmAttributes = -1;
static int hf_usb_wMaxPacketSize = -1;
static int hf_usb_bInterval = -1;
static int hf_usb_wTotalLength = -1;
static int hf_usb_bNumInterfaces = -1;
static int hf_usb_bConfigurationValue = -1;
static int hf_usb_iConfiguration = -1;
static int hf_usb_bMaxPower = -1;
static gint usb_hdr = -1;
static gint usb_setup_hdr = -1;
@ -134,6 +151,12 @@ static const value_string usb_langid_vals[] = {
{0, NULL}
};
#define IF_CLASS_MASSTORAGE 0x08
static const value_string usb_interfaceclass_vals[] = {
{IF_CLASS_MASSTORAGE, "Mass Storage Class"},
{0, NULL}
};
static const value_string usb_urb_type_vals[] = {
{URB_CONTROL_INPUT, "URB_CONTROL_INPUT"},
{URB_CONTROL_OUTPUT,"URB_CONTROL_OUTPUT"},
@ -348,13 +371,11 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, t
tree=proto_item_add_subtree(item, ett_descriptor_device);
}
/* bLength */
proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
len=tvb_get_guint8(tvb, offset);
offset++;
/* bDescriptorType */
proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
offset++;
@ -382,6 +403,182 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, t
}
/* 9.6.5 */
static int
dissect_usb_interface_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info _U_)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
int old_offset=offset;
if(parent_tree){
item=proto_tree_add_text(parent_tree, tvb, offset, 0, "INTERFACE DESCRIPTOR");
tree=proto_item_add_subtree(item, ett_descriptor_device);
}
/* bLength */
proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
offset++;
/* bDescriptorType */
proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
offset++;
/* bInterfaceNumber */
proto_tree_add_item(tree, hf_usb_bInterfaceNumber, tvb, offset, 1, TRUE);
offset++;
/* bAlternateSetting */
proto_tree_add_item(tree, hf_usb_bAlternateSetting, tvb, offset, 1, TRUE);
offset++;
/* bNumEndpoints */
proto_tree_add_item(tree, hf_usb_bNumEndpoints, tvb, offset, 1, TRUE);
offset++;
/* bInterfaceClass */
proto_tree_add_item(tree, hf_usb_bInterfaceClass, tvb, offset, 1, TRUE);
offset++;
/* bInterfaceSubClass */
proto_tree_add_item(tree, hf_usb_bInterfaceSubClass, tvb, offset, 1, TRUE);
offset++;
/* bInterfaceProtocol */
proto_tree_add_item(tree, hf_usb_bInterfaceProtocol, tvb, offset, 1, TRUE);
offset++;
/* iInterface */
proto_tree_add_item(tree, hf_usb_iInterface, tvb, offset, 1, TRUE);
offset++;
if(item){
proto_item_set_len(item, offset-old_offset);
}
return offset;
}
/* 9.6.6 */
static int
dissect_usb_endpoint_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info _U_)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
int old_offset=offset;
if(parent_tree){
item=proto_tree_add_text(parent_tree, tvb, offset, 0, "ENDPOINT DESCRIPTOR");
tree=proto_item_add_subtree(item, ett_descriptor_device);
}
/* bLength */
proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
offset++;
/* bDescriptorType */
proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
offset++;
/* bEndpointAddress */
proto_tree_add_item(tree, hf_usb_bEndpointAddress, tvb, offset, 1, TRUE);
offset++;
/* bmAttributes */
proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, TRUE);
offset++;
/* wMaxPacketSize */
proto_tree_add_item(tree, hf_usb_wMaxPacketSize, tvb, offset, 2, TRUE);
offset+=2;
/* bInterval */
proto_tree_add_item(tree, hf_usb_bInterval, tvb, offset, 1, TRUE);
offset++;
if(item){
proto_item_set_len(item, offset-old_offset);
}
return offset;
}
/* 9.6.3 */
static int
dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
int old_offset=offset;
guint16 len;
if(parent_tree){
item=proto_tree_add_text(parent_tree, tvb, offset, 0, "CONFIGURATION DESCRIPTOR");
tree=proto_item_add_subtree(item, ett_descriptor_device);
}
/* bLength */
proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, TRUE);
offset++;
/* bDescriptorType */
proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset, 1, TRUE);
offset++;
/* wTotalLength */
proto_tree_add_item(tree, hf_usb_wTotalLength, tvb, offset, 2, TRUE);
len=tvb_get_letohs(tvb, offset);
offset+=2;
/* bNumInterfaces */
proto_tree_add_item(tree, hf_usb_bNumInterfaces, tvb, offset, 1, TRUE);
offset++;
/* bConfigurationValue */
proto_tree_add_item(tree, hf_usb_bConfigurationValue, tvb, offset, 1, TRUE);
offset++;
/* iConfiguration */
proto_tree_add_item(tree, hf_usb_iConfiguration, tvb, offset, 1, TRUE);
offset++;
/* bmAttributes */
proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, TRUE);
offset++;
/* bMaxPower */
proto_tree_add_item(tree, hf_usb_bMaxPower, tvb, offset, 1, TRUE);
offset++;
/* decode any additional interface and endpoint descriptors */
while(len>(old_offset-offset)){
guint8 next_type;
if(tvb_length_remaining(tvb, offset)<2){
break;
}
next_type=tvb_get_guint8(tvb, offset+1);
switch(next_type){
case USB_DT_INTERFACE:
offset=dissect_usb_interface_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info);
break;
case USB_DT_ENDPOINT:
offset=dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_trans_info);
break;
default:
return offset;
}
}
if(item){
proto_item_set_len(item, offset-old_offset);
}
return offset;
}
static void
dissect_usb_setup_get_descriptor(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, gboolean is_request, usb_trans_info_t *usb_trans_info)
{
@ -416,9 +613,18 @@ dissect_usb_setup_get_descriptor(packet_info *pinfo, proto_tree *tree, tvbuff_t
case USB_DT_DEVICE:
offset=dissect_usb_device_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
case USB_DT_CONFIGURATION:
offset=dissect_usb_configuration_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
case USB_DT_STRING:
offset=dissect_usb_string_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
case USB_DT_INTERFACE:
offset=dissect_usb_interface_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
case USB_DT_ENDPOINT:
offset=dissect_usb_endpoint_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
case USB_DT_DEVICE_QUALIFIER:
offset=dissect_usb_device_qualifier_descriptor(pinfo, tree, tvb, offset, usb_trans_info);
break;
@ -740,7 +946,7 @@ proto_register_usb(void)
{ &hf_usb_setup,
{ "Setup", "usb.setup", FT_UINT32, BASE_DEC, NULL, 0x0,
"USB setup", HFILL }},
"USB setup", HFILL }},
{ &hf_usb_endpoint_number,
{ "Endpoint", "usb.endpoint_number", FT_UINT32, BASE_HEX, NULL, 0x0,
@ -863,6 +1069,70 @@ proto_register_usb(void)
{ "bString", "usb.bString", FT_STRING, BASE_NONE,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bInterfaceNumber,
{ "bInterfaceNumber", "usb.bInterfaceNumber", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bAlternateSetting,
{ "bAlternateSetting","usb.bAlternateSetting", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bNumEndpoints,
{ "bNumEndpoints","usb.bNumEndpoints", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bInterfaceClass,
{ "bInterfaceClass", "usb.bInterfaceClass", FT_UINT8, BASE_HEX,
VALS(usb_interfaceclass_vals), 0x0, "", HFILL }},
{ &hf_usb_bInterfaceSubClass,
{ "bInterfaceSubClass", "usb.bInterfaceSubClass", FT_UINT8, BASE_HEX,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bInterfaceProtocol,
{ "bInterfaceProtocol", "usb.bInterfaceProtocol", FT_UINT8, BASE_HEX,
NULL, 0x0, "", HFILL }},
{ &hf_usb_iInterface,
{ "iInterface", "usb.iInterface", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bEndpointAddress,
{ "bEndpointAddress", "usb.bEndpointAddress", FT_UINT8, BASE_HEX,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bmAttributes,
{ "bmAttributes", "usb.bmAttributes", FT_UINT8, BASE_HEX,
NULL, 0x0, "", HFILL }},
{ &hf_usb_wMaxPacketSize,
{ "wMaxPacketSize", "usb.wMaxPacketSize", FT_UINT16, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bInterval,
{ "bInterval", "usb.bInterval", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_wTotalLength,
{ "wTotalLength", "usb.wTotalLength", FT_UINT16, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bNumInterfaces,
{ "bNumInterfaces", "usb.bNumInterfaces", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bConfigurationValue,
{ "bConfigurationValue", "usb.bConfigurationValue", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_iConfiguration,
{ "iConfiguration", "usb.iConfiguration", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
{ &hf_usb_bMaxPower,
{ "bMaxPower", "usb.bMaxPower", FT_UINT8, BASE_DEC,
NULL, 0x0, "", HFILL }},
};
static gint *usb_subtrees[] = {