1 /*- 2 * Copyright (c) 2010 Weongyo Jeong <weongyo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/endian.h> 34 #include <sys/ioctl.h> 35 #include <sys/socket.h> 36 #include <sys/stat.h> 37 #include <sys/sysctl.h> 38 #include <sys/utsname.h> 39 #include <sys/queue.h> 40 #include <net/if.h> 41 #include <net/bpf.h> 42 #include <dev/usb/usb.h> 43 #include <dev/usb/usb_pf.h> 44 #include <dev/usb/usbdi.h> 45 #include <errno.h> 46 #include <fcntl.h> 47 #include <limits.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <stdint.h> 51 #include <string.h> 52 #include <time.h> 53 #include <unistd.h> 54 #include <sysexits.h> 55 #include <err.h> 56 57 #define BPF_STORE_JUMP(x,_c,_k,_jt,_jf) do { \ 58 (x).code = (_c); \ 59 (x).k = (_k); \ 60 (x).jt = (_jt); \ 61 (x).jf = (_jf); \ 62 } while (0) 63 64 #define BPF_STORE_STMT(x,_c,_k) do { \ 65 (x).code = (_c); \ 66 (x).k = (_k); \ 67 (x).jt = 0; \ 68 (x).jf = 0; \ 69 } while (0) 70 71 struct usb_filt { 72 STAILQ_ENTRY(usb_filt) entry; 73 int unit; 74 int endpoint; 75 }; 76 77 struct usbcap { 78 int fd; /* fd for /dev/usbpf */ 79 uint32_t bufsize; 80 uint8_t *buffer; 81 82 /* for -w option */ 83 int wfd; 84 /* for -r option */ 85 int rfd; 86 /* for -b option */ 87 int bfd; 88 }; 89 90 struct usbcap_filehdr { 91 uint32_t magic; 92 #define USBCAP_FILEHDR_MAGIC 0x9a90000e 93 uint8_t major; 94 uint8_t minor; 95 uint8_t reserved[26]; 96 } __packed; 97 98 struct header_32 { 99 /* capture timestamp */ 100 uint32_t ts_sec; 101 uint32_t ts_usec; 102 /* data length and alignment information */ 103 uint32_t caplen; 104 uint32_t datalen; 105 uint8_t hdrlen; 106 uint8_t align; 107 } __packed; 108 109 static int doexit = 0; 110 static int pkt_captured = 0; 111 static int verbose = 0; 112 static int uf_minor; 113 static const char *i_arg = "usbus0"; 114 static const char *r_arg = NULL; 115 static const char *w_arg = NULL; 116 static const char *b_arg = NULL; 117 static struct usbcap uc; 118 static const char *errstr_table[USB_ERR_MAX] = { 119 [USB_ERR_NORMAL_COMPLETION] = "0", 120 [USB_ERR_PENDING_REQUESTS] = "PENDING_REQUESTS", 121 [USB_ERR_NOT_STARTED] = "NOT_STARTED", 122 [USB_ERR_INVAL] = "INVAL", 123 [USB_ERR_NOMEM] = "NOMEM", 124 [USB_ERR_CANCELLED] = "CANCELLED", 125 [USB_ERR_BAD_ADDRESS] = "BAD_ADDRESS", 126 [USB_ERR_BAD_BUFSIZE] = "BAD_BUFSIZE", 127 [USB_ERR_BAD_FLAG] = "BAD_FLAG", 128 [USB_ERR_NO_CALLBACK] = "NO_CALLBACK", 129 [USB_ERR_IN_USE] = "IN_USE", 130 [USB_ERR_NO_ADDR] = "NO_ADDR", 131 [USB_ERR_NO_PIPE] = "NO_PIPE", 132 [USB_ERR_ZERO_NFRAMES] = "ZERO_NFRAMES", 133 [USB_ERR_ZERO_MAXP] = "ZERO_MAXP", 134 [USB_ERR_SET_ADDR_FAILED] = "SET_ADDR_FAILED", 135 [USB_ERR_NO_POWER] = "NO_POWER", 136 [USB_ERR_TOO_DEEP] = "TOO_DEEP", 137 [USB_ERR_IOERROR] = "IOERROR", 138 [USB_ERR_NOT_CONFIGURED] = "NOT_CONFIGURED", 139 [USB_ERR_TIMEOUT] = "TIMEOUT", 140 [USB_ERR_SHORT_XFER] = "SHORT_XFER", 141 [USB_ERR_STALLED] = "STALLED", 142 [USB_ERR_INTERRUPTED] = "INTERRUPTED", 143 [USB_ERR_DMA_LOAD_FAILED] = "DMA_LOAD_FAILED", 144 [USB_ERR_BAD_CONTEXT] = "BAD_CONTEXT", 145 [USB_ERR_NO_ROOT_HUB] = "NO_ROOT_HUB", 146 [USB_ERR_NO_INTR_THREAD] = "NO_INTR_THREAD", 147 [USB_ERR_NOT_LOCKED] = "NOT_LOCKED", 148 }; 149 150 static const char *xfertype_table[4] = { 151 [UE_CONTROL] = "CTRL", 152 [UE_ISOCHRONOUS] = "ISOC", 153 [UE_BULK] = "BULK", 154 [UE_INTERRUPT] = "INTR" 155 }; 156 157 static const char *speed_table[USB_SPEED_MAX] = { 158 [USB_SPEED_FULL] = "FULL", 159 [USB_SPEED_HIGH] = "HIGH", 160 [USB_SPEED_LOW] = "LOW", 161 [USB_SPEED_VARIABLE] = "VARI", 162 [USB_SPEED_SUPER] = "SUPER", 163 }; 164 165 static STAILQ_HEAD(,usb_filt) usb_filt_head = 166 STAILQ_HEAD_INITIALIZER(usb_filt_head); 167 168 static void 169 add_filter(int usb_filt_unit, int usb_filt_ep) 170 { 171 struct usb_filt *puf; 172 173 puf = malloc(sizeof(struct usb_filt)); 174 if (puf == NULL) 175 errx(EX_SOFTWARE, "Out of memory."); 176 177 puf->unit = usb_filt_unit; 178 puf->endpoint = usb_filt_ep; 179 180 STAILQ_INSERT_TAIL(&usb_filt_head, puf, entry); 181 } 182 183 static void 184 make_filter(struct bpf_program *pprog, int snapshot) 185 { 186 struct usb_filt *puf; 187 struct bpf_insn *dynamic_insn; 188 int len; 189 190 len = 0; 191 192 STAILQ_FOREACH(puf, &usb_filt_head, entry) 193 len++; 194 195 dynamic_insn = malloc(((len * 5) + 1) * sizeof(struct bpf_insn)); 196 197 if (dynamic_insn == NULL) 198 errx(EX_SOFTWARE, "Out of memory."); 199 200 len++; 201 202 if (len == 1) { 203 /* accept all packets */ 204 205 BPF_STORE_STMT(dynamic_insn[0], BPF_RET | BPF_K, snapshot); 206 207 goto done; 208 } 209 210 len = 0; 211 212 STAILQ_FOREACH(puf, &usb_filt_head, entry) { 213 const int addr_off = (uintptr_t)&((struct usbpf_pkthdr *)0)->up_address; 214 const int addr_ep = (uintptr_t)&((struct usbpf_pkthdr *)0)->up_endpoint; 215 216 if (puf->unit != -1) { 217 if (puf->endpoint != -1) { 218 BPF_STORE_STMT(dynamic_insn[len], 219 BPF_LD | BPF_B | BPF_ABS, addr_off); 220 len++; 221 BPF_STORE_JUMP(dynamic_insn[len], 222 BPF_JMP | BPF_JEQ | BPF_K, (uint8_t)puf->unit, 0, 3); 223 len++; 224 BPF_STORE_STMT(dynamic_insn[len], 225 BPF_LD | BPF_W | BPF_ABS, addr_ep); 226 len++; 227 BPF_STORE_JUMP(dynamic_insn[len], 228 BPF_JMP | BPF_JEQ | BPF_K, htobe32(puf->endpoint), 0, 1); 229 len++; 230 } else { 231 BPF_STORE_STMT(dynamic_insn[len], 232 BPF_LD | BPF_B | BPF_ABS, addr_off); 233 len++; 234 BPF_STORE_JUMP(dynamic_insn[len], 235 BPF_JMP | BPF_JEQ | BPF_K, (uint8_t)puf->unit, 0, 1); 236 len++; 237 } 238 } else { 239 if (puf->endpoint != -1) { 240 BPF_STORE_STMT(dynamic_insn[len], 241 BPF_LD | BPF_W | BPF_ABS, addr_ep); 242 len++; 243 BPF_STORE_JUMP(dynamic_insn[len], 244 BPF_JMP | BPF_JEQ | BPF_K, htobe32(puf->endpoint), 0, 1); 245 len++; 246 } 247 } 248 BPF_STORE_STMT(dynamic_insn[len], 249 BPF_RET | BPF_K, snapshot); 250 len++; 251 } 252 253 BPF_STORE_STMT(dynamic_insn[len], BPF_RET | BPF_K, 0); 254 len++; 255 256 done: 257 pprog->bf_len = len; 258 pprog->bf_insns = dynamic_insn; 259 } 260 261 static int 262 match_filter(int unit, int endpoint) 263 { 264 struct usb_filt *puf; 265 266 if (STAILQ_FIRST(&usb_filt_head) == NULL) 267 return (1); 268 269 STAILQ_FOREACH(puf, &usb_filt_head, entry) { 270 if ((puf->unit == -1 || puf->unit == unit) && 271 (puf->endpoint == -1 || puf->endpoint == endpoint)) 272 return (1); 273 } 274 return (0); 275 } 276 277 static void 278 free_filter(struct bpf_program *pprog) 279 { 280 struct usb_filt *puf; 281 282 while ((puf = STAILQ_FIRST(&usb_filt_head)) != NULL) { 283 STAILQ_REMOVE_HEAD(&usb_filt_head, entry); 284 free(puf); 285 } 286 free(pprog->bf_insns); 287 } 288 289 static void 290 handle_sigint(int sig) 291 { 292 293 (void)sig; 294 doexit = 1; 295 } 296 297 #define FLAGS(x, name) \ 298 (((x) & USBPF_FLAG_##name) ? #name "|" : "") 299 300 #define STATUS(x, name) \ 301 (((x) & USBPF_STATUS_##name) ? #name "|" : "") 302 303 static const char * 304 usb_errstr(uint32_t error) 305 { 306 if (error >= USB_ERR_MAX || errstr_table[error] == NULL) 307 return ("UNKNOWN"); 308 else 309 return (errstr_table[error]); 310 } 311 312 static const char * 313 usb_speedstr(uint8_t speed) 314 { 315 if (speed >= USB_SPEED_MAX || speed_table[speed] == NULL) 316 return ("UNKNOWN"); 317 else 318 return (speed_table[speed]); 319 } 320 321 static void 322 print_flags(uint32_t flags) 323 { 324 printf(" flags %#x <%s%s%s%s%s%s%s%s%s0>\n", 325 flags, 326 FLAGS(flags, FORCE_SHORT_XFER), 327 FLAGS(flags, SHORT_XFER_OK), 328 FLAGS(flags, SHORT_FRAMES_OK), 329 FLAGS(flags, PIPE_BOF), 330 FLAGS(flags, PROXY_BUFFER), 331 FLAGS(flags, EXT_BUFFER), 332 FLAGS(flags, MANUAL_STATUS), 333 FLAGS(flags, NO_PIPE_OK), 334 FLAGS(flags, STALL_PIPE)); 335 } 336 337 static void 338 print_status(uint32_t status) 339 { 340 printf(" status %#x <%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s0>\n", 341 status, 342 STATUS(status, OPEN), 343 STATUS(status, TRANSFERRING), 344 STATUS(status, DID_DMA_DELAY), 345 STATUS(status, DID_CLOSE), 346 STATUS(status, DRAINING), 347 STATUS(status, STARTED), 348 STATUS(status, BW_RECLAIMED), 349 STATUS(status, CONTROL_XFR), 350 STATUS(status, CONTROL_HDR), 351 STATUS(status, CONTROL_ACT), 352 STATUS(status, CONTROL_STALL), 353 STATUS(status, SHORT_FRAMES_OK), 354 STATUS(status, SHORT_XFER_OK), 355 STATUS(status, BDMA_ENABLE), 356 STATUS(status, BDMA_NO_POST_SYNC), 357 STATUS(status, BDMA_SETUP), 358 STATUS(status, ISOCHRONOUS_XFR), 359 STATUS(status, CURR_DMA_SET), 360 STATUS(status, CAN_CANCEL_IMMED), 361 STATUS(status, DOING_CALLBACK)); 362 } 363 364 /* 365 * Dump a byte into hex format. 366 */ 367 static void 368 hexbyte(char *buf, uint8_t temp) 369 { 370 uint8_t lo; 371 uint8_t hi; 372 373 lo = temp & 0xF; 374 hi = temp >> 4; 375 376 if (hi < 10) 377 buf[0] = '0' + hi; 378 else 379 buf[0] = 'A' + hi - 10; 380 381 if (lo < 10) 382 buf[1] = '0' + lo; 383 else 384 buf[1] = 'A' + lo - 10; 385 } 386 387 /* 388 * Display a region in traditional hexdump format. 389 */ 390 static void 391 hexdump(const uint8_t *region, uint32_t len) 392 { 393 const uint8_t *line; 394 char linebuf[128]; 395 int i; 396 int x; 397 int c; 398 399 for (line = region; line < (region + len); line += 16) { 400 401 i = 0; 402 403 linebuf[i] = ' '; 404 hexbyte(linebuf + i + 1, ((line - region) >> 8) & 0xFF); 405 hexbyte(linebuf + i + 3, (line - region) & 0xFF); 406 linebuf[i + 5] = ' '; 407 linebuf[i + 6] = ' '; 408 i += 7; 409 410 for (x = 0; x < 16; x++) { 411 if ((line + x) < (region + len)) { 412 hexbyte(linebuf + i, 413 *(const u_int8_t *)(line + x)); 414 } else { 415 linebuf[i] = '-'; 416 linebuf[i + 1] = '-'; 417 } 418 linebuf[i + 2] = ' '; 419 if (x == 7) { 420 linebuf[i + 3] = ' '; 421 i += 4; 422 } else { 423 i += 3; 424 } 425 } 426 linebuf[i] = ' '; 427 linebuf[i + 1] = '|'; 428 i += 2; 429 for (x = 0; x < 16; x++) { 430 if ((line + x) < (region + len)) { 431 c = *(const u_int8_t *)(line + x); 432 /* !isprint(c) */ 433 if ((c < ' ') || (c > '~')) 434 c = '.'; 435 linebuf[i] = c; 436 } else { 437 linebuf[i] = ' '; 438 } 439 i++; 440 } 441 linebuf[i] = '|'; 442 linebuf[i + 1] = 0; 443 i += 2; 444 puts(linebuf); 445 } 446 } 447 448 static void 449 print_apacket(const struct header_32 *hdr, const uint8_t *ptr, int ptr_len) 450 { 451 struct tm *tm; 452 struct usbpf_pkthdr up_temp; 453 struct usbpf_pkthdr *up; 454 struct timeval tv; 455 size_t len; 456 uint32_t x; 457 char buf[64]; 458 459 ptr += USBPF_HDR_LEN; 460 ptr_len -= USBPF_HDR_LEN; 461 if (ptr_len < 0) 462 return; 463 464 /* make sure we don't change the source buffer */ 465 memcpy(&up_temp, ptr - USBPF_HDR_LEN, sizeof(up_temp)); 466 up = &up_temp; 467 468 /* 469 * A packet from the kernel is based on little endian byte 470 * order. 471 */ 472 up->up_totlen = le32toh(up->up_totlen); 473 up->up_busunit = le32toh(up->up_busunit); 474 up->up_flags = le32toh(up->up_flags); 475 up->up_status = le32toh(up->up_status); 476 up->up_error = le32toh(up->up_error); 477 up->up_interval = le32toh(up->up_interval); 478 up->up_frames = le32toh(up->up_frames); 479 up->up_packet_size = le32toh(up->up_packet_size); 480 up->up_packet_count = le32toh(up->up_packet_count); 481 up->up_endpoint = le32toh(up->up_endpoint); 482 483 if (!match_filter(up->up_address, up->up_endpoint)) 484 return; 485 486 tv.tv_sec = hdr->ts_sec; 487 tv.tv_usec = hdr->ts_usec; 488 tm = localtime(&tv.tv_sec); 489 490 len = strftime(buf, sizeof(buf), "%H:%M:%S", tm); 491 492 if (verbose >= 0) { 493 printf("%.*s.%06ld usbus%d.%d %s-%s-EP=%08x,SPD=%s,NFR=%d,SLEN=%d,IVAL=%d%s%s\n", 494 (int)len, buf, tv.tv_usec, 495 (int)up->up_busunit, (int)up->up_address, 496 (up->up_type == USBPF_XFERTAP_SUBMIT) ? "SUBM" : "DONE", 497 xfertype_table[up->up_xfertype], 498 (unsigned int)up->up_endpoint, 499 usb_speedstr(up->up_speed), 500 (int)up->up_frames, 501 (int)(up->up_totlen - USBPF_HDR_LEN - 502 (USBPF_FRAME_HDR_LEN * up->up_frames)), 503 (int)up->up_interval, 504 (up->up_type == USBPF_XFERTAP_DONE) ? ",ERR=" : "", 505 (up->up_type == USBPF_XFERTAP_DONE) ? 506 usb_errstr(up->up_error) : ""); 507 } 508 509 if (verbose >= 1 || b_arg != NULL) { 510 for (x = 0; x != up->up_frames; x++) { 511 const struct usbpf_framehdr *uf; 512 uint32_t framelen; 513 uint32_t flags; 514 515 uf = (const struct usbpf_framehdr *)ptr; 516 ptr += USBPF_FRAME_HDR_LEN; 517 ptr_len -= USBPF_FRAME_HDR_LEN; 518 if (ptr_len < 0) 519 return; 520 521 framelen = le32toh(uf->length); 522 flags = le32toh(uf->flags); 523 524 if (verbose >= 1) { 525 printf(" frame[%u] %s %d bytes\n", 526 (unsigned int)x, 527 (flags & USBPF_FRAMEFLAG_READ) ? "READ" : "WRITE", 528 (int)framelen); 529 } 530 531 if (flags & USBPF_FRAMEFLAG_DATA_FOLLOWS) { 532 533 int tot_frame_len; 534 535 tot_frame_len = USBPF_FRAME_ALIGN(framelen); 536 537 ptr_len -= tot_frame_len; 538 539 if (tot_frame_len < 0 || 540 (int)framelen < 0 || (int)ptr_len < 0) 541 break; 542 543 if (b_arg != NULL) { 544 struct usbcap *p = &uc; 545 int ret; 546 ret = write(p->bfd, ptr, framelen); 547 if (ret != (int)framelen) 548 err(EXIT_FAILURE, "Could not write binary data"); 549 } 550 if (verbose >= 1) 551 hexdump(ptr, framelen); 552 553 ptr += tot_frame_len; 554 } 555 } 556 } 557 if (verbose >= 2) 558 print_flags(up->up_flags); 559 if (verbose >= 3) 560 print_status(up->up_status); 561 } 562 563 static void 564 fix_packets(uint8_t *data, const int datalen) 565 { 566 struct header_32 temp; 567 uint8_t *ptr; 568 uint8_t *next; 569 uint32_t hdrlen; 570 uint32_t caplen; 571 572 for (ptr = data; ptr < (data + datalen); ptr = next) { 573 574 const struct bpf_hdr *hdr; 575 576 hdr = (const struct bpf_hdr *)ptr; 577 578 temp.ts_sec = htole32(hdr->bh_tstamp.tv_sec); 579 temp.ts_usec = htole32(hdr->bh_tstamp.tv_usec); 580 temp.caplen = htole32(hdr->bh_caplen); 581 temp.datalen = htole32(hdr->bh_datalen); 582 temp.hdrlen = hdr->bh_hdrlen; 583 temp.align = BPF_WORDALIGN(1); 584 585 hdrlen = hdr->bh_hdrlen; 586 caplen = hdr->bh_caplen; 587 588 if ((hdrlen >= sizeof(temp)) && (hdrlen <= 255) && 589 ((ptr + hdrlen) <= (data + datalen))) { 590 memcpy(ptr, &temp, sizeof(temp)); 591 memset(ptr + sizeof(temp), 0, hdrlen - sizeof(temp)); 592 } else { 593 err(EXIT_FAILURE, "Invalid header length %d", hdrlen); 594 } 595 596 next = ptr + BPF_WORDALIGN(hdrlen + caplen); 597 598 if (next <= ptr) 599 err(EXIT_FAILURE, "Invalid length"); 600 } 601 } 602 603 static void 604 print_packets(uint8_t *data, const int datalen) 605 { 606 struct header_32 temp; 607 uint8_t *ptr; 608 uint8_t *next; 609 610 for (ptr = data; ptr < (data + datalen); ptr = next) { 611 612 const struct header_32 *hdr32; 613 614 hdr32 = (const struct header_32 *)ptr; 615 616 temp.ts_sec = le32toh(hdr32->ts_sec); 617 temp.ts_usec = le32toh(hdr32->ts_usec); 618 temp.caplen = le32toh(hdr32->caplen); 619 temp.datalen = le32toh(hdr32->datalen); 620 temp.hdrlen = hdr32->hdrlen; 621 temp.align = hdr32->align; 622 623 next = ptr + roundup2(temp.hdrlen + temp.caplen, temp.align); 624 625 if (next <= ptr) 626 err(EXIT_FAILURE, "Invalid length"); 627 628 if (verbose >= 0 || r_arg != NULL || b_arg != NULL) { 629 print_apacket(&temp, ptr + 630 temp.hdrlen, temp.caplen); 631 } 632 pkt_captured++; 633 } 634 } 635 636 static void 637 write_packets(struct usbcap *p, const uint8_t *data, const int datalen) 638 { 639 int len = htole32(datalen); 640 int ret; 641 642 ret = write(p->wfd, &len, sizeof(int)); 643 if (ret != sizeof(int)) { 644 err(EXIT_FAILURE, "Could not write length " 645 "field of USB data payload"); 646 } 647 ret = write(p->wfd, data, datalen); 648 if (ret != datalen) { 649 err(EXIT_FAILURE, "Could not write " 650 "complete USB data payload"); 651 } 652 } 653 654 static void 655 read_file(struct usbcap *p) 656 { 657 int datalen; 658 int ret; 659 uint8_t *data; 660 661 while ((ret = read(p->rfd, &datalen, sizeof(int))) == sizeof(int)) { 662 datalen = le32toh(datalen); 663 data = malloc(datalen); 664 if (data == NULL) 665 errx(EX_SOFTWARE, "Out of memory."); 666 ret = read(p->rfd, data, datalen); 667 if (ret != datalen) { 668 err(EXIT_FAILURE, "Could not read complete " 669 "USB data payload"); 670 } 671 if (uf_minor == 2) 672 fix_packets(data, datalen); 673 674 print_packets(data, datalen); 675 free(data); 676 } 677 } 678 679 static void 680 do_loop(struct usbcap *p) 681 { 682 int cc; 683 684 while (doexit == 0) { 685 cc = read(p->fd, (uint8_t *)p->buffer, p->bufsize); 686 if (cc < 0) { 687 switch (errno) { 688 case EINTR: 689 break; 690 default: 691 fprintf(stderr, "read: %s\n", strerror(errno)); 692 return; 693 } 694 continue; 695 } 696 if (cc == 0) 697 continue; 698 699 fix_packets(p->buffer, cc); 700 701 if (w_arg != NULL) 702 write_packets(p, p->buffer, cc); 703 print_packets(p->buffer, cc); 704 } 705 } 706 707 static void 708 init_rfile(struct usbcap *p) 709 { 710 struct usbcap_filehdr uf; 711 int ret; 712 713 p->rfd = open(r_arg, O_RDONLY); 714 if (p->rfd < 0) { 715 err(EXIT_FAILURE, "Could not open " 716 "'%s' for read", r_arg); 717 } 718 ret = read(p->rfd, &uf, sizeof(uf)); 719 if (ret != sizeof(uf)) { 720 err(EXIT_FAILURE, "Could not read USB capture " 721 "file header"); 722 } 723 if (le32toh(uf.magic) != USBCAP_FILEHDR_MAGIC) { 724 errx(EX_SOFTWARE, "Invalid magic field(0x%08x) " 725 "in USB capture file header.", 726 (unsigned int)le32toh(uf.magic)); 727 } 728 if (uf.major != 0) { 729 errx(EX_SOFTWARE, "Invalid major version(%d) " 730 "field in USB capture file header.", (int)uf.major); 731 } 732 733 uf_minor = uf.minor; 734 735 if (uf.minor != 3 && uf.minor != 2) { 736 errx(EX_SOFTWARE, "Invalid minor version(%d) " 737 "field in USB capture file header.", (int)uf.minor); 738 } 739 } 740 741 static void 742 init_wfile(struct usbcap *p) 743 { 744 struct usbcap_filehdr uf; 745 int ret; 746 747 p->wfd = open(w_arg, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); 748 if (p->wfd < 0) { 749 err(EXIT_FAILURE, "Could not open " 750 "'%s' for write", w_arg); 751 } 752 memset(&uf, 0, sizeof(uf)); 753 uf.magic = htole32(USBCAP_FILEHDR_MAGIC); 754 uf.major = 0; 755 uf.minor = 3; 756 ret = write(p->wfd, (const void *)&uf, sizeof(uf)); 757 if (ret != sizeof(uf)) { 758 err(EXIT_FAILURE, "Could not write " 759 "USB capture header"); 760 } 761 } 762 763 static void 764 usage(void) 765 { 766 767 #define FMT " %-14s %s\n" 768 fprintf(stderr, "usage: usbdump [options]\n"); 769 fprintf(stderr, FMT, "-i <usbusX>", "Listen on USB bus interface"); 770 fprintf(stderr, FMT, "-f <unit[.endpoint]>", "Specify a device and endpoint filter"); 771 fprintf(stderr, FMT, "-r <file>", "Read the raw packets from file"); 772 fprintf(stderr, FMT, "-s <snaplen>", "Snapshot bytes from each packet"); 773 fprintf(stderr, FMT, "-v", "Increase the verbose level"); 774 fprintf(stderr, FMT, "-b <file>", "Save raw version of all recorded data to file"); 775 fprintf(stderr, FMT, "-w <file>", "Write the raw packets to file"); 776 fprintf(stderr, FMT, "-h", "Display summary of command line options"); 777 #undef FMT 778 exit(EX_USAGE); 779 } 780 781 static void 782 check_usb_pf_sysctl(void) 783 { 784 int error; 785 int no_pf_val = 0; 786 size_t no_pf_len = sizeof(int); 787 788 /* check "hw.usb.no_pf" sysctl for 8- and 9- stable */ 789 790 error = sysctlbyname("hw.usb.no_pf", &no_pf_val, 791 &no_pf_len, NULL, 0); 792 if (error == 0 && no_pf_val != 0) { 793 warnx("The USB packet filter might be disabled."); 794 warnx("See the \"hw.usb.no_pf\" sysctl for more information."); 795 } 796 } 797 798 int 799 main(int argc, char *argv[]) 800 { 801 struct timeval tv; 802 struct bpf_program total_prog; 803 struct bpf_stat us; 804 struct bpf_version bv; 805 struct usbcap *p = &uc; 806 struct ifreq ifr; 807 long snapshot = 192; 808 uint32_t v; 809 int fd; 810 int o; 811 int filt_unit; 812 int filt_ep; 813 int s; 814 int ifindex; 815 const char *optstring; 816 char *pp; 817 818 optstring = "b:hi:r:s:vw:f:"; 819 while ((o = getopt(argc, argv, optstring)) != -1) { 820 switch (o) { 821 case 'i': 822 i_arg = optarg; 823 break; 824 case 'r': 825 r_arg = optarg; 826 init_rfile(p); 827 break; 828 case 's': 829 snapshot = strtol(optarg, &pp, 10); 830 errno = 0; 831 if (pp != NULL && *pp != 0) 832 usage(); 833 if (snapshot == 0 && errno == EINVAL) 834 usage(); 835 /* snapeshot == 0 is special */ 836 if (snapshot == 0) 837 snapshot = -1; 838 break; 839 case 'b': 840 b_arg = optarg; 841 break; 842 case 'v': 843 verbose++; 844 break; 845 case 'w': 846 w_arg = optarg; 847 init_wfile(p); 848 break; 849 case 'f': 850 filt_unit = strtol(optarg, &pp, 10); 851 filt_ep = -1; 852 if (pp != NULL) { 853 if (*pp == '.') { 854 filt_ep = strtol(pp + 1, &pp, 10); 855 if (pp != NULL && *pp != 0) 856 usage(); 857 } else if (*pp != 0) { 858 usage(); 859 } 860 } 861 add_filter(filt_unit, filt_ep); 862 break; 863 default: 864 usage(); 865 /* NOTREACHED */ 866 } 867 } 868 869 if (b_arg != NULL) { 870 p->bfd = open(b_arg, O_CREAT | O_TRUNC | 871 O_WRONLY, S_IRUSR | S_IWUSR); 872 if (p->bfd < 0) { 873 err(EXIT_FAILURE, "Could not open " 874 "'%s' for write", b_arg); 875 } 876 } 877 878 /* 879 * Require more verbosity to print anything when -w or -b is 880 * specified on the command line: 881 */ 882 if (w_arg != NULL || b_arg != NULL) 883 verbose--; 884 885 if (r_arg != NULL) { 886 read_file(p); 887 exit(EXIT_SUCCESS); 888 } 889 890 check_usb_pf_sysctl(); 891 892 p->fd = fd = open("/dev/bpf", O_RDONLY); 893 if (p->fd < 0) 894 err(EXIT_FAILURE, "Could not open BPF device"); 895 896 if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) 897 err(EXIT_FAILURE, "BIOCVERSION ioctl failed"); 898 899 if (bv.bv_major != BPF_MAJOR_VERSION || 900 bv.bv_minor < BPF_MINOR_VERSION) 901 errx(EXIT_FAILURE, "Kernel BPF filter out of date"); 902 903 /* USB transfers can be greater than 64KByte */ 904 v = 1U << 16; 905 906 /* clear ifr structure */ 907 memset(&ifr, 0, sizeof(ifr)); 908 909 /* Try to create usbusN interface if it is not available. */ 910 s = socket(AF_LOCAL, SOCK_DGRAM, 0); 911 if (s < 0) 912 errx(EXIT_FAILURE, "Could not open a socket"); 913 ifindex = if_nametoindex(i_arg); 914 if (ifindex == 0) { 915 (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); 916 if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) 917 errx(EXIT_FAILURE, "Invalid bus interface: %s", i_arg); 918 } 919 920 for ( ; v >= USBPF_HDR_LEN; v >>= 1) { 921 (void)ioctl(fd, BIOCSBLEN, (caddr_t)&v); 922 (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); 923 if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) 924 break; 925 } 926 if (v == 0) 927 errx(EXIT_FAILURE, "No buffer size worked."); 928 929 if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) 930 err(EXIT_FAILURE, "BIOCGBLEN ioctl failed"); 931 932 p->bufsize = v; 933 p->buffer = (uint8_t *)malloc(p->bufsize); 934 if (p->buffer == NULL) 935 errx(EX_SOFTWARE, "Out of memory."); 936 937 make_filter(&total_prog, snapshot); 938 939 if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) 940 err(EXIT_FAILURE, "BIOCSETF ioctl failed"); 941 942 free_filter(&total_prog); 943 944 /* 1 second read timeout */ 945 tv.tv_sec = 1; 946 tv.tv_usec = 0; 947 if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) 948 err(EXIT_FAILURE, "BIOCSRTIMEOUT ioctl failed"); 949 950 (void)signal(SIGINT, handle_sigint); 951 952 do_loop(p); 953 954 if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) 955 err(EXIT_FAILURE, "BIOCGSTATS ioctl failed"); 956 957 /* XXX what's difference between pkt_captured and us.us_recv? */ 958 printf("\n"); 959 printf("%d packets captured\n", pkt_captured); 960 printf("%d packets received by filter\n", us.bs_recv); 961 printf("%d packets dropped by kernel\n", us.bs_drop); 962 963 /* 964 * Destroy the usbusN interface only if it was created by 965 * usbdump(8). Ignore when it was already destroyed. 966 */ 967 if (ifindex == 0 && if_nametoindex(i_arg) > 0) { 968 (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); 969 if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) 970 warn("SIOCIFDESTROY ioctl failed"); 971 } 972 close(s); 973 974 if (p->fd > 0) 975 close(p->fd); 976 if (p->rfd > 0) 977 close(p->rfd); 978 if (p->wfd > 0) 979 close(p->wfd); 980 if (p->bfd > 0) 981 close(p->bfd); 982 983 return (EXIT_SUCCESS); 984 } 985