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
usbpcap_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)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
usbpcap_print_descriptor(int value)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
usbpcap_print_request_type(uByte request_type)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