static int usb_activate(pcap_t* handle) { struct pcap_usb_linux *handlep = handle->private; char full_path[USB_LINE_LEN]; /* Initialize some components of the pcap structure. */ handle->bufsize = handle->snapshot; handle->offset = 0; handle->linktype = DLT_USB_LINUX; handle->inject_op = usb_inject_linux; handle->setfilter_op = install_bpf_program; /* no kernel filtering */ handle->setdirection_op = usb_setdirection_linux; handle->set_datalink_op = NULL; /* can't change data link type */ handle->getnonblock_op = pcap_getnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd; /*get usb bus index from device name */ if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get USB bus index from %s", handle->opt.source); return PCAP_ERROR; } /*now select the read method: try to open binary interface */ snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd >= 0) { if (handle->opt.rfmon) { /* * Monitor mode doesn't apply to USB devices. */ close(handle->fd); return PCAP_ERROR_RFMON_NOTSUP; } /* binary api is available, try to use fast mmap access */ if (usb_mmap(handle)) { handle->linktype = DLT_USB_LINUX_MMAPPED; handle->stats_op = usb_stats_linux_bin; handle->read_op = usb_read_linux_mmap; handle->cleanup_op = usb_cleanup_linux_mmap; probe_devices(handlep->bus_index); /* * "handle->fd" is a real file, so "select()" and * "poll()" work on it. */ handle->selectable_fd = handle->fd; return 0; } /* can't mmap, use plain binary interface access */ handle->stats_op = usb_stats_linux_bin; handle->read_op = usb_read_linux_bin; probe_devices(handlep->bus_index); } else { /*Binary interface not available, try open text interface */ snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd < 0) { if (errno == ENOENT) { /* * Not found at the new location; try * the old location. */ snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); } if (handle->fd < 0) { /* no more fallback, give it up*/ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB bus file %s: %s", full_path, strerror(errno)); return PCAP_ERROR; } } if (handle->opt.rfmon) { /* * Monitor mode doesn't apply to USB devices. */ close(handle->fd); return PCAP_ERROR_RFMON_NOTSUP; } handle->stats_op = usb_stats_linux; handle->read_op = usb_read_linux; } /* * "handle->fd" is a real file, so "select()" and "poll()" * work on it. */ handle->selectable_fd = handle->fd; /* for plain binary access and text access we need to allocate the read * buffer */ handle->buffer = malloc(handle->bufsize); if (!handle->buffer) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); close(handle->fd); return PCAP_ERROR; } return 0; }
static int usb_activate(pcap_t* handle) { struct pcap_usb_linux *handlep = handle->priv; char full_path[USB_LINE_LEN]; /* * Turn a negative snapshot value (invalid), a snapshot value of * 0 (unspecified), or a value bigger than the normal maximum * value, into the maximum allowed value. * * If some application really *needs* a bigger snapshot * length, we should just increase MAXIMUM_SNAPLEN. */ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) handle->snapshot = MAXIMUM_SNAPLEN; /* Initialize some components of the pcap structure. */ handle->bufsize = handle->snapshot; handle->offset = 0; handle->linktype = DLT_USB_LINUX; handle->inject_op = usb_inject_linux; handle->setfilter_op = install_bpf_program; /* no kernel filtering */ handle->setdirection_op = usb_setdirection_linux; handle->set_datalink_op = NULL; /* can't change data link type */ handle->getnonblock_op = pcap_getnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd; /*get usb bus index from device name */ if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1) { pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get USB bus index from %s", handle->opt.device); return PCAP_ERROR; } if (have_binary_usbmon()) { /* * We have binary-mode support. * Try to open the binary interface. */ pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd < 0) { /* * The attempt failed; why? */ switch (errno) { case ENOENT: /* * The device doesn't exist. * That could either mean that there's * no support for monitoring USB buses * (which probably means "the usbmon * module isn't loaded") or that there * is but that *particular* device * doesn't exist (no "scan all buses" * device if the bus index is 0, no * such bus if the bus index isn't 0). */ return PCAP_ERROR_NO_SUCH_DEVICE; case EACCES: /* * We didn't have permission to open it. */ return PCAP_ERROR_PERM_DENIED; default: /* * Something went wrong. */ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't open USB bus file %s", full_path); return PCAP_ERROR; } } if (handle->opt.rfmon) { /* * Monitor mode doesn't apply to USB devices. */ close(handle->fd); return PCAP_ERROR_RFMON_NOTSUP; } /* try to use fast mmap access */ if (usb_mmap(handle)) { handle->linktype = DLT_USB_LINUX_MMAPPED; handle->stats_op = usb_stats_linux_bin; handle->read_op = usb_read_linux_mmap; handle->cleanup_op = usb_cleanup_linux_mmap; #ifdef HAVE_LINUX_USBDEVICE_FS_H probe_devices(handlep->bus_index); #endif /* * "handle->fd" is a real file, so * "select()" and "poll()" work on it. */ handle->selectable_fd = handle->fd; return 0; } /* can't mmap, use plain binary interface access */ handle->stats_op = usb_stats_linux_bin; handle->read_op = usb_read_linux_bin; #ifdef HAVE_LINUX_USBDEVICE_FS_H probe_devices(handlep->bus_index); #endif } else { /* * We don't have binary mode support. * Try opening the text-mode device. */ pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd < 0) { if (errno == ENOENT) { /* * Not found at the new location; try * the old location. */ pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); } if (handle->fd < 0) { /* * Is the problem that we didn't have * sufficient permission to open it? */ if (errno == EACCES) { /* * Yes - return that error. */ return PCAP_ERROR_PERM_DENIED; } /* * No - was the problem something other * than "it doesn't exist"? */ if (errno != ENOENT) { /* * Yes - return *that* error. */ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't open USB bus file %s", full_path); return PCAP_ERROR; } /* * No. Report that as "no such device". * (That could mean "no such USB bus" * or "monitoring not supported".) */ return PCAP_ERROR_NO_SUCH_DEVICE; } } if (handle->opt.rfmon) { /* * Monitor mode doesn't apply to USB devices. */ close(handle->fd); return PCAP_ERROR_RFMON_NOTSUP; } handle->stats_op = usb_stats_linux; handle->read_op = usb_read_linux; } /* * "handle->fd" is a real file, so "select()" and "poll()" * work on it. */ handle->selectable_fd = handle->fd; /* for plain binary access and text access we need to allocate the read * buffer */ handle->buffer = malloc(handle->bufsize); if (!handle->buffer) { pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "malloc"); close(handle->fd); return PCAP_ERROR; } return 0; }