/*
 * Copyright (c) 1993, 1994, 1995, 1996, 1997
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * sf-pcap.c - libpcap-file-format-specific code from savefile.c
 *	Extraction/creation by Jeffrey Mogul, DECWRL
 *	Modified by Steve McCanne, LBL.
 *
 * Used to save the received packet headers, after filtering, to
 * a file, and then read them later.
 * The first record in the file contains saved values for the machine
 * dependent values so we can print the dump file on any architecture.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <pcap-types.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif /* _WIN32 */

#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h> /* for INT_MAX */

#include "pcap-int.h"
#include "pcap-util.h"

#include "pcap-common.h"

#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif

#include "sf-pcap.h"

/*
 * Setting O_BINARY on DOS/Windows is a bit tricky
 */
#if defined(_WIN32)
  #define SET_BINMODE(f)  _setmode(_fileno(f), _O_BINARY)
#elif defined(MSDOS)
  #if defined(__HIGHC__)
  #define SET_BINMODE(f)  setmode(f, O_BINARY)
  #else
  #define SET_BINMODE(f)  setmode(fileno(f), O_BINARY)
  #endif
#endif

/*
 * Standard libpcap format.
 *
 * The same value is used in the rpcap protocol as an indication of
 * the server byte order, to let the client know whether it needs to
 * byte-swap some host-byte-order metadata.
 */
#define TCPDUMP_MAGIC		0xa1b2c3d4

/*
 * Alexey Kuznetzov's modified libpcap format.
 */
#define KUZNETZOV_TCPDUMP_MAGIC	0xa1b2cd34

/*
 * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
 * for another modified format.
 */
#define FMESQUITA_TCPDUMP_MAGIC	0xa1b234cd

/*
 * Navtel Communcations' format, with nanosecond timestamps,
 * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
 */
#define NAVTEL_TCPDUMP_MAGIC	0xa12b3c4d

/*
 * Normal libpcap format, except for seconds/nanoseconds timestamps,
 * as per a request by Ulf Lamping <ulf.lamping@web.de>
 */
#define NSEC_TCPDUMP_MAGIC	0xa1b23c4d

/*
 * Mechanism for storing information about a capture in the upper
 * 6 bits of a linktype value in a capture file.
 *
 * LT_LINKTYPE_EXT(x) extracts the additional information.
 *
 * The rest of the bits are for a value describing the link-layer
 * value.  LT_LINKTYPE(x) extracts that value.
 */
#define LT_LINKTYPE(x)		((x) & 0x03FFFFFF)
#define LT_LINKTYPE_EXT(x)	((x) & 0xFC000000)

static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);

#ifdef _WIN32
/*
 * This isn't exported on Windows, because it would only work if both
 * libpcap and the code using it were using the same C runtime; otherwise they
 * would be using different definitions of a FILE structure.
 *
 * Instead we define this as a macro in pcap/pcap.h that wraps the hopen
 * version that we do export, passing it a raw OS HANDLE, as defined by the
 * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
 * functions of the appropriate CRT.
 */
static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f);
#endif /* _WIN32 */

/*
 * Private data for reading pcap savefiles.
 */
typedef enum {
	NOT_SWAPPED,
	SWAPPED,
	MAYBE_SWAPPED
} swapped_type_t;

typedef enum {
	PASS_THROUGH,
	SCALE_UP,
	SCALE_DOWN
} tstamp_scale_type_t;

struct pcap_sf {
	size_t hdrsize;
	swapped_type_t lengths_swapped;
	tstamp_scale_type_t scale_type;
};

/*
 * Check whether this is a pcap savefile and, if it is, extract the
 * relevant information from the header.
 */
pcap_t *
pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
		  int *err)
{
	bpf_u_int32 magic_int;
	struct pcap_file_header hdr;
	size_t amt_read;
	pcap_t *p;
	int swapped = 0;
	struct pcap_sf *ps;

	/*
	 * Assume no read errors.
	 */
	*err = 0;

	/*
	 * Check whether the first 4 bytes of the file are the magic
	 * number for a pcap savefile, or for a byte-swapped pcap
	 * savefile.
	 */
	memcpy(&magic_int, magic, sizeof(magic_int));
	if (magic_int != TCPDUMP_MAGIC &&
	    magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
	    magic_int != NSEC_TCPDUMP_MAGIC) {
		magic_int = SWAPLONG(magic_int);
		if (magic_int != TCPDUMP_MAGIC &&
		    magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
		    magic_int != NSEC_TCPDUMP_MAGIC)
			return (NULL);	/* nope */
		swapped = 1;
	}

	/*
	 * They are.  Put the magic number in the header, and read
	 * the rest of the header.
	 */
	hdr.magic = magic_int;
	amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
	    sizeof(hdr) - sizeof(hdr.magic), fp);
	if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
		if (ferror(fp)) {
			pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
			    errno, "error reading dump file");
		} else {
			snprintf(errbuf, PCAP_ERRBUF_SIZE,
			    "truncated dump file; tried to read %zu file header bytes, only got %zu",
			    sizeof(hdr), amt_read);
		}
		*err = 1;
		return (NULL);
	}

	/*
	 * If it's a byte-swapped capture file, byte-swap the header.
	 */
	if (swapped) {
		hdr.version_major = SWAPSHORT(hdr.version_major);
		hdr.version_minor = SWAPSHORT(hdr.version_minor);
		hdr.thiszone = SWAPLONG(hdr.thiszone);
		hdr.sigfigs = SWAPLONG(hdr.sigfigs);
		hdr.snaplen = SWAPLONG(hdr.snaplen);
		hdr.linktype = SWAPLONG(hdr.linktype);
	}

	if (hdr.version_major < PCAP_VERSION_MAJOR) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
		    "archaic pcap savefile format");
		*err = 1;
		return (NULL);
	}

	/*
	 * currently only versions 2.[0-4] are supported with
	 * the exception of 543.0 for DG/UX tcpdump.
	 */
	if (! ((hdr.version_major == PCAP_VERSION_MAJOR &&
		hdr.version_minor <= PCAP_VERSION_MINOR) ||
	       (hdr.version_major == 543 &&
		hdr.version_minor == 0))) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
			 "unsupported pcap savefile version %u.%u",
			 hdr.version_major, hdr.version_minor);
		*err = 1;
		return NULL;
	}

	/*
	 * OK, this is a good pcap file.
	 * Allocate a pcap_t for it.
	 */
	p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
	if (p == NULL) {
		/* Allocation failed. */
		*err = 1;
		return (NULL);
	}
	p->swapped = swapped;
	p->version_major = hdr.version_major;
	p->version_minor = hdr.version_minor;
	p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
	p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
	p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);

	p->next_packet_op = pcap_next_packet;

	ps = p->priv;

	p->opt.tstamp_precision = precision;

	/*
	 * Will we need to scale the timestamps to match what the
	 * user wants?
	 */
	switch (precision) {

	case PCAP_TSTAMP_PRECISION_MICRO:
		if (magic_int == NSEC_TCPDUMP_MAGIC) {
			/*
			 * The file has nanoseconds, the user
			 * wants microseconds; scale the
			 * precision down.
			 */
			ps->scale_type = SCALE_DOWN;
		} else {
			/*
			 * The file has microseconds, the
			 * user wants microseconds; nothing to do.
			 */
			ps->scale_type = PASS_THROUGH;
		}
		break;

	case PCAP_TSTAMP_PRECISION_NANO:
		if (magic_int == NSEC_TCPDUMP_MAGIC) {
			/*
			 * The file has nanoseconds, the
			 * user wants nanoseconds; nothing to do.
			 */
			ps->scale_type = PASS_THROUGH;
		} else {
			/*
			 * The file has microseconds, the user
			 * wants nanoseconds; scale the
			 * precision up.
			 */
			ps->scale_type = SCALE_UP;
		}
		break;

	default:
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
		    "unknown time stamp resolution %u", precision);
		free(p);
		*err = 1;
		return (NULL);
	}

	/*
	 * We interchanged the caplen and len fields at version 2.3,
	 * in order to match the bpf header layout.  But unfortunately
	 * some files were written with version 2.3 in their headers
	 * but without the interchanged fields.
	 *
	 * In addition, DG/UX tcpdump writes out files with a version
	 * number of 543.0, and with the caplen and len fields in the
	 * pre-2.3 order.
	 */
	switch (hdr.version_major) {

	case 2:
		if (hdr.version_minor < 3)
			ps->lengths_swapped = SWAPPED;
		else if (hdr.version_minor == 3)
			ps->lengths_swapped = MAYBE_SWAPPED;
		else
			ps->lengths_swapped = NOT_SWAPPED;
		break;

	case 543:
		ps->lengths_swapped = SWAPPED;
		break;

	default:
		ps->lengths_swapped = NOT_SWAPPED;
		break;
	}

	if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
		/*
		 * XXX - the patch that's in some versions of libpcap
		 * changes the packet header but not the magic number,
		 * and some other versions with this magic number have
		 * some extra debugging information in the packet header;
		 * we'd have to use some hacks^H^H^H^H^Hheuristics to
		 * detect those variants.
		 *
		 * Ethereal does that, but it does so by trying to read
		 * the first two packets of the file with each of the
		 * record header formats.  That currently means it seeks
		 * backwards and retries the reads, which doesn't work
		 * on pipes.  We want to be able to read from a pipe, so
		 * that strategy won't work; we'd have to buffer some
		 * data ourselves and read from that buffer in order to
		 * make that work.
		 */
		ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);

		if (p->linktype == DLT_EN10MB) {
			/*
			 * This capture might have been done in raw mode
			 * or cooked mode.
			 *
			 * If it was done in cooked mode, p->snapshot was
			 * passed to recvfrom() as the buffer size, meaning
			 * that the most packet data that would be copied
			 * would be p->snapshot.  However, a faked Ethernet
			 * header would then have been added to it, so the
			 * most data that would be in a packet in the file
			 * would be p->snapshot + 14.
			 *
			 * We can't easily tell whether the capture was done
			 * in raw mode or cooked mode, so we'll assume it was
			 * cooked mode, and add 14 to the snapshot length.
			 * That means that, for a raw capture, the snapshot
			 * length will be misleading if you use it to figure
			 * out why a capture doesn't have all the packet data,
			 * but there's not much we can do to avoid that.
			 *
			 * But don't grow the snapshot length past the
			 * maximum value of an int.
			 */
			if (p->snapshot <= INT_MAX - 14)
				p->snapshot += 14;
			else
				p->snapshot = INT_MAX;
		}
	} else
		ps->hdrsize = sizeof(struct pcap_sf_pkthdr);

	/*
	 * Allocate a buffer for the packet data.
	 * Choose the minimum of the file's snapshot length and 2K bytes;
	 * that should be enough for most network packets - we'll grow it
	 * if necessary.  That way, we don't allocate a huge chunk of
	 * memory just because there's a huge snapshot length, as the
	 * snapshot length might be larger than the size of the largest
	 * packet.
	 */
	p->bufsize = p->snapshot;
	if (p->bufsize > 2048)
		p->bufsize = 2048;
	p->buffer = malloc(p->bufsize);
	if (p->buffer == NULL) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
		free(p);
		*err = 1;
		return (NULL);
	}

	p->cleanup_op = sf_cleanup;

	return (p);
}

/*
 * Grow the packet buffer to the specified size.
 */
static int
grow_buffer(pcap_t *p, u_int bufsize)
{
	void *bigger_buffer;

	bigger_buffer = realloc(p->buffer, bufsize);
	if (bigger_buffer == NULL) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
		return (0);
	}
	p->buffer = bigger_buffer;
	p->bufsize = bufsize;
	return (1);
}

/*
 * Read and return the next packet from the savefile.  Return the header
 * in hdr and a pointer to the contents in data.  Return 1 on success, 0
 * if there were no more packets, and -1 on an error.
 */
static int
pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
{
	struct pcap_sf *ps = p->priv;
	struct pcap_sf_patched_pkthdr sf_hdr;
	FILE *fp = p->rfile;
	size_t amt_read;
	bpf_u_int32 t;

	/*
	 * Read the packet header; the structure we use as a buffer
	 * is the longer structure for files generated by the patched
	 * libpcap, but if the file has the magic number for an
	 * unpatched libpcap we only read as many bytes as the regular
	 * header has.
	 */
	amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
	if (amt_read != ps->hdrsize) {
		if (ferror(fp)) {
			pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
			    errno, "error reading dump file");
			return (-1);
		} else {
			if (amt_read != 0) {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "truncated dump file; tried to read %zu header bytes, only got %zu",
				    ps->hdrsize, amt_read);
				return (-1);
			}
			/* EOF */
			return (0);
		}
	}

	if (p->swapped) {
		/* these were written in opposite byte order */
		hdr->caplen = SWAPLONG(sf_hdr.caplen);
		hdr->len = SWAPLONG(sf_hdr.len);
		hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
		hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
	} else {
		hdr->caplen = sf_hdr.caplen;
		hdr->len = sf_hdr.len;
		hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
		hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
	}

	switch (ps->scale_type) {

	case PASS_THROUGH:
		/*
		 * Just pass the time stamp through.
		 */
		break;

	case SCALE_UP:
		/*
		 * File has microseconds, user wants nanoseconds; convert
		 * it.
		 */
		hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
		break;

	case SCALE_DOWN:
		/*
		 * File has nanoseconds, user wants microseconds; convert
		 * it.
		 */
		hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
		break;
	}

	/* Swap the caplen and len fields, if necessary. */
	switch (ps->lengths_swapped) {

	case NOT_SWAPPED:
		break;

	case MAYBE_SWAPPED:
		if (hdr->caplen <= hdr->len) {
			/*
			 * The captured length is <= the actual length,
			 * so presumably they weren't swapped.
			 */
			break;
		}
		/* FALLTHROUGH */

	case SWAPPED:
		t = hdr->caplen;
		hdr->caplen = hdr->len;
		hdr->len = t;
		break;
	}

	/*
	 * Is the packet bigger than we consider sane?
	 */
	if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) {
		/*
		 * Yes.  This may be a damaged or fuzzed file.
		 *
		 * Is it bigger than the snapshot length?
		 * (We don't treat that as an error if it's not
		 * bigger than the maximum we consider sane; see
		 * below.)
		 */
		if (hdr->caplen > (bpf_u_int32)p->snapshot) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "invalid packet capture length %u, bigger than "
			    "snaplen of %d", hdr->caplen, p->snapshot);
		} else {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "invalid packet capture length %u, bigger than "
			    "maximum of %u", hdr->caplen,
			    max_snaplen_for_dlt(p->linktype));
		}
		return (-1);
	}

	if (hdr->caplen > (bpf_u_int32)p->snapshot) {
		/*
		 * The packet is bigger than the snapshot length
		 * for this file.
		 *
		 * This can happen due to Solaris 2.3 systems tripping
		 * over the BUFMOD problem and not setting the snapshot
		 * length correctly in the savefile header.
		 *
		 * libpcap 0.4 and later on Solaris 2.3 should set the
		 * snapshot length correctly in the pcap file header,
		 * even though they don't set a snapshot length in bufmod
		 * (the buggy bufmod chops off the *beginning* of the
		 * packet if a snapshot length is specified); they should
		 * also reduce the captured length, as supplied to the
		 * per-packet callback, to the snapshot length if it's
		 * greater than the snapshot length, so the code using
		 * libpcap should see the packet cut off at the snapshot
		 * length, even though the full packet is copied up to
		 * userland.
		 *
		 * However, perhaps some versions of libpcap failed to
		 * set the snapshot length correctly in the file header
		 * or the per-packet header, or perhaps this is a
		 * corrupted safefile or a savefile built/modified by a
		 * fuzz tester, so we check anyway.  We grow the buffer
		 * to be big enough for the snapshot length, read up
		 * to the snapshot length, discard the rest of the
		 * packet, and report the snapshot length as the captured
		 * length; we don't want to hand our caller a packet
		 * bigger than the snapshot length, because they might
		 * be assuming they'll never be handed such a packet,
		 * and might copy the packet into a snapshot-length-
		 * sized buffer, assuming it'll fit.
		 */
		size_t bytes_to_discard;
		size_t bytes_to_read, bytes_read;
		char discard_buf[4096];

		if (hdr->caplen > p->bufsize) {
			/*
			 * Grow the buffer to the snapshot length.
			 */
			if (!grow_buffer(p, p->snapshot))
				return (-1);
		}

		/*
		 * Read the first p->snapshot bytes into the buffer.
		 */
		amt_read = fread(p->buffer, 1, p->snapshot, fp);
		if (amt_read != (bpf_u_int32)p->snapshot) {
			if (ferror(fp)) {
				pcap_fmt_errmsg_for_errno(p->errbuf,
				     PCAP_ERRBUF_SIZE, errno,
				    "error reading dump file");
			} else {
				/*
				 * Yes, this uses hdr->caplen; technically,
				 * it's true, because we would try to read
				 * and discard the rest of those bytes, and
				 * that would fail because we got EOF before
				 * the read finished.
				 */
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "truncated dump file; tried to read %d captured bytes, only got %zu",
				    p->snapshot, amt_read);
			}
			return (-1);
		}

		/*
		 * Now read and discard what's left.
		 */
		bytes_to_discard = hdr->caplen - p->snapshot;
		bytes_read = amt_read;
		while (bytes_to_discard != 0) {
			bytes_to_read = bytes_to_discard;
			if (bytes_to_read > sizeof (discard_buf))
				bytes_to_read = sizeof (discard_buf);
			amt_read = fread(discard_buf, 1, bytes_to_read, fp);
			bytes_read += amt_read;
			if (amt_read != bytes_to_read) {
				if (ferror(fp)) {
					pcap_fmt_errmsg_for_errno(p->errbuf,
					    PCAP_ERRBUF_SIZE, errno,
					    "error reading dump file");
				} else {
					snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
					    "truncated dump file; tried to read %u captured bytes, only got %zu",
					    hdr->caplen, bytes_read);
				}
				return (-1);
			}
			bytes_to_discard -= amt_read;
		}

		/*
		 * Adjust caplen accordingly, so we don't get confused later
		 * as to how many bytes we have to play with.
		 */
		hdr->caplen = p->snapshot;
	} else {
		/*
		 * The packet is within the snapshot length for this file.
		 */
		if (hdr->caplen > p->bufsize) {
			/*
			 * Grow the buffer to the next power of 2, or
			 * the snaplen, whichever is lower.
			 */
			u_int new_bufsize;

			new_bufsize = hdr->caplen;
			/*
			 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
			 */
			new_bufsize--;
			new_bufsize |= new_bufsize >> 1;
			new_bufsize |= new_bufsize >> 2;
			new_bufsize |= new_bufsize >> 4;
			new_bufsize |= new_bufsize >> 8;
			new_bufsize |= new_bufsize >> 16;
			new_bufsize++;

			if (new_bufsize > (u_int)p->snapshot)
				new_bufsize = p->snapshot;

			if (!grow_buffer(p, new_bufsize))
				return (-1);
		}

		/* read the packet itself */
		amt_read = fread(p->buffer, 1, hdr->caplen, fp);
		if (amt_read != hdr->caplen) {
			if (ferror(fp)) {
				pcap_fmt_errmsg_for_errno(p->errbuf,
				    PCAP_ERRBUF_SIZE, errno,
				    "error reading dump file");
			} else {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "truncated dump file; tried to read %u captured bytes, only got %zu",
				    hdr->caplen, amt_read);
			}
			return (-1);
		}
	}
	*data = p->buffer;

	pcap_post_process(p->linktype, p->swapped, hdr, *data);

	return (1);
}

static int
sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen)
{
	struct pcap_file_header hdr;

	hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC;
	hdr.version_major = PCAP_VERSION_MAJOR;
	hdr.version_minor = PCAP_VERSION_MINOR;

	/*
	 * https://www.tcpdump.org/manpages/pcap-savefile.5.txt states:
	 * thiszone: 4-byte time zone offset; this is always 0.
	 * sigfigs:  4-byte number giving the accuracy of time stamps
	 *           in the file; this is always 0.
	 */
	hdr.thiszone = 0;
	hdr.sigfigs = 0;
	hdr.snaplen = snaplen;
	hdr.linktype = linktype;

	if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
		return (-1);

	return (0);
}

/*
 * Output a packet to the initialized dump file.
 */
void
pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
	register FILE *f;
	struct pcap_sf_pkthdr sf_hdr;

	f = (FILE *)user;
	/*
	 * If the output file handle is in an error state, don't write
	 * anything.
	 *
	 * While in principle a file handle can return from an error state
	 * to a normal state (for example if a disk that is full has space
	 * freed), we have possibly left a broken file already, and won't
	 * be able to clean it up. The safest option is to do nothing.
	 *
	 * Note that if we could guarantee that fwrite() was atomic we
	 * might be able to insure that we don't produce a corrupted file,
	 * but the standard defines fwrite() as a series of fputc() calls,
	 * so we really have no insurance that things are not fubared.
	 *
	 * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
	 */
	if (ferror(f))
		return;
	/*
	 * Better not try writing pcap files after
	 * 2038-01-19 03:14:07 UTC; switch to pcapng.
	 */
	sf_hdr.ts.tv_sec  = (bpf_int32)h->ts.tv_sec;
	sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
	sf_hdr.caplen     = h->caplen;
	sf_hdr.len        = h->len;
	/*
	 * We only write the packet if we can write the header properly.
	 *
	 * This doesn't prevent us from having corrupted output, and if we
	 * for some reason don't get a complete write we don't have any
	 * way to set ferror() to prevent future writes from being
	 * attempted, but it is better than nothing.
	 */
	if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
		(void)fwrite(sp, h->caplen, 1, f);
	}
}

static pcap_dumper_t *
pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
{

#if defined(_WIN32) || defined(MSDOS)
	/*
	 * If we're writing to the standard output, put it in binary
	 * mode, as savefiles are binary files.
	 *
	 * Otherwise, we turn off buffering.
	 * XXX - why?  And why not on the standard output?
	 */
	if (f == stdout)
		SET_BINMODE(f);
	else
		setvbuf(f, NULL, _IONBF, 0);
#endif
	if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "Can't write to %s", fname);
		if (f != stdout)
			(void)fclose(f);
		return (NULL);
	}
	return ((pcap_dumper_t *)f);
}

/*
 * Initialize so that sf_write() will output to the file named 'fname'.
 */
pcap_dumper_t *
pcap_dump_open(pcap_t *p, const char *fname)
{
	FILE *f;
	int linktype;

	/*
	 * If this pcap_t hasn't been activated, it doesn't have a
	 * link-layer type, so we can't use it.
	 */
	if (!p->activated) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: not-yet-activated pcap_t passed to pcap_dump_open",
		    fname);
		return (NULL);
	}
	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: link-layer type %d isn't supported in savefiles",
		    fname, p->linktype);
		return (NULL);
	}
	linktype |= p->linktype_ext;

	if (fname == NULL) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "A null pointer was supplied as the file name");
		return NULL;
	}
	if (fname[0] == '-' && fname[1] == '\0') {
		f = stdout;
		fname = "standard output";
	} else {
		/*
		 * "b" is supported as of C90, so *all* UN*Xes should
		 * support it, even though it does nothing.  It's
		 * required on Windows, as the file is a binary file
		 * and must be written in binary mode.
		 */
		f = charset_fopen(fname, "wb");
		if (f == NULL) {
			pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
			    errno, "%s", fname);
			return (NULL);
		}
	}
	return (pcap_setup_dump(p, linktype, f, fname));
}

#ifdef _WIN32
/*
 * Initialize so that sf_write() will output to a stream wrapping the given raw
 * OS file HANDLE.
 */
pcap_dumper_t *
pcap_dump_hopen(pcap_t *p, intptr_t osfd)
{
	int fd;
	FILE *file;

	fd = _open_osfhandle(osfd, _O_APPEND);
	if (fd < 0) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "_open_osfhandle");
		return NULL;
	}

	file = _fdopen(fd, "wb");
	if (file == NULL) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "_fdopen");
		_close(fd);
		return NULL;
	}

	return pcap_dump_fopen(p, file);
}
#endif /* _WIN32 */

/*
 * Initialize so that sf_write() will output to the given stream.
 */
#ifdef _WIN32
static
#endif /* _WIN32 */
pcap_dumper_t *
pcap_dump_fopen(pcap_t *p, FILE *f)
{
	int linktype;

	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "stream: link-layer type %d isn't supported in savefiles",
		    p->linktype);
		return (NULL);
	}
	linktype |= p->linktype_ext;

	return (pcap_setup_dump(p, linktype, f, "stream"));
}

pcap_dumper_t *
pcap_dump_open_append(pcap_t *p, const char *fname)
{
	FILE *f;
	int linktype;
	size_t amt_read;
	struct pcap_file_header ph;

	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: link-layer type %d isn't supported in savefiles",
		    fname, linktype);
		return (NULL);
	}

	if (fname == NULL) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "A null pointer was supplied as the file name");
		return NULL;
	}
	if (fname[0] == '-' && fname[1] == '\0')
		return (pcap_setup_dump(p, linktype, stdout, "standard output"));

	/*
	 * "a" will cause the file *not* to be truncated if it exists
	 * but will cause it to be created if it doesn't.  It will
	 * also cause all writes to be done at the end of the file,
	 * but will allow reads to be done anywhere in the file.  This
	 * is what we need, because we need to read from the beginning
	 * of the file to see if it already has a header and packets
	 * or if it doesn't.
	 *
	 * "b" is supported as of C90, so *all* UN*Xes should support it,
	 * even though it does nothing.  It's required on Windows, as the
	 * file is a binary file and must be read in binary mode.
	 */
	f = charset_fopen(fname, "ab+");
	if (f == NULL) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "%s", fname);
		return (NULL);
	}

	/*
	 * Try to read a pcap header.
	 *
	 * We do not assume that the file will be positioned at the
	 * beginning immediately after we've opened it - we seek to
	 * the beginning.  ISO C says it's implementation-defined
	 * whether the file position indicator is at the beginning
	 * or the end of the file after an append-mode open, and
	 * it wasn't obvious from the Single UNIX Specification
	 * or the Microsoft documentation how that works on SUS-
	 * compliant systems or on Windows.
	 */
	if (fseek(f, 0, SEEK_SET) == -1) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "Can't seek to the beginning of %s", fname);
		(void)fclose(f);
		return (NULL);
	}
	amt_read = fread(&ph, 1, sizeof (ph), f);
	if (amt_read != sizeof (ph)) {
		if (ferror(f)) {
			pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
			    errno, "%s", fname);
			(void)fclose(f);
			return (NULL);
		} else if (feof(f) && amt_read > 0) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: truncated pcap file header", fname);
			(void)fclose(f);
			return (NULL);
		}
	}

#if defined(_WIN32) || defined(MSDOS)
	/*
	 * We turn off buffering.
	 * XXX - why?  And why not on the standard output?
	 */
	setvbuf(f, NULL, _IONBF, 0);
#endif

	/*
	 * If a header is already present and:
	 *
	 *	it's not for a pcap file of the appropriate resolution
	 *	and the right byte order for this machine;
	 *
	 *	the link-layer header types don't match;
	 *
	 *	the snapshot lengths don't match;
	 *
	 * return an error.
	 */
	if (amt_read > 0) {
		/*
		 * A header is already present.
		 * Do the checks.
		 */
		switch (ph.magic) {

		case TCPDUMP_MAGIC:
			if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "%s: different time stamp precision, cannot append to file", fname);
				(void)fclose(f);
				return (NULL);
			}
			break;

		case NSEC_TCPDUMP_MAGIC:
			if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "%s: different time stamp precision, cannot append to file", fname);
				(void)fclose(f);
				return (NULL);
			}
			break;

		case SWAPLONG(TCPDUMP_MAGIC):
		case SWAPLONG(NSEC_TCPDUMP_MAGIC):
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different byte order, cannot append to file", fname);
			(void)fclose(f);
			return (NULL);

		case KUZNETZOV_TCPDUMP_MAGIC:
		case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
		case NAVTEL_TCPDUMP_MAGIC:
		case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: not a pcap file to which we can append", fname);
			(void)fclose(f);
			return (NULL);

		default:
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: not a pcap file", fname);
			(void)fclose(f);
			return (NULL);
		}

		/*
		 * Good version?
		 */
		if (ph.version_major != PCAP_VERSION_MAJOR ||
		    ph.version_minor != PCAP_VERSION_MINOR) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: version is %u.%u, cannot append to file", fname,
			    ph.version_major, ph.version_minor);
			(void)fclose(f);
			return (NULL);
		}
		if ((bpf_u_int32)linktype != ph.linktype) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different linktype, cannot append to file", fname);
			(void)fclose(f);
			return (NULL);
		}
		if ((bpf_u_int32)p->snapshot != ph.snaplen) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different snaplen, cannot append to file", fname);
			(void)fclose(f);
			return (NULL);
		}
	} else {
		/*
		 * A header isn't present; attempt to write it.
		 */
		if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
			pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
			    errno, "Can't write to %s", fname);
			(void)fclose(f);
			return (NULL);
		}
	}

	/*
	 * Start writing at the end of the file.
	 *
	 * XXX - this shouldn't be necessary, given that we're opening
	 * the file in append mode, and ISO C specifies that all writes
	 * are done at the end of the file in that mode.
	 */
	if (fseek(f, 0, SEEK_END) == -1) {
		pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
		    errno, "Can't seek to the end of %s", fname);
		(void)fclose(f);
		return (NULL);
	}
	return ((pcap_dumper_t *)f);
}

FILE *
pcap_dump_file(pcap_dumper_t *p)
{
	return ((FILE *)p);
}

long
pcap_dump_ftell(pcap_dumper_t *p)
{
	return (ftell((FILE *)p));
}

#if defined(HAVE_FSEEKO)
/*
 * We have fseeko(), so we have ftello().
 * If we have large file support (files larger than 2^31-1 bytes),
 * ftello() will give us a current file position with more than 32
 * bits.
 */
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
	return (ftello((FILE *)p));
}
#elif defined(_MSC_VER)
/*
 * We have Visual Studio; we support only 2005 and later, so we have
 * _ftelli64().
 */
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
	return (_ftelli64((FILE *)p));
}
#else
/*
 * We don't have ftello() or _ftelli64(), so fall back on ftell().
 * Either long is 64 bits, in which case ftell() should suffice,
 * or this is probably an older 32-bit UN*X without large file
 * support, which means you'll probably get errors trying to
 * write files > 2^31-1, so it won't matter anyway.
 *
 * XXX - what about MinGW?
 */
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
	return (ftell((FILE *)p));
}
#endif

int
pcap_dump_flush(pcap_dumper_t *p)
{

	if (fflush((FILE *)p) == EOF)
		return (-1);
	else
		return (0);
}

void
pcap_dump_close(pcap_dumper_t *p)
{

#ifdef notyet
	if (ferror((FILE *)p))
		return-an-error;
	/* XXX should check return from fclose() too */
#endif
	(void)fclose((FILE *)p);
}
