aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-usb.c
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2019-05-27 18:32:03 +0200
committerAnders Broman <a.broman58@gmail.com>2019-05-29 07:32:48 +0000
commit1e7db19ff90be5e1c79351910e8dbb3d1ad3090f (patch)
tree602f493f8f3f4c9f0a205a813121f02526959f85 /epan/dissectors/packet-usb.c
parent2eb1a0dd6102e6a2958457d12fc85becb30358d6 (diff)
USB: Dissect SuperSpeed Endpoint Companion descriptors
Mark undecoded data in endpoint descriptors with expert info. Bug: 15798 Change-Id: I392da00205274fb3f5eb947a54ba424d1edb041b Reviewed-on: https://code.wireshark.org/review/33386 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-usb.c')
-rw-r--r--epan/dissectors/packet-usb.c116
1 files changed, 109 insertions, 7 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index cb577594cf..715c7c07f7 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -239,6 +239,10 @@ static int hf_usb_wMaxPacketSize = -1;
static int hf_usb_wMaxPacketSize_size = -1;
static int hf_usb_wMaxPacketSize_slots = -1;
static int hf_usb_bInterval = -1;
+static int hf_usb_bMaxBurst = -1;
+static int hf_usb_bSSEndpointAttributeBulkMaxStreams = -1;
+static int hf_usb_bSSEndpointAttributeIsoMult = -1;
+static int hf_usb_wBytesPerInterval = -1;
static int hf_usb_wTotalLength = -1;
static int hf_usb_bNumInterfaces = -1;
static int hf_usb_bConfigurationValue = -1;
@@ -356,10 +360,12 @@ static gint ett_usbport_urb = -1;
static gint ett_usbport_keyword = -1;
static gint ett_transfer_flags = -1;
+static expert_field ei_usb_undecoded = EI_INIT;
static expert_field ei_usb_bLength_even = EI_INIT;
static expert_field ei_usb_bLength_too_short = EI_INIT;
static expert_field ei_usb_desc_length_invalid = EI_INIT;
static expert_field ei_usb_invalid_setup = EI_INIT;
+static expert_field ei_usb_ss_ep_companion_before_ep = EI_INIT;
static expert_field ei_usb_usbpcap_unknown_urb = EI_INIT;
static expert_field ei_usbport_invalid_path_depth = EI_INIT;
@@ -886,6 +892,12 @@ extern value_string_ext linux_negative_errno_vals_ext;
#define USB_DT_OTG 9
#define USB_DT_DEBUG 10
#define USB_DT_INTERFACE_ASSOCIATION 11
+/* these are from usb 3.0 specification */
+#define USB_DT_BOS 0x0F
+#define USB_DT_DEVICE_CAPABILITY 0x10
+#define USB_DT_SUPERSPEED_EP_COMPANION 0x30
+/* these are from usb 3.1 specification */
+#define USB_DT_SUPERSPEED_ISO_EP_COMPANION 0x31
/* There are only Standard Descriptor Types, Class-specific types are
provided by "usb.descriptor" descriptors table*/
@@ -901,10 +913,10 @@ static const value_string std_descriptor_type_vals[] = {
{USB_DT_OTG, "OTG"},
{USB_DT_DEBUG, "DEBUG"},
{USB_DT_INTERFACE_ASSOCIATION, "INTERFACE ASSOCIATION"},
- { 0x0F, "BOS"},
- { 0x10, "DEVICE CAPABILITY"},
- { 0x30, "SUPERSPEED USB ENDPOINT COMPANION"},
- { 0x31, "SUPERSPEED PLUS ISOCHRONOUS ENDPOINT COMPANION"},
+ {USB_DT_BOS, "BOS"},
+ {USB_DT_DEVICE_CAPABILITY, "DEVICE CAPABILITY"},
+ {USB_DT_SUPERSPEED_EP_COMPANION, "SUPERSPEED USB ENDPOINT COMPANION"},
+ {USB_DT_SUPERSPEED_ISO_EP_COMPANION, "SUPERSPEED PLUS ISOCHRONOUS ENDPOINT COMPANION"},
{0,NULL}
};
static value_string_ext std_descriptor_type_vals_ext =
@@ -2379,7 +2391,8 @@ void dissect_usb_endpoint_address(proto_tree *tree, tvbuff_t *tvb, int offset)
int
dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree,
tvbuff_t *tvb, int offset,
- usb_conv_info_t *usb_conv_info)
+ usb_conv_info_t *usb_conv_info,
+ guint8 *out_ep_type)
{
proto_item *item;
proto_tree *tree;
@@ -2439,6 +2452,9 @@ dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree,
/* bmAttributes */
ep_type = ENDPOINT_TYPE(tvb_get_guint8(tvb, offset));
+ if (out_ep_type) {
+ *out_ep_type = ep_type;
+ }
ep_attrib_item = proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, ENC_LITTLE_ENDIAN);
ep_attrib_tree = proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
@@ -2490,7 +2506,67 @@ dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree,
proto_item_set_len(item, len);
if (offset < old_offset+len) {
- /* skip unknown records */
+ /* mark unknown records as undecoded */
+ proto_tree_add_expert(tree, pinfo, &ei_usb_undecoded, tvb, offset, old_offset + len - offset);
+ offset = old_offset + len;
+ }
+
+ return offset;
+}
+
+static int
+dissect_usb_endpoint_companion_descriptor(packet_info *pinfo, proto_tree *parent_tree,
+ tvbuff_t *tvb, int offset,
+ usb_conv_info_t *usb_conv_info _U_,
+ guint8 ep_type)
+{
+ proto_item *item;
+ proto_tree *tree;
+ proto_item *ep_attrib_item;
+ proto_tree *ep_attrib_tree;
+ int old_offset = offset;
+ guint8 len;
+
+ tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_descriptor_device, &item, "SUPERSPEED ENDPOINT COMPANION DESCRIPTOR");
+
+ len = tvb_get_guint8(tvb, offset);
+ dissect_usb_descriptor_header(tree, tvb, offset, NULL);
+ offset += 2;
+
+ /* bMaxBurst */
+ proto_tree_add_item(tree, hf_usb_bMaxBurst, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+
+ /* bmAttributes */
+ ep_attrib_item = proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ switch (ep_type) {
+ case ENDPOINT_TYPE_CONTROL:
+ break;
+ case ENDPOINT_TYPE_ISOCHRONOUS:
+ ep_attrib_tree = proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
+ proto_tree_add_item(ep_attrib_tree, hf_usb_bSSEndpointAttributeIsoMult, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ break;
+ case ENDPOINT_TYPE_BULK:
+ ep_attrib_tree = proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
+ proto_tree_add_item(ep_attrib_tree, hf_usb_bSSEndpointAttributeBulkMaxStreams, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ break;
+ case ENDPOINT_TYPE_INTERRUPT:
+ break;
+ default:
+ expert_add_info(pinfo, ep_attrib_item, &ei_usb_ss_ep_companion_before_ep);
+ break;
+ }
+ offset += 1;
+
+ /* wBytesPerInterval */
+ proto_tree_add_item(tree, hf_usb_wBytesPerInterval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_item_set_len(item, len);
+
+ if (offset < old_offset + len) {
+ /* mark unknown records as undecoded */
+ proto_tree_add_expert(tree, pinfo, &ei_usb_undecoded, tvb, offset, old_offset + len - offset);
offset = old_offset + len;
}
@@ -2586,6 +2662,7 @@ dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_
proto_item *flags_item;
proto_tree *flags_tree;
guint8 flags;
+ guint8 last_ep_type = ENDPOINT_TYPE_NOT_SET;
proto_item *power_item;
guint8 power;
gboolean truncation_expected;
@@ -2673,11 +2750,14 @@ dissect_usb_configuration_descriptor(packet_info *pinfo _U_, proto_tree *parent_
offset = dissect_usb_interface_descriptor(pinfo, parent_tree, tvb, offset, usb_conv_info);
break;
case USB_DT_ENDPOINT:
- offset = dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_conv_info);
+ offset = dissect_usb_endpoint_descriptor(pinfo, parent_tree, tvb, offset, usb_conv_info, &last_ep_type);
break;
case USB_DT_INTERFACE_ASSOCIATION:
offset = dissect_usb_interface_assn_descriptor(pinfo, parent_tree, tvb, offset, usb_conv_info);
break;
+ case USB_DT_SUPERSPEED_EP_COMPANION:
+ offset = dissect_usb_endpoint_companion_descriptor(pinfo, parent_tree, tvb, offset, usb_conv_info, last_ep_type);
+ break;
default:
next_tvb = tvb_new_subset_length(tvb, offset, next_len);
if (dissector_try_uint_new(usb_descriptor_dissector_table, usb_conv_info->interfaceClass, next_tvb, pinfo, parent_tree, TRUE, usb_conv_info)) {
@@ -6060,6 +6140,26 @@ proto_register_usb(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }},
+ { &hf_usb_bMaxBurst,
+ { "bMaxBurst", "usb.bMaxBurst",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Valid values are from 0 to 15. For control endpoints this value shall be 0.", HFILL }},
+
+ { &hf_usb_bSSEndpointAttributeBulkMaxStreams,
+ { "MaxStreams", "usb.bmAttributes.MaxStreams",
+ FT_UINT8, BASE_DEC, NULL, 0x0F,
+ "Number of streams = 2 to the power MaxStreams", HFILL }},
+
+ { &hf_usb_bSSEndpointAttributeIsoMult,
+ { "Mult", "usb.bmAttributes.Mult",
+ FT_UINT8, BASE_DEC, NULL, 0x03,
+ "Maximum number of packets = bMaxBurst * (Mult + 1)", HFILL } },
+
+ { &hf_usb_wBytesPerInterval,
+ { "wBytesPerInterval", "usb.wBytesPerInterval",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL } },
+
{ &hf_usb_wTotalLength,
{ "wTotalLength", "usb.wTotalLength",
FT_UINT16, BASE_DEC, NULL, 0x0,
@@ -6443,10 +6543,12 @@ proto_register_usb(void)
};
static ei_register_info ei[] = {
+ { &ei_usb_undecoded, { "usb.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
{ &ei_usb_bLength_even, { "usb.bLength.even", PI_PROTOCOL, PI_WARN, "Invalid STRING DESCRIPTOR Length (must be even)", EXPFILL }},
{ &ei_usb_bLength_too_short, { "usb.bLength.too_short", PI_MALFORMED, PI_ERROR, "Invalid STRING DESCRIPTOR Length (must be 2 or larger)", EXPFILL }},
{ &ei_usb_desc_length_invalid, { "usb.desc_length.invalid", PI_MALFORMED, PI_ERROR, "Invalid descriptor length", EXPFILL }},
{ &ei_usb_invalid_setup, { "usb.setup.invalid", PI_MALFORMED, PI_ERROR, "Only control URBs may contain a setup packet", EXPFILL }},
+ { &ei_usb_ss_ep_companion_before_ep, { "usb.bmAttributes.invalid_order", PI_MALFORMED, PI_ERROR, "SuperSpeed Endpoint Companion must come after Endpoint Descriptor", EXPFILL }},
{ &ei_usb_usbpcap_unknown_urb, { "usb.usbpcap.unknown_urb", PI_MALFORMED, PI_ERROR, "USBPcap did not recognize URB Function code (report to desowin.org/USBPcap)", EXPFILL }}
};
static ei_register_info ei_usbport[] = {