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