1 1.1 christos /* 2 1.1 christos * Copyright (c) 1993, 1994, 1995, 1996, 1997 3 1.1 christos * The Regents of the University of California. All rights reserved. 4 1.1 christos * 5 1.1 christos * Redistribution and use in source and binary forms, with or without 6 1.1 christos * modification, are permitted provided that: (1) source code distributions 7 1.1 christos * retain the above copyright notice and this paragraph in its entirety, (2) 8 1.1 christos * distributions including binary code include the above copyright notice and 9 1.1 christos * this paragraph in its entirety in the documentation or other materials 10 1.1 christos * provided with the distribution, and (3) all advertising materials mentioning 11 1.1 christos * features or use of this software display the following acknowledgement: 12 1.1 christos * ``This product includes software developed by the University of California, 13 1.1 christos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 1.1 christos * the University nor the names of its contributors may be used to endorse 15 1.1 christos * or promote products derived from this software without specific prior 16 1.1 christos * written permission. 17 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 1.1 christos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 1.1 christos * 21 1.1 christos * pcap-usb-linux-common.h - common code for everything that needs to 22 1.1.1.2 christos * deal with Linux USB captures, whether live or in a capture file; 23 1.1.1.2 christos * the later means that this is *not* Linux-only. 24 1.1 christos */ 25 1.1 christos 26 1.1.1.2 christos #include <limits.h> 27 1.1.1.2 christos 28 1.1.1.2 christos /* 29 1.1.1.2 christos * Return the sum of the two u_int arguments if that sum fits in a u_int, 30 1.1.1.2 christos * and return UINT_MAX otherwise. 31 1.1.1.2 christos */ 32 1.1.1.2 christos static inline u_int 33 1.1.1.2 christos u_int_sum(u_int a, u_int b) 34 1.1.1.2 christos { 35 1.1.1.2 christos return (((b) <= UINT_MAX - (a)) ? (a) + (b) : UINT_MAX); 36 1.1.1.2 christos } 37 1.1.1.2 christos 38 1.1.1.2 christos /* 39 1.1.1.2 christos * Is this a completion event for an isochronous transfer? 40 1.1.1.2 christos */ 41 1.1.1.2 christos static inline int 42 1.1.1.2 christos is_isochronous_transfer_completion(const pcap_usb_header_mmapped *hdr) 43 1.1.1.2 christos { 44 1.1.1.2 christos return (hdr->transfer_type == URB_ISOCHRONOUS && 45 1.1.1.2 christos hdr->event_type == URB_COMPLETE && 46 1.1.1.2 christos (hdr->endpoint_number & URB_TRANSFER_IN)); 47 1.1.1.2 christos } 48 1.1.1.2 christos 49 1.1.1.2 christos /* 50 1.1.1.2 christos * Total length of the pseudo-header, including the isochronous 51 1.1.1.2 christos * descriptors. 52 1.1.1.2 christos */ 53 1.1.1.2 christos static inline uint32_t 54 1.1.1.2 christos iso_pseudo_header_len(const pcap_usb_header_mmapped *usb_hdr) 55 1.1.1.2 christos { 56 1.1.1.2 christos return (sizeof(pcap_usb_header_mmapped) + 57 1.1.1.2 christos usb_hdr->ndesc * sizeof (usb_isodesc)); 58 1.1.1.2 christos } 59 1.1.1.2 christos 60 1.1.1.2 christos /* 61 1.1.1.2 christos * Calculate the packet length for a "this is complete" incoming 62 1.1.1.2 christos * isochronous transfer event. 63 1.1.1.2 christos * 64 1.1.1.2 christos * Calculating that from hdr->urb_len is not correct, because the 65 1.1.1.2 christos * data is not contiguous, and the isochroous descriptors show how 66 1.1.1.2 christos * it's scattered. 67 1.1.1.2 christos */ 68 1.1.1.2 christos static inline u_int 69 1.1.1.2 christos incoming_isochronous_transfer_completed_len(struct pcap_pkthdr *phdr, 70 1.1.1.2 christos const u_char *bp) 71 1.1.1.2 christos { 72 1.1.1.2 christos const pcap_usb_header_mmapped *hdr; 73 1.1.1.2 christos u_int bytes_left; 74 1.1.1.2 christos const usb_isodesc *descs; 75 1.1.1.2 christos u_int pre_truncation_data_len; 76 1.1.1.2 christos 77 1.1.1.2 christos /* 78 1.1.1.2 christos * All callers of this routine must ensure that pkth->caplen is 79 1.1.1.2 christos * >= sizeof (pcap_usb_header_mmapped). 80 1.1.1.2 christos */ 81 1.1.1.2 christos bytes_left = phdr->caplen; 82 1.1.1.2 christos bytes_left -= sizeof (pcap_usb_header_mmapped); 83 1.1.1.2 christos 84 1.1.1.2 christos hdr = (const pcap_usb_header_mmapped *) bp; 85 1.1.1.2 christos descs = (const usb_isodesc *) (bp + sizeof(pcap_usb_header_mmapped)); 86 1.1.1.2 christos 87 1.1.1.2 christos /* 88 1.1.1.2 christos * Find the end of the last chunk of data in the buffer 89 1.1.1.2 christos * referred to by the isochronous descriptors; that indicates 90 1.1.1.2 christos * how far into the buffer the data would have gone. 91 1.1.1.2 christos * 92 1.1.1.2 christos * Make sure we don't run past the end of the captured data 93 1.1.1.2 christos * while processing the isochronous descriptors. 94 1.1.1.2 christos */ 95 1.1.1.2 christos pre_truncation_data_len = 0; 96 1.1.1.2 christos for (uint32_t desc = 0; 97 1.1.1.2 christos desc < hdr->ndesc && bytes_left >= sizeof (usb_isodesc); 98 1.1.1.2 christos desc++, bytes_left -= sizeof (usb_isodesc)) { 99 1.1.1.2 christos u_int desc_end; 100 1.1.1.2 christos 101 1.1.1.2 christos if (descs[desc].len != 0) { 102 1.1.1.2 christos /* 103 1.1.1.2 christos * Compute the end offset of the data 104 1.1.1.2 christos * for this descriptor, i.e. the offset 105 1.1.1.2 christos * of the byte after the data. Clamp 106 1.1.1.2 christos * the sum at UINT_MAX, so that it fits 107 1.1.1.2 christos * in a u_int. 108 1.1.1.2 christos */ 109 1.1.1.2 christos desc_end = u_int_sum(descs[desc].offset, 110 1.1.1.2 christos descs[desc].len); 111 1.1.1.2 christos if (desc_end > pre_truncation_data_len) 112 1.1.1.2 christos pre_truncation_data_len = desc_end; 113 1.1.1.2 christos } 114 1.1.1.2 christos } 115 1.1.1.2 christos 116 1.1.1.2 christos /* 117 1.1.1.2 christos * Return the sum of the total header length (memory-mapped 118 1.1.1.2 christos * header and ISO descriptors) and the data length, clamped 119 1.1.1.2 christos * to UINT_MAX. 120 1.1.1.2 christos * 121 1.1.1.2 christos * We've made sure that the number of descriptors is 122 1.1.1.2 christos * <= USB_MAXDESC, so we know that the total size, 123 1.1.1.2 christos * in bytes, of the descriptors fits in a 32-bit 124 1.1.1.2 christos * integer. 125 1.1.1.2 christos */ 126 1.1.1.2 christos return (u_int_sum(iso_pseudo_header_len(hdr), pre_truncation_data_len)); 127 1.1.1.2 christos } 128