diff options
author | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2020-02-24 13:12:15 +0000 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2020-02-24 13:12:15 +0000 |
commit | 7797c01d09497f0de4787e2c9d252da2bde4c118 (patch) | |
tree | 0eb736b227164adc3efbb7a3dd15c62992f0cec3 | |
parent | 8698348e98435e443b51811bbb7a49f2a2cff9bc (diff) |
extend decoding of control transfers:
- print the stage name
- print additional information about the request for Setup packets
- GET_DESCRIPTOR requests are further decoded
tweaks and ok mpi@
-rw-r--r-- | usr.sbin/tcpdump/print-usbpcap.c | 199 |
1 files changed, 198 insertions, 1 deletions
diff --git a/usr.sbin/tcpdump/print-usbpcap.c b/usr.sbin/tcpdump/print-usbpcap.c index b53bd34cd51..324d9024479 100644 --- a/usr.sbin/tcpdump/print-usbpcap.c +++ b/usr.sbin/tcpdump/print-usbpcap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-usbpcap.c,v 1.3 2020/02/22 14:05:08 jasper Exp $ */ +/* $OpenBSD: print-usbpcap.c,v 1.4 2020/02/24 13:12:14 jasper Exp $ */ /* * Copyright (c) 2018 Martin Pieuchot <mpi@openbsd.org> @@ -28,6 +28,15 @@ #endif const char *usbpcap_xfer_type[] = {"isoc", "intr", "ctrl", "bulk"}; +const char *usbpcap_control_stages[] = {"setup", "data", "setatus"}; +const char *usbpcap_request_codes[] = { + "GET_STATUS", "CLEAR_FEATURE", "?", "SET_FEATURE", "?", "SET_ADDRESS", + "GET_DESCRIPTOR", "SET_DESCRIPTOR", "GET_CONFIG", "SET_CONFIG", + "GET_INTERFACE", "SET_INTERFACE", "SYNCH_FRAME", +}; + +void usbpcap_print_descriptor(int); +void usbpcap_print_request_type(uByte); void usbpcap_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) @@ -65,6 +74,42 @@ usbpcap_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) printf(" dlen=%u", letoh32(uph->uph_dlen)); + if (uph->uph_xfertype == USBPCAP_TRANSFER_CONTROL) { + struct usbpcap_ctl_hdr *ctl_hdr = (struct usbpcap_ctl_hdr *)p; + + if (ctl_hdr->uch_stage < nitems(usbpcap_control_stages)) + printf(" stage=%s", + usbpcap_control_stages[ctl_hdr->uch_stage]); + else + printf(" stage=?"); + + if (ctl_hdr->uch_stage == USBPCAP_CONTROL_STAGE_SETUP) { + /* Setup packets must be 8 bytes in size as per + * 9.3 USB Device Requests. */ + if (letoh32(uph->uph_dlen != 8)) + goto trunc; + + usb_device_request_t *req = (usb_device_request_t *) + (p + sizeof(struct usbpcap_ctl_hdr)); + + usbpcap_print_request_type(req->bmRequestType); + + if (req->bRequest < nitems(usbpcap_request_codes)) + printf(" bRequest=%s", + usbpcap_request_codes[req->bRequest]); + else + printf(" bRequest=?"); + + if (req->bRequest == UR_GET_DESCRIPTOR) + usbpcap_print_descriptor(UGETW(req->wValue)); + else + printf(" wValue=0x%04x", UGETW(req->wValue)); + + printf(" wIndex=%04x", UGETW(req->wIndex)); + printf(" wLength=%u", UGETW(req->wLength)); + } + } + if (xflag) default_print(p + sizeof(*uph), length - sizeof(*uph)); out: @@ -73,3 +118,155 @@ out: trunc: printf("[|usb]"); } + +void +usbpcap_print_descriptor(int value) +{ + printf(" type="); + switch (value >> 8) { + case UDESC_DEVICE: + printf("DEVICE"); + break; + case UDESC_CONFIG: + printf("CONFIGURATION"); + break; + case UDESC_STRING: + printf("STRING"); + break; + case UDESC_INTERFACE: + printf("INTERFACE"); + break; + case UDESC_ENDPOINT: + printf("ENDPOINT"); + break; + case UDESC_DEVICE_QUALIFIER: + printf("DEVICE_QUALIFIER"); + break; + case UDESC_OTHER_SPEED_CONFIGURATION: + printf("OTHER_SPEED_CONFIGURATION"); + break; + case UDESC_INTERFACE_POWER: + printf("INTERFACE_POWER"); + break; + case UDESC_OTG: + printf("OTG"); + break; + case UDESC_DEBUG: + printf("DEBUG"); + break; + case UDESC_IFACE_ASSOC: + printf("INTERFACE_ASSOCIATION"); + break; + case UDESC_BOS: + printf("BOS"); + break; + case UDESC_DEVICE_CAPABILITY: + printf("DEVICE_CAPABILITY"); + break; + case UDESC_CS_DEVICE: + printf("CS_DEVICE"); + break; + case UDESC_CS_CONFIG: + printf("CS_CONFIGURATION"); + break; + case UDESC_CS_STRING: + printf("CS_STRING"); + break; + case UDESC_CS_INTERFACE: + printf("CS_INTERFACE"); + break; + case UDESC_CS_ENDPOINT: + printf("CS_ENDPOINT"); + break; + case UDESC_HUB: + printf("HUB"); + break; + case UDESC_SS_HUB: + printf("SS_HUB"); + break; + case UDESC_ENDPOINT_SS_COMP: + printf("SS_COMPANION"); + break; + default: + printf("?"); + } + + printf(" index=0x%02x", value & 0xff); +} + +void +usbpcap_print_request_type(uByte request_type) +{ + printf(" bmRequestType="); + + switch (request_type) { + case UT_READ_DEVICE: + printf("UT_READ_DEVICE"); + break; + case UT_READ_INTERFACE: + printf("UT_READ_INTERFACE"); + break; + case UT_READ_ENDPOINT: + printf("UT_READ_ENDPOINT"); + break; + case UT_WRITE_DEVICE: + printf("UT_WRITE_DEVICE"); + break; + case UT_WRITE_INTERFACE: + printf("UT_WRITE_INTERFACE"); + break; + case UT_WRITE_ENDPOINT: + printf("UT_WRITE_ENDPOINT"); + break; + case UT_READ_CLASS_DEVICE: + printf("UT_READ_CLASS_DEVICE"); + break; + case UT_READ_CLASS_INTERFACE: + printf("UT_READ_CLASS_INTERFACE"); + break; + case UT_READ_CLASS_OTHER: + printf("UT_READ_CLASS_OTHER"); + break; + case UT_READ_CLASS_ENDPOINT: + printf("UT_READ_CLASS_ENDPOINT"); + break; + case UT_WRITE_CLASS_DEVICE: + printf("UT_WRITE_CLASS_DEVICE"); + break; + case UT_WRITE_CLASS_INTERFACE: + printf("UT_WRITE_CLASS_INTERFACE"); + break; + case UT_WRITE_CLASS_OTHER: + printf("UT_WRITE_CLASS_OTHER"); + break; + case UT_WRITE_CLASS_ENDPOINT: + printf("UT_WRITE_CLASS_ENDPOINT"); + break; + case UT_READ_VENDOR_DEVICE: + printf("UT_READ_VENDOR_DEVICE"); + break; + case UT_READ_VENDOR_INTERFACE: + printf("UT_READ_VENDOR_INTERFACE"); + break; + case UT_READ_VENDOR_OTHER: + printf("UT_READ_VENDOR_OTHER"); + break; + case UT_READ_VENDOR_ENDPOINT: + printf("UT_READ_VENDOR_ENDPOINT"); + break; + case UT_WRITE_VENDOR_DEVICE: + printf("UT_WRITE_VENDOR_DEVICE"); + break; + case UT_WRITE_VENDOR_INTERFACE: + printf("UT_WRITE_VENDOR_INTERFACE"); + break; + case UT_WRITE_VENDOR_OTHER: + printf("UT_WRITE_VENDOR_OTHER"); + break; + case UT_WRITE_VENDOR_ENDPOINT: + printf("UT_WRITE_VENDOR_ENDPOINT"); + break; + default: + printf("?"); + } +} |