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