xref: /freebsd/contrib/libpcap/savefile.c (revision 6f9cba8f8b5efd16249633e52483ea351876b67b)
18cf6c252SPaul Traina /*
2a4b5b39fSBill Fenner  * Copyright (c) 1993, 1994, 1995, 1996, 1997
38cf6c252SPaul Traina  *	The Regents of the University of California.  All rights reserved.
48cf6c252SPaul Traina  *
58cf6c252SPaul Traina  * Redistribution and use in source and binary forms, with or without
68cf6c252SPaul Traina  * modification, are permitted provided that: (1) source code distributions
78cf6c252SPaul Traina  * retain the above copyright notice and this paragraph in its entirety, (2)
88cf6c252SPaul Traina  * distributions including binary code include the above copyright notice and
98cf6c252SPaul Traina  * this paragraph in its entirety in the documentation or other materials
108cf6c252SPaul Traina  * provided with the distribution, and (3) all advertising materials mentioning
118cf6c252SPaul Traina  * features or use of this software display the following acknowledgement:
128cf6c252SPaul Traina  * ``This product includes software developed by the University of California,
138cf6c252SPaul Traina  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
148cf6c252SPaul Traina  * the University nor the names of its contributors may be used to endorse
158cf6c252SPaul Traina  * or promote products derived from this software without specific prior
168cf6c252SPaul Traina  * written permission.
178cf6c252SPaul Traina  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
188cf6c252SPaul Traina  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
198cf6c252SPaul Traina  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
203052b236SBill Fenner  *
218cf6c252SPaul Traina  * savefile.c - supports offline use of tcpdump
228cf6c252SPaul Traina  *	Extraction/creation by Jeffrey Mogul, DECWRL
238cf6c252SPaul Traina  *	Modified by Steve McCanne, LBL.
248cf6c252SPaul Traina  *
258cf6c252SPaul Traina  * Used to save the received packet headers, after filtering, to
268cf6c252SPaul Traina  * a file, and then read them later.
278cf6c252SPaul Traina  * The first record in the file contains saved values for the machine
288cf6c252SPaul Traina  * dependent values so we can print the dump file on any architecture.
298cf6c252SPaul Traina  */
308cf6c252SPaul Traina 
31dc2c7305SBill Fenner #ifdef HAVE_CONFIG_H
32b00ab754SHans Petter Selasky #include <config.h>
333052b236SBill Fenner #endif
343052b236SBill Fenner 
35b00ab754SHans Petter Selasky #include <pcap-types.h>
36ada6f083SXin LI #ifdef _WIN32
37b00ab754SHans Petter Selasky #include <io.h>
38b00ab754SHans Petter Selasky #include <fcntl.h>
39ada6f083SXin LI #endif /* _WIN32 */
40a0ee43a1SRui Paulo 
418cf6c252SPaul Traina #include <errno.h>
428cf6c252SPaul Traina #include <memory.h>
438cf6c252SPaul Traina #include <stdio.h>
448cf6c252SPaul Traina #include <stdlib.h>
45dc2c7305SBill Fenner #include <string.h>
4657e22627SCy Schubert #include <limits.h> /* for INT_MAX */
478cf6c252SPaul Traina 
488cf6c252SPaul Traina #include "pcap-int.h"
498cf6c252SPaul Traina 
508cf6c252SPaul Traina #ifdef HAVE_OS_PROTO_H
518cf6c252SPaul Traina #include "os-proto.h"
528cf6c252SPaul Traina #endif
538cf6c252SPaul Traina 
54a0ee43a1SRui Paulo #include "sf-pcap.h"
55b00ab754SHans Petter Selasky #include "sf-pcapng.h"
5657e22627SCy Schubert #include "pcap-common.h"
57*6f9cba8fSJoseph Mingrone #include "charconv.h"
588cf6c252SPaul Traina 
59ada6f083SXin LI #ifdef _WIN32
60ada6f083SXin LI /*
61*6f9cba8fSJoseph Mingrone  * This isn't exported on Windows, because it would only work if both
6257e22627SCy Schubert  * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise,
6357e22627SCy Schubert  * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it
64ada6f083SXin LI  * could be different if they're using different versions of the C runtime.
65ada6f083SXin LI  *
66*6f9cba8fSJoseph Mingrone  * Instead, pcap/pcap.h defines it as a macro that wraps the hopen version,
67*6f9cba8fSJoseph Mingrone  * with the wrapper calling _fileno() and _get_osfhandle() themselves,
68*6f9cba8fSJoseph Mingrone  * so that it convert the appropriate CRT version's FILE structure to
69ada6f083SXin LI  * a HANDLE (which is OS-defined, not CRT-defined, and is part of the Win32
70ada6f083SXin LI  * and Win64 ABIs).
71ada6f083SXin LI  */
72ada6f083SXin LI static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
73ada6f083SXin LI #endif
74ada6f083SXin LI 
75dc2c7305SBill Fenner /*
7604fb2745SSam Leffler  * Setting O_BINARY on DOS/Windows is a bit tricky
7704fb2745SSam Leffler  */
78ada6f083SXin LI #if defined(_WIN32)
79ee2dd488SSam Leffler   #define SET_BINMODE(f)  _setmode(_fileno(f), _O_BINARY)
8004fb2745SSam Leffler #elif defined(MSDOS)
8104fb2745SSam Leffler   #if defined(__HIGHC__)
8204fb2745SSam Leffler   #define SET_BINMODE(f)  setmode(f, O_BINARY)
8304fb2745SSam Leffler   #else
8404fb2745SSam Leffler   #define SET_BINMODE(f)  setmode(fileno(f), O_BINARY)
8504fb2745SSam Leffler   #endif
8604fb2745SSam Leffler #endif
8704fb2745SSam Leffler 
88feb4ecdbSBruce M Simpson static int
89b00ab754SHans Petter Selasky sf_getnonblock(pcap_t *p _U_)
90feb4ecdbSBruce M Simpson {
91feb4ecdbSBruce M Simpson 	/*
92feb4ecdbSBruce M Simpson 	 * This is a savefile, not a live capture file, so never say
93feb4ecdbSBruce M Simpson 	 * it's in non-blocking mode.
94feb4ecdbSBruce M Simpson 	 */
95feb4ecdbSBruce M Simpson 	return (0);
96feb4ecdbSBruce M Simpson }
97feb4ecdbSBruce M Simpson 
98feb4ecdbSBruce M Simpson static int
99b00ab754SHans Petter Selasky sf_setnonblock(pcap_t *p, int nonblock _U_)
100feb4ecdbSBruce M Simpson {
101feb4ecdbSBruce M Simpson 	/*
102d1e87331SXin LI 	 * This is a savefile, not a live capture file, so reject
103d1e87331SXin LI 	 * requests to put it in non-blocking mode.  (If it's a
104d1e87331SXin LI 	 * pipe, it could be put in non-blocking mode, but that
105d1e87331SXin LI 	 * would significantly complicate the code to read packets,
106d1e87331SXin LI 	 * as it would have to handle reading partial packets and
107d1e87331SXin LI 	 * keeping the state of the read.)
108feb4ecdbSBruce M Simpson 	 */
109*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
110d1e87331SXin LI 	    "Savefiles cannot be put into non-blocking mode");
111d1e87331SXin LI 	return (-1);
112feb4ecdbSBruce M Simpson }
113feb4ecdbSBruce M Simpson 
114feb4ecdbSBruce M Simpson static int
115*6f9cba8fSJoseph Mingrone sf_cant_set_rfmon(pcap_t *p _U_)
116*6f9cba8fSJoseph Mingrone {
117*6f9cba8fSJoseph Mingrone 	/*
118*6f9cba8fSJoseph Mingrone 	 * This is a savefile, not a device on which you can capture,
119*6f9cba8fSJoseph Mingrone 	 * so never say it supports being put into monitor mode.
120*6f9cba8fSJoseph Mingrone 	 */
121*6f9cba8fSJoseph Mingrone 	return (0);
122*6f9cba8fSJoseph Mingrone }
123*6f9cba8fSJoseph Mingrone 
124*6f9cba8fSJoseph Mingrone static int
125b00ab754SHans Petter Selasky sf_stats(pcap_t *p, struct pcap_stat *ps _U_)
126feb4ecdbSBruce M Simpson {
127*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
128feb4ecdbSBruce M Simpson 	    "Statistics aren't available from savefiles");
129feb4ecdbSBruce M Simpson 	return (-1);
130feb4ecdbSBruce M Simpson }
131feb4ecdbSBruce M Simpson 
132ada6f083SXin LI #ifdef _WIN32
133ada6f083SXin LI static struct pcap_stat *
134*6f9cba8fSJoseph Mingrone sf_stats_ex(pcap_t *p, int *size _U_)
135ada6f083SXin LI {
136*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
137ada6f083SXin LI 	    "Statistics aren't available from savefiles");
138ada6f083SXin LI 	return (NULL);
139ada6f083SXin LI }
140ada6f083SXin LI 
141a8e07101SRui Paulo static int
142*6f9cba8fSJoseph Mingrone sf_setbuff(pcap_t *p, int dim _U_)
143a8e07101SRui Paulo {
144*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
145a8e07101SRui Paulo 	    "The kernel buffer size cannot be set while reading from a file");
146a8e07101SRui Paulo 	return (-1);
147a8e07101SRui Paulo }
148a8e07101SRui Paulo 
149a8e07101SRui Paulo static int
150*6f9cba8fSJoseph Mingrone sf_setmode(pcap_t *p, int mode _U_)
151a8e07101SRui Paulo {
152*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
153a8e07101SRui Paulo 	    "impossible to set mode while reading from a file");
154a8e07101SRui Paulo 	return (-1);
155a8e07101SRui Paulo }
156a8e07101SRui Paulo 
157a8e07101SRui Paulo static int
158*6f9cba8fSJoseph Mingrone sf_setmintocopy(pcap_t *p, int size _U_)
159a8e07101SRui Paulo {
160*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
161a8e07101SRui Paulo 	    "The mintocopy parameter cannot be set while reading from a file");
162a8e07101SRui Paulo 	return (-1);
163a8e07101SRui Paulo }
164ada6f083SXin LI 
165ada6f083SXin LI static HANDLE
166ada6f083SXin LI sf_getevent(pcap_t *pcap)
167ada6f083SXin LI {
168*6f9cba8fSJoseph Mingrone 	(void)snprintf(pcap->errbuf, sizeof(pcap->errbuf),
169ada6f083SXin LI 	    "The read event cannot be retrieved while reading from a file");
170ada6f083SXin LI 	return (INVALID_HANDLE_VALUE);
171ada6f083SXin LI }
172ada6f083SXin LI 
173ada6f083SXin LI static int
174ada6f083SXin LI sf_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
175ada6f083SXin LI     size_t *lenp _U_)
176ada6f083SXin LI {
177*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
178ada6f083SXin LI 	    "An OID get request cannot be performed on a file");
179ada6f083SXin LI 	return (PCAP_ERROR);
180ada6f083SXin LI }
181ada6f083SXin LI 
182ada6f083SXin LI static int
183ada6f083SXin LI sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
184ada6f083SXin LI     size_t *lenp _U_)
185ada6f083SXin LI {
186*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
187ada6f083SXin LI 	    "An OID set request cannot be performed on a file");
188ada6f083SXin LI 	return (PCAP_ERROR);
189ada6f083SXin LI }
190ada6f083SXin LI 
191ada6f083SXin LI static u_int
192*6f9cba8fSJoseph Mingrone sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
193ada6f083SXin LI {
19457e22627SCy Schubert 	pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
195ada6f083SXin LI 	    PCAP_ERRBUF_SIZE);
196ada6f083SXin LI 	return (0);
197ada6f083SXin LI }
198ada6f083SXin LI 
199ada6f083SXin LI static int
200*6f9cba8fSJoseph Mingrone sf_setuserbuffer(pcap_t *p, int size _U_)
201ada6f083SXin LI {
202*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
203ada6f083SXin LI 	    "The user buffer cannot be set when reading from a file");
204ada6f083SXin LI 	return (-1);
205ada6f083SXin LI }
206ada6f083SXin LI 
207ada6f083SXin LI static int
208*6f9cba8fSJoseph Mingrone sf_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
209ada6f083SXin LI {
210*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
211ada6f083SXin LI 	    "Live packet dumping cannot be performed when reading from a file");
212ada6f083SXin LI 	return (-1);
213ada6f083SXin LI }
214ada6f083SXin LI 
215ada6f083SXin LI static int
216*6f9cba8fSJoseph Mingrone sf_live_dump_ended(pcap_t *p, int sync _U_)
217ada6f083SXin LI {
218*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
219ada6f083SXin LI 	    "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
220ada6f083SXin LI 	return (-1);
221ada6f083SXin LI }
222ada6f083SXin LI 
223ada6f083SXin LI static PAirpcapHandle
224*6f9cba8fSJoseph Mingrone sf_get_airpcap_handle(pcap_t *pcap _U_)
225ada6f083SXin LI {
226ada6f083SXin LI 	return (NULL);
227ada6f083SXin LI }
228a8e07101SRui Paulo #endif
229a8e07101SRui Paulo 
23004fb2745SSam Leffler static int
231*6f9cba8fSJoseph Mingrone sf_inject(pcap_t *p, const void *buf _U_, int size _U_)
23204fb2745SSam Leffler {
23357e22627SCy Schubert 	pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
23404fb2745SSam Leffler 	    PCAP_ERRBUF_SIZE);
23504fb2745SSam Leffler 	return (-1);
23604fb2745SSam Leffler }
23704fb2745SSam Leffler 
238ee2dd488SSam Leffler /*
239ee2dd488SSam Leffler  * Set direction flag: Which packets do we accept on a forwarding
240ee2dd488SSam Leffler  * single device? IN, OUT or both?
241ee2dd488SSam Leffler  */
242ee2dd488SSam Leffler static int
243b00ab754SHans Petter Selasky sf_setdirection(pcap_t *p, pcap_direction_t d _U_)
244ee2dd488SSam Leffler {
245*6f9cba8fSJoseph Mingrone 	snprintf(p->errbuf, sizeof(p->errbuf),
246ee2dd488SSam Leffler 	    "Setting direction is not supported on savefiles");
247ee2dd488SSam Leffler 	return (-1);
248ee2dd488SSam Leffler }
249ee2dd488SSam Leffler 
250681ed54cSXin LI void
251a8e07101SRui Paulo sf_cleanup(pcap_t *p)
252feb4ecdbSBruce M Simpson {
253681ed54cSXin LI 	if (p->rfile != stdin)
254681ed54cSXin LI 		(void)fclose(p->rfile);
255a0ee43a1SRui Paulo 	if (p->buffer != NULL)
256a0ee43a1SRui Paulo 		free(p->buffer);
257d1e87331SXin LI 	pcap_freecode(&p->fcode);
258feb4ecdbSBruce M Simpson }
259feb4ecdbSBruce M Simpson 
260*6f9cba8fSJoseph Mingrone #ifdef _WIN32
261*6f9cba8fSJoseph Mingrone /*
262*6f9cba8fSJoseph Mingrone  * Wrapper for fopen() and _wfopen().
263*6f9cba8fSJoseph Mingrone  *
264*6f9cba8fSJoseph Mingrone  * If we're in UTF-8 mode, map the pathname from UTF-8 to UTF-16LE and
265*6f9cba8fSJoseph Mingrone  * call _wfopen().
266*6f9cba8fSJoseph Mingrone  *
267*6f9cba8fSJoseph Mingrone  * If we're not, just use fopen(); that'll treat it as being in the
268*6f9cba8fSJoseph Mingrone  * local code page.
269*6f9cba8fSJoseph Mingrone  */
270*6f9cba8fSJoseph Mingrone FILE *
271*6f9cba8fSJoseph Mingrone charset_fopen(const char *path, const char *mode)
272*6f9cba8fSJoseph Mingrone {
273*6f9cba8fSJoseph Mingrone 	wchar_t *utf16_path;
274*6f9cba8fSJoseph Mingrone #define MAX_MODE_LEN	16
275*6f9cba8fSJoseph Mingrone 	wchar_t utf16_mode[MAX_MODE_LEN+1];
276*6f9cba8fSJoseph Mingrone 	int i;
277*6f9cba8fSJoseph Mingrone 	char c;
278*6f9cba8fSJoseph Mingrone 	FILE *fp;
279*6f9cba8fSJoseph Mingrone 	int save_errno;
280*6f9cba8fSJoseph Mingrone 
281*6f9cba8fSJoseph Mingrone 	if (pcap_utf_8_mode) {
282*6f9cba8fSJoseph Mingrone 		/*
283*6f9cba8fSJoseph Mingrone 		 * Map from UTF-8 to UTF-16LE.
284*6f9cba8fSJoseph Mingrone 		 * Fail if there are invalid characters in the input
285*6f9cba8fSJoseph Mingrone 		 * string, rather than converting them to REPLACEMENT
286*6f9cba8fSJoseph Mingrone 		 * CHARACTER; the latter is appropriate for strings
287*6f9cba8fSJoseph Mingrone 		 * to be displayed to the user, but for file names
288*6f9cba8fSJoseph Mingrone 		 * you just want the attempt to open the file to fail.
289*6f9cba8fSJoseph Mingrone 		 */
290*6f9cba8fSJoseph Mingrone 		utf16_path = cp_to_utf_16le(CP_UTF8, path,
291*6f9cba8fSJoseph Mingrone 		    MB_ERR_INVALID_CHARS);
292*6f9cba8fSJoseph Mingrone 		if (utf16_path == NULL) {
293*6f9cba8fSJoseph Mingrone 			/*
294*6f9cba8fSJoseph Mingrone 			 * Error.  Assume errno has been set.
295*6f9cba8fSJoseph Mingrone 			 *
296*6f9cba8fSJoseph Mingrone 			 * XXX - what about Windows errors?
297*6f9cba8fSJoseph Mingrone 			 */
298*6f9cba8fSJoseph Mingrone 			return (NULL);
299*6f9cba8fSJoseph Mingrone 		}
300*6f9cba8fSJoseph Mingrone 
301*6f9cba8fSJoseph Mingrone 		/*
302*6f9cba8fSJoseph Mingrone 		 * Now convert the mode to UTF-16LE as well.
303*6f9cba8fSJoseph Mingrone 		 * We assume the mode is ASCII, and that
304*6f9cba8fSJoseph Mingrone 		 * it's short, so that's easy.
305*6f9cba8fSJoseph Mingrone 		 */
306*6f9cba8fSJoseph Mingrone 		for (i = 0; (c = *mode) != '\0'; i++, mode++) {
307*6f9cba8fSJoseph Mingrone 			if (c > 0x7F) {
308*6f9cba8fSJoseph Mingrone 				/* Not an ASCII character; fail with EINVAL. */
309*6f9cba8fSJoseph Mingrone 				free(utf16_path);
310*6f9cba8fSJoseph Mingrone 				errno = EINVAL;
311*6f9cba8fSJoseph Mingrone 				return (NULL);
312*6f9cba8fSJoseph Mingrone 			}
313*6f9cba8fSJoseph Mingrone 			if (i >= MAX_MODE_LEN) {
314*6f9cba8fSJoseph Mingrone 				/* The mode string is longer than we allow. */
315*6f9cba8fSJoseph Mingrone 				free(utf16_path);
316*6f9cba8fSJoseph Mingrone 				errno = EINVAL;
317*6f9cba8fSJoseph Mingrone 				return (NULL);
318*6f9cba8fSJoseph Mingrone 			}
319*6f9cba8fSJoseph Mingrone 			utf16_mode[i] = c;
320*6f9cba8fSJoseph Mingrone 		}
321*6f9cba8fSJoseph Mingrone 		utf16_mode[i] = '\0';
322*6f9cba8fSJoseph Mingrone 
323*6f9cba8fSJoseph Mingrone 		/*
324*6f9cba8fSJoseph Mingrone 		 * OK, we have UTF-16LE strings; hand them to
325*6f9cba8fSJoseph Mingrone 		 * _wfopen().
326*6f9cba8fSJoseph Mingrone 		 */
327*6f9cba8fSJoseph Mingrone 		fp = _wfopen(utf16_path, utf16_mode);
328*6f9cba8fSJoseph Mingrone 
329*6f9cba8fSJoseph Mingrone 		/*
330*6f9cba8fSJoseph Mingrone 		 * Make sure freeing the UTF-16LE string doesn't
331*6f9cba8fSJoseph Mingrone 		 * overwrite the error code we got from _wfopen().
332*6f9cba8fSJoseph Mingrone 		 */
333*6f9cba8fSJoseph Mingrone 		save_errno = errno;
334*6f9cba8fSJoseph Mingrone 		free(utf16_path);
335*6f9cba8fSJoseph Mingrone 		errno = save_errno;
336*6f9cba8fSJoseph Mingrone 
337*6f9cba8fSJoseph Mingrone 		return (fp);
338*6f9cba8fSJoseph Mingrone 	} else {
339*6f9cba8fSJoseph Mingrone 		/*
340*6f9cba8fSJoseph Mingrone 		 * This takes strings in the local code page as an
341*6f9cba8fSJoseph Mingrone 		 * argument.
342*6f9cba8fSJoseph Mingrone 		 */
343*6f9cba8fSJoseph Mingrone 		return (fopen(path, mode));
344*6f9cba8fSJoseph Mingrone 	}
345*6f9cba8fSJoseph Mingrone }
346*6f9cba8fSJoseph Mingrone #endif
347*6f9cba8fSJoseph Mingrone 
3488cf6c252SPaul Traina pcap_t *
349681ed54cSXin LI pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
350681ed54cSXin LI 					char *errbuf)
3518cf6c252SPaul Traina {
35204fb2745SSam Leffler 	FILE *fp;
35304fb2745SSam Leffler 	pcap_t *p;
35404fb2745SSam Leffler 
355ada6f083SXin LI 	if (fname == NULL) {
356*6f9cba8fSJoseph Mingrone 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
357ada6f083SXin LI 		    "A null pointer was supplied as the file name");
358ada6f083SXin LI 		return (NULL);
359ada6f083SXin LI 	}
36004fb2745SSam Leffler 	if (fname[0] == '-' && fname[1] == '\0')
361ee2dd488SSam Leffler 	{
36204fb2745SSam Leffler 		fp = stdin;
363*6f9cba8fSJoseph Mingrone 		if (fp == NULL) {
364*6f9cba8fSJoseph Mingrone 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
365*6f9cba8fSJoseph Mingrone 			    "The standard input is not open");
366*6f9cba8fSJoseph Mingrone 			return (NULL);
367*6f9cba8fSJoseph Mingrone 		}
368ada6f083SXin LI #if defined(_WIN32) || defined(MSDOS)
369ee2dd488SSam Leffler 		/*
370ee2dd488SSam Leffler 		 * We're reading from the standard input, so put it in binary
371ee2dd488SSam Leffler 		 * mode, as savefiles are binary files.
372ee2dd488SSam Leffler 		 */
373ee2dd488SSam Leffler 		SET_BINMODE(fp);
374ee2dd488SSam Leffler #endif
375ee2dd488SSam Leffler 	}
37604fb2745SSam Leffler 	else {
377b00ab754SHans Petter Selasky 		/*
378*6f9cba8fSJoseph Mingrone 		 * Use charset_fopen(); on Windows, it tests whether we're
379*6f9cba8fSJoseph Mingrone 		 * in "local code page" or "UTF-8" mode, and treats the
380*6f9cba8fSJoseph Mingrone 		 * pathname appropriately, and on other platforms, it just
381*6f9cba8fSJoseph Mingrone 		 * wraps fopen().
382*6f9cba8fSJoseph Mingrone 		 *
383b00ab754SHans Petter Selasky 		 * "b" is supported as of C90, so *all* UN*Xes should
384*6f9cba8fSJoseph Mingrone 		 * support it, even though it does nothing.  For MS-DOS,
385*6f9cba8fSJoseph Mingrone 		 * we again need it.
386b00ab754SHans Petter Selasky 		 */
387*6f9cba8fSJoseph Mingrone 		fp = charset_fopen(fname, "rb");
38804fb2745SSam Leffler 		if (fp == NULL) {
389b00ab754SHans Petter Selasky 			pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
390b00ab754SHans Petter Selasky 			    errno, "%s", fname);
39104fb2745SSam Leffler 			return (NULL);
39204fb2745SSam Leffler 		}
39304fb2745SSam Leffler 	}
394681ed54cSXin LI 	p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf);
39504fb2745SSam Leffler 	if (p == NULL) {
39604fb2745SSam Leffler 		if (fp != stdin)
39704fb2745SSam Leffler 			fclose(fp);
39804fb2745SSam Leffler 	}
39904fb2745SSam Leffler 	return (p);
40004fb2745SSam Leffler }
40104fb2745SSam Leffler 
402681ed54cSXin LI pcap_t *
403681ed54cSXin LI pcap_open_offline(const char *fname, char *errbuf)
404681ed54cSXin LI {
405681ed54cSXin LI 	return (pcap_open_offline_with_tstamp_precision(fname,
406681ed54cSXin LI 	    PCAP_TSTAMP_PRECISION_MICRO, errbuf));
407681ed54cSXin LI }
408681ed54cSXin LI 
409ada6f083SXin LI #ifdef _WIN32
410681ed54cSXin LI pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
411681ed54cSXin LI     char *errbuf)
412a8e07101SRui Paulo {
413a8e07101SRui Paulo 	int fd;
414a8e07101SRui Paulo 	FILE *file;
415a8e07101SRui Paulo 
416a8e07101SRui Paulo 	fd = _open_osfhandle(osfd, _O_RDONLY);
417a8e07101SRui Paulo 	if ( fd < 0 )
418a8e07101SRui Paulo 	{
419b00ab754SHans Petter Selasky 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
420b00ab754SHans Petter Selasky 		    errno, "_open_osfhandle");
421a8e07101SRui Paulo 		return NULL;
422a8e07101SRui Paulo 	}
423a8e07101SRui Paulo 
424a8e07101SRui Paulo 	file = _fdopen(fd, "rb");
425a8e07101SRui Paulo 	if ( file == NULL )
426a8e07101SRui Paulo 	{
427b00ab754SHans Petter Selasky 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
428b00ab754SHans Petter Selasky 		    errno, "_fdopen");
42957e22627SCy Schubert 		_close(fd);
430a8e07101SRui Paulo 		return NULL;
431a8e07101SRui Paulo 	}
432a8e07101SRui Paulo 
433681ed54cSXin LI 	return pcap_fopen_offline_with_tstamp_precision(file, precision,
434681ed54cSXin LI 	    errbuf);
435681ed54cSXin LI }
436681ed54cSXin LI 
437681ed54cSXin LI pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
438681ed54cSXin LI {
439681ed54cSXin LI 	return pcap_hopen_offline_with_tstamp_precision(osfd,
440681ed54cSXin LI 	    PCAP_TSTAMP_PRECISION_MICRO, errbuf);
441a8e07101SRui Paulo }
442a8e07101SRui Paulo #endif
443a8e07101SRui Paulo 
44457e22627SCy Schubert /*
44557e22627SCy Schubert  * Given a link-layer header type and snapshot length, return a
44657e22627SCy Schubert  * snapshot length to use when reading the file; it's guaranteed
44757e22627SCy Schubert  * to be > 0 and <= INT_MAX.
44857e22627SCy Schubert  *
44957e22627SCy Schubert  * XXX - the only reason why we limit it to <= INT_MAX is so that
45057e22627SCy Schubert  * it fits in p->snapshot, and the only reason that p->snapshot is
45157e22627SCy Schubert  * signed is that pcap_snapshot() returns an int, not an unsigned int.
45257e22627SCy Schubert  */
45357e22627SCy Schubert bpf_u_int32
45457e22627SCy Schubert pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
45557e22627SCy Schubert {
45657e22627SCy Schubert 	if (snaplen == 0 || snaplen > INT_MAX) {
45757e22627SCy Schubert 		/*
45857e22627SCy Schubert 		 * Bogus snapshot length; use the maximum for this
45957e22627SCy Schubert 		 * link-layer type as a fallback.
46057e22627SCy Schubert 		 *
46157e22627SCy Schubert 		 * XXX - we don't clamp snapshot lengths that are
46257e22627SCy Schubert 		 * <= INT_MAX but > max_snaplen_for_dlt(linktype),
46357e22627SCy Schubert 		 * so a capture file could cause us to allocate
46457e22627SCy Schubert 		 * a Really Big Buffer.
46557e22627SCy Schubert 		 */
46657e22627SCy Schubert 		snaplen = max_snaplen_for_dlt(linktype);
46757e22627SCy Schubert 	}
46857e22627SCy Schubert 	return snaplen;
46957e22627SCy Schubert }
47057e22627SCy Schubert 
47157e22627SCy Schubert static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
472a0ee43a1SRui Paulo 	pcap_check_header,
473a0ee43a1SRui Paulo 	pcap_ng_check_header
474a0ee43a1SRui Paulo };
475a0ee43a1SRui Paulo 
476a0ee43a1SRui Paulo #define	N_FILE_TYPES	(sizeof check_headers / sizeof check_headers[0])
477a0ee43a1SRui Paulo 
478ada6f083SXin LI #ifdef _WIN32
479a8e07101SRui Paulo static
480a8e07101SRui Paulo #endif
48104fb2745SSam Leffler pcap_t *
482681ed54cSXin LI pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
483681ed54cSXin LI     char *errbuf)
48404fb2745SSam Leffler {
4858cf6c252SPaul Traina 	register pcap_t *p;
48657e22627SCy Schubert 	uint8_t magic[4];
487a0ee43a1SRui Paulo 	size_t amt_read;
488a0ee43a1SRui Paulo 	u_int i;
489681ed54cSXin LI 	int err;
4908cf6c252SPaul Traina 
491a0ee43a1SRui Paulo 	/*
492*6f9cba8fSJoseph Mingrone 	 * Fail if we were passed a NULL fp.
493*6f9cba8fSJoseph Mingrone 	 *
494*6f9cba8fSJoseph Mingrone 	 * That shouldn't happen if we're opening with a path name, but
495*6f9cba8fSJoseph Mingrone 	 * it could happen if buggy code is opening with a FILE * and
496*6f9cba8fSJoseph Mingrone 	 * didn't bother to make sure the FILE * isn't null.
497*6f9cba8fSJoseph Mingrone 	 */
498*6f9cba8fSJoseph Mingrone 	if (fp == NULL) {
499*6f9cba8fSJoseph Mingrone 		snprintf(errbuf, PCAP_ERRBUF_SIZE,
500*6f9cba8fSJoseph Mingrone 		    "Null FILE * pointer provided to savefile open routine");
501*6f9cba8fSJoseph Mingrone 		return (NULL);
502*6f9cba8fSJoseph Mingrone 	}
503*6f9cba8fSJoseph Mingrone 
504*6f9cba8fSJoseph Mingrone 	/*
505a0ee43a1SRui Paulo 	 * Read the first 4 bytes of the file; the network analyzer dump
506b00ab754SHans Petter Selasky 	 * file formats we support (pcap and pcapng), and several other
507a0ee43a1SRui Paulo 	 * formats we might support in the future (such as snoop, DOS and
508a0ee43a1SRui Paulo 	 * Windows Sniffer, and Microsoft Network Monitor) all have magic
509a0ee43a1SRui Paulo 	 * numbers that are unique in their first 4 bytes.
510a0ee43a1SRui Paulo 	 */
51157e22627SCy Schubert 	amt_read = fread(&magic, 1, sizeof(magic), fp);
512a0ee43a1SRui Paulo 	if (amt_read != sizeof(magic)) {
51304fb2745SSam Leffler 		if (ferror(fp)) {
514b00ab754SHans Petter Selasky 			pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
515b00ab754SHans Petter Selasky 			    errno, "error reading dump file");
51604fb2745SSam Leffler 		} else {
517*6f9cba8fSJoseph Mingrone 			snprintf(errbuf, PCAP_ERRBUF_SIZE,
518*6f9cba8fSJoseph Mingrone 			    "truncated dump file; tried to read %zu file header bytes, only got %zu",
51957e22627SCy Schubert 			    sizeof(magic), amt_read);
5208cf6c252SPaul Traina 		}
521681ed54cSXin LI 		return (NULL);
5228cf6c252SPaul Traina 	}
523a0ee43a1SRui Paulo 
524dc2c7305SBill Fenner 	/*
525a0ee43a1SRui Paulo 	 * Try all file types.
526dc2c7305SBill Fenner 	 */
527a0ee43a1SRui Paulo 	for (i = 0; i < N_FILE_TYPES; i++) {
528681ed54cSXin LI 		p = (*check_headers[i])(magic, fp, precision, errbuf, &err);
529681ed54cSXin LI 		if (p != NULL) {
530681ed54cSXin LI 			/* Yup, that's it. */
531681ed54cSXin LI 			goto found;
532681ed54cSXin LI 		}
533681ed54cSXin LI 		if (err) {
534ef96d74fSMax Laier 			/*
535a0ee43a1SRui Paulo 			 * Error trying to read the header.
536ef96d74fSMax Laier 			 */
537681ed54cSXin LI 			return (NULL);
538ef96d74fSMax Laier 		}
539a0ee43a1SRui Paulo 	}
540a0ee43a1SRui Paulo 
541a0ee43a1SRui Paulo 	/*
542a0ee43a1SRui Paulo 	 * Well, who knows what this mess is....
543a0ee43a1SRui Paulo 	 */
544*6f9cba8fSJoseph Mingrone 	snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
545681ed54cSXin LI 	return (NULL);
546a0ee43a1SRui Paulo 
547a0ee43a1SRui Paulo found:
548681ed54cSXin LI 	p->rfile = fp;
5498cf6c252SPaul Traina 
55004fb2745SSam Leffler 	/* Padding only needed for live capture fcode */
55104fb2745SSam Leffler 	p->fddipad = 0;
5528cf6c252SPaul Traina 
553ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS)
554feb4ecdbSBruce M Simpson 	/*
555feb4ecdbSBruce M Simpson 	 * You can do "select()" and "poll()" on plain files on most
556feb4ecdbSBruce M Simpson 	 * platforms, and should be able to do so on pipes.
557feb4ecdbSBruce M Simpson 	 *
558feb4ecdbSBruce M Simpson 	 * You can't do "select()" on anything other than sockets in
559feb4ecdbSBruce M Simpson 	 * Windows, so, on Win32 systems, we don't have "selectable_fd".
560feb4ecdbSBruce M Simpson 	 */
561feb4ecdbSBruce M Simpson 	p->selectable_fd = fileno(fp);
562feb4ecdbSBruce M Simpson #endif
563feb4ecdbSBruce M Simpson 
564*6f9cba8fSJoseph Mingrone 	p->can_set_rfmon_op = sf_cant_set_rfmon;
565feb4ecdbSBruce M Simpson 	p->read_op = pcap_offline_read;
56604fb2745SSam Leffler 	p->inject_op = sf_inject;
567feb4ecdbSBruce M Simpson 	p->setfilter_op = install_bpf_program;
568ee2dd488SSam Leffler 	p->setdirection_op = sf_setdirection;
569feb4ecdbSBruce M Simpson 	p->set_datalink_op = NULL;	/* we don't support munging link-layer headers */
570feb4ecdbSBruce M Simpson 	p->getnonblock_op = sf_getnonblock;
571feb4ecdbSBruce M Simpson 	p->setnonblock_op = sf_setnonblock;
572feb4ecdbSBruce M Simpson 	p->stats_op = sf_stats;
573ada6f083SXin LI #ifdef _WIN32
574ada6f083SXin LI 	p->stats_ex_op = sf_stats_ex;
575a8e07101SRui Paulo 	p->setbuff_op = sf_setbuff;
576a8e07101SRui Paulo 	p->setmode_op = sf_setmode;
577a8e07101SRui Paulo 	p->setmintocopy_op = sf_setmintocopy;
578ada6f083SXin LI 	p->getevent_op = sf_getevent;
579ada6f083SXin LI 	p->oid_get_request_op = sf_oid_get_request;
580ada6f083SXin LI 	p->oid_set_request_op = sf_oid_set_request;
581ada6f083SXin LI 	p->sendqueue_transmit_op = sf_sendqueue_transmit;
582ada6f083SXin LI 	p->setuserbuffer_op = sf_setuserbuffer;
583ada6f083SXin LI 	p->live_dump_op = sf_live_dump;
584ada6f083SXin LI 	p->live_dump_ended_op = sf_live_dump_ended;
585ada6f083SXin LI 	p->get_airpcap_handle_op = sf_get_airpcap_handle;
586a8e07101SRui Paulo #endif
587681ed54cSXin LI 
588681ed54cSXin LI 	/*
589681ed54cSXin LI 	 * For offline captures, the standard one-shot callback can
590681ed54cSXin LI 	 * be used for pcap_next()/pcap_next_ex().
591681ed54cSXin LI 	 */
592681ed54cSXin LI 	p->oneshot_callback = pcap_oneshot;
593681ed54cSXin LI 
594ada6f083SXin LI 	/*
595*6f9cba8fSJoseph Mingrone 	 * Default breakloop operation.
596*6f9cba8fSJoseph Mingrone 	 */
597*6f9cba8fSJoseph Mingrone 	p->breakloop_op = pcap_breakloop_common;
598*6f9cba8fSJoseph Mingrone 
599*6f9cba8fSJoseph Mingrone 	/*
600ada6f083SXin LI 	 * Savefiles never require special BPF code generation.
601ada6f083SXin LI 	 */
602ada6f083SXin LI 	p->bpf_codegen_flags = 0;
603ada6f083SXin LI 
604a8e07101SRui Paulo 	p->activated = 1;
605feb4ecdbSBruce M Simpson 
6068cf6c252SPaul Traina 	return (p);
607681ed54cSXin LI }
608681ed54cSXin LI 
609*6f9cba8fSJoseph Mingrone /*
610*6f9cba8fSJoseph Mingrone  * This isn't needed on Windows; we #define pcap_fopen_offline() as
611*6f9cba8fSJoseph Mingrone  * a wrapper around pcap_hopen_offline(), and we don't call it from
612*6f9cba8fSJoseph Mingrone  * inside this file, so it's unused.
613*6f9cba8fSJoseph Mingrone  */
614*6f9cba8fSJoseph Mingrone #ifndef _WIN32
615681ed54cSXin LI pcap_t *
616681ed54cSXin LI pcap_fopen_offline(FILE *fp, char *errbuf)
617681ed54cSXin LI {
618681ed54cSXin LI 	return (pcap_fopen_offline_with_tstamp_precision(fp,
619681ed54cSXin LI 	    PCAP_TSTAMP_PRECISION_MICRO, errbuf));
6208cf6c252SPaul Traina }
621*6f9cba8fSJoseph Mingrone #endif
6228cf6c252SPaul Traina 
6238cf6c252SPaul Traina /*
624a0ee43a1SRui Paulo  * Read packets from a capture file, and call the callback for each
625a0ee43a1SRui Paulo  * packet.
6268cf6c252SPaul Traina  * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
6278cf6c252SPaul Traina  */
6288cf6c252SPaul Traina int
6298cf6c252SPaul Traina pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
6308cf6c252SPaul Traina {
63104fb2745SSam Leffler 	struct bpf_insn *fcode;
6328cf6c252SPaul Traina 	int n = 0;
633a0ee43a1SRui Paulo 	u_char *data;
6348cf6c252SPaul Traina 
635*6f9cba8fSJoseph Mingrone 	/*
636*6f9cba8fSJoseph Mingrone 	 * This can conceivably process more than INT_MAX packets,
637*6f9cba8fSJoseph Mingrone 	 * which would overflow the packet count, causing it either
638*6f9cba8fSJoseph Mingrone 	 * to look like a negative number, and thus cause us to
639*6f9cba8fSJoseph Mingrone 	 * return a value that looks like an error, or overflow
640*6f9cba8fSJoseph Mingrone 	 * back into positive territory, and thus cause us to
641*6f9cba8fSJoseph Mingrone 	 * return a too-low count.
642*6f9cba8fSJoseph Mingrone 	 *
643*6f9cba8fSJoseph Mingrone 	 * Therefore, if the packet count is unlimited, we clip
644*6f9cba8fSJoseph Mingrone 	 * it at INT_MAX; this routine is not expected to
645*6f9cba8fSJoseph Mingrone 	 * process packets indefinitely, so that's not an issue.
646*6f9cba8fSJoseph Mingrone 	 */
647*6f9cba8fSJoseph Mingrone 	if (PACKET_COUNT_IS_UNLIMITED(cnt))
648*6f9cba8fSJoseph Mingrone 		cnt = INT_MAX;
649*6f9cba8fSJoseph Mingrone 
650*6f9cba8fSJoseph Mingrone 	for (;;) {
6518cf6c252SPaul Traina 		struct pcap_pkthdr h;
652*6f9cba8fSJoseph Mingrone 		int status;
6538cf6c252SPaul Traina 
654feb4ecdbSBruce M Simpson 		/*
655feb4ecdbSBruce M Simpson 		 * Has "pcap_breakloop()" been called?
656feb4ecdbSBruce M Simpson 		 * If so, return immediately - if we haven't read any
657feb4ecdbSBruce M Simpson 		 * packets, clear the flag and return -2 to indicate
658feb4ecdbSBruce M Simpson 		 * that we were told to break out of the loop, otherwise
659feb4ecdbSBruce M Simpson 		 * leave the flag set, so that the *next* call will break
660feb4ecdbSBruce M Simpson 		 * out of the loop without having read any packets, and
661feb4ecdbSBruce M Simpson 		 * return the number of packets we've processed so far.
662feb4ecdbSBruce M Simpson 		 */
663feb4ecdbSBruce M Simpson 		if (p->break_loop) {
664feb4ecdbSBruce M Simpson 			if (n == 0) {
665feb4ecdbSBruce M Simpson 				p->break_loop = 0;
666feb4ecdbSBruce M Simpson 				return (-2);
667feb4ecdbSBruce M Simpson 			} else
668feb4ecdbSBruce M Simpson 				return (n);
669feb4ecdbSBruce M Simpson 		}
670feb4ecdbSBruce M Simpson 
671681ed54cSXin LI 		status = p->next_packet_op(p, &h, &data);
672*6f9cba8fSJoseph Mingrone 		if (status < 0) {
673*6f9cba8fSJoseph Mingrone 			/*
674*6f9cba8fSJoseph Mingrone 			 * Error.  Pass it back to the caller.
675*6f9cba8fSJoseph Mingrone 			 */
6768cf6c252SPaul Traina 			return (status);
6778cf6c252SPaul Traina 		}
678*6f9cba8fSJoseph Mingrone 		if (status == 0) {
679*6f9cba8fSJoseph Mingrone 			/*
680*6f9cba8fSJoseph Mingrone 			 * EOF.  Nothing more to process;
681*6f9cba8fSJoseph Mingrone 			 */
682*6f9cba8fSJoseph Mingrone 			break;
683*6f9cba8fSJoseph Mingrone 		}
6848cf6c252SPaul Traina 
685*6f9cba8fSJoseph Mingrone 		/*
686*6f9cba8fSJoseph Mingrone 		 * OK, we've read a packet; run it through the filter
687*6f9cba8fSJoseph Mingrone 		 * and, if it passes, process it.
688*6f9cba8fSJoseph Mingrone 		 */
68904fb2745SSam Leffler 		if ((fcode = p->fcode.bf_insns) == NULL ||
690*6f9cba8fSJoseph Mingrone 		    pcap_filter(fcode, data, h.len, h.caplen)) {
691a0ee43a1SRui Paulo 			(*callback)(user, &h, data);
692*6f9cba8fSJoseph Mingrone 			n++;	/* count the packet */
693*6f9cba8fSJoseph Mingrone 			if (n >= cnt)
6948cf6c252SPaul Traina 				break;
6958cf6c252SPaul Traina 		}
6968cf6c252SPaul Traina 	}
6978cf6c252SPaul Traina 	/*XXX this breaks semantics tcpslice expects */
6988cf6c252SPaul Traina 	return (n);
6998cf6c252SPaul Traina }
700