1 /* $OpenBSD: print-usbpcap.c,v 1.5 2020/03/23 09:38:26 patrick Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Martin Pieuchot <mpi@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <dev/usb/usb.h> 20 #include <dev/usb/usbpcap.h> 21 22 #include <pcap.h> 23 24 #include "interface.h" 25 26 #ifndef nitems 27 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 28 #endif 29 30 const char *usbpcap_xfer_type[] = {"isoc", "intr", "ctrl", "bulk"}; 31 const char *usbpcap_control_stages[] = {"setup", "data", "status"}; 32 const char *usbpcap_request_codes[] = { 33 "GET_STATUS", "CLEAR_FEATURE", "?", "SET_FEATURE", "?", "SET_ADDRESS", 34 "GET_DESCRIPTOR", "SET_DESCRIPTOR", "GET_CONFIG", "SET_CONFIG", 35 "GET_INTERFACE", "SET_INTERFACE", "SYNCH_FRAME", 36 }; 37 38 void usbpcap_print_descriptor(int); 39 void usbpcap_print_request_type(uByte); 40 41 void 42 usbpcap_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 43 { 44 u_int length = h->len; 45 u_int caplen = h->caplen; 46 const struct usbpcap_pkt_hdr *uph; 47 u_int16_t hdrlen; 48 49 ts_print(&h->ts); 50 51 /* check length */ 52 if (caplen < sizeof(uint16_t) || length < sizeof(*uph)) 53 goto trunc; 54 55 uph = (struct usbpcap_pkt_hdr *)p; 56 hdrlen = letoh16(uph->uph_hlen); 57 if (hdrlen < sizeof(*uph)) { 58 printf("[usb: invalid header length %u!]", hdrlen); 59 goto out; 60 } 61 62 if (caplen < hdrlen) 63 goto trunc; 64 65 printf("bus %u %c addr %u: ep%u", 66 letoh16(uph->uph_bus), 67 ((uph->uph_info & USBPCAP_INFO_DIRECTION_IN) ? '<' : '>'), 68 letoh16(uph->uph_devaddr), UE_GET_ADDR(uph->uph_epaddr)); 69 70 if (uph->uph_xfertype < nitems(usbpcap_xfer_type)) 71 printf(" %s", usbpcap_xfer_type[uph->uph_xfertype]); 72 else 73 printf(" ??"); 74 75 printf(" dlen=%u", letoh32(uph->uph_dlen)); 76 77 if (uph->uph_xfertype == USBPCAP_TRANSFER_CONTROL) { 78 struct usbpcap_ctl_hdr *ctl_hdr = (struct usbpcap_ctl_hdr *)p; 79 80 if (ctl_hdr->uch_stage < nitems(usbpcap_control_stages)) 81 printf(" stage=%s", 82 usbpcap_control_stages[ctl_hdr->uch_stage]); 83 else 84 printf(" stage=?"); 85 86 if (ctl_hdr->uch_stage == USBPCAP_CONTROL_STAGE_SETUP) { 87 /* Setup packets must be 8 bytes in size as per 88 * 9.3 USB Device Requests. */ 89 if (letoh32(uph->uph_dlen != 8)) 90 goto trunc; 91 92 usb_device_request_t *req = (usb_device_request_t *) 93 (p + sizeof(struct usbpcap_ctl_hdr)); 94 95 usbpcap_print_request_type(req->bmRequestType); 96 97 if (req->bRequest < nitems(usbpcap_request_codes)) 98 printf(" bRequest=%s", 99 usbpcap_request_codes[req->bRequest]); 100 else 101 printf(" bRequest=?"); 102 103 if (req->bRequest == UR_GET_DESCRIPTOR) 104 usbpcap_print_descriptor(UGETW(req->wValue)); 105 else 106 printf(" wValue=0x%04x", UGETW(req->wValue)); 107 108 printf(" wIndex=%04x", UGETW(req->wIndex)); 109 printf(" wLength=%u", UGETW(req->wLength)); 110 } 111 } 112 113 if (xflag) 114 default_print(p + sizeof(*uph), length - sizeof(*uph)); 115 out: 116 putchar('\n'); 117 return; 118 trunc: 119 printf("[|usb]"); 120 } 121 122 void 123 usbpcap_print_descriptor(int value) 124 { 125 printf(" type="); 126 switch (value >> 8) { 127 case UDESC_DEVICE: 128 printf("DEVICE"); 129 break; 130 case UDESC_CONFIG: 131 printf("CONFIGURATION"); 132 break; 133 case UDESC_STRING: 134 printf("STRING"); 135 break; 136 case UDESC_INTERFACE: 137 printf("INTERFACE"); 138 break; 139 case UDESC_ENDPOINT: 140 printf("ENDPOINT"); 141 break; 142 case UDESC_DEVICE_QUALIFIER: 143 printf("DEVICE_QUALIFIER"); 144 break; 145 case UDESC_OTHER_SPEED_CONFIGURATION: 146 printf("OTHER_SPEED_CONFIGURATION"); 147 break; 148 case UDESC_INTERFACE_POWER: 149 printf("INTERFACE_POWER"); 150 break; 151 case UDESC_OTG: 152 printf("OTG"); 153 break; 154 case UDESC_DEBUG: 155 printf("DEBUG"); 156 break; 157 case UDESC_IFACE_ASSOC: 158 printf("INTERFACE_ASSOCIATION"); 159 break; 160 case UDESC_BOS: 161 printf("BOS"); 162 break; 163 case UDESC_DEVICE_CAPABILITY: 164 printf("DEVICE_CAPABILITY"); 165 break; 166 case UDESC_CS_DEVICE: 167 printf("CS_DEVICE"); 168 break; 169 case UDESC_CS_CONFIG: 170 printf("CS_CONFIGURATION"); 171 break; 172 case UDESC_CS_STRING: 173 printf("CS_STRING"); 174 break; 175 case UDESC_CS_INTERFACE: 176 printf("CS_INTERFACE"); 177 break; 178 case UDESC_CS_ENDPOINT: 179 printf("CS_ENDPOINT"); 180 break; 181 case UDESC_HUB: 182 printf("HUB"); 183 break; 184 case UDESC_SS_HUB: 185 printf("SS_HUB"); 186 break; 187 case UDESC_ENDPOINT_SS_COMP: 188 printf("SS_COMPANION"); 189 break; 190 default: 191 printf("?"); 192 } 193 194 printf(" index=0x%02x", value & 0xff); 195 } 196 197 void 198 usbpcap_print_request_type(uByte request_type) 199 { 200 printf(" bmRequestType="); 201 202 switch (request_type) { 203 case UT_READ_DEVICE: 204 printf("UT_READ_DEVICE"); 205 break; 206 case UT_READ_INTERFACE: 207 printf("UT_READ_INTERFACE"); 208 break; 209 case UT_READ_ENDPOINT: 210 printf("UT_READ_ENDPOINT"); 211 break; 212 case UT_WRITE_DEVICE: 213 printf("UT_WRITE_DEVICE"); 214 break; 215 case UT_WRITE_INTERFACE: 216 printf("UT_WRITE_INTERFACE"); 217 break; 218 case UT_WRITE_ENDPOINT: 219 printf("UT_WRITE_ENDPOINT"); 220 break; 221 case UT_READ_CLASS_DEVICE: 222 printf("UT_READ_CLASS_DEVICE"); 223 break; 224 case UT_READ_CLASS_INTERFACE: 225 printf("UT_READ_CLASS_INTERFACE"); 226 break; 227 case UT_READ_CLASS_OTHER: 228 printf("UT_READ_CLASS_OTHER"); 229 break; 230 case UT_READ_CLASS_ENDPOINT: 231 printf("UT_READ_CLASS_ENDPOINT"); 232 break; 233 case UT_WRITE_CLASS_DEVICE: 234 printf("UT_WRITE_CLASS_DEVICE"); 235 break; 236 case UT_WRITE_CLASS_INTERFACE: 237 printf("UT_WRITE_CLASS_INTERFACE"); 238 break; 239 case UT_WRITE_CLASS_OTHER: 240 printf("UT_WRITE_CLASS_OTHER"); 241 break; 242 case UT_WRITE_CLASS_ENDPOINT: 243 printf("UT_WRITE_CLASS_ENDPOINT"); 244 break; 245 case UT_READ_VENDOR_DEVICE: 246 printf("UT_READ_VENDOR_DEVICE"); 247 break; 248 case UT_READ_VENDOR_INTERFACE: 249 printf("UT_READ_VENDOR_INTERFACE"); 250 break; 251 case UT_READ_VENDOR_OTHER: 252 printf("UT_READ_VENDOR_OTHER"); 253 break; 254 case UT_READ_VENDOR_ENDPOINT: 255 printf("UT_READ_VENDOR_ENDPOINT"); 256 break; 257 case UT_WRITE_VENDOR_DEVICE: 258 printf("UT_WRITE_VENDOR_DEVICE"); 259 break; 260 case UT_WRITE_VENDOR_INTERFACE: 261 printf("UT_WRITE_VENDOR_INTERFACE"); 262 break; 263 case UT_WRITE_VENDOR_OTHER: 264 printf("UT_WRITE_VENDOR_OTHER"); 265 break; 266 case UT_WRITE_VENDOR_ENDPOINT: 267 printf("UT_WRITE_VENDOR_ENDPOINT"); 268 break; 269 default: 270 printf("?"); 271 } 272 } 273