Coverage Report

Created: 2023-06-07 06:26

/src/libpcap/sf-pcap.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
 * sf-pcap.c - libpcap-file-format-specific code from savefile.c
22
 *  Extraction/creation by Jeffrey Mogul, DECWRL
23
 *  Modified by Steve McCanne, LBL.
24
 *
25
 * Used to save the received packet headers, after filtering, to
26
 * a file, and then read them later.
27
 * The first record in the file contains saved values for the machine
28
 * dependent values so we can print the dump file on any architecture.
29
 */
30
31
#ifdef HAVE_CONFIG_H
32
#include <config.h>
33
#endif
34
35
#include <pcap-types.h>
36
#ifdef _WIN32
37
#include <io.h>
38
#include <fcntl.h>
39
#endif /* _WIN32 */
40
41
#include <errno.h>
42
#include <memory.h>
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
#include <limits.h> /* for INT_MAX */
47
48
#include "pcap-int.h"
49
#include "pcap-util.h"
50
51
#include "pcap-common.h"
52
53
#ifdef HAVE_OS_PROTO_H
54
#include "os-proto.h"
55
#endif
56
57
#include "sf-pcap.h"
58
59
/*
60
 * Setting O_BINARY on DOS/Windows is a bit tricky
61
 */
62
#if defined(_WIN32)
63
  #define SET_BINMODE(f)  _setmode(_fileno(f), _O_BINARY)
64
#elif defined(MSDOS)
65
  #if defined(__HIGHC__)
66
  #define SET_BINMODE(f)  setmode(f, O_BINARY)
67
  #else
68
  #define SET_BINMODE(f)  setmode(fileno(f), O_BINARY)
69
  #endif
70
#endif
71
72
/*
73
 * Standard libpcap format.
74
 *
75
 * The same value is used in the rpcap protocol as an indication of
76
 * the server byte order, to let the client know whether it needs to
77
 * byte-swap some host-byte-order metadata.
78
 */
79
16.2k
#define TCPDUMP_MAGIC   0xa1b2c3d4
80
81
/*
82
 * Alexey Kuznetzov's modified libpcap format.
83
 */
84
17.3k
#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
85
86
/*
87
 * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
88
 * for another modified format.
89
 */
90
#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
91
92
/*
93
 * Navtel Communcations' format, with nanosecond timestamps,
94
 * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
95
 */
96
0
#define NAVTEL_TCPDUMP_MAGIC  0xa12b3c4d
97
98
/*
99
 * Normal libpcap format, except for seconds/nanoseconds timestamps,
100
 * as per a request by Ulf Lamping <ulf.lamping@web.de>
101
 */
102
9.15k
#define NSEC_TCPDUMP_MAGIC  0xa1b23c4d
103
104
/*
105
 * Used for identification of cbpf-savefile(5).
106
 */
107
#define CBPF_SAVEFILE_MAGIC 0xa1b2c3cb
108
109
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
110
111
#ifdef _WIN32
112
/*
113
 * This isn't exported on Windows, because it would only work if both
114
 * libpcap and the code using it were using the same C runtime; otherwise they
115
 * would be using different definitions of a FILE structure.
116
 *
117
 * Instead we define this as a macro in pcap/pcap.h that wraps the hopen
118
 * version that we do export, passing it a raw OS HANDLE, as defined by the
119
 * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
120
 * functions of the appropriate CRT.
121
 */
122
static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f);
123
#endif /* _WIN32 */
124
125
/*
126
 * Private data for reading pcap savefiles.
127
 */
128
typedef enum {
129
  NOT_SWAPPED,
130
  SWAPPED,
131
  MAYBE_SWAPPED
132
} swapped_type_t;
133
134
typedef enum {
135
  PASS_THROUGH,
136
  SCALE_UP,
137
  SCALE_DOWN
138
} tstamp_scale_type_t;
139
140
struct pcap_sf {
141
  size_t hdrsize;
142
  swapped_type_t lengths_swapped;
143
  tstamp_scale_type_t scale_type;
144
};
145
146
/*
147
 * Check whether this is a pcap savefile and, if it is, extract the
148
 * relevant information from the header.
149
 */
150
pcap_t *
151
pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
152
      int *err)
153
4.09k
{
154
4.09k
  bpf_u_int32 magic_int;
155
4.09k
  struct pcap_file_header hdr;
156
4.09k
  size_t amt_read;
157
4.09k
  pcap_t *p;
158
4.09k
  int swapped = 0;
159
4.09k
  struct pcap_sf *ps;
160
161
  /*
162
   * Assume no read errors.
163
   */
164
4.09k
  *err = 0;
165
166
  /*
167
   * Check whether the first 4 bytes of the file are the magic
168
   * number for a pcap savefile, or for a byte-swapped pcap
169
   * savefile.
170
   */
171
4.09k
  memcpy(&magic_int, magic, sizeof(magic_int));
172
4.09k
  if (magic_int != TCPDUMP_MAGIC &&
173
4.09k
      magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
174
4.09k
      magic_int != NSEC_TCPDUMP_MAGIC) {
175
4.00k
    magic_int = SWAPLONG(magic_int);
176
4.00k
    if (magic_int != TCPDUMP_MAGIC &&
177
4.00k
        magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
178
4.00k
        magic_int != NSEC_TCPDUMP_MAGIC)
179
1.63k
      return (NULL);  /* nope */
180
2.37k
    swapped = 1;
181
2.37k
  }
182
183
  /*
184
   * They are.  Put the magic number in the header, and read
185
   * the rest of the header.
186
   */
187
2.45k
  hdr.magic = magic_int;
188
2.45k
  amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
189
2.45k
      sizeof(hdr) - sizeof(hdr.magic), fp);
190
2.45k
  if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
191
14
    if (ferror(fp)) {
192
0
      pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
193
0
          errno, "error reading dump file");
194
14
    } else {
195
14
      snprintf(errbuf, PCAP_ERRBUF_SIZE,
196
14
          "truncated dump file; tried to read %zu file header bytes, only got %zu",
197
14
          sizeof(hdr), amt_read);
198
14
    }
199
14
    *err = 1;
200
14
    return (NULL);
201
14
  }
202
203
  /*
204
   * If it's a byte-swapped capture file, byte-swap the header.
205
   */
206
2.44k
  if (swapped) {
207
2.36k
    hdr.version_major = SWAPSHORT(hdr.version_major);
208
2.36k
    hdr.version_minor = SWAPSHORT(hdr.version_minor);
209
2.36k
    hdr.thiszone = SWAPLONG(hdr.thiszone);
210
2.36k
    hdr.sigfigs = SWAPLONG(hdr.sigfigs);
211
2.36k
    hdr.snaplen = SWAPLONG(hdr.snaplen);
212
2.36k
    hdr.linktype = SWAPLONG(hdr.linktype);
213
2.36k
  }
214
215
2.44k
  if (hdr.version_major < PCAP_VERSION_MAJOR) {
216
2
    snprintf(errbuf, PCAP_ERRBUF_SIZE,
217
2
        "archaic pcap savefile format");
218
2
    *err = 1;
219
2
    return (NULL);
220
2
  }
221
222
  /*
223
   * currently only versions 2.[0-4] are supported with
224
   * the exception of 543.0 for DG/UX tcpdump.
225
   */
226
2.43k
  if (! ((hdr.version_major == PCAP_VERSION_MAJOR &&
227
2.43k
    hdr.version_minor <= PCAP_VERSION_MINOR) ||
228
2.43k
         (hdr.version_major == 543 &&
229
77
    hdr.version_minor == 0))) {
230
58
    snprintf(errbuf, PCAP_ERRBUF_SIZE,
231
58
       "unsupported pcap savefile version %u.%u",
232
58
       hdr.version_major, hdr.version_minor);
233
58
    *err = 1;
234
58
    return NULL;
235
58
  }
236
237
  /*
238
   * Check the main reserved field.
239
   */
240
2.38k
  if (LT_RESERVED1(hdr.linktype) != 0) {
241
10
    snprintf(errbuf, PCAP_ERRBUF_SIZE,
242
10
       "savefile linktype reserved field not zero (0x%08x)",
243
10
       LT_RESERVED1(hdr.linktype));
244
10
    *err = 1;
245
10
    return NULL;
246
10
  }
247
248
  /*
249
   * OK, this is a good pcap file.
250
   * Allocate a pcap_t for it.
251
   */
252
2.37k
  p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
253
2.37k
  if (p == NULL) {
254
    /* Allocation failed. */
255
0
    *err = 1;
256
0
    return (NULL);
257
0
  }
258
2.37k
  p->swapped = swapped;
259
2.37k
  p->version_major = hdr.version_major;
260
2.37k
  p->version_minor = hdr.version_minor;
261
2.37k
  p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
262
2.37k
  p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
263
2.37k
  p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
264
265
2.37k
  p->next_packet_op = pcap_next_packet;
266
267
2.37k
  ps = p->priv;
268
269
2.37k
  p->opt.tstamp_precision = precision;
270
271
  /*
272
   * Will we need to scale the timestamps to match what the
273
   * user wants?
274
   */
275
2.37k
  switch (precision) {
276
277
2.37k
  case PCAP_TSTAMP_PRECISION_MICRO:
278
2.37k
    if (magic_int == NSEC_TCPDUMP_MAGIC) {
279
      /*
280
       * The file has nanoseconds, the user
281
       * wants microseconds; scale the
282
       * precision down.
283
       */
284
1.10k
      ps->scale_type = SCALE_DOWN;
285
1.26k
    } else {
286
      /*
287
       * The file has microseconds, the
288
       * user wants microseconds; nothing to do.
289
       */
290
1.26k
      ps->scale_type = PASS_THROUGH;
291
1.26k
    }
292
2.37k
    break;
293
294
0
  case PCAP_TSTAMP_PRECISION_NANO:
295
0
    if (magic_int == NSEC_TCPDUMP_MAGIC) {
296
      /*
297
       * The file has nanoseconds, the
298
       * user wants nanoseconds; nothing to do.
299
       */
300
0
      ps->scale_type = PASS_THROUGH;
301
0
    } else {
302
      /*
303
       * The file has microseconds, the user
304
       * wants nanoseconds; scale the
305
       * precision up.
306
       */
307
0
      ps->scale_type = SCALE_UP;
308
0
    }
309
0
    break;
310
311
0
  default:
312
0
    snprintf(errbuf, PCAP_ERRBUF_SIZE,
313
0
        "unknown time stamp resolution %u", precision);
314
0
    free(p);
315
0
    *err = 1;
316
0
    return (NULL);
317
2.37k
  }
318
319
  /*
320
   * We interchanged the caplen and len fields at version 2.3,
321
   * in order to match the bpf header layout.  But unfortunately
322
   * some files were written with version 2.3 in their headers
323
   * but without the interchanged fields.
324
   *
325
   * In addition, DG/UX tcpdump writes out files with a version
326
   * number of 543.0, and with the caplen and len fields in the
327
   * pre-2.3 order.
328
   */
329
2.37k
  switch (hdr.version_major) {
330
331
2.35k
  case 2:
332
2.35k
    if (hdr.version_minor < 3)
333
671
      ps->lengths_swapped = SWAPPED;
334
1.68k
    else if (hdr.version_minor == 3)
335
1.29k
      ps->lengths_swapped = MAYBE_SWAPPED;
336
390
    else
337
390
      ps->lengths_swapped = NOT_SWAPPED;
338
2.35k
    break;
339
340
18
  case 543:
341
18
    ps->lengths_swapped = SWAPPED;
342
18
    break;
343
344
0
  default:
345
0
    ps->lengths_swapped = NOT_SWAPPED;
346
0
    break;
347
2.37k
  }
348
349
2.37k
  if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
350
    /*
351
     * XXX - the patch that's in some versions of libpcap
352
     * changes the packet header but not the magic number,
353
     * and some other versions with this magic number have
354
     * some extra debugging information in the packet header;
355
     * we'd have to use some hacks^H^H^H^H^Hheuristics to
356
     * detect those variants.
357
     *
358
     * Ethereal does that, but it does so by trying to read
359
     * the first two packets of the file with each of the
360
     * record header formats.  That currently means it seeks
361
     * backwards and retries the reads, which doesn't work
362
     * on pipes.  We want to be able to read from a pipe, so
363
     * that strategy won't work; we'd have to buffer some
364
     * data ourselves and read from that buffer in order to
365
     * make that work.
366
     */
367
82
    ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
368
369
82
    if (p->linktype == DLT_EN10MB) {
370
      /*
371
       * This capture might have been done in raw mode
372
       * or cooked mode.
373
       *
374
       * If it was done in cooked mode, p->snapshot was
375
       * passed to recvfrom() as the buffer size, meaning
376
       * that the most packet data that would be copied
377
       * would be p->snapshot.  However, a faked Ethernet
378
       * header would then have been added to it, so the
379
       * most data that would be in a packet in the file
380
       * would be p->snapshot + 14.
381
       *
382
       * We can't easily tell whether the capture was done
383
       * in raw mode or cooked mode, so we'll assume it was
384
       * cooked mode, and add 14 to the snapshot length.
385
       * That means that, for a raw capture, the snapshot
386
       * length will be misleading if you use it to figure
387
       * out why a capture doesn't have all the packet data,
388
       * but there's not much we can do to avoid that.
389
       *
390
       * But don't grow the snapshot length past the
391
       * maximum value of an int.
392
       */
393
57
      if (p->snapshot <= INT_MAX - 14)
394
55
        p->snapshot += 14;
395
2
      else
396
2
        p->snapshot = INT_MAX;
397
57
    }
398
82
  } else
399
2.28k
    ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
400
401
  /*
402
   * Allocate a buffer for the packet data.
403
   * Choose the minimum of the file's snapshot length and 2K bytes;
404
   * that should be enough for most network packets - we'll grow it
405
   * if necessary.  That way, we don't allocate a huge chunk of
406
   * memory just because there's a huge snapshot length, as the
407
   * snapshot length might be larger than the size of the largest
408
   * packet.
409
   */
410
2.37k
  p->bufsize = p->snapshot;
411
2.37k
  if (p->bufsize > 2048)
412
2.18k
    p->bufsize = 2048;
413
2.37k
  p->buffer = malloc(p->bufsize);
414
2.37k
  if (p->buffer == NULL) {
415
0
    snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
416
0
    free(p);
417
0
    *err = 1;
418
0
    return (NULL);
419
0
  }
420
421
2.37k
  p->cleanup_op = pcap_sf_cleanup;
422
423
2.37k
  return (p);
424
2.37k
}
425
426
/*
427
 * Grow the packet buffer to the specified size.
428
 */
429
static int
430
grow_buffer(pcap_t *p, u_int bufsize)
431
1.51k
{
432
1.51k
  void *bigger_buffer;
433
434
1.51k
  bigger_buffer = realloc(p->buffer, bufsize);
435
1.51k
  if (bigger_buffer == NULL) {
436
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
437
0
    return (0);
438
0
  }
439
1.51k
  p->buffer = bigger_buffer;
440
1.51k
  p->bufsize = bufsize;
441
1.51k
  return (1);
442
1.51k
}
443
444
/*
445
 * Read and return the next packet from the savefile.  Return the header
446
 * in hdr and a pointer to the contents in data.  Return 1 on success, 0
447
 * if there were no more packets, and -1 on an error.
448
 */
449
static int
450
pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
451
19.8k
{
452
19.8k
  struct pcap_sf *ps = p->priv;
453
19.8k
  struct pcap_sf_patched_pkthdr sf_hdr;
454
19.8k
  FILE *fp = p->rfile;
455
19.8k
  size_t amt_read;
456
19.8k
  bpf_u_int32 t;
457
458
  /*
459
   * Read the packet header; the structure we use as a buffer
460
   * is the longer structure for files generated by the patched
461
   * libpcap, but if the file has the magic number for an
462
   * unpatched libpcap we only read as many bytes as the regular
463
   * header has.
464
   */
465
19.8k
  amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
466
19.8k
  if (amt_read != ps->hdrsize) {
467
2.08k
    if (ferror(fp)) {
468
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
469
0
          errno, "error reading dump file");
470
0
      return (-1);
471
2.08k
    } else {
472
2.08k
      if (amt_read != 0) {
473
22
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
474
22
            "truncated dump file; tried to read %zu header bytes, only got %zu",
475
22
            ps->hdrsize, amt_read);
476
22
        return (-1);
477
22
      }
478
      /* EOF */
479
2.06k
      return (0);
480
2.08k
    }
481
2.08k
  }
482
483
17.7k
  if (p->swapped) {
484
    /* these were written in opposite byte order */
485
17.5k
    hdr->caplen = SWAPLONG(sf_hdr.caplen);
486
17.5k
    hdr->len = SWAPLONG(sf_hdr.len);
487
17.5k
    hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
488
17.5k
    hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
489
17.5k
  } else {
490
245
    hdr->caplen = sf_hdr.caplen;
491
245
    hdr->len = sf_hdr.len;
492
245
    hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
493
245
    hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
494
245
  }
495
496
17.7k
  switch (ps->scale_type) {
497
498
8.64k
  case PASS_THROUGH:
499
    /*
500
     * Just pass the time stamp through.
501
     */
502
8.64k
    break;
503
504
0
  case SCALE_UP:
505
    /*
506
     * File has microseconds, user wants nanoseconds; convert
507
     * it.
508
     */
509
0
    hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
510
0
    break;
511
512
9.14k
  case SCALE_DOWN:
513
    /*
514
     * File has nanoseconds, user wants microseconds; convert
515
     * it.
516
     */
517
9.14k
    hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
518
9.14k
    break;
519
17.7k
  }
520
521
  /* Swap the caplen and len fields, if necessary. */
522
17.7k
  switch (ps->lengths_swapped) {
523
524
3.36k
  case NOT_SWAPPED:
525
3.36k
    break;
526
527
10.0k
  case MAYBE_SWAPPED:
528
10.0k
    if (hdr->caplen <= hdr->len) {
529
      /*
530
       * The captured length is <= the actual length,
531
       * so presumably they weren't swapped.
532
       */
533
7.15k
      break;
534
7.15k
    }
535
    /* FALLTHROUGH */
536
537
7.26k
  case SWAPPED:
538
7.26k
    t = hdr->caplen;
539
7.26k
    hdr->caplen = hdr->len;
540
7.26k
    hdr->len = t;
541
7.26k
    break;
542
17.7k
  }
543
544
  /*
545
   * Is the packet bigger than we consider sane?
546
   */
547
17.7k
  if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) {
548
    /*
549
     * Yes.  This may be a damaged or fuzzed file.
550
     *
551
     * Is it bigger than the snapshot length?
552
     * (We don't treat that as an error if it's not
553
     * bigger than the maximum we consider sane; see
554
     * below.)
555
     */
556
78
    if (hdr->caplen > (bpf_u_int32)p->snapshot) {
557
62
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
558
62
          "invalid packet capture length %u, bigger than "
559
62
          "snaplen of %d", hdr->caplen, p->snapshot);
560
62
    } else {
561
16
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
562
16
          "invalid packet capture length %u, bigger than "
563
16
          "maximum of %u", hdr->caplen,
564
16
          max_snaplen_for_dlt(p->linktype));
565
16
    }
566
78
    return (-1);
567
78
  }
568
569
17.7k
  if (hdr->caplen > (bpf_u_int32)p->snapshot) {
570
    /*
571
     * The packet is bigger than the snapshot length
572
     * for this file.
573
     *
574
     * This can happen due to Solaris 2.3 systems tripping
575
     * over the BUFMOD problem and not setting the snapshot
576
     * length correctly in the savefile header.
577
     *
578
     * libpcap 0.4 and later on Solaris 2.3 should set the
579
     * snapshot length correctly in the pcap file header,
580
     * even though they don't set a snapshot length in bufmod
581
     * (the buggy bufmod chops off the *beginning* of the
582
     * packet if a snapshot length is specified); they should
583
     * also reduce the captured length, as supplied to the
584
     * per-packet callback, to the snapshot length if it's
585
     * greater than the snapshot length, so the code using
586
     * libpcap should see the packet cut off at the snapshot
587
     * length, even though the full packet is copied up to
588
     * userland.
589
     *
590
     * However, perhaps some versions of libpcap failed to
591
     * set the snapshot length correctly in the file header
592
     * or the per-packet header, or perhaps this is a
593
     * corrupted safefile or a savefile built/modified by a
594
     * fuzz tester, so we check anyway.  We grow the buffer
595
     * to be big enough for the snapshot length, read up
596
     * to the snapshot length, discard the rest of the
597
     * packet, and report the snapshot length as the captured
598
     * length; we don't want to hand our caller a packet
599
     * bigger than the snapshot length, because they might
600
     * be assuming they'll never be handed such a packet,
601
     * and might copy the packet into a snapshot-length-
602
     * sized buffer, assuming it'll fit.
603
     */
604
1.26k
    size_t bytes_to_discard;
605
1.26k
    size_t bytes_to_read, bytes_read;
606
1.26k
    char discard_buf[4096];
607
608
1.26k
    if (hdr->caplen > p->bufsize) {
609
      /*
610
       * Grow the buffer to the snapshot length.
611
       */
612
1.26k
      if (!grow_buffer(p, p->snapshot))
613
0
        return (-1);
614
1.26k
    }
615
616
    /*
617
     * Read the first p->snapshot bytes into the buffer.
618
     */
619
1.26k
    amt_read = fread(p->buffer, 1, p->snapshot, fp);
620
1.26k
    if (amt_read != (bpf_u_int32)p->snapshot) {
621
65
      if (ferror(fp)) {
622
0
        pcap_fmt_errmsg_for_errno(p->errbuf,
623
0
             PCAP_ERRBUF_SIZE, errno,
624
0
            "error reading dump file");
625
65
      } else {
626
        /*
627
         * Yes, this uses hdr->caplen; technically,
628
         * it's true, because we would try to read
629
         * and discard the rest of those bytes, and
630
         * that would fail because we got EOF before
631
         * the read finished.
632
         */
633
65
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
634
65
            "truncated dump file; tried to read %d captured bytes, only got %zu",
635
65
            p->snapshot, amt_read);
636
65
      }
637
65
      return (-1);
638
65
    }
639
640
    /*
641
     * Now read and discard what's left.
642
     */
643
1.20k
    bytes_to_discard = hdr->caplen - p->snapshot;
644
1.20k
    bytes_read = amt_read;
645
2.39k
    while (bytes_to_discard != 0) {
646
1.24k
      bytes_to_read = bytes_to_discard;
647
1.24k
      if (bytes_to_read > sizeof (discard_buf))
648
64
        bytes_to_read = sizeof (discard_buf);
649
1.24k
      amt_read = fread(discard_buf, 1, bytes_to_read, fp);
650
1.24k
      bytes_read += amt_read;
651
1.24k
      if (amt_read != bytes_to_read) {
652
42
        if (ferror(fp)) {
653
0
          pcap_fmt_errmsg_for_errno(p->errbuf,
654
0
              PCAP_ERRBUF_SIZE, errno,
655
0
              "error reading dump file");
656
42
        } else {
657
42
          snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
658
42
              "truncated dump file; tried to read %u captured bytes, only got %zu",
659
42
              hdr->caplen, bytes_read);
660
42
        }
661
42
        return (-1);
662
42
      }
663
1.19k
      bytes_to_discard -= amt_read;
664
1.19k
    }
665
666
    /*
667
     * Adjust caplen accordingly, so we don't get confused later
668
     * as to how many bytes we have to play with.
669
     */
670
1.15k
    hdr->caplen = p->snapshot;
671
16.4k
  } else {
672
    /*
673
     * The packet is within the snapshot length for this file.
674
     */
675
16.4k
    if (hdr->caplen > p->bufsize) {
676
      /*
677
       * Grow the buffer to the next power of 2, or
678
       * the snaplen, whichever is lower.
679
       */
680
252
      u_int new_bufsize;
681
682
252
      new_bufsize = hdr->caplen;
683
      /*
684
       * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
685
       */
686
252
      new_bufsize--;
687
252
      new_bufsize |= new_bufsize >> 1;
688
252
      new_bufsize |= new_bufsize >> 2;
689
252
      new_bufsize |= new_bufsize >> 4;
690
252
      new_bufsize |= new_bufsize >> 8;
691
252
      new_bufsize |= new_bufsize >> 16;
692
252
      new_bufsize++;
693
694
252
      if (new_bufsize > (u_int)p->snapshot)
695
33
        new_bufsize = p->snapshot;
696
697
252
      if (!grow_buffer(p, new_bufsize))
698
0
        return (-1);
699
252
    }
700
701
    /* read the packet itself */
702
16.4k
    amt_read = fread(p->buffer, 1, hdr->caplen, fp);
703
16.4k
    if (amt_read != hdr->caplen) {
704
101
      if (ferror(fp)) {
705
0
        pcap_fmt_errmsg_for_errno(p->errbuf,
706
0
            PCAP_ERRBUF_SIZE, errno,
707
0
            "error reading dump file");
708
101
      } else {
709
101
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
710
101
            "truncated dump file; tried to read %u captured bytes, only got %zu",
711
101
            hdr->caplen, amt_read);
712
101
      }
713
101
      return (-1);
714
101
    }
715
16.4k
  }
716
17.5k
  *data = p->buffer;
717
718
17.5k
  pcap_post_process(p->linktype, p->swapped, hdr, *data);
719
720
17.5k
  return (1);
721
17.7k
}
722
723
static int
724
sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen)
725
0
{
726
0
  struct pcap_file_header hdr;
727
728
0
  hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC;
729
0
  hdr.version_major = PCAP_VERSION_MAJOR;
730
0
  hdr.version_minor = PCAP_VERSION_MINOR;
731
732
  /*
733
   * https://www.tcpdump.org/manpages/pcap-savefile.5.txt states:
734
   * thiszone (Reserved1): 4-byte not used - SHOULD be filled with 0
735
   * sigfigs (Reserved2):  4-byte not used - SHOULD be filled with 0
736
   */
737
0
  hdr.thiszone = 0;
738
0
  hdr.sigfigs = 0;
739
0
  hdr.snaplen = snaplen;
740
0
  hdr.linktype = linktype;
741
742
0
  if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
743
0
    return (-1);
744
745
0
  return (0);
746
0
}
747
748
/*
749
 * Output a packet to the initialized dump file.
750
 */
751
void
752
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
753
0
{
754
0
  register FILE *f;
755
0
  struct pcap_sf_pkthdr sf_hdr;
756
757
0
  f = (FILE *)user;
758
  /*
759
   * If the output file handle is in an error state, don't write
760
   * anything.
761
   *
762
   * While in principle a file handle can return from an error state
763
   * to a normal state (for example if a disk that is full has space
764
   * freed), we have possibly left a broken file already, and won't
765
   * be able to clean it up. The safest option is to do nothing.
766
   *
767
   * Note that if we could guarantee that fwrite() was atomic we
768
   * might be able to insure that we don't produce a corrupted file,
769
   * but the standard defines fwrite() as a series of fputc() calls,
770
   * so we really have no insurance that things are not fubared.
771
   *
772
   * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
773
   */
774
0
  if (ferror(f))
775
0
    return;
776
  /*
777
   * Better not try writing pcap files after
778
   * 2038-01-19 03:14:07 UTC; switch to pcapng.
779
   */
780
0
  sf_hdr.ts.tv_sec  = (bpf_int32)h->ts.tv_sec;
781
0
  sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
782
0
  sf_hdr.caplen     = h->caplen;
783
0
  sf_hdr.len        = h->len;
784
  /*
785
   * We only write the packet if we can write the header properly.
786
   *
787
   * This doesn't prevent us from having corrupted output, and if we
788
   * for some reason don't get a complete write we don't have any
789
   * way to set ferror() to prevent future writes from being
790
   * attempted, but it is better than nothing.
791
   */
792
0
  if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
793
0
    (void)fwrite(sp, h->caplen, 1, f);
794
0
  }
795
0
}
796
797
static pcap_dumper_t *
798
pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
799
0
{
800
801
#if defined(_WIN32) || defined(MSDOS)
802
  /*
803
   * If we're writing to the standard output, put it in binary
804
   * mode, as savefiles are binary files.
805
   *
806
   * Otherwise, we turn off buffering.
807
   * XXX - why?  And why not on the standard output?
808
   */
809
  if (f == stdout)
810
    SET_BINMODE(f);
811
  else
812
    setvbuf(f, NULL, _IONBF, 0);
813
#endif
814
0
  if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
815
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
816
0
        errno, "Can't write to %s", fname);
817
0
    if (f != stdout)
818
0
      (void)fclose(f);
819
0
    return (NULL);
820
0
  }
821
0
  return ((pcap_dumper_t *)f);
822
0
}
823
824
/*
825
 * Initialize so that sf_write() will output to the file named 'fname'.
826
 */
827
pcap_dumper_t *
828
pcap_dump_open(pcap_t *p, const char *fname)
829
0
{
830
0
  FILE *f;
831
0
  int linktype;
832
833
  /*
834
   * If this pcap_t hasn't been activated, it doesn't have a
835
   * link-layer type, so we can't use it.
836
   */
837
0
  if (!p->activated) {
838
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
839
0
        "%s: not-yet-activated pcap_t passed to pcap_dump_open",
840
0
        fname);
841
0
    return (NULL);
842
0
  }
843
0
  linktype = dlt_to_linktype(p->linktype);
844
0
  if (linktype == -1) {
845
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
846
0
        "%s: link-layer type %d isn't supported in savefiles",
847
0
        fname, p->linktype);
848
0
    return (NULL);
849
0
  }
850
0
  linktype |= p->linktype_ext;
851
852
0
  if (fname == NULL) {
853
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
854
0
        "A null pointer was supplied as the file name");
855
0
    return NULL;
856
0
  }
857
0
  if (fname[0] == '-' && fname[1] == '\0') {
858
0
    f = stdout;
859
0
    fname = "standard output";
860
0
  } else {
861
    /*
862
     * "b" is supported as of C90, so *all* UN*Xes should
863
     * support it, even though it does nothing.  It's
864
     * required on Windows, as the file is a binary file
865
     * and must be written in binary mode.
866
     */
867
0
    f = pcap_charset_fopen(fname, "wb");
868
0
    if (f == NULL) {
869
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
870
0
          errno, "%s", fname);
871
0
      return (NULL);
872
0
    }
873
0
  }
874
0
  return (pcap_setup_dump(p, linktype, f, fname));
875
0
}
876
877
#ifdef _WIN32
878
/*
879
 * Initialize so that sf_write() will output to a stream wrapping the given raw
880
 * OS file HANDLE.
881
 */
882
pcap_dumper_t *
883
pcap_dump_hopen(pcap_t *p, intptr_t osfd)
884
{
885
  int fd;
886
  FILE *file;
887
888
  fd = _open_osfhandle(osfd, _O_APPEND);
889
  if (fd < 0) {
890
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
891
        errno, "_open_osfhandle");
892
    return NULL;
893
  }
894
895
  file = _fdopen(fd, "wb");
896
  if (file == NULL) {
897
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
898
        errno, "_fdopen");
899
    _close(fd);
900
    return NULL;
901
  }
902
903
  return pcap_dump_fopen(p, file);
904
}
905
#endif /* _WIN32 */
906
907
/*
908
 * Initialize so that sf_write() will output to the given stream.
909
 */
910
#ifdef _WIN32
911
static
912
#endif /* _WIN32 */
913
pcap_dumper_t *
914
pcap_dump_fopen(pcap_t *p, FILE *f)
915
0
{
916
0
  int linktype;
917
918
0
  linktype = dlt_to_linktype(p->linktype);
919
0
  if (linktype == -1) {
920
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
921
0
        "stream: link-layer type %d isn't supported in savefiles",
922
0
        p->linktype);
923
0
    return (NULL);
924
0
  }
925
0
  linktype |= p->linktype_ext;
926
927
0
  return (pcap_setup_dump(p, linktype, f, "stream"));
928
0
}
929
930
pcap_dumper_t *
931
pcap_dump_open_append(pcap_t *p, const char *fname)
932
0
{
933
0
  FILE *f;
934
0
  int linktype;
935
0
  size_t amt_read;
936
0
  struct pcap_file_header ph;
937
938
0
  linktype = dlt_to_linktype(p->linktype);
939
0
  if (linktype == -1) {
940
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
941
0
        "%s: link-layer type %d isn't supported in savefiles",
942
0
        fname, linktype);
943
0
    return (NULL);
944
0
  }
945
946
0
  if (fname == NULL) {
947
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
948
0
        "A null pointer was supplied as the file name");
949
0
    return NULL;
950
0
  }
951
0
  if (fname[0] == '-' && fname[1] == '\0')
952
0
    return (pcap_setup_dump(p, linktype, stdout, "standard output"));
953
954
  /*
955
   * "a" will cause the file *not* to be truncated if it exists
956
   * but will cause it to be created if it doesn't.  It will
957
   * also cause all writes to be done at the end of the file,
958
   * but will allow reads to be done anywhere in the file.  This
959
   * is what we need, because we need to read from the beginning
960
   * of the file to see if it already has a header and packets
961
   * or if it doesn't.
962
   *
963
   * "b" is supported as of C90, so *all* UN*Xes should support it,
964
   * even though it does nothing.  It's required on Windows, as the
965
   * file is a binary file and must be read in binary mode.
966
   */
967
0
  f = pcap_charset_fopen(fname, "ab+");
968
0
  if (f == NULL) {
969
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
970
0
        errno, "%s", fname);
971
0
    return (NULL);
972
0
  }
973
974
  /*
975
   * Try to read a pcap header.
976
   *
977
   * We do not assume that the file will be positioned at the
978
   * beginning immediately after we've opened it - we seek to
979
   * the beginning.  ISO C says it's implementation-defined
980
   * whether the file position indicator is at the beginning
981
   * or the end of the file after an append-mode open, and
982
   * it wasn't obvious from the Single UNIX Specification
983
   * or the Microsoft documentation how that works on SUS-
984
   * compliant systems or on Windows.
985
   */
986
0
  if (fseek(f, 0, SEEK_SET) == -1) {
987
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
988
0
        errno, "Can't seek to the beginning of %s", fname);
989
0
    (void)fclose(f);
990
0
    return (NULL);
991
0
  }
992
0
  amt_read = fread(&ph, 1, sizeof (ph), f);
993
0
  if (amt_read != sizeof (ph)) {
994
0
    if (ferror(f)) {
995
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
996
0
          errno, "%s", fname);
997
0
      (void)fclose(f);
998
0
      return (NULL);
999
0
    } else if (feof(f) && amt_read > 0) {
1000
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1001
0
          "%s: truncated pcap file header", fname);
1002
0
      (void)fclose(f);
1003
0
      return (NULL);
1004
0
    }
1005
0
  }
1006
1007
#if defined(_WIN32) || defined(MSDOS)
1008
  /*
1009
   * We turn off buffering.
1010
   * XXX - why?  And why not on the standard output?
1011
   */
1012
  setvbuf(f, NULL, _IONBF, 0);
1013
#endif
1014
1015
  /*
1016
   * If a header is already present and:
1017
   *
1018
   *  it's not for a pcap file of the appropriate resolution
1019
   *  and the right byte order for this machine;
1020
   *
1021
   *  the link-layer header types don't match;
1022
   *
1023
   *  the snapshot lengths don't match;
1024
   *
1025
   * return an error.
1026
   */
1027
0
  if (amt_read > 0) {
1028
    /*
1029
     * A header is already present.
1030
     * Do the checks.
1031
     */
1032
0
    switch (ph.magic) {
1033
1034
0
    case TCPDUMP_MAGIC:
1035
0
      if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
1036
0
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1037
0
            "%s: different time stamp precision, cannot append to file", fname);
1038
0
        (void)fclose(f);
1039
0
        return (NULL);
1040
0
      }
1041
0
      break;
1042
1043
0
    case NSEC_TCPDUMP_MAGIC:
1044
0
      if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
1045
0
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1046
0
            "%s: different time stamp precision, cannot append to file", fname);
1047
0
        (void)fclose(f);
1048
0
        return (NULL);
1049
0
      }
1050
0
      break;
1051
1052
0
    case SWAPLONG(TCPDUMP_MAGIC):
1053
0
    case SWAPLONG(NSEC_TCPDUMP_MAGIC):
1054
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1055
0
          "%s: different byte order, cannot append to file", fname);
1056
0
      (void)fclose(f);
1057
0
      return (NULL);
1058
1059
0
    case KUZNETZOV_TCPDUMP_MAGIC:
1060
0
    case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
1061
0
    case NAVTEL_TCPDUMP_MAGIC:
1062
0
    case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
1063
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1064
0
          "%s: not a pcap file to which we can append", fname);
1065
0
      (void)fclose(f);
1066
0
      return (NULL);
1067
1068
0
    default:
1069
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1070
0
          "%s: not a pcap file", fname);
1071
0
      (void)fclose(f);
1072
0
      return (NULL);
1073
0
    }
1074
1075
    /*
1076
     * Good version?
1077
     */
1078
0
    if (ph.version_major != PCAP_VERSION_MAJOR ||
1079
0
        ph.version_minor != PCAP_VERSION_MINOR) {
1080
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1081
0
          "%s: version is %u.%u, cannot append to file", fname,
1082
0
          ph.version_major, ph.version_minor);
1083
0
      (void)fclose(f);
1084
0
      return (NULL);
1085
0
    }
1086
0
    if ((bpf_u_int32)linktype != ph.linktype) {
1087
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1088
0
          "%s: different linktype, cannot append to file", fname);
1089
0
      (void)fclose(f);
1090
0
      return (NULL);
1091
0
    }
1092
0
    if ((bpf_u_int32)p->snapshot != ph.snaplen) {
1093
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1094
0
          "%s: different snaplen, cannot append to file", fname);
1095
0
      (void)fclose(f);
1096
0
      return (NULL);
1097
0
    }
1098
0
  } else {
1099
    /*
1100
     * A header isn't present; attempt to write it.
1101
     */
1102
0
    if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
1103
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1104
0
          errno, "Can't write to %s", fname);
1105
0
      (void)fclose(f);
1106
0
      return (NULL);
1107
0
    }
1108
0
  }
1109
1110
  /*
1111
   * Start writing at the end of the file.
1112
   *
1113
   * XXX - this shouldn't be necessary, given that we're opening
1114
   * the file in append mode, and ISO C specifies that all writes
1115
   * are done at the end of the file in that mode.
1116
   */
1117
0
  if (fseek(f, 0, SEEK_END) == -1) {
1118
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1119
0
        errno, "Can't seek to the end of %s", fname);
1120
0
    (void)fclose(f);
1121
0
    return (NULL);
1122
0
  }
1123
0
  return ((pcap_dumper_t *)f);
1124
0
}
1125
1126
FILE *
1127
pcap_dump_file(pcap_dumper_t *p)
1128
0
{
1129
0
  return ((FILE *)p);
1130
0
}
1131
1132
long
1133
pcap_dump_ftell(pcap_dumper_t *p)
1134
0
{
1135
0
  return (ftell((FILE *)p));
1136
0
}
1137
1138
#if defined(HAVE_FSEEKO)
1139
/*
1140
 * We have fseeko(), so we have ftello().
1141
 * If we have large file support (files larger than 2^31-1 bytes),
1142
 * ftello() will give us a current file position with more than 32
1143
 * bits.
1144
 */
1145
int64_t
1146
pcap_dump_ftell64(pcap_dumper_t *p)
1147
0
{
1148
0
  return (ftello((FILE *)p));
1149
0
}
1150
#elif defined(_MSC_VER)
1151
/*
1152
 * We have Visual Studio; we support only 2005 and later, so we have
1153
 * _ftelli64().
1154
 */
1155
int64_t
1156
pcap_dump_ftell64(pcap_dumper_t *p)
1157
{
1158
  return (_ftelli64((FILE *)p));
1159
}
1160
#else
1161
/*
1162
 * We don't have ftello() or _ftelli64(), so fall back on ftell().
1163
 * Either long is 64 bits, in which case ftell() should suffice,
1164
 * or this is probably an older 32-bit UN*X without large file
1165
 * support, which means you'll probably get errors trying to
1166
 * write files > 2^31-1, so it won't matter anyway.
1167
 *
1168
 * XXX - what about MinGW?
1169
 */
1170
int64_t
1171
pcap_dump_ftell64(pcap_dumper_t *p)
1172
{
1173
  return (ftell((FILE *)p));
1174
}
1175
#endif
1176
1177
int
1178
pcap_dump_flush(pcap_dumper_t *p)
1179
0
{
1180
1181
0
  if (fflush((FILE *)p) == EOF)
1182
0
    return (-1);
1183
0
  else
1184
0
    return (0);
1185
0
}
1186
1187
void
1188
pcap_dump_close(pcap_dumper_t *p)
1189
0
{
1190
1191
#ifdef notyet
1192
  if (ferror((FILE *)p))
1193
    return-an-error;
1194
  /* XXX should check return from fclose() too */
1195
#endif
1196
0
  (void)fclose((FILE *)p);
1197
0
}