]> The Tcpdump Group git mirrors - libpcap/blob - sf-pcap.c
CI: Test with IPv6 support enabled/disabled
[libpcap] / sf-pcap.c
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 #define TCPDUMP_MAGIC 0xa1b2c3d4
80
81 /*
82 * Alexey Kuznetzov's modified libpcap format.
83 */
84 #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 #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 #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 {
154 bpf_u_int32 magic_int;
155 struct pcap_file_header hdr;
156 size_t amt_read;
157 pcap_t *p;
158 int swapped = 0;
159 struct pcap_sf *ps;
160
161 /*
162 * Assume no read errors.
163 */
164 *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 memcpy(&magic_int, magic, sizeof(magic_int));
172 if (magic_int != TCPDUMP_MAGIC &&
173 magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
174 magic_int != NSEC_TCPDUMP_MAGIC) {
175 magic_int = SWAPLONG(magic_int);
176 if (magic_int != TCPDUMP_MAGIC &&
177 magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
178 magic_int != NSEC_TCPDUMP_MAGIC)
179 return (NULL); /* nope */
180 swapped = 1;
181 }
182
183 /*
184 * They are. Put the magic number in the header, and read
185 * the rest of the header.
186 */
187 hdr.magic = magic_int;
188 amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
189 sizeof(hdr) - sizeof(hdr.magic), fp);
190 if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
191 if (ferror(fp)) {
192 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
193 errno, "error reading dump file");
194 } else {
195 snprintf(errbuf, PCAP_ERRBUF_SIZE,
196 "truncated dump file; tried to read %zu file header bytes, only got %zu",
197 sizeof(hdr), amt_read);
198 }
199 *err = 1;
200 return (NULL);
201 }
202
203 /*
204 * If it's a byte-swapped capture file, byte-swap the header.
205 */
206 if (swapped) {
207 hdr.version_major = SWAPSHORT(hdr.version_major);
208 hdr.version_minor = SWAPSHORT(hdr.version_minor);
209 hdr.thiszone = SWAPLONG(hdr.thiszone);
210 hdr.sigfigs = SWAPLONG(hdr.sigfigs);
211 hdr.snaplen = SWAPLONG(hdr.snaplen);
212 hdr.linktype = SWAPLONG(hdr.linktype);
213 }
214
215 if (hdr.version_major < PCAP_VERSION_MAJOR) {
216 snprintf(errbuf, PCAP_ERRBUF_SIZE,
217 "archaic pcap savefile format");
218 *err = 1;
219 return (NULL);
220 }
221
222 /*
223 * currently only versions 2.[0-4] are supported with
224 * the exception of 543.0 for DG/UX tcpdump.
225 */
226 if (! ((hdr.version_major == PCAP_VERSION_MAJOR &&
227 hdr.version_minor <= PCAP_VERSION_MINOR) ||
228 (hdr.version_major == 543 &&
229 hdr.version_minor == 0))) {
230 snprintf(errbuf, PCAP_ERRBUF_SIZE,
231 "unsupported pcap savefile version %u.%u",
232 hdr.version_major, hdr.version_minor);
233 *err = 1;
234 return NULL;
235 }
236
237 /*
238 * Check the main reserved field.
239 */
240 if (LT_RESERVED1(hdr.linktype) != 0) {
241 snprintf(errbuf, PCAP_ERRBUF_SIZE,
242 "savefile linktype reserved field not zero (0x%08x)",
243 LT_RESERVED1(hdr.linktype));
244 *err = 1;
245 return NULL;
246 }
247
248 /*
249 * OK, this is a good pcap file.
250 * Allocate a pcap_t for it.
251 */
252 p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
253 if (p == NULL) {
254 /* Allocation failed. */
255 *err = 1;
256 return (NULL);
257 }
258 p->swapped = swapped;
259 p->version_major = hdr.version_major;
260 p->version_minor = hdr.version_minor;
261 p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
262 p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
263 p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
264
265 p->next_packet_op = pcap_next_packet;
266
267 ps = p->priv;
268
269 p->opt.tstamp_precision = precision;
270
271 /*
272 * Will we need to scale the timestamps to match what the
273 * user wants?
274 */
275 switch (precision) {
276
277 case PCAP_TSTAMP_PRECISION_MICRO:
278 if (magic_int == NSEC_TCPDUMP_MAGIC) {
279 /*
280 * The file has nanoseconds, the user
281 * wants microseconds; scale the
282 * precision down.
283 */
284 ps->scale_type = SCALE_DOWN;
285 } else {
286 /*
287 * The file has microseconds, the
288 * user wants microseconds; nothing to do.
289 */
290 ps->scale_type = PASS_THROUGH;
291 }
292 break;
293
294 case PCAP_TSTAMP_PRECISION_NANO:
295 if (magic_int == NSEC_TCPDUMP_MAGIC) {
296 /*
297 * The file has nanoseconds, the
298 * user wants nanoseconds; nothing to do.
299 */
300 ps->scale_type = PASS_THROUGH;
301 } else {
302 /*
303 * The file has microseconds, the user
304 * wants nanoseconds; scale the
305 * precision up.
306 */
307 ps->scale_type = SCALE_UP;
308 }
309 break;
310
311 default:
312 snprintf(errbuf, PCAP_ERRBUF_SIZE,
313 "unknown time stamp resolution %u", precision);
314 free(p);
315 *err = 1;
316 return (NULL);
317 }
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 switch (hdr.version_major) {
330
331 case 2:
332 if (hdr.version_minor < 3)
333 ps->lengths_swapped = SWAPPED;
334 else if (hdr.version_minor == 3)
335 ps->lengths_swapped = MAYBE_SWAPPED;
336 else
337 ps->lengths_swapped = NOT_SWAPPED;
338 break;
339
340 case 543:
341 ps->lengths_swapped = SWAPPED;
342 break;
343
344 default:
345 ps->lengths_swapped = NOT_SWAPPED;
346 break;
347 }
348
349 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 ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
368
369 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 if (p->snapshot <= INT_MAX - 14)
394 p->snapshot += 14;
395 else
396 p->snapshot = INT_MAX;
397 }
398 } else
399 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 p->bufsize = p->snapshot;
411 if (p->bufsize > 2048)
412 p->bufsize = 2048;
413 p->buffer = malloc(p->bufsize);
414 if (p->buffer == NULL) {
415 snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
416 free(p);
417 *err = 1;
418 return (NULL);
419 }
420
421 p->cleanup_op = sf_cleanup;
422
423 return (p);
424 }
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 {
432 void *bigger_buffer;
433
434 bigger_buffer = realloc(p->buffer, bufsize);
435 if (bigger_buffer == NULL) {
436 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
437 return (0);
438 }
439 p->buffer = bigger_buffer;
440 p->bufsize = bufsize;
441 return (1);
442 }
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 {
452 struct pcap_sf *ps = p->priv;
453 struct pcap_sf_patched_pkthdr sf_hdr;
454 FILE *fp = p->rfile;
455 size_t amt_read;
456 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 amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
466 if (amt_read != ps->hdrsize) {
467 if (ferror(fp)) {
468 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
469 errno, "error reading dump file");
470 return (-1);
471 } else {
472 if (amt_read != 0) {
473 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
474 "truncated dump file; tried to read %zu header bytes, only got %zu",
475 ps->hdrsize, amt_read);
476 return (-1);
477 }
478 /* EOF */
479 return (0);
480 }
481 }
482
483 if (p->swapped) {
484 /* these were written in opposite byte order */
485 hdr->caplen = SWAPLONG(sf_hdr.caplen);
486 hdr->len = SWAPLONG(sf_hdr.len);
487 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
488 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
489 } else {
490 hdr->caplen = sf_hdr.caplen;
491 hdr->len = sf_hdr.len;
492 hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
493 hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
494 }
495
496 switch (ps->scale_type) {
497
498 case PASS_THROUGH:
499 /*
500 * Just pass the time stamp through.
501 */
502 break;
503
504 case SCALE_UP:
505 /*
506 * File has microseconds, user wants nanoseconds; convert
507 * it.
508 */
509 hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
510 break;
511
512 case SCALE_DOWN:
513 /*
514 * File has nanoseconds, user wants microseconds; convert
515 * it.
516 */
517 hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
518 break;
519 }
520
521 /* Swap the caplen and len fields, if necessary. */
522 switch (ps->lengths_swapped) {
523
524 case NOT_SWAPPED:
525 break;
526
527 case MAYBE_SWAPPED:
528 if (hdr->caplen <= hdr->len) {
529 /*
530 * The captured length is <= the actual length,
531 * so presumably they weren't swapped.
532 */
533 break;
534 }
535 /* FALLTHROUGH */
536
537 case SWAPPED:
538 t = hdr->caplen;
539 hdr->caplen = hdr->len;
540 hdr->len = t;
541 break;
542 }
543
544 /*
545 * Is the packet bigger than we consider sane?
546 */
547 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 if (hdr->caplen > (bpf_u_int32)p->snapshot) {
557 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
558 "invalid packet capture length %u, bigger than "
559 "snaplen of %d", hdr->caplen, p->snapshot);
560 } else {
561 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
562 "invalid packet capture length %u, bigger than "
563 "maximum of %u", hdr->caplen,
564 max_snaplen_for_dlt(p->linktype));
565 }
566 return (-1);
567 }
568
569 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 size_t bytes_to_discard;
605 size_t bytes_to_read, bytes_read;
606 char discard_buf[4096];
607
608 if (hdr->caplen > p->bufsize) {
609 /*
610 * Grow the buffer to the snapshot length.
611 */
612 if (!grow_buffer(p, p->snapshot))
613 return (-1);
614 }
615
616 /*
617 * Read the first p->snapshot bytes into the buffer.
618 */
619 amt_read = fread(p->buffer, 1, p->snapshot, fp);
620 if (amt_read != (bpf_u_int32)p->snapshot) {
621 if (ferror(fp)) {
622 pcap_fmt_errmsg_for_errno(p->errbuf,
623 PCAP_ERRBUF_SIZE, errno,
624 "error reading dump file");
625 } 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 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
634 "truncated dump file; tried to read %d captured bytes, only got %zu",
635 p->snapshot, amt_read);
636 }
637 return (-1);
638 }
639
640 /*
641 * Now read and discard what's left.
642 */
643 bytes_to_discard = hdr->caplen - p->snapshot;
644 bytes_read = amt_read;
645 while (bytes_to_discard != 0) {
646 bytes_to_read = bytes_to_discard;
647 if (bytes_to_read > sizeof (discard_buf))
648 bytes_to_read = sizeof (discard_buf);
649 amt_read = fread(discard_buf, 1, bytes_to_read, fp);
650 bytes_read += amt_read;
651 if (amt_read != bytes_to_read) {
652 if (ferror(fp)) {
653 pcap_fmt_errmsg_for_errno(p->errbuf,
654 PCAP_ERRBUF_SIZE, errno,
655 "error reading dump file");
656 } else {
657 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
658 "truncated dump file; tried to read %u captured bytes, only got %zu",
659 hdr->caplen, bytes_read);
660 }
661 return (-1);
662 }
663 bytes_to_discard -= amt_read;
664 }
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 hdr->caplen = p->snapshot;
671 } else {
672 /*
673 * The packet is within the snapshot length for this file.
674 */
675 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 u_int new_bufsize;
681
682 new_bufsize = hdr->caplen;
683 /*
684 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
685 */
686 new_bufsize--;
687 new_bufsize |= new_bufsize >> 1;
688 new_bufsize |= new_bufsize >> 2;
689 new_bufsize |= new_bufsize >> 4;
690 new_bufsize |= new_bufsize >> 8;
691 new_bufsize |= new_bufsize >> 16;
692 new_bufsize++;
693
694 if (new_bufsize > (u_int)p->snapshot)
695 new_bufsize = p->snapshot;
696
697 if (!grow_buffer(p, new_bufsize))
698 return (-1);
699 }
700
701 /* read the packet itself */
702 amt_read = fread(p->buffer, 1, hdr->caplen, fp);
703 if (amt_read != hdr->caplen) {
704 if (ferror(fp)) {
705 pcap_fmt_errmsg_for_errno(p->errbuf,
706 PCAP_ERRBUF_SIZE, errno,
707 "error reading dump file");
708 } else {
709 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
710 "truncated dump file; tried to read %u captured bytes, only got %zu",
711 hdr->caplen, amt_read);
712 }
713 return (-1);
714 }
715 }
716 *data = p->buffer;
717
718 pcap_post_process(p->linktype, p->swapped, hdr, *data);
719
720 return (1);
721 }
722
723 static int
724 sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen)
725 {
726 struct pcap_file_header hdr;
727
728 hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC;
729 hdr.version_major = PCAP_VERSION_MAJOR;
730 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 hdr.thiszone = 0;
738 hdr.sigfigs = 0;
739 hdr.snaplen = snaplen;
740 hdr.linktype = linktype;
741
742 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
743 return (-1);
744
745 return (0);
746 }
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 {
754 register FILE *f;
755 struct pcap_sf_pkthdr sf_hdr;
756
757 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 if (ferror(f))
775 return;
776 /*
777 * Better not try writing pcap files after
778 * 2038-01-19 03:14:07 UTC; switch to pcapng.
779 */
780 sf_hdr.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
781 sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
782 sf_hdr.caplen = h->caplen;
783 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 if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
793 (void)fwrite(sp, h->caplen, 1, f);
794 }
795 }
796
797 static pcap_dumper_t *
798 pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
799 {
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 if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
815 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
816 errno, "Can't write to %s", fname);
817 if (f != stdout)
818 (void)fclose(f);
819 return (NULL);
820 }
821 return ((pcap_dumper_t *)f);
822 }
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 {
830 FILE *f;
831 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 if (!p->activated) {
838 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
839 "%s: not-yet-activated pcap_t passed to pcap_dump_open",
840 fname);
841 return (NULL);
842 }
843 linktype = dlt_to_linktype(p->linktype);
844 if (linktype == -1) {
845 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
846 "%s: link-layer type %d isn't supported in savefiles",
847 fname, p->linktype);
848 return (NULL);
849 }
850 linktype |= p->linktype_ext;
851
852 if (fname == NULL) {
853 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
854 "A null pointer was supplied as the file name");
855 return NULL;
856 }
857 if (fname[0] == '-' && fname[1] == '\0') {
858 f = stdout;
859 fname = "standard output";
860 } 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 f = charset_fopen(fname, "wb");
868 if (f == NULL) {
869 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
870 errno, "%s", fname);
871 return (NULL);
872 }
873 }
874 return (pcap_setup_dump(p, linktype, f, fname));
875 }
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 {
916 int linktype;
917
918 linktype = dlt_to_linktype(p->linktype);
919 if (linktype == -1) {
920 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
921 "stream: link-layer type %d isn't supported in savefiles",
922 p->linktype);
923 return (NULL);
924 }
925 linktype |= p->linktype_ext;
926
927 return (pcap_setup_dump(p, linktype, f, "stream"));
928 }
929
930 pcap_dumper_t *
931 pcap_dump_open_append(pcap_t *p, const char *fname)
932 {
933 FILE *f;
934 int linktype;
935 size_t amt_read;
936 struct pcap_file_header ph;
937
938 linktype = dlt_to_linktype(p->linktype);
939 if (linktype == -1) {
940 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
941 "%s: link-layer type %d isn't supported in savefiles",
942 fname, linktype);
943 return (NULL);
944 }
945
946 if (fname == NULL) {
947 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
948 "A null pointer was supplied as the file name");
949 return NULL;
950 }
951 if (fname[0] == '-' && fname[1] == '\0')
952 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 f = charset_fopen(fname, "ab+");
968 if (f == NULL) {
969 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
970 errno, "%s", fname);
971 return (NULL);
972 }
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 if (fseek(f, 0, SEEK_SET) == -1) {
987 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
988 errno, "Can't seek to the beginning of %s", fname);
989 (void)fclose(f);
990 return (NULL);
991 }
992 amt_read = fread(&ph, 1, sizeof (ph), f);
993 if (amt_read != sizeof (ph)) {
994 if (ferror(f)) {
995 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
996 errno, "%s", fname);
997 (void)fclose(f);
998 return (NULL);
999 } else if (feof(f) && amt_read > 0) {
1000 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1001 "%s: truncated pcap file header", fname);
1002 (void)fclose(f);
1003 return (NULL);
1004 }
1005 }
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 if (amt_read > 0) {
1028 /*
1029 * A header is already present.
1030 * Do the checks.
1031 */
1032 switch (ph.magic) {
1033
1034 case TCPDUMP_MAGIC:
1035 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
1036 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1037 "%s: different time stamp precision, cannot append to file", fname);
1038 (void)fclose(f);
1039 return (NULL);
1040 }
1041 break;
1042
1043 case NSEC_TCPDUMP_MAGIC:
1044 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
1045 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1046 "%s: different time stamp precision, cannot append to file", fname);
1047 (void)fclose(f);
1048 return (NULL);
1049 }
1050 break;
1051
1052 case SWAPLONG(TCPDUMP_MAGIC):
1053 case SWAPLONG(NSEC_TCPDUMP_MAGIC):
1054 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1055 "%s: different byte order, cannot append to file", fname);
1056 (void)fclose(f);
1057 return (NULL);
1058
1059 case KUZNETZOV_TCPDUMP_MAGIC:
1060 case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
1061 case NAVTEL_TCPDUMP_MAGIC:
1062 case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
1063 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1064 "%s: not a pcap file to which we can append", fname);
1065 (void)fclose(f);
1066 return (NULL);
1067
1068 default:
1069 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1070 "%s: not a pcap file", fname);
1071 (void)fclose(f);
1072 return (NULL);
1073 }
1074
1075 /*
1076 * Good version?
1077 */
1078 if (ph.version_major != PCAP_VERSION_MAJOR ||
1079 ph.version_minor != PCAP_VERSION_MINOR) {
1080 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1081 "%s: version is %u.%u, cannot append to file", fname,
1082 ph.version_major, ph.version_minor);
1083 (void)fclose(f);
1084 return (NULL);
1085 }
1086 if ((bpf_u_int32)linktype != ph.linktype) {
1087 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1088 "%s: different linktype, cannot append to file", fname);
1089 (void)fclose(f);
1090 return (NULL);
1091 }
1092 if ((bpf_u_int32)p->snapshot != ph.snaplen) {
1093 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1094 "%s: different snaplen, cannot append to file", fname);
1095 (void)fclose(f);
1096 return (NULL);
1097 }
1098 } else {
1099 /*
1100 * A header isn't present; attempt to write it.
1101 */
1102 if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
1103 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1104 errno, "Can't write to %s", fname);
1105 (void)fclose(f);
1106 return (NULL);
1107 }
1108 }
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 if (fseek(f, 0, SEEK_END) == -1) {
1118 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1119 errno, "Can't seek to the end of %s", fname);
1120 (void)fclose(f);
1121 return (NULL);
1122 }
1123 return ((pcap_dumper_t *)f);
1124 }
1125
1126 FILE *
1127 pcap_dump_file(pcap_dumper_t *p)
1128 {
1129 return ((FILE *)p);
1130 }
1131
1132 long
1133 pcap_dump_ftell(pcap_dumper_t *p)
1134 {
1135 return (ftell((FILE *)p));
1136 }
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 {
1148 return (ftello((FILE *)p));
1149 }
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 {
1180
1181 if (fflush((FILE *)p) == EOF)
1182 return (-1);
1183 else
1184 return (0);
1185 }
1186
1187 void
1188 pcap_dump_close(pcap_dumper_t *p)
1189 {
1190
1191 #ifdef notyet
1192 if (ferror((FILE *)p))
1193 return-an-error;
1194 /* XXX should check return from fclose() too */
1195 #endif
1196 (void)fclose((FILE *)p);
1197 }