1 /* 2 * Copyright (c) 2006 Paolo Abeni (Italy) 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 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * USB sniffing API implementation for Linux platform 31 * By Paolo Abeni <paolo.abeni@email.it> 32 * Modifications: Kris Katterjohn <katterjohn@gmail.com> 33 * 34 */ 35 36 #ifdef HAVE_CONFIG_H 37 #include "config.h" 38 #endif 39 40 #include "pcap-int.h" 41 #include "pcap-usb-linux.h" 42 #include "pcap/usb.h" 43 44 #ifdef NEED_STRERROR_H 45 #include "strerror.h" 46 #endif 47 48 #include <ctype.h> 49 #include <errno.h> 50 #include <stdlib.h> 51 #include <unistd.h> 52 #include <fcntl.h> 53 #include <string.h> 54 #include <dirent.h> 55 #include <byteswap.h> 56 #include <netinet/in.h> 57 #include <sys/ioctl.h> 58 #include <sys/mman.h> 59 #ifdef HAVE_LINUX_USBDEVICE_FS_H 60 /* 61 * We might need <linux/compiler.h> to define __user for 62 * <linux/usbdevice_fs.h>. 63 */ 64 #ifdef HAVE_LINUX_COMPILER_H 65 #include <linux/compiler.h> 66 #endif /* HAVE_LINUX_COMPILER_H */ 67 #include <linux/usbdevice_fs.h> 68 #endif /* HAVE_LINUX_USBDEVICE_FS_H */ 69 70 #define USB_IFACE "usbmon" 71 #define USB_TEXT_DIR_OLD "/sys/kernel/debug/usbmon" 72 #define USB_TEXT_DIR "/sys/kernel/debug/usb/usbmon" 73 #define SYS_USB_BUS_DIR "/sys/bus/usb/devices" 74 #define PROC_USB_BUS_DIR "/proc/bus/usb" 75 #define USB_LINE_LEN 4096 76 77 #if __BYTE_ORDER == __LITTLE_ENDIAN 78 #define htols(s) s 79 #define htoll(l) l 80 #define htol64(ll) ll 81 #else 82 #define htols(s) bswap_16(s) 83 #define htoll(l) bswap_32(l) 84 #define htol64(ll) bswap_64(ll) 85 #endif 86 87 struct mon_bin_stats { 88 u_int32_t queued; 89 u_int32_t dropped; 90 }; 91 92 struct mon_bin_get { 93 pcap_usb_header *hdr; 94 void *data; 95 size_t data_len; /* Length of data (can be zero) */ 96 }; 97 98 struct mon_bin_mfetch { 99 int32_t *offvec; /* Vector of events fetched */ 100 int32_t nfetch; /* Number of events to fetch (out: fetched) */ 101 int32_t nflush; /* Number of events to flush */ 102 }; 103 104 #define MON_IOC_MAGIC 0x92 105 106 #define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1) 107 #define MON_IOCX_URB _IOWR(MON_IOC_MAGIC, 2, struct mon_bin_hdr) 108 #define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) 109 #define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4) 110 #define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5) 111 #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) 112 #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) 113 #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) 114 115 #define MON_BIN_SETUP 0x1 /* setup hdr is present*/ 116 #define MON_BIN_SETUP_ZERO 0x2 /* setup buffer is not available */ 117 #define MON_BIN_DATA_ZERO 0x4 /* data buffer is not available */ 118 #define MON_BIN_ERROR 0x8 119 120 /* 121 * Private data for capturing on Linux USB. 122 */ 123 struct pcap_usb_linux { 124 u_char *mmapbuf; /* memory-mapped region pointer */ 125 size_t mmapbuflen; /* size of region */ 126 int bus_index; 127 u_int packets_read; 128 }; 129 130 /* forward declaration */ 131 static int usb_activate(pcap_t *); 132 static int usb_stats_linux(pcap_t *, struct pcap_stat *); 133 static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *); 134 static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *); 135 static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *); 136 static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *); 137 static int usb_inject_linux(pcap_t *, const void *, size_t); 138 static int usb_setdirection_linux(pcap_t *, pcap_direction_t); 139 static void usb_cleanup_linux_mmap(pcap_t *); 140 141 /* facility to add an USB device to the device list*/ 142 static int 143 usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str) 144 { 145 char dev_name[10]; 146 char dev_descr[30]; 147 snprintf(dev_name, 10, USB_IFACE"%d", n); 148 snprintf(dev_descr, 30, "USB bus number %d", n); 149 150 if (pcap_add_if(alldevsp, dev_name, 0, 151 dev_descr, err_str) < 0) 152 return -1; 153 return 0; 154 } 155 156 int 157 usb_findalldevs(pcap_if_t **alldevsp, char *err_str) 158 { 159 struct dirent* data; 160 int ret = 0; 161 DIR* dir; 162 int n; 163 char* name; 164 size_t len; 165 166 /* try scanning sysfs usb bus directory */ 167 dir = opendir(SYS_USB_BUS_DIR); 168 if (dir != NULL) { 169 while ((ret == 0) && ((data = readdir(dir)) != 0)) { 170 name = data->d_name; 171 172 if (strncmp(name, "usb", 3) != 0) 173 continue; 174 175 if (sscanf(&name[3], "%d", &n) == 0) 176 continue; 177 178 ret = usb_dev_add(alldevsp, n, err_str); 179 } 180 181 closedir(dir); 182 return ret; 183 } 184 185 /* that didn't work; try scanning procfs usb bus directory */ 186 dir = opendir(PROC_USB_BUS_DIR); 187 if (dir != NULL) { 188 while ((ret == 0) && ((data = readdir(dir)) != 0)) { 189 name = data->d_name; 190 len = strlen(name); 191 192 /* if this file name does not end with a number it's not of our interest */ 193 if ((len < 1) || !isdigit(name[--len])) 194 continue; 195 while (isdigit(name[--len])); 196 if (sscanf(&name[len+1], "%d", &n) != 1) 197 continue; 198 199 ret = usb_dev_add(alldevsp, n, err_str); 200 } 201 202 closedir(dir); 203 return ret; 204 } 205 206 /* neither of them worked */ 207 return 0; 208 } 209 210 static 211 int usb_mmap(pcap_t* handle) 212 { 213 struct pcap_usb_linux *handlep = handle->priv; 214 int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE); 215 if (len < 0) 216 return 0; 217 218 handlep->mmapbuflen = len; 219 handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ, 220 MAP_SHARED, handle->fd, 0); 221 return handlep->mmapbuf != MAP_FAILED; 222 } 223 224 #ifdef HAVE_LINUX_USBDEVICE_FS_H 225 226 #define CTRL_TIMEOUT (5*1000) /* milliseconds */ 227 228 #define USB_DIR_IN 0x80 229 #define USB_TYPE_STANDARD 0x00 230 #define USB_RECIP_DEVICE 0x00 231 232 #define USB_REQ_GET_DESCRIPTOR 6 233 234 #define USB_DT_DEVICE 1 235 236 /* probe the descriptors of the devices attached to the bus */ 237 /* the descriptors will end up in the captured packet stream */ 238 /* and be decoded by external apps like wireshark */ 239 /* without these identifying probes packet data can't be fully decoded */ 240 static void 241 probe_devices(int bus) 242 { 243 struct usbdevfs_ctrltransfer ctrl; 244 struct dirent* data; 245 int ret = 0; 246 char buf[40]; 247 DIR* dir; 248 249 /* scan usb bus directories for device nodes */ 250 snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus); 251 dir = opendir(buf); 252 if (!dir) 253 return; 254 255 while ((ret >= 0) && ((data = readdir(dir)) != 0)) { 256 int fd; 257 char* name = data->d_name; 258 259 if (name[0] == '.') 260 continue; 261 262 snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name); 263 264 fd = open(buf, O_RDWR); 265 if (fd == -1) 266 continue; 267 268 /* 269 * Sigh. Different kernels have different member names 270 * for this structure. 271 */ 272 #ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 273 ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; 274 ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; 275 ctrl.wValue = USB_DT_DEVICE << 8; 276 ctrl.wIndex = 0; 277 ctrl.wLength = sizeof(buf); 278 #else 279 ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; 280 ctrl.request = USB_REQ_GET_DESCRIPTOR; 281 ctrl.value = USB_DT_DEVICE << 8; 282 ctrl.index = 0; 283 ctrl.length = sizeof(buf); 284 #endif 285 ctrl.data = buf; 286 ctrl.timeout = CTRL_TIMEOUT; 287 288 ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl); 289 290 close(fd); 291 } 292 closedir(dir); 293 } 294 #endif /* HAVE_LINUX_USBDEVICE_FS_H */ 295 296 pcap_t * 297 usb_create(const char *device, char *ebuf, int *is_ours) 298 { 299 const char *cp; 300 char *cpend; 301 long devnum; 302 pcap_t *p; 303 304 /* Does this look like a USB monitoring device? */ 305 cp = strrchr(device, '/'); 306 if (cp == NULL) 307 cp = device; 308 /* Does it begin with USB_IFACE? */ 309 if (strncmp(cp, USB_IFACE, sizeof USB_IFACE - 1) != 0) { 310 /* Nope, doesn't begin with USB_IFACE */ 311 *is_ours = 0; 312 return NULL; 313 } 314 /* Yes - is USB_IFACE followed by a number? */ 315 cp += sizeof USB_IFACE - 1; 316 devnum = strtol(cp, &cpend, 10); 317 if (cpend == cp || *cpend != '\0') { 318 /* Not followed by a number. */ 319 *is_ours = 0; 320 return NULL; 321 } 322 if (devnum < 0) { 323 /* Followed by a non-valid number. */ 324 *is_ours = 0; 325 return NULL; 326 } 327 328 /* OK, it's probably ours. */ 329 *is_ours = 1; 330 331 p = pcap_create_common(device, ebuf, sizeof (struct pcap_usb_linux)); 332 if (p == NULL) 333 return (NULL); 334 335 p->activate_op = usb_activate; 336 return (p); 337 } 338 339 static int 340 usb_activate(pcap_t* handle) 341 { 342 struct pcap_usb_linux *handlep = handle->priv; 343 char full_path[USB_LINE_LEN]; 344 345 /* Initialize some components of the pcap structure. */ 346 handle->bufsize = handle->snapshot; 347 handle->offset = 0; 348 handle->linktype = DLT_USB_LINUX; 349 350 handle->inject_op = usb_inject_linux; 351 handle->setfilter_op = install_bpf_program; /* no kernel filtering */ 352 handle->setdirection_op = usb_setdirection_linux; 353 handle->set_datalink_op = NULL; /* can't change data link type */ 354 handle->getnonblock_op = pcap_getnonblock_fd; 355 handle->setnonblock_op = pcap_setnonblock_fd; 356 357 /*get usb bus index from device name */ 358 if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1) 359 { 360 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 361 "Can't get USB bus index from %s", handle->opt.source); 362 return PCAP_ERROR; 363 } 364 365 /*now select the read method: try to open binary interface */ 366 snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); 367 handle->fd = open(full_path, O_RDONLY, 0); 368 if (handle->fd >= 0) 369 { 370 if (handle->opt.rfmon) { 371 /* 372 * Monitor mode doesn't apply to USB devices. 373 */ 374 close(handle->fd); 375 return PCAP_ERROR_RFMON_NOTSUP; 376 } 377 378 /* binary api is available, try to use fast mmap access */ 379 if (usb_mmap(handle)) { 380 handle->linktype = DLT_USB_LINUX_MMAPPED; 381 handle->stats_op = usb_stats_linux_bin; 382 handle->read_op = usb_read_linux_mmap; 383 handle->cleanup_op = usb_cleanup_linux_mmap; 384 #ifdef HAVE_LINUX_USBDEVICE_FS_H 385 probe_devices(handlep->bus_index); 386 #endif 387 388 /* 389 * "handle->fd" is a real file, so "select()" and 390 * "poll()" work on it. 391 */ 392 handle->selectable_fd = handle->fd; 393 return 0; 394 } 395 396 /* can't mmap, use plain binary interface access */ 397 handle->stats_op = usb_stats_linux_bin; 398 handle->read_op = usb_read_linux_bin; 399 #ifdef HAVE_LINUX_USBDEVICE_FS_H 400 probe_devices(handlep->bus_index); 401 #endif 402 } 403 else { 404 /*Binary interface not available, try open text interface */ 405 snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); 406 handle->fd = open(full_path, O_RDONLY, 0); 407 if (handle->fd < 0) 408 { 409 if (errno == ENOENT) 410 { 411 /* 412 * Not found at the new location; try 413 * the old location. 414 */ 415 snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index); 416 handle->fd = open(full_path, O_RDONLY, 0); 417 } 418 if (handle->fd < 0) { 419 /* no more fallback, give it up*/ 420 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 421 "Can't open USB bus file %s: %s", full_path, strerror(errno)); 422 return PCAP_ERROR; 423 } 424 } 425 426 if (handle->opt.rfmon) { 427 /* 428 * Monitor mode doesn't apply to USB devices. 429 */ 430 close(handle->fd); 431 return PCAP_ERROR_RFMON_NOTSUP; 432 } 433 434 handle->stats_op = usb_stats_linux; 435 handle->read_op = usb_read_linux; 436 } 437 438 /* 439 * "handle->fd" is a real file, so "select()" and "poll()" 440 * work on it. 441 */ 442 handle->selectable_fd = handle->fd; 443 444 /* for plain binary access and text access we need to allocate the read 445 * buffer */ 446 handle->buffer = malloc(handle->bufsize); 447 if (!handle->buffer) { 448 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 449 "malloc: %s", pcap_strerror(errno)); 450 close(handle->fd); 451 return PCAP_ERROR; 452 } 453 return 0; 454 } 455 456 static inline int 457 ascii_to_int(char c) 458 { 459 return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10); 460 } 461 462 /* 463 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and 464 * <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string 465 * format description 466 */ 467 static int 468 usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) 469 { 470 /* see: 471 * /usr/src/linux/Documentation/usb/usbmon.txt 472 * for message format 473 */ 474 struct pcap_usb_linux *handlep = handle->priv; 475 unsigned timestamp; 476 int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len; 477 char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN]; 478 char *string = line; 479 u_char * rawdata = handle->buffer; 480 struct pcap_pkthdr pkth; 481 pcap_usb_header* uhdr = (pcap_usb_header*)handle->buffer; 482 u_char urb_transfer=0; 483 int incoming=0; 484 485 /* ignore interrupt system call errors */ 486 do { 487 ret = read(handle->fd, line, USB_LINE_LEN - 1); 488 if (handle->break_loop) 489 { 490 handle->break_loop = 0; 491 return -2; 492 } 493 } while ((ret == -1) && (errno == EINTR)); 494 if (ret < 0) 495 { 496 if (errno == EAGAIN) 497 return 0; /* no data there */ 498 499 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 500 "Can't read from fd %d: %s", handle->fd, strerror(errno)); 501 return -1; 502 } 503 504 /* read urb header; %n argument may increment return value, but it's 505 * not mandatory, so does not count on it*/ 506 string[ret] = 0; 507 ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, ×tamp, &etype, 508 &pipeid1, &pipeid2, &dev_addr, &ep_num, status, 509 &cnt); 510 if (ret < 8) 511 { 512 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 513 "Can't parse USB bus message '%s', too few tokens (expected 8 got %d)", 514 string, ret); 515 return -1; 516 } 517 uhdr->id = tag; 518 uhdr->device_address = dev_addr; 519 uhdr->bus_id = handlep->bus_index; 520 uhdr->status = 0; 521 string += cnt; 522 523 /* don't use usbmon provided timestamp, since it have low precision*/ 524 if (gettimeofday(&pkth.ts, NULL) < 0) 525 { 526 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 527 "Can't get timestamp for message '%s' %d:%s", 528 string, errno, strerror(errno)); 529 return -1; 530 } 531 uhdr->ts_sec = pkth.ts.tv_sec; 532 uhdr->ts_usec = pkth.ts.tv_usec; 533 534 /* parse endpoint information */ 535 if (pipeid1 == 'C') 536 urb_transfer = URB_CONTROL; 537 else if (pipeid1 == 'Z') 538 urb_transfer = URB_ISOCHRONOUS; 539 else if (pipeid1 == 'I') 540 urb_transfer = URB_INTERRUPT; 541 else if (pipeid1 == 'B') 542 urb_transfer = URB_BULK; 543 if (pipeid2 == 'i') { 544 ep_num |= URB_TRANSFER_IN; 545 incoming = 1; 546 } 547 if (etype == 'C') 548 incoming = !incoming; 549 550 /* direction check*/ 551 if (incoming) 552 { 553 if (handle->direction == PCAP_D_OUT) 554 return 0; 555 } 556 else 557 if (handle->direction == PCAP_D_IN) 558 return 0; 559 uhdr->event_type = etype; 560 uhdr->transfer_type = urb_transfer; 561 uhdr->endpoint_number = ep_num; 562 pkth.caplen = sizeof(pcap_usb_header); 563 rawdata += sizeof(pcap_usb_header); 564 565 /* check if this is a setup packet */ 566 ret = sscanf(status, "%d", &dummy); 567 if (ret != 1) 568 { 569 /* this a setup packet, setup data can be filled with underscore if 570 * usbmon has not been able to read them, so we must parse this fields as 571 * strings */ 572 pcap_usb_setup* shdr; 573 char str1[3], str2[3], str3[5], str4[5], str5[5]; 574 ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4, 575 str5, &cnt); 576 if (ret < 5) 577 { 578 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 579 "Can't parse USB bus message '%s', too few tokens (expected 5 got %d)", 580 string, ret); 581 return -1; 582 } 583 string += cnt; 584 585 /* try to convert to corresponding integer */ 586 shdr = &uhdr->setup; 587 shdr->bmRequestType = strtoul(str1, 0, 16); 588 shdr->bRequest = strtoul(str2, 0, 16); 589 shdr->wValue = htols(strtoul(str3, 0, 16)); 590 shdr->wIndex = htols(strtoul(str4, 0, 16)); 591 shdr->wLength = htols(strtoul(str5, 0, 16)); 592 593 uhdr->setup_flag = 0; 594 } 595 else 596 uhdr->setup_flag = 1; 597 598 /* read urb data */ 599 ret = sscanf(string, " %d%n", &urb_len, &cnt); 600 if (ret < 1) 601 { 602 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 603 "Can't parse urb length from '%s'", string); 604 return -1; 605 } 606 string += cnt; 607 608 /* urb tag is not present if urb length is 0, so we can stop here 609 * text parsing */ 610 pkth.len = urb_len+pkth.caplen; 611 uhdr->urb_len = urb_len; 612 uhdr->data_flag = 1; 613 data_len = 0; 614 if (uhdr->urb_len == 0) 615 goto got; 616 617 /* check for data presence; data is present if and only if urb tag is '=' */ 618 if (sscanf(string, " %c", &urb_tag) != 1) 619 { 620 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 621 "Can't parse urb tag from '%s'", string); 622 return -1; 623 } 624 625 if (urb_tag != '=') 626 goto got; 627 628 /* skip urb tag and following space */ 629 string += 3; 630 631 /* if we reach this point we got some urb data*/ 632 uhdr->data_flag = 0; 633 634 /* read all urb data; if urb length is greater then the usbmon internal 635 * buffer length used by the kernel to spool the URB, we get only 636 * a partial information. 637 * At least until linux 2.6.17 there is no way to set usbmon intenal buffer 638 * length and default value is 130. */ 639 while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < handle->snapshot)) 640 { 641 rawdata[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]); 642 rawdata++; 643 string+=2; 644 if (string[0] == ' ') 645 string++; 646 pkth.caplen++; 647 data_len++; 648 } 649 650 got: 651 uhdr->data_len = data_len; 652 if (pkth.caplen > handle->snapshot) 653 pkth.caplen = handle->snapshot; 654 655 if (handle->fcode.bf_insns == NULL || 656 bpf_filter(handle->fcode.bf_insns, handle->buffer, 657 pkth.len, pkth.caplen)) { 658 handlep->packets_read++; 659 callback(user, &pkth, handle->buffer); 660 return 1; 661 } 662 return 0; /* didn't pass filter */ 663 } 664 665 static int 666 usb_inject_linux(pcap_t *handle, const void *buf, size_t size) 667 { 668 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on " 669 "USB devices"); 670 return (-1); 671 } 672 673 static int 674 usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) 675 { 676 struct pcap_usb_linux *handlep = handle->priv; 677 int dummy, ret, consumed, cnt; 678 char string[USB_LINE_LEN]; 679 char token[USB_LINE_LEN]; 680 char * ptr = string; 681 int fd; 682 683 snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index); 684 fd = open(string, O_RDONLY, 0); 685 if (fd < 0) 686 { 687 if (errno == ENOENT) 688 { 689 /* 690 * Not found at the new location; try the old 691 * location. 692 */ 693 snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index); 694 fd = open(string, O_RDONLY, 0); 695 } 696 if (fd < 0) { 697 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 698 "Can't open USB stats file %s: %s", 699 string, strerror(errno)); 700 return -1; 701 } 702 } 703 704 /* read stats line */ 705 do { 706 ret = read(fd, string, USB_LINE_LEN-1); 707 } while ((ret == -1) && (errno == EINTR)); 708 close(fd); 709 710 if (ret < 0) 711 { 712 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 713 "Can't read stats from fd %d ", fd); 714 return -1; 715 } 716 string[ret] = 0; 717 718 /* extract info on dropped urbs */ 719 for (consumed=0; consumed < ret; ) { 720 /* from the sscanf man page: 721 * The C standard says: "Execution of a %n directive does 722 * not increment the assignment count returned at the completion 723 * of execution" but the Corrigendum seems to contradict this. 724 * Do not make any assumptions on the effect of %n conversions 725 * on the return value and explicitly check for cnt assignmet*/ 726 int ntok; 727 728 cnt = -1; 729 ntok = sscanf(ptr, "%s%n", token, &cnt); 730 if ((ntok < 1) || (cnt < 0)) 731 break; 732 consumed += cnt; 733 ptr += cnt; 734 if (strcmp(token, "nreaders") == 0) 735 ret = sscanf(ptr, "%d", &stats->ps_drop); 736 else 737 ret = sscanf(ptr, "%d", &dummy); 738 if (ntok != 1) 739 break; 740 consumed += cnt; 741 ptr += cnt; 742 } 743 744 stats->ps_recv = handlep->packets_read; 745 stats->ps_ifdrop = 0; 746 return 0; 747 } 748 749 static int 750 usb_setdirection_linux(pcap_t *p, pcap_direction_t d) 751 { 752 p->direction = d; 753 return 0; 754 } 755 756 757 static int 758 usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats) 759 { 760 struct pcap_usb_linux *handlep = handle->priv; 761 int ret; 762 struct mon_bin_stats st; 763 ret = ioctl(handle->fd, MON_IOCG_STATS, &st); 764 if (ret < 0) 765 { 766 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 767 "Can't read stats from fd %d:%s ", handle->fd, strerror(errno)); 768 return -1; 769 } 770 771 stats->ps_recv = handlep->packets_read + st.queued; 772 stats->ps_drop = st.dropped; 773 stats->ps_ifdrop = 0; 774 return 0; 775 } 776 777 /* 778 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and 779 * <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI 780 */ 781 static int 782 usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) 783 { 784 struct pcap_usb_linux *handlep = handle->priv; 785 struct mon_bin_get info; 786 int ret; 787 struct pcap_pkthdr pkth; 788 int clen = handle->snapshot - sizeof(pcap_usb_header); 789 790 /* the usb header is going to be part of 'packet' data*/ 791 info.hdr = (pcap_usb_header*) handle->buffer; 792 info.data = handle->buffer + sizeof(pcap_usb_header); 793 info.data_len = clen; 794 795 /* ignore interrupt system call errors */ 796 do { 797 ret = ioctl(handle->fd, MON_IOCX_GET, &info); 798 if (handle->break_loop) 799 { 800 handle->break_loop = 0; 801 return -2; 802 } 803 } while ((ret == -1) && (errno == EINTR)); 804 if (ret < 0) 805 { 806 if (errno == EAGAIN) 807 return 0; /* no data there */ 808 809 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 810 "Can't read from fd %d: %s", handle->fd, strerror(errno)); 811 return -1; 812 } 813 814 /* we can get less that than really captured from kernel, depending on 815 * snaplen, so adjust header accordingly */ 816 if (info.hdr->data_len < clen) 817 clen = info.hdr->data_len; 818 info.hdr->data_len = clen; 819 pkth.caplen = clen + sizeof(pcap_usb_header); 820 pkth.len = info.hdr->data_len + sizeof(pcap_usb_header); 821 pkth.ts.tv_sec = info.hdr->ts_sec; 822 pkth.ts.tv_usec = info.hdr->ts_usec; 823 824 if (handle->fcode.bf_insns == NULL || 825 bpf_filter(handle->fcode.bf_insns, handle->buffer, 826 pkth.len, pkth.caplen)) { 827 handlep->packets_read++; 828 callback(user, &pkth, handle->buffer); 829 return 1; 830 } 831 832 return 0; /* didn't pass filter */ 833 } 834 835 /* 836 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and 837 * <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI 838 */ 839 #define VEC_SIZE 32 840 static int 841 usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) 842 { 843 struct pcap_usb_linux *handlep = handle->priv; 844 struct mon_bin_mfetch fetch; 845 int32_t vec[VEC_SIZE]; 846 struct pcap_pkthdr pkth; 847 pcap_usb_header* hdr; 848 int nflush = 0; 849 int packets = 0; 850 int clen, max_clen; 851 852 max_clen = handle->snapshot - sizeof(pcap_usb_header); 853 854 for (;;) { 855 int i, ret; 856 int limit = max_packets - packets; 857 if (limit <= 0) 858 limit = VEC_SIZE; 859 if (limit > VEC_SIZE) 860 limit = VEC_SIZE; 861 862 /* try to fetch as many events as possible*/ 863 fetch.offvec = vec; 864 fetch.nfetch = limit; 865 fetch.nflush = nflush; 866 /* ignore interrupt system call errors */ 867 do { 868 ret = ioctl(handle->fd, MON_IOCX_MFETCH, &fetch); 869 if (handle->break_loop) 870 { 871 handle->break_loop = 0; 872 return -2; 873 } 874 } while ((ret == -1) && (errno == EINTR)); 875 if (ret < 0) 876 { 877 if (errno == EAGAIN) 878 return 0; /* no data there */ 879 880 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 881 "Can't mfetch fd %d: %s", handle->fd, strerror(errno)); 882 return -1; 883 } 884 885 /* keep track of processed events, we will flush them later */ 886 nflush = fetch.nfetch; 887 for (i=0; i<fetch.nfetch; ++i) { 888 /* discard filler */ 889 hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]]; 890 if (hdr->event_type == '@') 891 continue; 892 893 /* we can get less that than really captured from kernel, depending on 894 * snaplen, so adjust header accordingly */ 895 clen = max_clen; 896 if (hdr->data_len < clen) 897 clen = hdr->data_len; 898 899 /* get packet info from header*/ 900 pkth.caplen = clen + sizeof(pcap_usb_header_mmapped); 901 pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped); 902 pkth.ts.tv_sec = hdr->ts_sec; 903 pkth.ts.tv_usec = hdr->ts_usec; 904 905 if (handle->fcode.bf_insns == NULL || 906 bpf_filter(handle->fcode.bf_insns, (u_char*) hdr, 907 pkth.len, pkth.caplen)) { 908 handlep->packets_read++; 909 callback(user, &pkth, (u_char*) hdr); 910 packets++; 911 } 912 } 913 914 /* with max_packets specifying "unlimited" we stop afer the first chunk*/ 915 if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets)) 916 break; 917 } 918 919 /* flush pending events*/ 920 ioctl(handle->fd, MON_IOCH_MFLUSH, nflush); 921 return packets; 922 } 923 924 static void 925 usb_cleanup_linux_mmap(pcap_t* handle) 926 { 927 struct pcap_usb_linux *handlep = handle->priv; 928 929 /* if we have a memory-mapped buffer, unmap it */ 930 if (handlep->mmapbuf != NULL) { 931 munmap(handlep->mmapbuf, handlep->mmapbuflen); 932 handlep->mmapbuf = NULL; 933 } 934 pcap_cleanup_live_common(handle); 935 } 936