Coverage Report

Created: 2025-08-24 06:47

/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
pcap-util.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
}