Coverage Report

Created: 2021-11-03 07:11

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