Coverage Report

Created: 2024-07-23 06:08

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