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