Coverage Report

Created: 2023-01-25 06:41

/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
42.4k
#define TCPDUMP_MAGIC   0xa1b2c3d4
80
81
/*
82
 * Alexey Kuznetzov's modified libpcap format.
83
 */
84
47.0k
#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
25.7k
#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
17.8k
{
154
17.8k
  bpf_u_int32 magic_int;
155
17.8k
  struct pcap_file_header hdr;
156
17.8k
  size_t amt_read;
157
17.8k
  pcap_t *p;
158
17.8k
  int swapped = 0;
159
17.8k
  struct pcap_sf *ps;
160
161
  /*
162
   * Assume no read errors.
163
   */
164
17.8k
  *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
17.8k
  memcpy(&magic_int, magic, sizeof(magic_int));
172
17.8k
  if (magic_int != TCPDUMP_MAGIC &&
173
17.8k
      magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
174
17.8k
      magic_int != NSEC_TCPDUMP_MAGIC) {
175
3.40k
    magic_int = SWAPLONG(magic_int);
176
3.40k
    if (magic_int != TCPDUMP_MAGIC &&
177
3.40k
        magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
178
3.40k
        magic_int != NSEC_TCPDUMP_MAGIC)
179
1.53k
      return (NULL);  /* nope */
180
1.87k
    swapped = 1;
181
1.87k
  }
182
183
  /*
184
   * They are.  Put the magic number in the header, and read
185
   * the rest of the header.
186
   */
187
16.2k
  hdr.magic = magic_int;
188
16.2k
  amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
189
16.2k
      sizeof(hdr) - sizeof(hdr.magic), fp);
190
16.2k
  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
16.2k
  if (swapped) {
207
1.86k
    hdr.version_major = SWAPSHORT(hdr.version_major);
208
1.86k
    hdr.version_minor = SWAPSHORT(hdr.version_minor);
209
1.86k
    hdr.thiszone = SWAPLONG(hdr.thiszone);
210
1.86k
    hdr.sigfigs = SWAPLONG(hdr.sigfigs);
211
1.86k
    hdr.snaplen = SWAPLONG(hdr.snaplen);
212
1.86k
    hdr.linktype = SWAPLONG(hdr.linktype);
213
1.86k
  }
214
215
16.2k
  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
16.2k
  if (! ((hdr.version_major == PCAP_VERSION_MAJOR &&
227
16.2k
    hdr.version_minor <= PCAP_VERSION_MINOR) ||
228
16.2k
         (hdr.version_major == 543 &&
229
65
    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
16.1k
  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
16.1k
  p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
253
16.1k
  if (p == NULL) {
254
    /* Allocation failed. */
255
0
    *err = 1;
256
0
    return (NULL);
257
0
  }
258
16.1k
  p->swapped = swapped;
259
16.1k
  p->version_major = hdr.version_major;
260
16.1k
  p->version_minor = hdr.version_minor;
261
16.1k
  p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
262
16.1k
  p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
263
16.1k
  p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
264
265
16.1k
  p->next_packet_op = pcap_next_packet;
266
267
16.1k
  ps = p->priv;
268
269
16.1k
  p->opt.tstamp_precision = precision;
270
271
  /*
272
   * Will we need to scale the timestamps to match what the
273
   * user wants?
274
   */
275
16.1k
  switch (precision) {
276
277
0
  case PCAP_TSTAMP_PRECISION_MICRO:
278
0
    if (magic_int == NSEC_TCPDUMP_MAGIC) {
279
      /*
280
       * The file has nanoseconds, the user
281
       * wants microseconds; scale the
282
       * precision down.
283
       */
284
0
      ps->scale_type = SCALE_DOWN;
285
0
    } else {
286
      /*
287
       * The file has microseconds, the
288
       * user wants microseconds; nothing to do.
289
       */
290
0
      ps->scale_type = PASS_THROUGH;
291
0
    }
292
0
    break;
293
294
16.1k
  case PCAP_TSTAMP_PRECISION_NANO:
295
16.1k
    if (magic_int == NSEC_TCPDUMP_MAGIC) {
296
      /*
297
       * The file has nanoseconds, the
298
       * user wants nanoseconds; nothing to do.
299
       */
300
4.64k
      ps->scale_type = PASS_THROUGH;
301
11.5k
    } else {
302
      /*
303
       * The file has microseconds, the user
304
       * wants nanoseconds; scale the
305
       * precision up.
306
       */
307
11.5k
      ps->scale_type = SCALE_UP;
308
11.5k
    }
309
16.1k
    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
16.1k
  }
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
16.1k
  switch (hdr.version_major) {
330
331
16.1k
  case 2:
332
16.1k
    if (hdr.version_minor < 3)
333
1.21k
      ps->lengths_swapped = SWAPPED;
334
14.9k
    else if (hdr.version_minor == 3)
335
12.5k
      ps->lengths_swapped = MAYBE_SWAPPED;
336
2.41k
    else
337
2.41k
      ps->lengths_swapped = NOT_SWAPPED;
338
16.1k
    break;
339
340
3
  case 543:
341
3
    ps->lengths_swapped = SWAPPED;
342
3
    break;
343
344
0
  default:
345
0
    ps->lengths_swapped = NOT_SWAPPED;
346
0
    break;
347
16.1k
  }
348
349
16.1k
  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
87
    ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
368
369
87
    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
59
      if (p->snapshot <= INT_MAX - 14)
394
57
        p->snapshot += 14;
395
2
      else
396
2
        p->snapshot = INT_MAX;
397
59
    }
398
87
  } else
399
16.1k
    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
16.1k
  p->bufsize = p->snapshot;
411
16.1k
  if (p->bufsize > 2048)
412
14.1k
    p->bufsize = 2048;
413
16.1k
  p->buffer = malloc(p->bufsize);
414
16.1k
  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
16.1k
  p->cleanup_op = sf_cleanup;
422
423
16.1k
  return (p);
424
16.1k
}
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
66.6k
{
432
66.6k
  void *bigger_buffer;
433
434
66.6k
  bigger_buffer = realloc(p->buffer, bufsize);
435
66.6k
  if (bigger_buffer == NULL) {
436
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
437
0
    return (0);
438
0
  }
439
66.6k
  p->buffer = bigger_buffer;
440
66.6k
  p->bufsize = bufsize;
441
66.6k
  return (1);
442
66.6k
}
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
913k
{
452
913k
  struct pcap_sf *ps = p->priv;
453
913k
  struct pcap_sf_patched_pkthdr sf_hdr;
454
913k
  FILE *fp = p->rfile;
455
913k
  size_t amt_read;
456
913k
  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
913k
  amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
466
913k
  if (amt_read != ps->hdrsize) {
467
12.8k
    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
12.8k
    } else {
472
12.8k
      if (amt_read != 0) {
473
3.29k
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
474
3.29k
            "truncated dump file; tried to read %zu header bytes, only got %zu",
475
3.29k
            ps->hdrsize, amt_read);
476
3.29k
        return (-1);
477
3.29k
      }
478
      /* EOF */
479
9.56k
      return (0);
480
12.8k
    }
481
12.8k
  }
482
483
900k
  if (p->swapped) {
484
    /* these were written in opposite byte order */
485
47.9k
    hdr->caplen = SWAPLONG(sf_hdr.caplen);
486
47.9k
    hdr->len = SWAPLONG(sf_hdr.len);
487
47.9k
    hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
488
47.9k
    hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
489
852k
  } else {
490
852k
    hdr->caplen = sf_hdr.caplen;
491
852k
    hdr->len = sf_hdr.len;
492
852k
    hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
493
852k
    hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
494
852k
  }
495
496
900k
  switch (ps->scale_type) {
497
498
301k
  case PASS_THROUGH:
499
    /*
500
     * Just pass the time stamp through.
501
     */
502
301k
    break;
503
504
598k
  case SCALE_UP:
505
    /*
506
     * File has microseconds, user wants nanoseconds; convert
507
     * it.
508
     */
509
598k
    hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
510
598k
    break;
511
512
0
  case SCALE_DOWN:
513
    /*
514
     * File has nanoseconds, user wants microseconds; convert
515
     * it.
516
     */
517
0
    hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
518
0
    break;
519
900k
  }
520
521
  /* Swap the caplen and len fields, if necessary. */
522
900k
  switch (ps->lengths_swapped) {
523
524
15.5k
  case NOT_SWAPPED:
525
15.5k
    break;
526
527
878k
  case MAYBE_SWAPPED:
528
878k
    if (hdr->caplen <= hdr->len) {
529
      /*
530
       * The captured length is <= the actual length,
531
       * so presumably they weren't swapped.
532
       */
533
593k
      break;
534
593k
    }
535
    /* FALLTHROUGH */
536
537
291k
  case SWAPPED:
538
291k
    t = hdr->caplen;
539
291k
    hdr->caplen = hdr->len;
540
291k
    hdr->len = t;
541
291k
    break;
542
900k
  }
543
544
  /*
545
   * Is the packet bigger than we consider sane?
546
   */
547
900k
  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
1.98k
    if (hdr->caplen > (bpf_u_int32)p->snapshot) {
557
1.61k
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
558
1.61k
          "invalid packet capture length %u, bigger than "
559
1.61k
          "snaplen of %d", hdr->caplen, p->snapshot);
560
1.61k
    } else {
561
371
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
562
371
          "invalid packet capture length %u, bigger than "
563
371
          "maximum of %u", hdr->caplen,
564
371
          max_snaplen_for_dlt(p->linktype));
565
371
    }
566
1.98k
    return (-1);
567
1.98k
  }
568
569
898k
  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
65.4k
    size_t bytes_to_discard;
605
65.4k
    size_t bytes_to_read, bytes_read;
606
65.4k
    char discard_buf[4096];
607
608
65.4k
    if (hdr->caplen > p->bufsize) {
609
      /*
610
       * Grow the buffer to the snapshot length.
611
       */
612
65.4k
      if (!grow_buffer(p, p->snapshot))
613
0
        return (-1);
614
65.4k
    }
615
616
    /*
617
     * Read the first p->snapshot bytes into the buffer.
618
     */
619
65.4k
    amt_read = fread(p->buffer, 1, p->snapshot, fp);
620
65.4k
    if (amt_read != (bpf_u_int32)p->snapshot) {
621
204
      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
204
      } 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
204
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
634
204
            "truncated dump file; tried to read %d captured bytes, only got %zu",
635
204
            p->snapshot, amt_read);
636
204
      }
637
204
      return (-1);
638
204
    }
639
640
    /*
641
     * Now read and discard what's left.
642
     */
643
65.2k
    bytes_to_discard = hdr->caplen - p->snapshot;
644
65.2k
    bytes_read = amt_read;
645
130k
    while (bytes_to_discard != 0) {
646
65.6k
      bytes_to_read = bytes_to_discard;
647
65.6k
      if (bytes_to_read > sizeof (discard_buf))
648
470
        bytes_to_read = sizeof (discard_buf);
649
65.6k
      amt_read = fread(discard_buf, 1, bytes_to_read, fp);
650
65.6k
      bytes_read += amt_read;
651
65.6k
      if (amt_read != bytes_to_read) {
652
132
        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
132
        } else {
657
132
          snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
658
132
              "truncated dump file; tried to read %u captured bytes, only got %zu",
659
132
              hdr->caplen, bytes_read);
660
132
        }
661
132
        return (-1);
662
132
      }
663
65.5k
      bytes_to_discard -= amt_read;
664
65.5k
    }
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
65.1k
    hdr->caplen = p->snapshot;
671
832k
  } else {
672
    /*
673
     * The packet is within the snapshot length for this file.
674
     */
675
832k
    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
1.13k
      u_int new_bufsize;
681
682
1.13k
      new_bufsize = hdr->caplen;
683
      /*
684
       * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
685
       */
686
1.13k
      new_bufsize--;
687
1.13k
      new_bufsize |= new_bufsize >> 1;
688
1.13k
      new_bufsize |= new_bufsize >> 2;
689
1.13k
      new_bufsize |= new_bufsize >> 4;
690
1.13k
      new_bufsize |= new_bufsize >> 8;
691
1.13k
      new_bufsize |= new_bufsize >> 16;
692
1.13k
      new_bufsize++;
693
694
1.13k
      if (new_bufsize > (u_int)p->snapshot)
695
45
        new_bufsize = p->snapshot;
696
697
1.13k
      if (!grow_buffer(p, new_bufsize))
698
0
        return (-1);
699
1.13k
    }
700
701
    /* read the packet itself */
702
832k
    amt_read = fread(p->buffer, 1, hdr->caplen, fp);
703
832k
    if (amt_read != hdr->caplen) {
704
931
      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
931
      } else {
709
931
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
710
931
            "truncated dump file; tried to read %u captured bytes, only got %zu",
711
931
            hdr->caplen, amt_read);
712
931
      }
713
931
      return (-1);
714
931
    }
715
832k
  }
716
897k
  *data = p->buffer;
717
718
897k
  pcap_post_process(p->linktype, p->swapped, hdr, *data);
719
720
897k
  return (1);
721
898k
}
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: 4-byte time zone offset; this is always 0.
735
   * sigfigs:  4-byte number giving the accuracy of time stamps
736
   *           in the file; this is always 0.
737
   */
738
0
  hdr.thiszone = 0;
739
0
  hdr.sigfigs = 0;
740
0
  hdr.snaplen = snaplen;
741
0
  hdr.linktype = linktype;
742
743
0
  if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
744
0
    return (-1);
745
746
0
  return (0);
747
0
}
748
749
/*
750
 * Output a packet to the initialized dump file.
751
 */
752
void
753
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
754
0
{
755
0
  register FILE *f;
756
0
  struct pcap_sf_pkthdr sf_hdr;
757
758
0
  f = (FILE *)user;
759
  /*
760
   * If the output file handle is in an error state, don't write
761
   * anything.
762
   *
763
   * While in principle a file handle can return from an error state
764
   * to a normal state (for example if a disk that is full has space
765
   * freed), we have possibly left a broken file already, and won't
766
   * be able to clean it up. The safest option is to do nothing.
767
   *
768
   * Note that if we could guarantee that fwrite() was atomic we
769
   * might be able to insure that we don't produce a corrupted file,
770
   * but the standard defines fwrite() as a series of fputc() calls,
771
   * so we really have no insurance that things are not fubared.
772
   *
773
   * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
774
   */
775
0
  if (ferror(f))
776
0
    return;
777
  /*
778
   * Better not try writing pcap files after
779
   * 2038-01-19 03:14:07 UTC; switch to pcapng.
780
   */
781
0
  sf_hdr.ts.tv_sec  = (bpf_int32)h->ts.tv_sec;
782
0
  sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
783
0
  sf_hdr.caplen     = h->caplen;
784
0
  sf_hdr.len        = h->len;
785
  /*
786
   * We only write the packet if we can write the header properly.
787
   *
788
   * This doesn't prevent us from having corrupted output, and if we
789
   * for some reason don't get a complete write we don't have any
790
   * way to set ferror() to prevent future writes from being
791
   * attempted, but it is better than nothing.
792
   */
793
0
  if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
794
0
    (void)fwrite(sp, h->caplen, 1, f);
795
0
  }
796
0
}
797
798
static pcap_dumper_t *
799
pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
800
0
{
801
802
#if defined(_WIN32) || defined(MSDOS)
803
  /*
804
   * If we're writing to the standard output, put it in binary
805
   * mode, as savefiles are binary files.
806
   *
807
   * Otherwise, we turn off buffering.
808
   * XXX - why?  And why not on the standard output?
809
   */
810
  if (f == stdout)
811
    SET_BINMODE(f);
812
  else
813
    setvbuf(f, NULL, _IONBF, 0);
814
#endif
815
0
  if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
816
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
817
0
        errno, "Can't write to %s", fname);
818
0
    if (f != stdout)
819
0
      (void)fclose(f);
820
0
    return (NULL);
821
0
  }
822
0
  return ((pcap_dumper_t *)f);
823
0
}
824
825
/*
826
 * Initialize so that sf_write() will output to the file named 'fname'.
827
 */
828
pcap_dumper_t *
829
pcap_dump_open(pcap_t *p, const char *fname)
830
0
{
831
0
  FILE *f;
832
0
  int linktype;
833
834
  /*
835
   * If this pcap_t hasn't been activated, it doesn't have a
836
   * link-layer type, so we can't use it.
837
   */
838
0
  if (!p->activated) {
839
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
840
0
        "%s: not-yet-activated pcap_t passed to pcap_dump_open",
841
0
        fname);
842
0
    return (NULL);
843
0
  }
844
0
  linktype = dlt_to_linktype(p->linktype);
845
0
  if (linktype == -1) {
846
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
847
0
        "%s: link-layer type %d isn't supported in savefiles",
848
0
        fname, p->linktype);
849
0
    return (NULL);
850
0
  }
851
0
  linktype |= p->linktype_ext;
852
853
0
  if (fname == NULL) {
854
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
855
0
        "A null pointer was supplied as the file name");
856
0
    return NULL;
857
0
  }
858
0
  if (fname[0] == '-' && fname[1] == '\0') {
859
0
    f = stdout;
860
0
    fname = "standard output";
861
0
  } else {
862
    /*
863
     * "b" is supported as of C90, so *all* UN*Xes should
864
     * support it, even though it does nothing.  It's
865
     * required on Windows, as the file is a binary file
866
     * and must be written in binary mode.
867
     */
868
0
    f = charset_fopen(fname, "wb");
869
0
    if (f == NULL) {
870
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
871
0
          errno, "%s", fname);
872
0
      return (NULL);
873
0
    }
874
0
  }
875
0
  return (pcap_setup_dump(p, linktype, f, fname));
876
0
}
877
878
#ifdef _WIN32
879
/*
880
 * Initialize so that sf_write() will output to a stream wrapping the given raw
881
 * OS file HANDLE.
882
 */
883
pcap_dumper_t *
884
pcap_dump_hopen(pcap_t *p, intptr_t osfd)
885
{
886
  int fd;
887
  FILE *file;
888
889
  fd = _open_osfhandle(osfd, _O_APPEND);
890
  if (fd < 0) {
891
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
892
        errno, "_open_osfhandle");
893
    return NULL;
894
  }
895
896
  file = _fdopen(fd, "wb");
897
  if (file == NULL) {
898
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
899
        errno, "_fdopen");
900
    _close(fd);
901
    return NULL;
902
  }
903
904
  return pcap_dump_fopen(p, file);
905
}
906
#endif /* _WIN32 */
907
908
/*
909
 * Initialize so that sf_write() will output to the given stream.
910
 */
911
#ifdef _WIN32
912
static
913
#endif /* _WIN32 */
914
pcap_dumper_t *
915
pcap_dump_fopen(pcap_t *p, FILE *f)
916
0
{
917
0
  int linktype;
918
919
0
  linktype = dlt_to_linktype(p->linktype);
920
0
  if (linktype == -1) {
921
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
922
0
        "stream: link-layer type %d isn't supported in savefiles",
923
0
        p->linktype);
924
0
    return (NULL);
925
0
  }
926
0
  linktype |= p->linktype_ext;
927
928
0
  return (pcap_setup_dump(p, linktype, f, "stream"));
929
0
}
930
931
pcap_dumper_t *
932
pcap_dump_open_append(pcap_t *p, const char *fname)
933
0
{
934
0
  FILE *f;
935
0
  int linktype;
936
0
  size_t amt_read;
937
0
  struct pcap_file_header ph;
938
939
0
  linktype = dlt_to_linktype(p->linktype);
940
0
  if (linktype == -1) {
941
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
942
0
        "%s: link-layer type %d isn't supported in savefiles",
943
0
        fname, linktype);
944
0
    return (NULL);
945
0
  }
946
947
0
  if (fname == NULL) {
948
0
    snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
949
0
        "A null pointer was supplied as the file name");
950
0
    return NULL;
951
0
  }
952
0
  if (fname[0] == '-' && fname[1] == '\0')
953
0
    return (pcap_setup_dump(p, linktype, stdout, "standard output"));
954
955
  /*
956
   * "a" will cause the file *not* to be truncated if it exists
957
   * but will cause it to be created if it doesn't.  It will
958
   * also cause all writes to be done at the end of the file,
959
   * but will allow reads to be done anywhere in the file.  This
960
   * is what we need, because we need to read from the beginning
961
   * of the file to see if it already has a header and packets
962
   * or if it doesn't.
963
   *
964
   * "b" is supported as of C90, so *all* UN*Xes should support it,
965
   * even though it does nothing.  It's required on Windows, as the
966
   * file is a binary file and must be read in binary mode.
967
   */
968
0
  f = charset_fopen(fname, "ab+");
969
0
  if (f == NULL) {
970
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
971
0
        errno, "%s", fname);
972
0
    return (NULL);
973
0
  }
974
975
  /*
976
   * Try to read a pcap header.
977
   *
978
   * We do not assume that the file will be positioned at the
979
   * beginning immediately after we've opened it - we seek to
980
   * the beginning.  ISO C says it's implementation-defined
981
   * whether the file position indicator is at the beginning
982
   * or the end of the file after an append-mode open, and
983
   * it wasn't obvious from the Single UNIX Specification
984
   * or the Microsoft documentation how that works on SUS-
985
   * compliant systems or on Windows.
986
   */
987
0
  if (fseek(f, 0, SEEK_SET) == -1) {
988
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
989
0
        errno, "Can't seek to the beginning of %s", fname);
990
0
    (void)fclose(f);
991
0
    return (NULL);
992
0
  }
993
0
  amt_read = fread(&ph, 1, sizeof (ph), f);
994
0
  if (amt_read != sizeof (ph)) {
995
0
    if (ferror(f)) {
996
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
997
0
          errno, "%s", fname);
998
0
      (void)fclose(f);
999
0
      return (NULL);
1000
0
    } else if (feof(f) && amt_read > 0) {
1001
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1002
0
          "%s: truncated pcap file header", fname);
1003
0
      (void)fclose(f);
1004
0
      return (NULL);
1005
0
    }
1006
0
  }
1007
1008
#if defined(_WIN32) || defined(MSDOS)
1009
  /*
1010
   * We turn off buffering.
1011
   * XXX - why?  And why not on the standard output?
1012
   */
1013
  setvbuf(f, NULL, _IONBF, 0);
1014
#endif
1015
1016
  /*
1017
   * If a header is already present and:
1018
   *
1019
   *  it's not for a pcap file of the appropriate resolution
1020
   *  and the right byte order for this machine;
1021
   *
1022
   *  the link-layer header types don't match;
1023
   *
1024
   *  the snapshot lengths don't match;
1025
   *
1026
   * return an error.
1027
   */
1028
0
  if (amt_read > 0) {
1029
    /*
1030
     * A header is already present.
1031
     * Do the checks.
1032
     */
1033
0
    switch (ph.magic) {
1034
1035
0
    case TCPDUMP_MAGIC:
1036
0
      if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
1037
0
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1038
0
            "%s: different time stamp precision, cannot append to file", fname);
1039
0
        (void)fclose(f);
1040
0
        return (NULL);
1041
0
      }
1042
0
      break;
1043
1044
0
    case NSEC_TCPDUMP_MAGIC:
1045
0
      if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
1046
0
        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1047
0
            "%s: different time stamp precision, cannot append to file", fname);
1048
0
        (void)fclose(f);
1049
0
        return (NULL);
1050
0
      }
1051
0
      break;
1052
1053
0
    case SWAPLONG(TCPDUMP_MAGIC):
1054
0
    case SWAPLONG(NSEC_TCPDUMP_MAGIC):
1055
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1056
0
          "%s: different byte order, cannot append to file", fname);
1057
0
      (void)fclose(f);
1058
0
      return (NULL);
1059
1060
0
    case KUZNETZOV_TCPDUMP_MAGIC:
1061
0
    case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
1062
0
    case NAVTEL_TCPDUMP_MAGIC:
1063
0
    case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
1064
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1065
0
          "%s: not a pcap file to which we can append", fname);
1066
0
      (void)fclose(f);
1067
0
      return (NULL);
1068
1069
0
    default:
1070
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1071
0
          "%s: not a pcap file", fname);
1072
0
      (void)fclose(f);
1073
0
      return (NULL);
1074
0
    }
1075
1076
    /*
1077
     * Good version?
1078
     */
1079
0
    if (ph.version_major != PCAP_VERSION_MAJOR ||
1080
0
        ph.version_minor != PCAP_VERSION_MINOR) {
1081
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1082
0
          "%s: version is %u.%u, cannot append to file", fname,
1083
0
          ph.version_major, ph.version_minor);
1084
0
      (void)fclose(f);
1085
0
      return (NULL);
1086
0
    }
1087
0
    if ((bpf_u_int32)linktype != ph.linktype) {
1088
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1089
0
          "%s: different linktype, cannot append to file", fname);
1090
0
      (void)fclose(f);
1091
0
      return (NULL);
1092
0
    }
1093
0
    if ((bpf_u_int32)p->snapshot != ph.snaplen) {
1094
0
      snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1095
0
          "%s: different snaplen, cannot append to file", fname);
1096
0
      (void)fclose(f);
1097
0
      return (NULL);
1098
0
    }
1099
0
  } else {
1100
    /*
1101
     * A header isn't present; attempt to write it.
1102
     */
1103
0
    if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
1104
0
      pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1105
0
          errno, "Can't write to %s", fname);
1106
0
      (void)fclose(f);
1107
0
      return (NULL);
1108
0
    }
1109
0
  }
1110
1111
  /*
1112
   * Start writing at the end of the file.
1113
   *
1114
   * XXX - this shouldn't be necessary, given that we're opening
1115
   * the file in append mode, and ISO C specifies that all writes
1116
   * are done at the end of the file in that mode.
1117
   */
1118
0
  if (fseek(f, 0, SEEK_END) == -1) {
1119
0
    pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1120
0
        errno, "Can't seek to the end of %s", fname);
1121
0
    (void)fclose(f);
1122
0
    return (NULL);
1123
0
  }
1124
0
  return ((pcap_dumper_t *)f);
1125
0
}
1126
1127
FILE *
1128
pcap_dump_file(pcap_dumper_t *p)
1129
0
{
1130
0
  return ((FILE *)p);
1131
0
}
1132
1133
long
1134
pcap_dump_ftell(pcap_dumper_t *p)
1135
0
{
1136
0
  return (ftell((FILE *)p));
1137
0
}
1138
1139
#if defined(HAVE_FSEEKO)
1140
/*
1141
 * We have fseeko(), so we have ftello().
1142
 * If we have large file support (files larger than 2^31-1 bytes),
1143
 * ftello() will give us a current file position with more than 32
1144
 * bits.
1145
 */
1146
int64_t
1147
pcap_dump_ftell64(pcap_dumper_t *p)
1148
0
{
1149
0
  return (ftello((FILE *)p));
1150
0
}
1151
#elif defined(_MSC_VER)
1152
/*
1153
 * We have Visual Studio; we support only 2005 and later, so we have
1154
 * _ftelli64().
1155
 */
1156
int64_t
1157
pcap_dump_ftell64(pcap_dumper_t *p)
1158
{
1159
  return (_ftelli64((FILE *)p));
1160
}
1161
#else
1162
/*
1163
 * We don't have ftello() or _ftelli64(), so fall back on ftell().
1164
 * Either long is 64 bits, in which case ftell() should suffice,
1165
 * or this is probably an older 32-bit UN*X without large file
1166
 * support, which means you'll probably get errors trying to
1167
 * write files > 2^31-1, so it won't matter anyway.
1168
 *
1169
 * XXX - what about MinGW?
1170
 */
1171
int64_t
1172
pcap_dump_ftell64(pcap_dumper_t *p)
1173
{
1174
  return (ftell((FILE *)p));
1175
}
1176
#endif
1177
1178
int
1179
pcap_dump_flush(pcap_dumper_t *p)
1180
0
{
1181
1182
0
  if (fflush((FILE *)p) == EOF)
1183
0
    return (-1);
1184
0
  else
1185
0
    return (0);
1186
0
}
1187
1188
void
1189
pcap_dump_close(pcap_dumper_t *p)
1190
0
{
1191
1192
#ifdef notyet
1193
  if (ferror((FILE *)p))
1194
    return-an-error;
1195
  /* XXX should check return from fclose() too */
1196
#endif
1197
0
  (void)fclose((FILE *)p);
1198
0
}