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