2 * Copyright (c) 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
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.
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.
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.
35 #include <pcap-types.h>
46 #include <limits.h> /* for INT_MAX */
50 #include "pcap-common.h"
52 #ifdef HAVE_OS_PROTO_H
59 * Setting O_BINARY on DOS/Windows is a bit tricky
62 #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
64 #if defined(__HIGHC__)
65 #define SET_BINMODE(f) setmode(f, O_BINARY)
67 #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
72 * Standard libpcap format.
74 #define TCPDUMP_MAGIC 0xa1b2c3d4
77 * Alexey Kuznetzov's modified libpcap format.
79 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
82 * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
83 * for another modified format.
85 #define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
88 * Navtel Communcations' format, with nanosecond timestamps,
89 * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
91 #define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
94 * Normal libpcap format, except for seconds/nanoseconds timestamps,
95 * as per a request by Ulf Lamping <ulf.lamping@web.de>
97 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
99 static int pcap_next_packet(pcap_t
*p
, struct pcap_pkthdr
*hdr
, u_char
**datap
);
103 * This isn't exported on Windows, because it would only work if both
104 * libpcap and the code using it were using the same C runtime; otherwise they
105 * would be using different definitions of a FILE structure.
107 * Instead we define this as a macro in pcap/pcap.h that wraps the hopen
108 * version that we do export, passing it a raw OS HANDLE, as defined by the
109 * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
110 * functions of the appropriate CRT.
112 static pcap_dumper_t
*pcap_dump_fopen(pcap_t
*p
, FILE *f
);
116 * Private data for reading pcap savefiles.
128 } tstamp_scale_type_t
;
132 swapped_type_t lengths_swapped
;
133 tstamp_scale_type_t scale_type
;
137 * Check whether this is a pcap savefile and, if it is, extract the
138 * relevant information from the header.
141 pcap_check_header(const uint8_t *magic
, FILE *fp
, u_int precision
, char *errbuf
,
144 bpf_u_int32 magic_int
;
145 struct pcap_file_header hdr
;
152 * Assume no read errors.
157 * Check whether the first 4 bytes of the file are the magic
158 * number for a pcap savefile, or for a byte-swapped pcap
161 memcpy(&magic_int
, magic
, sizeof(magic_int
));
162 if (magic_int
!= TCPDUMP_MAGIC
&&
163 magic_int
!= KUZNETZOV_TCPDUMP_MAGIC
&&
164 magic_int
!= NSEC_TCPDUMP_MAGIC
) {
165 magic_int
= SWAPLONG(magic_int
);
166 if (magic_int
!= TCPDUMP_MAGIC
&&
167 magic_int
!= KUZNETZOV_TCPDUMP_MAGIC
&&
168 magic_int
!= NSEC_TCPDUMP_MAGIC
)
169 return (NULL
); /* nope */
174 * They are. Put the magic number in the header, and read
175 * the rest of the header.
177 hdr
.magic
= magic_int
;
178 amt_read
= fread(((char *)&hdr
) + sizeof hdr
.magic
, 1,
179 sizeof(hdr
) - sizeof(hdr
.magic
), fp
);
180 if (amt_read
!= sizeof(hdr
) - sizeof(hdr
.magic
)) {
182 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
183 errno
, "error reading dump file");
185 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
186 "truncated dump file; tried to read %zu file header bytes, only got %zu",
187 sizeof(hdr
), amt_read
);
194 * If it's a byte-swapped capture file, byte-swap the header.
197 hdr
.version_major
= SWAPSHORT(hdr
.version_major
);
198 hdr
.version_minor
= SWAPSHORT(hdr
.version_minor
);
199 hdr
.thiszone
= SWAPLONG(hdr
.thiszone
);
200 hdr
.sigfigs
= SWAPLONG(hdr
.sigfigs
);
201 hdr
.snaplen
= SWAPLONG(hdr
.snaplen
);
202 hdr
.linktype
= SWAPLONG(hdr
.linktype
);
205 if (hdr
.version_major
< PCAP_VERSION_MAJOR
) {
206 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
207 "archaic pcap savefile format");
213 * currently only versions 2.[0-4] are supported with
214 * the exception of 543.0 for DG/UX tcpdump.
216 if (! ((hdr
.version_major
== PCAP_VERSION_MAJOR
&&
217 hdr
.version_minor
<= PCAP_VERSION_MINOR
) ||
218 (hdr
.version_major
== 543 &&
219 hdr
.version_minor
== 0))) {
220 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
221 "unsupported pcap savefile version %u.%u",
222 hdr
.version_major
, hdr
.version_minor
);
228 * Check the main reserved field.
230 if (LT_RESERVED1(hdr
.linktype
) != 0) {
231 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
232 "savefile linktype reserved field not zero (0x%08x)",
233 LT_RESERVED1(hdr
.linktype
));
239 * OK, this is a good pcap file.
240 * Allocate a pcap_t for it.
242 p
= PCAP_OPEN_OFFLINE_COMMON(errbuf
, struct pcap_sf
);
244 /* Allocation failed. */
248 p
->swapped
= swapped
;
249 p
->version_major
= hdr
.version_major
;
250 p
->version_minor
= hdr
.version_minor
;
251 p
->linktype
= linktype_to_dlt(LT_LINKTYPE(hdr
.linktype
));
252 p
->linktype_ext
= LT_LINKTYPE_EXT(hdr
.linktype
);
253 p
->snapshot
= pcap_adjust_snapshot(p
->linktype
, hdr
.snaplen
);
255 p
->next_packet_op
= pcap_next_packet
;
259 p
->opt
.tstamp_precision
= precision
;
262 * Will we need to scale the timestamps to match what the
267 case PCAP_TSTAMP_PRECISION_MICRO
:
268 if (magic_int
== NSEC_TCPDUMP_MAGIC
) {
270 * The file has nanoseconds, the user
271 * wants microseconds; scale the
274 ps
->scale_type
= SCALE_DOWN
;
277 * The file has microseconds, the
278 * user wants microseconds; nothing to do.
280 ps
->scale_type
= PASS_THROUGH
;
284 case PCAP_TSTAMP_PRECISION_NANO
:
285 if (magic_int
== NSEC_TCPDUMP_MAGIC
) {
287 * The file has nanoseconds, the
288 * user wants nanoseconds; nothing to do.
290 ps
->scale_type
= PASS_THROUGH
;
293 * The file has microseconds, the user
294 * wants nanoseconds; scale the
297 ps
->scale_type
= SCALE_UP
;
302 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
303 "unknown time stamp resolution %u", precision
);
310 * We interchanged the caplen and len fields at version 2.3,
311 * in order to match the bpf header layout. But unfortunately
312 * some files were written with version 2.3 in their headers
313 * but without the interchanged fields.
315 * In addition, DG/UX tcpdump writes out files with a version
316 * number of 543.0, and with the caplen and len fields in the
319 switch (hdr
.version_major
) {
322 if (hdr
.version_minor
< 3)
323 ps
->lengths_swapped
= SWAPPED
;
324 else if (hdr
.version_minor
== 3)
325 ps
->lengths_swapped
= MAYBE_SWAPPED
;
327 ps
->lengths_swapped
= NOT_SWAPPED
;
331 ps
->lengths_swapped
= SWAPPED
;
335 ps
->lengths_swapped
= NOT_SWAPPED
;
339 if (magic_int
== KUZNETZOV_TCPDUMP_MAGIC
) {
341 * XXX - the patch that's in some versions of libpcap
342 * changes the packet header but not the magic number,
343 * and some other versions with this magic number have
344 * some extra debugging information in the packet header;
345 * we'd have to use some hacks^H^H^H^H^Hheuristics to
346 * detect those variants.
348 * Ethereal does that, but it does so by trying to read
349 * the first two packets of the file with each of the
350 * record header formats. That currently means it seeks
351 * backwards and retries the reads, which doesn't work
352 * on pipes. We want to be able to read from a pipe, so
353 * that strategy won't work; we'd have to buffer some
354 * data ourselves and read from that buffer in order to
357 ps
->hdrsize
= sizeof(struct pcap_sf_patched_pkthdr
);
359 if (p
->linktype
== DLT_EN10MB
) {
361 * This capture might have been done in raw mode
364 * If it was done in cooked mode, p->snapshot was
365 * passed to recvfrom() as the buffer size, meaning
366 * that the most packet data that would be copied
367 * would be p->snapshot. However, a faked Ethernet
368 * header would then have been added to it, so the
369 * most data that would be in a packet in the file
370 * would be p->snapshot + 14.
372 * We can't easily tell whether the capture was done
373 * in raw mode or cooked mode, so we'll assume it was
374 * cooked mode, and add 14 to the snapshot length.
375 * That means that, for a raw capture, the snapshot
376 * length will be misleading if you use it to figure
377 * out why a capture doesn't have all the packet data,
378 * but there's not much we can do to avoid that.
380 * But don't grow the snapshot length past the
381 * maximum value of an int.
383 if (p
->snapshot
<= INT_MAX
- 14)
386 p
->snapshot
= INT_MAX
;
389 ps
->hdrsize
= sizeof(struct pcap_sf_pkthdr
);
392 * Allocate a buffer for the packet data.
393 * Choose the minimum of the file's snapshot length and 2K bytes;
394 * that should be enough for most network packets - we'll grow it
395 * if necessary. That way, we don't allocate a huge chunk of
396 * memory just because there's a huge snapshot length, as the
397 * snapshot length might be larger than the size of the largest
400 p
->bufsize
= p
->snapshot
;
401 if (p
->bufsize
> 2048)
403 p
->buffer
= malloc(p
->bufsize
);
404 if (p
->buffer
== NULL
) {
405 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "out of memory");
411 p
->cleanup_op
= sf_cleanup
;
417 * Grow the packet buffer to the specified size.
420 grow_buffer(pcap_t
*p
, u_int bufsize
)
424 bigger_buffer
= realloc(p
->buffer
, bufsize
);
425 if (bigger_buffer
== NULL
) {
426 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "out of memory");
429 p
->buffer
= bigger_buffer
;
430 p
->bufsize
= bufsize
;
435 * Read and return the next packet from the savefile. Return the header
436 * in hdr and a pointer to the contents in data. Return 1 on success, 0
437 * if there were no more packets, and -1 on an error.
440 pcap_next_packet(pcap_t
*p
, struct pcap_pkthdr
*hdr
, u_char
**data
)
442 struct pcap_sf
*ps
= p
->priv
;
443 struct pcap_sf_patched_pkthdr sf_hdr
;
449 * Read the packet header; the structure we use as a buffer
450 * is the longer structure for files generated by the patched
451 * libpcap, but if the file has the magic number for an
452 * unpatched libpcap we only read as many bytes as the regular
455 amt_read
= fread(&sf_hdr
, 1, ps
->hdrsize
, fp
);
456 if (amt_read
!= ps
->hdrsize
) {
458 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
459 errno
, "error reading dump file");
463 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
464 "truncated dump file; tried to read %zu header bytes, only got %zu",
465 ps
->hdrsize
, amt_read
);
474 /* these were written in opposite byte order */
475 hdr
->caplen
= SWAPLONG(sf_hdr
.caplen
);
476 hdr
->len
= SWAPLONG(sf_hdr
.len
);
477 hdr
->ts
.tv_sec
= SWAPLONG(sf_hdr
.ts
.tv_sec
);
478 hdr
->ts
.tv_usec
= SWAPLONG(sf_hdr
.ts
.tv_usec
);
480 hdr
->caplen
= sf_hdr
.caplen
;
481 hdr
->len
= sf_hdr
.len
;
482 hdr
->ts
.tv_sec
= sf_hdr
.ts
.tv_sec
;
483 hdr
->ts
.tv_usec
= sf_hdr
.ts
.tv_usec
;
486 switch (ps
->scale_type
) {
490 * Just pass the time stamp through.
496 * File has microseconds, user wants nanoseconds; convert
499 hdr
->ts
.tv_usec
= hdr
->ts
.tv_usec
* 1000;
504 * File has nanoseconds, user wants microseconds; convert
507 hdr
->ts
.tv_usec
= hdr
->ts
.tv_usec
/ 1000;
511 /* Swap the caplen and len fields, if necessary. */
512 switch (ps
->lengths_swapped
) {
518 if (hdr
->caplen
<= hdr
->len
) {
520 * The captured length is <= the actual length,
521 * so presumably they weren't swapped.
529 hdr
->caplen
= hdr
->len
;
535 * Is the packet bigger than we consider sane?
537 if (hdr
->caplen
> max_snaplen_for_dlt(p
->linktype
)) {
539 * Yes. This may be a damaged or fuzzed file.
541 * Is it bigger than the snapshot length?
542 * (We don't treat that as an error if it's not
543 * bigger than the maximum we consider sane; see
546 if (hdr
->caplen
> (bpf_u_int32
)p
->snapshot
) {
547 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
548 "invalid packet capture length %u, bigger than "
549 "snaplen of %d", hdr
->caplen
, p
->snapshot
);
551 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
552 "invalid packet capture length %u, bigger than "
553 "maximum of %u", hdr
->caplen
,
554 max_snaplen_for_dlt(p
->linktype
));
559 if (hdr
->caplen
> (bpf_u_int32
)p
->snapshot
) {
561 * The packet is bigger than the snapshot length
564 * This can happen due to Solaris 2.3 systems tripping
565 * over the BUFMOD problem and not setting the snapshot
566 * length correctly in the savefile header.
568 * libpcap 0.4 and later on Solaris 2.3 should set the
569 * snapshot length correctly in the pcap file header,
570 * even though they don't set a snapshot length in bufmod
571 * (the buggy bufmod chops off the *beginning* of the
572 * packet if a snapshot length is specified); they should
573 * also reduce the captured length, as supplied to the
574 * per-packet callback, to the snapshot length if it's
575 * greater than the snapshot length, so the code using
576 * libpcap should see the packet cut off at the snapshot
577 * length, even though the full packet is copied up to
580 * However, perhaps some versions of libpcap failed to
581 * set the snapshot length currectly in the file header
582 * or the per-packet header, or perhaps this is a
583 * corrupted safefile or a savefile built/modified by a
584 * fuzz tester, so we check anyway. We grow the buffer
585 * to be big enough for the snapshot length, read up
586 * to the snapshot length, discard the rest of the
587 * packet, and report the snapshot length as the captured
588 * length; we don't want to hand our caller a packet
589 * bigger than the snapshot length, because they might
590 * be assuming they'll never be handed such a packet,
591 * and might copy the packet into a snapshot-length-
592 * sized buffer, assuming it'll fit.
594 size_t bytes_to_discard
;
595 size_t bytes_to_read
, bytes_read
;
596 char discard_buf
[4096];
598 if (hdr
->caplen
> p
->bufsize
) {
600 * Grow the buffer to the snapshot length.
602 if (!grow_buffer(p
, p
->snapshot
))
607 * Read the first p->snapshot bytes into the buffer.
609 amt_read
= fread(p
->buffer
, 1, p
->snapshot
, fp
);
610 if (amt_read
!= (bpf_u_int32
)p
->snapshot
) {
612 pcap_fmt_errmsg_for_errno(p
->errbuf
,
613 PCAP_ERRBUF_SIZE
, errno
,
614 "error reading dump file");
617 * Yes, this uses hdr->caplen; technically,
618 * it's true, because we would try to read
619 * and discard the rest of those bytes, and
620 * that would fail because we got EOF before
623 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
624 "truncated dump file; tried to read %d captured bytes, only got %zu",
625 p
->snapshot
, amt_read
);
631 * Now read and discard what's left.
633 bytes_to_discard
= hdr
->caplen
- p
->snapshot
;
634 bytes_read
= amt_read
;
635 while (bytes_to_discard
!= 0) {
636 bytes_to_read
= bytes_to_discard
;
637 if (bytes_to_read
> sizeof (discard_buf
))
638 bytes_to_read
= sizeof (discard_buf
);
639 amt_read
= fread(discard_buf
, 1, bytes_to_read
, fp
);
640 bytes_read
+= amt_read
;
641 if (amt_read
!= bytes_to_read
) {
643 pcap_fmt_errmsg_for_errno(p
->errbuf
,
644 PCAP_ERRBUF_SIZE
, errno
,
645 "error reading dump file");
647 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
648 "truncated dump file; tried to read %u captured bytes, only got %zu",
649 hdr
->caplen
, bytes_read
);
653 bytes_to_discard
-= amt_read
;
657 * Adjust caplen accordingly, so we don't get confused later
658 * as to how many bytes we have to play with.
660 hdr
->caplen
= p
->snapshot
;
663 * The packet is within the snapshot length for this file.
665 if (hdr
->caplen
> p
->bufsize
) {
667 * Grow the buffer to the next power of 2, or
668 * the snaplen, whichever is lower.
672 new_bufsize
= hdr
->caplen
;
674 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
677 new_bufsize
|= new_bufsize
>> 1;
678 new_bufsize
|= new_bufsize
>> 2;
679 new_bufsize
|= new_bufsize
>> 4;
680 new_bufsize
|= new_bufsize
>> 8;
681 new_bufsize
|= new_bufsize
>> 16;
684 if (new_bufsize
> (u_int
)p
->snapshot
)
685 new_bufsize
= p
->snapshot
;
687 if (!grow_buffer(p
, new_bufsize
))
691 /* read the packet itself */
692 amt_read
= fread(p
->buffer
, 1, hdr
->caplen
, fp
);
693 if (amt_read
!= hdr
->caplen
) {
695 pcap_fmt_errmsg_for_errno(p
->errbuf
,
696 PCAP_ERRBUF_SIZE
, errno
,
697 "error reading dump file");
699 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
700 "truncated dump file; tried to read %u captured bytes, only got %zu",
701 hdr
->caplen
, amt_read
);
709 swap_pseudo_headers(p
->linktype
, hdr
, *data
);
711 fixup_pcap_pkthdr(p
->linktype
, hdr
, *data
);
717 sf_write_header(pcap_t
*p
, FILE *fp
, int linktype
, int snaplen
)
719 struct pcap_file_header hdr
;
721 hdr
.magic
= p
->opt
.tstamp_precision
== PCAP_TSTAMP_PRECISION_NANO
? NSEC_TCPDUMP_MAGIC
: TCPDUMP_MAGIC
;
722 hdr
.version_major
= PCAP_VERSION_MAJOR
;
723 hdr
.version_minor
= PCAP_VERSION_MINOR
;
726 * https://www.tcpdump.org/manpages/pcap-savefile.5.txt states:
727 * thiszone: 4-byte time zone offset; this is always 0.
728 * sigfigs: 4-byte number giving the accuracy of time stamps
729 * in the file; this is always 0.
733 hdr
.snaplen
= snaplen
;
734 hdr
.linktype
= linktype
;
736 if (fwrite((char *)&hdr
, sizeof(hdr
), 1, fp
) != 1)
743 * Output a packet to the initialized dump file.
746 pcap_dump(u_char
*user
, const struct pcap_pkthdr
*h
, const u_char
*sp
)
749 struct pcap_sf_pkthdr sf_hdr
;
753 * If the output file handle is in an error state, don't write
756 * While in principle a file handle can return from an error state
757 * to a normal state (for example if a disk that is full has space
758 * freed), we have possibly left a broken file already, and won't
759 * be able to clean it up. The safest option is to do nothing.
761 * Note that if we could guarantee that fwrite() was atomic we
762 * might be able to insure that we don't produce a corrupted file,
763 * but the standard defines fwrite() as a series of fputc() calls,
764 * so we really have no insurance that things are not fubared.
766 * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
771 * Better not try writing pcap files after
772 * 2038-01-19 03:14:07 UTC; switch to pcapng.
774 sf_hdr
.ts
.tv_sec
= (bpf_int32
)h
->ts
.tv_sec
;
775 sf_hdr
.ts
.tv_usec
= (bpf_int32
)h
->ts
.tv_usec
;
776 sf_hdr
.caplen
= h
->caplen
;
779 * We only write the packet if we can write the header properly.
781 * This doesn't prevent us from having corrupted output, and if we
782 * for some reason don't get a complete write we don't have any
783 * way to set ferror() to prevent future writes from being
784 * attempted, but it is better than nothing.
786 if (fwrite(&sf_hdr
, sizeof(sf_hdr
), 1, f
) == 1) {
787 (void)fwrite(sp
, h
->caplen
, 1, f
);
791 static pcap_dumper_t
*
792 pcap_setup_dump(pcap_t
*p
, int linktype
, FILE *f
, const char *fname
)
795 #if defined(_WIN32) || defined(MSDOS)
797 * If we're writing to the standard output, put it in binary
798 * mode, as savefiles are binary files.
800 * Otherwise, we turn off buffering.
801 * XXX - why? And why not on the standard output?
806 setvbuf(f
, NULL
, _IONBF
, 0);
808 if (sf_write_header(p
, f
, linktype
, p
->snapshot
) == -1) {
809 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
810 errno
, "Can't write to %s", fname
);
815 return ((pcap_dumper_t
*)f
);
819 * Initialize so that sf_write() will output to the file named 'fname'.
822 pcap_dump_open(pcap_t
*p
, const char *fname
)
828 * If this pcap_t hasn't been activated, it doesn't have a
829 * link-layer type, so we can't use it.
832 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
833 "%s: not-yet-activated pcap_t passed to pcap_dump_open",
837 linktype
= dlt_to_linktype(p
->linktype
);
838 if (linktype
== -1) {
839 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
840 "%s: link-layer type %d isn't supported in savefiles",
844 linktype
|= p
->linktype_ext
;
847 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
848 "A null pointer was supplied as the file name");
851 if (fname
[0] == '-' && fname
[1] == '\0') {
853 fname
= "standard output";
856 * "b" is supported as of C90, so *all* UN*Xes should
857 * support it, even though it does nothing. It's
858 * required on Windows, as the file is a binary file
859 * and must be written in binary mode.
861 f
= charset_fopen(fname
, "wb");
863 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
868 return (pcap_setup_dump(p
, linktype
, f
, fname
));
873 * Initialize so that sf_write() will output to a stream wrapping the given raw
877 pcap_dump_hopen(pcap_t
*p
, intptr_t osfd
)
882 fd
= _open_osfhandle(osfd
, _O_APPEND
);
884 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
885 errno
, "_open_osfhandle");
889 file
= _fdopen(fd
, "wb");
891 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
897 return pcap_dump_fopen(p
, file
);
902 * Initialize so that sf_write() will output to the given stream.
908 pcap_dump_fopen(pcap_t
*p
, FILE *f
)
912 linktype
= dlt_to_linktype(p
->linktype
);
913 if (linktype
== -1) {
914 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
915 "stream: link-layer type %d isn't supported in savefiles",
919 linktype
|= p
->linktype_ext
;
921 return (pcap_setup_dump(p
, linktype
, f
, "stream"));
925 pcap_dump_open_append(pcap_t
*p
, const char *fname
)
930 struct pcap_file_header ph
;
932 linktype
= dlt_to_linktype(p
->linktype
);
933 if (linktype
== -1) {
934 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
935 "%s: link-layer type %d isn't supported in savefiles",
941 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
942 "A null pointer was supplied as the file name");
945 if (fname
[0] == '-' && fname
[1] == '\0')
946 return (pcap_setup_dump(p
, linktype
, stdout
, "standard output"));
949 * "a" will cause the file *not* to be truncated if it exists
950 * but will cause it to be created if it doesn't. It will
951 * also cause all writes to be done at the end of the file,
952 * but will allow reads to be done anywhere in the file. This
953 * is what we need, because we need to read from the beginning
954 * of the file to see if it already has a header and packets
957 * "b" is supported as of C90, so *all* UN*Xes should support it,
958 * even though it does nothing. It's required on Windows, as the
959 * file is a binary file and must be read in binary mode.
961 f
= charset_fopen(fname
, "ab+");
963 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
969 * Try to read a pcap header.
971 * We do not assume that the file will be positioned at the
972 * beginning immediately after we've opened it - we seek to
973 * the beginning. ISO C says it's implementation-defined
974 * whether the file position indicator is at the beginning
975 * or the end of the file after an append-mode open, and
976 * it wasn't obvious from the Single UNIX Specification
977 * or the Microsoft documentation how that works on SUS-
978 * compliant systems or on Windows.
980 if (fseek(f
, 0, SEEK_SET
) == -1) {
981 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
982 errno
, "Can't seek to the beginning of %s", fname
);
986 amt_read
= fread(&ph
, 1, sizeof (ph
), f
);
987 if (amt_read
!= sizeof (ph
)) {
989 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
993 } else if (feof(f
) && amt_read
> 0) {
994 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
995 "%s: truncated pcap file header", fname
);
1001 #if defined(_WIN32) || defined(MSDOS)
1003 * We turn off buffering.
1004 * XXX - why? And why not on the standard output?
1006 setvbuf(f
, NULL
, _IONBF
, 0);
1010 * If a header is already present and:
1012 * it's not for a pcap file of the appropriate resolution
1013 * and the right byte order for this machine;
1015 * the link-layer header types don't match;
1017 * the snapshot lengths don't match;
1023 * A header is already present.
1029 if (p
->opt
.tstamp_precision
!= PCAP_TSTAMP_PRECISION_MICRO
) {
1030 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1031 "%s: different time stamp precision, cannot append to file", fname
);
1037 case NSEC_TCPDUMP_MAGIC
:
1038 if (p
->opt
.tstamp_precision
!= PCAP_TSTAMP_PRECISION_NANO
) {
1039 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1040 "%s: different time stamp precision, cannot append to file", fname
);
1046 case SWAPLONG(TCPDUMP_MAGIC
):
1047 case SWAPLONG(NSEC_TCPDUMP_MAGIC
):
1048 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1049 "%s: different byte order, cannot append to file", fname
);
1053 case KUZNETZOV_TCPDUMP_MAGIC
:
1054 case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC
):
1055 case NAVTEL_TCPDUMP_MAGIC
:
1056 case SWAPLONG(NAVTEL_TCPDUMP_MAGIC
):
1057 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1058 "%s: not a pcap file to which we can append", fname
);
1063 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1064 "%s: not a pcap file", fname
);
1072 if (ph
.version_major
!= PCAP_VERSION_MAJOR
||
1073 ph
.version_minor
!= PCAP_VERSION_MINOR
) {
1074 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1075 "%s: version is %u.%u, cannot append to file", fname
,
1076 ph
.version_major
, ph
.version_minor
);
1080 if ((bpf_u_int32
)linktype
!= ph
.linktype
) {
1081 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1082 "%s: different linktype, cannot append to file", fname
);
1086 if ((bpf_u_int32
)p
->snapshot
!= ph
.snaplen
) {
1087 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1088 "%s: different snaplen, cannot append to file", fname
);
1094 * A header isn't present; attempt to write it.
1096 if (sf_write_header(p
, f
, linktype
, p
->snapshot
) == -1) {
1097 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1098 errno
, "Can't write to %s", fname
);
1105 * Start writing at the end of the file.
1107 * XXX - this shouldn't be necessary, given that we're opening
1108 * the file in append mode, and ISO C specifies that all writes
1109 * are done at the end of the file in that mode.
1111 if (fseek(f
, 0, SEEK_END
) == -1) {
1112 pcap_fmt_errmsg_for_errno(p
->errbuf
, PCAP_ERRBUF_SIZE
,
1113 errno
, "Can't seek to the end of %s", fname
);
1117 return ((pcap_dumper_t
*)f
);
1121 pcap_dump_file(pcap_dumper_t
*p
)
1127 pcap_dump_ftell(pcap_dumper_t
*p
)
1129 return (ftell((FILE *)p
));
1132 #if defined(HAVE_FSEEKO)
1134 * We have fseeko(), so we have ftello().
1135 * If we have large file support (files larger than 2^31-1 bytes),
1136 * ftello() will give us a current file position with more than 32
1140 pcap_dump_ftell64(pcap_dumper_t
*p
)
1142 return (ftello((FILE *)p
));
1144 #elif defined(_MSC_VER)
1146 * We have Visual Studio; we support only 2005 and later, so we have
1150 pcap_dump_ftell64(pcap_dumper_t
*p
)
1152 return (_ftelli64((FILE *)p
));
1156 * We don't have ftello() or _ftelli64(), so fall back on ftell().
1157 * Either long is 64 bits, in which case ftell() should suffice,
1158 * or this is probably an older 32-bit UN*X without large file
1159 * support, which means you'll probably get errors trying to
1160 * write files > 2^31-1, so it won't matter anyway.
1162 * XXX - what about MinGW?
1165 pcap_dump_ftell64(pcap_dumper_t
*p
)
1167 return (ftell((FILE *)p
));
1172 pcap_dump_flush(pcap_dumper_t
*p
)
1175 if (fflush((FILE *)p
) == EOF
)
1182 pcap_dump_close(pcap_dumper_t
*p
)
1186 if (ferror((FILE *)p
))
1188 /* XXX should check return from fclose() too */
1190 (void)fclose((FILE *)p
);