diff options
Diffstat (limited to 'pcap-usb-linux.c')
-rw-r--r-- | pcap-usb-linux.c | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index 726e4a8a6462..bc39b1db445f 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -33,14 +33,12 @@ * */ -#ifdef HAVE_CONFIG_H #include <config.h> -#endif +#include "pcap/usb.h" #include "pcap-int.h" #include "pcap-usb-linux.h" #include "pcap-usb-linux-common.h" -#include "pcap/usb.h" #include "extract.h" @@ -157,7 +155,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str) * "connected" vs. "disconnected", as that's a property * that would apply to a particular USB interface. */ - if (add_dev(devlistp, dev_name, + if (pcapint_add_dev(devlistp, dev_name, PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "Raw USB traffic, all USB buses", err_str) == NULL) return -1; @@ -169,7 +167,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str) * PCAP_IF_CONNECTION_STATUS_DISCONNECTED? */ snprintf(dev_descr, 30, "Raw USB traffic, bus number %d", n); - if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL) + if (pcapint_add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL) return -1; } @@ -254,7 +252,7 @@ usb_set_ring_size(pcap_t* handle, int header_size) /* * Will this get an error? - * (There's no wqy to query the minimum or maximum, so we just + * (There's no way to query the minimum or maximum, so we just * copy the value from the kernel source. We don't round it * up to a multiple of the page size.) */ @@ -277,7 +275,7 @@ usb_set_ring_size(pcap_t* handle, int header_size) } if (ioctl(handle->fd, MON_IOCT_RING_SIZE, ring_size) == -1) { - pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't set ring size from fd %d", handle->fd); return -1; } @@ -482,11 +480,11 @@ usb_activate(pcap_t* handle) handle->linktype = DLT_USB_LINUX; handle->inject_op = usb_inject_linux; - handle->setfilter_op = install_bpf_program; /* no kernel filtering */ + handle->setfilter_op = pcapint_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; + handle->getnonblock_op = pcapint_getnonblock_fd; + handle->setnonblock_op = pcapint_setnonblock_fd; /*get usb bus index from device name */ if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1) @@ -544,7 +542,7 @@ DIAG_ON_FORMAT_TRUNCATION /* * Something went wrong. */ - pcap_fmt_errmsg_for_errno(handle->errbuf, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't open USB bus file %s", full_path); return PCAP_ERROR; @@ -609,7 +607,7 @@ DIAG_ON_FORMAT_TRUNCATION * buffer */ handle->buffer = malloc(handle->bufsize); if (!handle->buffer) { - pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "malloc"); close(handle->fd); return PCAP_ERROR; @@ -645,7 +643,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats) ret = ioctl(handle->fd, MON_IOCG_STATS, &st); if (ret < 0) { - pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't read stats from fd %d", handle->fd); return -1; } @@ -688,7 +686,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u if (errno == EAGAIN) return 0; /* no data there */ - pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't read from fd %d", handle->fd); return -1; } @@ -717,14 +715,14 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u pkth.caplen = sizeof(pcap_usb_header) + clen; if (info.hdr->data_flag) { /* - * No data; just base the on-the-wire length on + * No data; just base the original length on * info.hdr->data_len (so that it's >= the captured * length). */ pkth.len = sizeof(pcap_usb_header) + info.hdr->data_len; } else { /* - * We got data; base the on-the-wire length on + * We got data; base the original length on * info.hdr->urb_len, so that it includes data * discarded by the USB monitor device due to * its buffer being too small. @@ -735,7 +733,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u pkth.ts.tv_usec = info.hdr->ts_usec; if (handle->fcode.bf_insns == NULL || - pcap_filter(handle->fcode.bf_insns, handle->buffer, + pcapint_filter(handle->fcode.bf_insns, handle->buffer, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, handle->buffer); @@ -818,7 +816,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch if (errno == EAGAIN) return 0; /* no data there */ - pcap_fmt_errmsg_for_errno(handle->errbuf, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't mfetch fd %d", handle->fd); return -1; @@ -877,34 +875,53 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen; if (hdr->data_flag) { /* - * No data; just base the on-the-wire length + * No data; just base the original length * on hdr->data_len (so that it's >= the - * captured length). + * captured length). Clamp the result + * at UINT_MAX, so it fits in an unsigned + * int. */ - pkth.len = sizeof(pcap_usb_header_mmapped) + - hdr->data_len; + pkth.len = u_int_sum(sizeof(pcap_usb_header_mmapped), + hdr->data_len); } else { /* - * We got data; base the on-the-wire length - * on hdr->urb_len, so that it includes - * data discarded by the USB monitor device - * due to its buffer being too small. - */ - pkth.len = sizeof(pcap_usb_header_mmapped) + - (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len; - - /* - * Now clean it up if it's a completion - * event for an incoming isochronous - * transfer. + * We got data. */ - fix_linux_usb_mmapped_length(&pkth, bp); + if (is_isochronous_transfer_completion(hdr)) { + /* + * For isochronous transfer completion + * events, hdr->urb_len doesn't take + * into account the way the data is + * put into the buffer, as it doesn't + * count any padding between the + * chunks of isochronous data, so + * we have to calculate the amount + * of data from the isochronous + * descriptors. + */ + pkth.len = incoming_isochronous_transfer_completed_len(&pkth, bp); + } else { + /* + * For everything else, the original + * data length is just the length of + * the memory-mapped Linux USB header + * plus hdr->urb_len; we use + * hdr->urb_len so that it includes + * data discarded by the USB monitor + * device due to its buffer being + * too small. Clamp the result at + * UINT_MAX, so it fits in an + * unsigned int. + */ + pkth.len = u_int_sum(sizeof(pcap_usb_header_mmapped), + hdr->urb_len); + } } pkth.ts.tv_sec = (time_t)hdr->ts_sec; pkth.ts.tv_usec = hdr->ts_usec; if (handle->fcode.bf_insns == NULL || - pcap_filter(handle->fcode.bf_insns, (u_char*) hdr, + pcapint_filter(handle->fcode.bf_insns, (u_char*) hdr, pkth.len, pkth.caplen)) { handlep->packets_read++; callback(user, &pkth, (u_char*) hdr); @@ -913,7 +930,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch } /* - * If max_packets specifiesg "unlimited", we stop after + * If max_packets specifies "unlimited", we stop after * the first chunk. */ if (PACKET_COUNT_IS_UNLIMITED(max_packets) || @@ -923,7 +940,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch /* flush pending events*/ if (ioctl(handle->fd, MON_IOCH_MFLUSH, nflush) == -1) { - pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "Can't mflush fd %d", handle->fd); return -1; } @@ -940,5 +957,5 @@ usb_cleanup_linux_mmap(pcap_t* handle) munmap(handlep->mmapbuf, handlep->mmapbuflen); handlep->mmapbuf = NULL; } - pcap_cleanup_live_common(handle); + pcapint_cleanup_live_common(handle); } |