Coverage Report

Created: 2025-12-14 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libpcap/pcap-util.c
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-util.c - common code for various files
22
 */
23
24
#include <config.h>
25
26
#include <stddef.h>
27
28
#include <pcap-types.h>
29
30
#include "pcap/can_socketcan.h"
31
#include "pcap/sll.h"
32
#include "pcap/usb.h"
33
#include "pcap/nflog.h"
34
35
#include "pcap-int.h"
36
#include "extract.h"
37
#include "pcap-usb-linux-common.h"
38
39
#include "pcap-util.h"
40
#include "pflog.h"
41
42
/*
43
 * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields
44
 * that are saved in host byte order.
45
 *
46
 * When reading a DLT_PFLOG packet, we need to convert those fields from
47
 * the byte order of the host that wrote the file to this host's byte
48
 * order.
49
 */
50
static void
51
swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
52
5.71k
{
53
5.71k
  u_int caplen = hdr->caplen;
54
5.71k
  u_int length = hdr->len;
55
5.71k
  u_int pfloghdr_length;
56
5.71k
  struct pfloghdr *pflhdr = (struct pfloghdr *)buf;
57
58
5.71k
  if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) ||
59
4.20k
      length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
60
    /* Not enough data to have the uid field */
61
1.91k
    return;
62
1.91k
  }
63
64
3.80k
  pfloghdr_length = pflhdr->length;
65
66
3.80k
  if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) {
67
    /* Header doesn't include uid field */
68
512
    return;
69
512
  }
70
3.29k
  pflhdr->uid = SWAPLONG(pflhdr->uid);
71
72
3.29k
  if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) ||
73
2.98k
      length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
74
    /* Not enough data to have the pid field */
75
571
    return;
76
571
  }
77
2.72k
  if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) {
78
    /* Header doesn't include pid field */
79
276
    return;
80
276
  }
81
2.44k
  pflhdr->pid = SWAPLONG(pflhdr->pid);
82
83
2.44k
  if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) ||
84
2.11k
      length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
85
    /* Not enough data to have the rule_uid field */
86
596
    return;
87
596
  }
88
1.85k
  if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) {
89
    /* Header doesn't include rule_uid field */
90
293
    return;
91
293
  }
92
1.55k
  pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid);
93
94
1.55k
  if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) ||
95
1.06k
      length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
96
    /* Not enough data to have the rule_pid field */
97
752
    return;
98
752
  }
99
806
  if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) {
100
    /* Header doesn't include rule_pid field */
101
273
    return;
102
273
  }
103
533
  pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid);
104
533
}
105
106
/*
107
 * Linux cooked capture packets with a protocol type of LINUX_SLL_P_CAN or
108
 * LINUX_SLL_P_CANFD have SocketCAN CAN classic/CAN FD headers in front
109
 * of the payload,with the CAN ID being in the byte order of the host
110
 * that wrote the packet, and Linux cooked capture packets with a protocol
111
 * type of LINUX_SLL_P_CANXL have SocketCAN CAN XL headers in front of the
112
 * payload with the protocol/VCID field, the payload length, and the
113
 * acceptance field in the byte order of the host that wrote the packet.
114
 *
115
 * When reading a Linux cooked capture packet, we need to check for those
116
 * packets and, if the byte order host that wrote the packet, as
117
 * indicated by the byte order of the pcap file or pcapng section
118
 * containing the packet, is the opposite of our byte order, convert
119
 * the header files to our byte order by byte-swapping them.
120
 */
121
static void
122
swap_socketcan_header(uint16_t protocol, u_int caplen, u_int length,
123
    u_char *buf)
124
10.0k
{
125
10.0k
  pcap_can_socketcan_hdr *hdrp;
126
10.0k
  pcap_can_socketcan_xl_hdr *xl_hdrp;
127
128
10.0k
  switch (protocol) {
129
130
1.99k
  case LINUX_SLL_P_CAN:
131
3.62k
  case LINUX_SLL_P_CANFD:
132
    /*
133
     * CAN classic/CAN FD packet; fix up the packet's header
134
     * by byte-swapping the CAN ID field.
135
     */
136
3.62k
    hdrp = (pcap_can_socketcan_hdr *)buf;
137
3.62k
    if (caplen < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id) ||
138
2.84k
        length < (u_int) (offsetof(pcap_can_socketcan_hdr, can_id) + sizeof hdrp->can_id)) {
139
      /* Not enough data to have the can_id field */
140
1.58k
      return;
141
1.58k
    }
142
2.03k
    hdrp->can_id = SWAPLONG(hdrp->can_id);
143
2.03k
    break;
144
145
5.28k
  case LINUX_SLL_P_CANXL:
146
    /*
147
     * CAN XL packet; fix up the packet's header by
148
     * byte-swapping the priority/VCID field, the
149
     * payload length, and the acceptance field.
150
     */
151
5.28k
    xl_hdrp = (pcap_can_socketcan_xl_hdr *)buf;
152
5.28k
    if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid) ||
153
4.61k
        length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, priority_vcid) + sizeof xl_hdrp->priority_vcid)) {
154
      /* Not enough data to have the priority_vcid field */
155
1.19k
      return;
156
1.19k
    }
157
4.09k
    xl_hdrp->priority_vcid = SWAPLONG(xl_hdrp->priority_vcid);
158
4.09k
    if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length) ||
159
3.27k
        length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, payload_length) + sizeof xl_hdrp->payload_length)) {
160
      /* Not enough data to have the payload_length field */
161
1.61k
      return;
162
1.61k
    }
163
2.47k
    xl_hdrp->payload_length = SWAPSHORT(xl_hdrp->payload_length);
164
2.47k
    if (caplen < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field) ||
165
1.68k
        length < (u_int) (offsetof(pcap_can_socketcan_xl_hdr, acceptance_field) + sizeof xl_hdrp->acceptance_field)) {
166
      /* Not enough data to have the acceptance_field field */
167
1.31k
      return;
168
1.31k
    }
169
1.16k
    xl_hdrp->acceptance_field = SWAPLONG(xl_hdrp->acceptance_field);
170
1.16k
    break;
171
172
1.11k
  default:
173
    /*
174
     * Not a CAN packet; nothing to do.
175
     */
176
1.11k
    break;
177
10.0k
  }
178
10.0k
}
179
180
/*
181
 * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
182
 * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
183
 * with the CAN ID being in host byte order.
184
 *
185
 * When reading a DLT_LINUX_SLL packet, we need to check for those
186
 * packets and convert the CAN ID from the byte order of the host that
187
 * wrote the file to this host's byte order.
188
 */
189
static void
190
swap_linux_sll_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
191
8.36k
{
192
8.36k
  u_int caplen = hdr->caplen;
193
8.36k
  u_int length = hdr->len;
194
8.36k
  struct sll_header *shdr = (struct sll_header *)buf;
195
196
8.36k
  if (caplen < (u_int) sizeof(struct sll_header) ||
197
5.88k
      length < (u_int) sizeof(struct sll_header)) {
198
    /* Not enough data to have the protocol field */
199
2.88k
    return;
200
2.88k
  }
201
202
  /*
203
   * Byte-swap what needs to be byte-swapped.
204
   */
205
5.48k
  swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll_protocol),
206
5.48k
      caplen - (u_int) sizeof(struct sll_header),
207
5.48k
      length - (u_int) sizeof(struct sll_header),
208
5.48k
      buf + sizeof(struct sll_header));
209
5.48k
}
210
211
/*
212
 * The same applies for DLT_LINUX_SLL2.
213
 */
214
static void
215
swap_linux_sll2_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
216
5.79k
{
217
5.79k
  u_int caplen = hdr->caplen;
218
5.79k
  u_int length = hdr->len;
219
5.79k
  struct sll2_header *shdr = (struct sll2_header *)buf;
220
221
5.79k
  if (caplen < (u_int) sizeof(struct sll2_header) ||
222
4.93k
      length < (u_int) sizeof(struct sll2_header)) {
223
    /* Not enough data to have the protocol field */
224
1.25k
    return;
225
1.25k
  }
226
227
  /*
228
   * Byte-swap what needs to be byte-swapped.
229
   */
230
4.54k
  swap_socketcan_header(EXTRACT_BE_U_2(&shdr->sll2_protocol),
231
4.54k
      caplen - (u_int) sizeof(struct sll2_header),
232
4.54k
      length - (u_int) sizeof(struct sll2_header),
233
4.54k
      buf + sizeof(struct sll2_header));
234
4.54k
}
235
236
/*
237
 * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
238
 * byte order when capturing (it's supplied directly from a
239
 * memory-mapped buffer shared by the kernel).
240
 *
241
 * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we
242
 * need to convert it from the byte order of the host that wrote the
243
 * file to this host's byte order.
244
 */
245
static void
246
swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
247
    int header_len_64_bytes)
248
19.3k
{
249
19.3k
  pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
250
19.3k
  bpf_u_int32 offset = 0;
251
252
  /*
253
   * "offset" is the offset *past* the field we're swapping;
254
   * we skip the field *before* checking to make sure
255
   * the captured data length includes the entire field.
256
   */
257
258
  /*
259
   * The URB id is a totally opaque value; do we really need to
260
   * convert it to the reading host's byte order???
261
   */
262
19.3k
  offset += 8;      /* skip past id */
263
19.3k
  if (hdr->caplen < offset)
264
2.61k
    return;
265
16.7k
  uhdr->id = SWAPLL(uhdr->id);
266
267
16.7k
  offset += 4;      /* skip past various 1-byte fields */
268
269
16.7k
  offset += 2;      /* skip past bus_id */
270
16.7k
  if (hdr->caplen < offset)
271
841
    return;
272
15.8k
  uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
273
274
15.8k
  offset += 2;      /* skip past various 1-byte fields */
275
276
15.8k
  offset += 8;      /* skip past ts_sec */
277
15.8k
  if (hdr->caplen < offset)
278
892
    return;
279
14.9k
  uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
280
281
14.9k
  offset += 4;      /* skip past ts_usec */
282
14.9k
  if (hdr->caplen < offset)
283
786
    return;
284
14.2k
  uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
285
286
14.2k
  offset += 4;      /* skip past status */
287
14.2k
  if (hdr->caplen < offset)
288
796
    return;
289
13.4k
  uhdr->status = SWAPLONG(uhdr->status);
290
291
13.4k
  offset += 4;      /* skip past urb_len */
292
13.4k
  if (hdr->caplen < offset)
293
785
    return;
294
12.6k
  uhdr->urb_len = SWAPLONG(uhdr->urb_len);
295
296
12.6k
  offset += 4;      /* skip past data_len */
297
12.6k
  if (hdr->caplen < offset)
298
784
    return;
299
11.8k
  uhdr->data_len = SWAPLONG(uhdr->data_len);
300
301
11.8k
  if (uhdr->transfer_type == URB_ISOCHRONOUS) {
302
9.73k
    offset += 4;      /* skip past s.iso.error_count */
303
9.73k
    if (hdr->caplen < offset)
304
791
      return;
305
8.94k
    uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
306
307
8.94k
    offset += 4;      /* skip past s.iso.numdesc */
308
8.94k
    if (hdr->caplen < offset)
309
787
      return;
310
8.15k
    uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
311
8.15k
  } else
312
2.10k
    offset += 8;      /* skip USB setup header */
313
314
  /*
315
   * With the old header, there are no isochronous descriptors
316
   * after the header.
317
   *
318
   * With the new header, the actual number of descriptors in
319
   * the header is not s.iso.numdesc, it's ndesc - only the
320
   * first N descriptors, for some value of N, are put into
321
   * the header, and ndesc is set to the actual number copied.
322
   * In addition, if s.iso.numdesc is negative, no descriptors
323
   * are captured, and ndesc is set to 0.
324
   */
325
10.2k
  if (header_len_64_bytes) {
326
    /*
327
     * This is either the "version 1" header, with
328
     * 16 bytes of additional fields at the end, or
329
     * a "version 0" header from a memory-mapped
330
     * capture, with 16 bytes of zeroed-out padding
331
     * at the end.  Byte swap them as if this were
332
     * a "version 1" header.
333
     */
334
9.36k
    offset += 4;      /* skip past interval */
335
9.36k
    if (hdr->caplen < offset)
336
659
      return;
337
8.70k
    uhdr->interval = SWAPLONG(uhdr->interval);
338
339
8.70k
    offset += 4;      /* skip past start_frame */
340
8.70k
    if (hdr->caplen < offset)
341
392
      return;
342
8.31k
    uhdr->start_frame = SWAPLONG(uhdr->start_frame);
343
344
8.31k
    offset += 4;      /* skip past xfer_flags */
345
8.31k
    if (hdr->caplen < offset)
346
393
      return;
347
7.92k
    uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
348
349
7.92k
    offset += 4;      /* skip past ndesc */
350
7.92k
    if (hdr->caplen < offset)
351
444
      return;
352
7.48k
    uhdr->ndesc = SWAPLONG(uhdr->ndesc);
353
354
7.48k
    if (uhdr->transfer_type == URB_ISOCHRONOUS) {
355
      /* swap the values in struct linux_usb_isodesc */
356
6.40k
      usb_isodesc *pisodesc;
357
6.40k
      uint32_t i;
358
359
6.40k
      pisodesc = (usb_isodesc *)(void *)(buf+offset);
360
58.6k
      for (i = 0; i < uhdr->ndesc; i++) {
361
54.6k
        offset += 4;    /* skip past status */
362
54.6k
        if (hdr->caplen < offset)
363
1.18k
          return;
364
53.4k
        pisodesc->status = SWAPLONG(pisodesc->status);
365
366
53.4k
        offset += 4;    /* skip past offset */
367
53.4k
        if (hdr->caplen < offset)
368
668
          return;
369
52.7k
        pisodesc->offset = SWAPLONG(pisodesc->offset);
370
371
52.7k
        offset += 4;    /* skip past len */
372
52.7k
        if (hdr->caplen < offset)
373
564
          return;
374
52.2k
        pisodesc->len = SWAPLONG(pisodesc->len);
375
376
52.2k
        offset += 4;    /* skip past padding */
377
378
52.2k
        pisodesc++;
379
52.2k
      }
380
6.40k
    }
381
7.48k
  }
382
10.2k
}
383
384
/*
385
 * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
386
 * data.  They begin with a fixed-length header with big-endian fields,
387
 * followed by a set of TLVs, where the type and length are in host
388
 * byte order but the values are either big-endian or are a raw byte
389
 * sequence that's the same regardless of the host's byte order.
390
 *
391
 * When reading a DLT_NFLOG packet, we need to convert the type and
392
 * length values from the byte order of the host that wrote the file
393
 * to the byte order of this host.
394
 */
395
static void
396
swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
397
4.78k
{
398
4.78k
  u_char *p = buf;
399
4.78k
  nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
400
4.78k
  nflog_tlv_t *tlv;
401
4.78k
  u_int caplen = hdr->caplen;
402
4.78k
  u_int length = hdr->len;
403
4.78k
  u_int size;
404
405
4.78k
  if (caplen < (u_int) sizeof(nflog_hdr_t) ||
406
4.07k
      length < (u_int) sizeof(nflog_hdr_t)) {
407
    /* Not enough data to have any TLVs. */
408
1.09k
    return;
409
1.09k
  }
410
411
3.68k
  if (nfhdr->nflog_version != 0) {
412
    /* Unknown NFLOG version */
413
542
    return;
414
542
  }
415
416
3.14k
  length -= sizeof(nflog_hdr_t);
417
3.14k
  caplen -= sizeof(nflog_hdr_t);
418
3.14k
  p += sizeof(nflog_hdr_t);
419
420
4.32k
  while (caplen >= sizeof(nflog_tlv_t)) {
421
2.97k
    tlv = (nflog_tlv_t *) p;
422
423
    /* Swap the type and length. */
424
2.97k
    tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
425
2.97k
    tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
426
427
    /* Get the length of the TLV. */
428
2.97k
    size = tlv->tlv_length;
429
2.97k
    if (size % 4 != 0)
430
1.00k
      size += 4 - size % 4;
431
432
    /* Is the TLV's length less than the minimum? */
433
2.97k
    if (size < sizeof(nflog_tlv_t)) {
434
      /* Yes. Give up now. */
435
1.06k
      return;
436
1.06k
    }
437
438
    /* Do we have enough data for the full TLV? */
439
1.91k
    if (caplen < size || length < size) {
440
      /* No. */
441
733
      return;
442
733
    }
443
444
    /* Skip over the TLV. */
445
1.18k
    length -= size;
446
1.18k
    caplen -= size;
447
1.18k
    p += size;
448
1.18k
  }
449
3.14k
}
450
451
static void
452
swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
453
50.9k
{
454
  /*
455
   * Convert pseudo-headers from the byte order of
456
   * the host on which the file was saved to our
457
   * byte order, as necessary.
458
   */
459
50.9k
  switch (linktype) {
460
461
5.71k
  case DLT_PFLOG:
462
5.71k
    swap_pflog_header(hdr, data);
463
5.71k
    break;
464
465
8.36k
  case DLT_LINUX_SLL:
466
8.36k
    swap_linux_sll_socketcan_header(hdr, data);
467
8.36k
    break;
468
469
5.79k
  case DLT_LINUX_SLL2:
470
5.79k
    swap_linux_sll2_socketcan_header(hdr, data);
471
5.79k
    break;
472
473
4.91k
  case DLT_USB_LINUX:
474
4.91k
    swap_linux_usb_header(hdr, data, 0);
475
4.91k
    break;
476
477
14.4k
  case DLT_USB_LINUX_MMAPPED:
478
14.4k
    swap_linux_usb_header(hdr, data, 1);
479
14.4k
    break;
480
481
4.78k
  case DLT_NFLOG:
482
4.78k
    swap_nflog_header(hdr, data);
483
4.78k
    break;
484
50.9k
  }
485
50.9k
}
486
487
static inline int
488
packet_length_might_be_wrong(struct pcap_pkthdr *hdr,
489
    const pcap_usb_header_mmapped *usb_hdr)
490
4.14k
{
491
4.14k
  uint32_t old_style_packet_length;
492
493
  /*
494
   * Calculate the packet length the old way.
495
   * We know that the multiplication won't overflow, but
496
   * we don't know that the additions won't.  Calculate
497
   * it with no overflow checks, as that's how it
498
   * would have been calculated when it was captured.
499
   */
500
4.14k
  old_style_packet_length = iso_pseudo_header_len(usb_hdr) +
501
4.14k
      usb_hdr->urb_len;
502
4.14k
  return (hdr->len == old_style_packet_length);
503
4.14k
}
504
505
void
506
pcapint_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr,
507
    u_char *data)
508
55.8k
{
509
55.8k
  if (swapped)
510
50.9k
    swap_pseudo_headers(linktype, hdr, data);
511
512
  /*
513
   * Is this a memory-mapped Linux USB capture?
514
   */
515
55.8k
  if (linktype == DLT_USB_LINUX_MMAPPED) {
516
    /*
517
     * Yes.
518
     *
519
     * In older versions of libpcap, in memory-mapped Linux
520
     * USB captures, the original length of completion events
521
     * for incoming isochronous transfers was miscalculated;
522
     * it needed to be calculated based on the offsets and
523
     * lengths in the descriptors, not on the raw URB length,
524
     * but it wasn't.
525
     *
526
     * If this packet contains transferred data (yes, data_flag
527
     * is 0 if we *do* have data), it's a completion event
528
     * for an incoming isochronous transfer, and the
529
     * transfer length appears to have been calculated
530
     * from the raw URB length, fix it.
531
     *
532
     * We only do this if we have the full USB pseudo-header,
533
     * because we will have to look at that header and at
534
     * all of the isochronous descriptors.
535
     */
536
14.4k
    if (hdr->caplen < sizeof (pcap_usb_header_mmapped)) {
537
      /*
538
       * We don't have the full pseudo-header.
539
       */
540
6.94k
      return;
541
6.94k
    }
542
543
7.50k
    const pcap_usb_header_mmapped *usb_hdr =
544
7.50k
        (const pcap_usb_header_mmapped *) data;
545
546
    /*
547
     * Make sure the number of descriptors is sane.
548
     *
549
     * The Linux binary USB monitor code limits the number of
550
     * isochronous descriptors to 128; if the number in the file
551
     * is larger than that, either 1) the file's been damaged
552
     * or 2) the file was produced after the number was raised
553
     * in the kernel.
554
     *
555
     * In case 1), the number can't be trusted, so don't rely on
556
     * it to attempt to fix the original length field in the pcap
557
     * or pcapng header.
558
     *
559
     * In case 2), the system was probably running a version of
560
     * libpcap that didn't miscalculate the original length, so
561
     * it probably doesn't need to be fixed.
562
     *
563
     * This avoids the possibility of the product of the number of
564
     * descriptors and the size of descriptors won't overflow an
565
     * unsigned 32-bit integer.
566
     */
567
7.50k
    if (usb_hdr->ndesc > USB_MAXDESC)
568
1.57k
      return;
569
570
5.93k
    if (!usb_hdr->data_flag &&
571
5.29k
        is_isochronous_transfer_completion(usb_hdr) &&
572
4.14k
        packet_length_might_be_wrong(hdr, usb_hdr)) {
573
2.90k
      u_int len;
574
575
      /*
576
       * Make sure we have all of the descriptors,
577
       * as we will have to look at all of them.
578
       *
579
       * If not, we don't bother trying to fix
580
       * anything.
581
       */
582
2.90k
      if (hdr->caplen < iso_pseudo_header_len(usb_hdr))
583
677
        return;
584
585
      /*
586
       * Calculate what the length should have been.
587
       */
588
2.22k
      len = incoming_isochronous_transfer_completed_len(hdr,
589
2.22k
          data);
590
591
      /*
592
       * len is the smaller of UINT_MAX and the total
593
       * header plus data length.  That's guaranteed
594
       * to fit in a UINT_MAX.
595
       *
596
       * Don't reduce the original length to a value
597
       * below the captured length, however, as that
598
       * is bogus.
599
       */
600
2.22k
      if (len >= hdr->caplen)
601
1.86k
        hdr->len = len;
602
603
      /*
604
       * If the captured length is greater than the
605
       * length, use the captured length.
606
       *
607
       * For completion events for incoming isochronous
608
       * transfers, it's based on data_len, which is
609
       * calculated the same way we calculated
610
       * pre_truncation_data_len above, except that
611
       * it has access to all the isochronous descriptors,
612
       * not just the ones that the kernel were able to
613
       * provide us or, for a capture file, that weren't
614
       * sliced off by a snapshot length.
615
       *
616
       * However, it might have been reduced by the USB
617
       * capture mechanism arbitrarily limiting the amount
618
       * of data it provides to userland, or by the libpcap
619
       * capture code limiting it to being no more than the
620
       * snapshot, so we don't want to just use it all the
621
       * time; we only do so to try to get a better estimate
622
       * of the actual length - and to make sure the
623
       * original length is always >= the captured length.
624
       */
625
2.22k
      if (hdr->caplen > hdr->len)
626
338
        hdr->len = hdr->caplen;
627
2.22k
    }
628
5.93k
  }
629
55.8k
}