diff options
author | Krzysztof Opasiak <k.opasiak@samsung.com> | 2019-08-14 01:16:13 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-08-20 04:27:26 +0000 |
commit | 4278234a1db0d98247f2062a879f78cc9d741d6d (patch) | |
tree | 938ef73defee328a48c9cae80bb087ac791ba0fb /epan | |
parent | d8385b42e20129ad694293d225dd6a3f141bfd1b (diff) |
USBLL: Use custom address dissector instead of usb one
Usage of USB address dissector creates several challenges. In order to
improve user experience let's create a custom address dissector.
This allows us to not only drop the busid parameter but also replace
endpoint parameter with hub port for SPLIT transactions.
The address may be one of 3 forms:
- host
- <device address>.<endpoint>
- <hub address>:<hub port> (for SPLIT transactions)
This also adds 3 new fields (source, destination and addr) with
exactly the same meaning as in usb. It also renames current addr field
to device_addr.
Strongly based on initial work by:
Maciej Purski <maciej.purski@gmail.com>
Ping-Bug: 15908
Change-Id: I5702295d7ef9076c3e0373de35ea4ac3cb2a0709
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Reviewed-on: https://code.wireshark.org/review/34279
Reviewed-by: Tomasz Moń <desowin@gmail.com>
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')
-rw-r--r-- | epan/dissectors/packet-usbll.c | 167 |
1 files changed, 142 insertions, 25 deletions
diff --git a/epan/dissectors/packet-usbll.c b/epan/dissectors/packet-usbll.c index d911b60bbe..23af7bbb7e 100644 --- a/epan/dissectors/packet-usbll.c +++ b/epan/dissectors/packet-usbll.c @@ -18,13 +18,15 @@ #include <epan/expert.h> #include <epan/crc16-tvb.h> #include <wsutil/crc5.h> +#include <epan/address_types.h> +#include <epan/to_str.h> #include "packet-usb.h" static int proto_usbll = -1; /* Fields defined by USB 2.0 standard */ static int hf_usbll_pid = -1; -static int hf_usbll_addr = -1; +static int hf_usbll_device_addr = -1; static int hf_usbll_endp = -1; static int hf_usbll_crc5 = -1; static int hf_usbll_crc5_status = -1; @@ -41,6 +43,10 @@ static int hf_usbll_split_iso_se = -1; static int hf_usbll_split_et = -1; static int hf_usbll_split_crc5 = -1; static int hf_usbll_split_crc5_status = -1; +static int hf_usbll_src = -1; +static int hf_usbll_dst = -1; +static int hf_usbll_addr = -1; + static int ett_usbll = -1; @@ -50,6 +56,8 @@ static expert_field ei_wrong_crc5 = EI_INIT; static expert_field ei_wrong_split_crc5 = EI_INIT; static expert_field ei_wrong_crc16 = EI_INIT; +static int usbll_address_type = -1; + static dissector_handle_t usbll_handle; /* USB packet ID is 4-bit. It is send in octet alongside complemented form. @@ -131,10 +139,112 @@ static const value_string usb_endpoint_type_vals[] = { #define TOKEN_BITS_GET_ADDRESS(bits) (bits & 0x007F) #define TOKEN_BITS_GET_ENDPOINT(bits) ((bits & 0x0780) >> 7) -#define SPLIT_BITS_GET_HUB_ADDRESS(bits) (bits & 0x007F) +#define SPLIT_BITS_GET_HUB_ADDRESS(bits) (guint8)(bits & 0x007F) +#define SPLIT_BITS_GET_HUB_PORT(bits) (guint8)((bits & 0x7F00) >> 8) #define SPLIT_BITS_GET_ENDPOINT_TYPE(bits) ((bits & 0x060000) >> 17) #define SPLIT_BIT_START_COMPLETE 0x0080 +#define USBLL_ADDRESS_STANDARD 0 +#define USBLL_ADDRESS_HOST 0x01 +#define USBLL_ADDRESS_HUB_PORT 0x02 +#define USBLL_ADDRESS_HOST_TO_DEV 0 +#define USBLL_ADDRESS_DEV_TO_HOST 0x04 + +#define USBLL_ADDRESS_IS_DEV_TO_HOST(flags) \ + (flags & USBLL_ADDRESS_DEV_TO_HOST) + +#define USBLL_ADDRESS_IS_HOST_TO_DEV(flags) \ + (!USBLL_ADDRESS_IS_DEV_TO_HOST(flags)) + +typedef struct { + guint8 flags; + guint8 device; + guint8 endpoint; +} usbll_address_t; + +static int usbll_addr_to_str(const address* addr, gchar *buf, int buf_len) +{ + const usbll_address_t *addrp = (const usbll_address_t *)addr->data; + + if (addrp->flags & USBLL_ADDRESS_HOST) { + g_strlcpy(buf, "host", buf_len); + } else if (addrp->flags & USBLL_ADDRESS_HUB_PORT) { + /* + * in split transaction we use : to mark that the last part is port not + * endpoint + */ + g_snprintf(buf, buf_len, "%d:%d", addrp->device, + addrp->endpoint); + } else { + /* Just a standard address.endpoint notation */ + g_snprintf(buf, buf_len, "%d.%d", addrp->device, + addrp->endpoint); + } + + return (int)(strlen(buf)+1); +} + +static int usbll_addr_str_len(const address* addr _U_) +{ + return 50; /* The same as for usb */ +} + +static void usbll_set_address(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint8 device, guint8 endpoint, guint8 flags) +{ + proto_item *sub_item; + usbll_address_t *src_addr, *dst_addr; + guint8 *str_src_addr, *str_dst_addr; + + src_addr = wmem_new0(wmem_file_scope(), usbll_address_t); + dst_addr = wmem_new0(wmem_file_scope(), usbll_address_t); + + if (USBLL_ADDRESS_IS_HOST_TO_DEV(flags)) { + src_addr->flags = USBLL_ADDRESS_HOST; + + dst_addr->device = device; + dst_addr->endpoint = endpoint; + if (flags & USBLL_ADDRESS_HUB_PORT) { + dst_addr->flags = USBLL_ADDRESS_HUB_PORT; + pinfo->ptype = PT_NONE; + } else { + pinfo->ptype = PT_USB; + pinfo->destport = dst_addr->endpoint; + } + } else { + dst_addr->flags = USBLL_ADDRESS_HOST; + src_addr->device = device; + src_addr->endpoint = endpoint; + + pinfo->ptype = PT_USB; + pinfo->srcport = src_addr->endpoint; + pinfo->destport = NO_ENDPOINT; + + } + + pinfo->p2p_dir = USBLL_ADDRESS_IS_HOST_TO_DEV(flags) ? P2P_DIR_SENT : P2P_DIR_RECV; + + set_address(&pinfo->net_src, usbll_address_type, sizeof(usbll_address_t), (char *)src_addr); + copy_address_shallow(&pinfo->src, &pinfo->net_src); + + set_address(&pinfo->net_dst, usbll_address_type, sizeof(usbll_address_t), (char *)dst_addr); + copy_address_shallow(&pinfo->dst, &pinfo->net_dst); + + str_src_addr = address_to_str(wmem_packet_scope(), &pinfo->src); + str_dst_addr = address_to_str(wmem_packet_scope(), &pinfo->dst); + + sub_item = proto_tree_add_string(tree, hf_usbll_src, tvb, 0, 0, str_src_addr); + proto_item_set_generated(sub_item); + + sub_item = proto_tree_add_string(tree, hf_usbll_addr, tvb, 0, 0, str_src_addr); + proto_item_set_hidden(sub_item); + + sub_item = proto_tree_add_string(tree, hf_usbll_dst, tvb, 0, 0, str_dst_addr); + proto_item_set_generated(sub_item); + + sub_item = proto_tree_add_string(tree, hf_usbll_addr, tvb, 0, 0, str_dst_addr); + proto_item_set_hidden(sub_item); +} + static gint dissect_usbll_sof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { @@ -154,17 +264,12 @@ dissect_usbll_sof(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offs static gint dissect_usbll_token(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { - /* USB address has bus id as when capturing at URB level there are usually multiple root hubs - * to select from. Until someone has specific need to connect multiple hardware sniffers at - * the same time and analyze that in Wireshark, this code simply sets the bus id to 0. - */ - const guint16 bus_id = 0; - guint16 device_address; - int endpoint; - guint16 address_bits; + guint8 device_address; + guint8 endpoint; + guint16 address_bits; static const int *address_fields[] = { - &hf_usbll_addr, + &hf_usbll_device_addr, &hf_usbll_endp, NULL }; @@ -172,7 +277,7 @@ dissect_usbll_token(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint of address_bits = tvb_get_letohs(tvb, offset); device_address = TOKEN_BITS_GET_ADDRESS(address_bits); endpoint = TOKEN_BITS_GET_ENDPOINT(address_bits); - usb_set_addr(tree, tvb, pinfo, bus_id, device_address, endpoint, TRUE); + usbll_set_address(tree, tvb, pinfo, device_address, endpoint, USBLL_ADDRESS_HOST_TO_DEV); proto_tree_add_bitmask_list_value(tree, tvb, offset, 2, address_fields, address_bits); proto_tree_add_checksum(tree, tvb, offset, @@ -207,13 +312,8 @@ dissect_usbll_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs static gint dissect_usbll_split(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { - /* USB address has bus id as when capturing at URB level there are usually multiple root hubs - * to select from. Until someone has specific need to connect multiple hardware sniffers at - * the same time and analyze that in Wireshark, this code simply sets the bus id to 0. - */ - const guint16 bus_id = 0; - guint16 device_address; - int endpoint; + guint8 hub_address; + guint8 hub_port; /* S/E fields have special meaning for Isochronous transfers */ gint32 tmp = tvb_get_gint24(tvb, offset, ENC_LITTLE_ENDIAN); @@ -235,10 +335,10 @@ dissect_usbll_split(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint of NULL }; - device_address = SPLIT_BITS_GET_HUB_ADDRESS(tmp); - /* There is no endpoint information in the packet, show it as endpoint 0 */ - endpoint = 0; - usb_set_addr(tree, tvb, pinfo, bus_id, device_address, endpoint, TRUE); + hub_address = SPLIT_BITS_GET_HUB_ADDRESS(tmp); + hub_port = SPLIT_BITS_GET_HUB_PORT(tmp); + + usbll_set_address(tree, tvb, pinfo, hub_address, hub_port, USBLL_ADDRESS_HOST_TO_DEV | USBLL_ADDRESS_HUB_PORT); col_append_str(pinfo->cinfo, COL_INFO, (tmp & SPLIT_BIT_START_COMPLETE) ? " Complete" : " Start"); @@ -335,8 +435,8 @@ proto_register_usbll(void) FT_UINT8, BASE_HEX|BASE_EXT_STRING, &usb_packetid_vals_ext, 0x00, "USB Packet ID", HFILL }}, - { &hf_usbll_addr, - { "Address", "usbll.addr", + { &hf_usbll_device_addr, + { "Address", "usbll.device_addr", FT_UINT16, BASE_DEC, NULL, 0x007F, NULL, HFILL }}, { &hf_usbll_endp, @@ -404,6 +504,18 @@ proto_register_usbll(void) { "CRC5 Status", "usbll.split_crc5.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0, NULL, HFILL }}, + { &hf_usbll_src, + { "Source", "usbll.src", + FT_STRING, STR_ASCII, NULL, 0x0, + NULL, HFILL }}, + { &hf_usbll_dst, + { "Destination", "usbll.dst", + FT_STRING, STR_ASCII, NULL, 0x0, + NULL, HFILL }}, + { &hf_usbll_addr, + { "Source or Destination", "usbll.addr", + FT_STRING, STR_ASCII, NULL, 0x0, + NULL, HFILL }} }; static ei_register_info ei[] = { @@ -426,6 +538,11 @@ proto_register_usbll(void) expert_register_field_array(expert_module, ei, array_length(ei)); register_dissector("usbll", dissect_usbll_packet, proto_usbll); + + usbll_address_type = address_type_dissector_register("AT_USBLL", "USBLL Address", + usbll_addr_to_str, usbll_addr_str_len, + NULL, NULL, NULL, NULL, NULL); + } void |