1 /* $OpenBSD: print-usbpcap.c,v 1.6 2023/03/13 13:36:56 claudio 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 caplen = h->caplen; 45 const struct usbpcap_pkt_hdr *uph; 46 u_int16_t hdrlen; 47 48 ts_print(&h->ts); 49 50 /* set required globals */ 51 snapend = p + caplen; 52 53 /* check length */ 54 uph = (struct usbpcap_pkt_hdr *)p; 55 TCHECK(uph->uph_hlen); 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 TCHECK(uph[0]); 63 64 printf("bus %u %c addr %u: ep%u", 65 letoh16(uph->uph_bus), 66 ((uph->uph_info & USBPCAP_INFO_DIRECTION_IN) ? '<' : '>'), 67 letoh16(uph->uph_devaddr), UE_GET_ADDR(uph->uph_epaddr)); 68 69 if (uph->uph_xfertype < nitems(usbpcap_xfer_type)) 70 printf(" %s", usbpcap_xfer_type[uph->uph_xfertype]); 71 else 72 printf(" ??"); 73 74 printf(" dlen=%u", letoh32(uph->uph_dlen)); 75 76 TCHECK2(uph[0], hdrlen); 77 78 if (uph->uph_xfertype == USBPCAP_TRANSFER_CONTROL) { 79 struct usbpcap_ctl_hdr *ctl_hdr = (struct usbpcap_ctl_hdr *)p; 80 81 TCHECK(ctl_hdr->uch_stage); 82 if (ctl_hdr->uch_stage < nitems(usbpcap_control_stages)) 83 printf(" stage=%s", 84 usbpcap_control_stages[ctl_hdr->uch_stage]); 85 else 86 printf(" stage=?"); 87 88 if (ctl_hdr->uch_stage == USBPCAP_CONTROL_STAGE_SETUP) { 89 usb_device_request_t *req; 90 91 req = (usb_device_request_t *) 92 (p + sizeof(struct usbpcap_ctl_hdr)); 93 94 /* Setup packets must be 8 bytes in size as per 95 * 9.3 USB Device Requests. */ 96 if (letoh32(uph->uph_dlen != 8)) { 97 printf("[usb: invalid data length %u!]", 98 letoh32(uph->uph_dlen)); 99 goto out; 100 } 101 TCHECK(req[0]); 102 103 usbpcap_print_request_type(req->bmRequestType); 104 105 if (req->bRequest < nitems(usbpcap_request_codes)) 106 printf(" bRequest=%s", 107 usbpcap_request_codes[req->bRequest]); 108 else 109 printf(" bRequest=?"); 110 111 if (req->bRequest == UR_GET_DESCRIPTOR) 112 usbpcap_print_descriptor(UGETW(req->wValue)); 113 else 114 printf(" wValue=0x%04x", UGETW(req->wValue)); 115 116 printf(" wIndex=%04x", UGETW(req->wIndex)); 117 printf(" wLength=%u", UGETW(req->wLength)); 118 } 119 } 120 121 if (xflag) { 122 if (eflag) 123 default_print(p, caplen); 124 else 125 default_print(p + hdrlen, caplen - hdrlen); 126 } 127 out: 128 putchar('\n'); 129 return; 130 trunc: 131 printf("[|usb]\n"); 132 } 133 134 void 135 usbpcap_print_descriptor(int value) 136 { 137 printf(" type="); 138 switch (value >> 8) { 139 case UDESC_DEVICE: 140 printf("DEVICE"); 141 break; 142 case UDESC_CONFIG: 143 printf("CONFIGURATION"); 144 break; 145 case UDESC_STRING: 146 printf("STRING"); 147 break; 148 case UDESC_INTERFACE: 149 printf("INTERFACE"); 150 break; 151 case UDESC_ENDPOINT: 152 printf("ENDPOINT"); 153 break; 154 case UDESC_DEVICE_QUALIFIER: 155 printf("DEVICE_QUALIFIER"); 156 break; 157 case UDESC_OTHER_SPEED_CONFIGURATION: 158 printf("OTHER_SPEED_CONFIGURATION"); 159 break; 160 case UDESC_INTERFACE_POWER: 161 printf("INTERFACE_POWER"); 162 break; 163 case UDESC_OTG: 164 printf("OTG"); 165 break; 166 case UDESC_DEBUG: 167 printf("DEBUG"); 168 break; 169 case UDESC_IFACE_ASSOC: 170 printf("INTERFACE_ASSOCIATION"); 171 break; 172 case UDESC_BOS: 173 printf("BOS"); 174 break; 175 case UDESC_DEVICE_CAPABILITY: 176 printf("DEVICE_CAPABILITY"); 177 break; 178 case UDESC_CS_DEVICE: 179 printf("CS_DEVICE"); 180 break; 181 case UDESC_CS_CONFIG: 182 printf("CS_CONFIGURATION"); 183 break; 184 case UDESC_CS_STRING: 185 printf("CS_STRING"); 186 break; 187 case UDESC_CS_INTERFACE: 188 printf("CS_INTERFACE"); 189 break; 190 case UDESC_CS_ENDPOINT: 191 printf("CS_ENDPOINT"); 192 break; 193 case UDESC_HUB: 194 printf("HUB"); 195 break; 196 case UDESC_SS_HUB: 197 printf("SS_HUB"); 198 break; 199 case UDESC_ENDPOINT_SS_COMP: 200 printf("SS_COMPANION"); 201 break; 202 default: 203 printf("?"); 204 } 205 206 printf(" index=0x%02x", value & 0xff); 207 } 208 209 void 210 usbpcap_print_request_type(uByte request_type) 211 { 212 printf(" bmRequestType="); 213 214 switch (request_type) { 215 case UT_READ_DEVICE: 216 printf("UT_READ_DEVICE"); 217 break; 218 case UT_READ_INTERFACE: 219 printf("UT_READ_INTERFACE"); 220 break; 221 case UT_READ_ENDPOINT: 222 printf("UT_READ_ENDPOINT"); 223 break; 224 case UT_WRITE_DEVICE: 225 printf("UT_WRITE_DEVICE"); 226 break; 227 case UT_WRITE_INTERFACE: 228 printf("UT_WRITE_INTERFACE"); 229 break; 230 case UT_WRITE_ENDPOINT: 231 printf("UT_WRITE_ENDPOINT"); 232 break; 233 case UT_READ_CLASS_DEVICE: 234 printf("UT_READ_CLASS_DEVICE"); 235 break; 236 case UT_READ_CLASS_INTERFACE: 237 printf("UT_READ_CLASS_INTERFACE"); 238 break; 239 case UT_READ_CLASS_OTHER: 240 printf("UT_READ_CLASS_OTHER"); 241 break; 242 case UT_READ_CLASS_ENDPOINT: 243 printf("UT_READ_CLASS_ENDPOINT"); 244 break; 245 case UT_WRITE_CLASS_DEVICE: 246 printf("UT_WRITE_CLASS_DEVICE"); 247 break; 248 case UT_WRITE_CLASS_INTERFACE: 249 printf("UT_WRITE_CLASS_INTERFACE"); 250 break; 251 case UT_WRITE_CLASS_OTHER: 252 printf("UT_WRITE_CLASS_OTHER"); 253 break; 254 case UT_WRITE_CLASS_ENDPOINT: 255 printf("UT_WRITE_CLASS_ENDPOINT"); 256 break; 257 case UT_READ_VENDOR_DEVICE: 258 printf("UT_READ_VENDOR_DEVICE"); 259 break; 260 case UT_READ_VENDOR_INTERFACE: 261 printf("UT_READ_VENDOR_INTERFACE"); 262 break; 263 case UT_READ_VENDOR_OTHER: 264 printf("UT_READ_VENDOR_OTHER"); 265 break; 266 case UT_READ_VENDOR_ENDPOINT: 267 printf("UT_READ_VENDOR_ENDPOINT"); 268 break; 269 case UT_WRITE_VENDOR_DEVICE: 270 printf("UT_WRITE_VENDOR_DEVICE"); 271 break; 272 case UT_WRITE_VENDOR_INTERFACE: 273 printf("UT_WRITE_VENDOR_INTERFACE"); 274 break; 275 case UT_WRITE_VENDOR_OTHER: 276 printf("UT_WRITE_VENDOR_OTHER"); 277 break; 278 case UT_WRITE_VENDOR_ENDPOINT: 279 printf("UT_WRITE_VENDOR_ENDPOINT"); 280 break; 281 default: 282 printf("?"); 283 } 284 } 285