diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-01-27 16:00:33 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-01-27 16:04:01 -0800 |
commit | 3b3c4069c56f44ad9b603ceb8bee412d69a6cd9e (patch) | |
tree | 611e6161b7555b5ff0df36a335e590f7e7dd9804 | |
parent | c6ea8334a341271345b8ca6d0e4c7fd5d3e87418 (diff) | |
download | libpcap-3b3c4069c56f44ad9b603ceb8bee412d69a6cd9e.tar.gz |
Fix the swapping of isochronous descriptors.
From looking at the Linux USB monitoring code:
With the old header, there are no isochronous descriptors after the
header.
With the new header, the actual number of descriptors in the header is
not s.iso.numdesc, it's ndesc - only the first N descriptors, for some
value of N, are put into the header, and ndesc is set to the actual
number copied. In addition, if s.iso.numdesc is negative, no
descriptors are captured, and ndesc is set to 0.
-rw-r--r-- | pcap-common.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/pcap-common.c b/pcap-common.c index 974152f2..282cbfc1 100644 --- a/pcap-common.c +++ b/pcap-common.c @@ -1009,8 +1009,6 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf, { pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf; bpf_u_int32 offset = 0; - usb_isodesc *pisodesc; - int32_t numdesc, i; /* * "offset" is the offset *past* the field we're swapping; @@ -1074,6 +1072,17 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf, } else offset += 8; /* skip USB setup header */ + /* + * With the old header, there are no isochronous descriptors + * after the header. + * + * With the new header, the actual number of descriptors in + * the header is not s.iso.numdesc, it's ndesc - only the + * first N descriptors, for some value of N, are put into + * the header, and ndesc is set to the actual number copied. + * In addition, if s.iso.numdesc is negative, no descriptors + * are captured, and ndesc is set to 0. + */ if (header_len_64_bytes) { /* * This is either the "version 1" header, with @@ -1102,31 +1111,33 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf, if (hdr->caplen < offset) return; uhdr->ndesc = SWAPLONG(uhdr->ndesc); - } - if (uhdr->transfer_type == URB_ISOCHRONOUS) { - /* swap the values in struct linux_usb_isodesc */ - pisodesc = (usb_isodesc *)(void *)(buf+offset); - numdesc = uhdr->s.iso.numdesc; - for (i = 0; i < numdesc; i++) { - offset += 4; /* skip past status */ - if (hdr->caplen < offset) - return; - pisodesc->status = SWAPLONG(pisodesc->status); - - offset += 4; /* skip past offset */ - if (hdr->caplen < offset) - return; - pisodesc->offset = SWAPLONG(pisodesc->offset); - - offset += 4; /* skip past len */ - if (hdr->caplen < offset) - return; - pisodesc->len = SWAPLONG(pisodesc->len); - - offset += 4; /* skip past padding */ - - pisodesc++; + if (uhdr->transfer_type == URB_ISOCHRONOUS) { + /* swap the values in struct linux_usb_isodesc */ + usb_isodesc *pisodesc; + u_int32_t i; + + pisodesc = (usb_isodesc *)(void *)(buf+offset); + for (i = 0; i < uhdr->ndesc; i++) { + offset += 4; /* skip past status */ + if (hdr->caplen < offset) + return; + pisodesc->status = SWAPLONG(pisodesc->status); + + offset += 4; /* skip past offset */ + if (hdr->caplen < offset) + return; + pisodesc->offset = SWAPLONG(pisodesc->offset); + + offset += 4; /* skip past len */ + if (hdr->caplen < offset) + return; + pisodesc->len = SWAPLONG(pisodesc->len); + + offset += 4; /* skip past padding */ + + pisodesc++; + } } } } |