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
31b00ab754SHans Petter Selasky #include <config.h>
323052b236SBill Fenner
33b00ab754SHans Petter Selasky #include <pcap-types.h>
34ada6f083SXin LI #ifdef _WIN32
35b00ab754SHans Petter Selasky #include <io.h>
36b00ab754SHans Petter Selasky #include <fcntl.h>
37ada6f083SXin LI #endif /* _WIN32 */
38a0ee43a1SRui Paulo
398cf6c252SPaul Traina #include <errno.h>
408cf6c252SPaul Traina #include <memory.h>
418cf6c252SPaul Traina #include <stdio.h>
428cf6c252SPaul Traina #include <stdlib.h>
43dc2c7305SBill Fenner #include <string.h>
4457e22627SCy Schubert #include <limits.h> /* for INT_MAX */
458cf6c252SPaul Traina
468cf6c252SPaul Traina #include "pcap-int.h"
478cf6c252SPaul Traina
488cf6c252SPaul Traina #ifdef HAVE_OS_PROTO_H
498cf6c252SPaul Traina #include "os-proto.h"
508cf6c252SPaul Traina #endif
518cf6c252SPaul Traina
52a0ee43a1SRui Paulo #include "sf-pcap.h"
53b00ab754SHans Petter Selasky #include "sf-pcapng.h"
5457e22627SCy Schubert #include "pcap-common.h"
556f9cba8fSJoseph Mingrone #include "charconv.h"
568cf6c252SPaul Traina
57ada6f083SXin LI #ifdef _WIN32
58ada6f083SXin LI /*
596f9cba8fSJoseph Mingrone * This isn't exported on Windows, because it would only work if both
6057e22627SCy Schubert * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise,
6157e22627SCy Schubert * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it
62ada6f083SXin LI * could be different if they're using different versions of the C runtime.
63ada6f083SXin LI *
646f9cba8fSJoseph Mingrone * Instead, pcap/pcap.h defines it as a macro that wraps the hopen version,
656f9cba8fSJoseph Mingrone * with the wrapper calling _fileno() and _get_osfhandle() themselves,
666f9cba8fSJoseph Mingrone * so that it convert the appropriate CRT version's FILE structure to
67ada6f083SXin LI * a HANDLE (which is OS-defined, not CRT-defined, and is part of the Win32
68ada6f083SXin LI * and Win64 ABIs).
69ada6f083SXin LI */
70ada6f083SXin LI static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
71ada6f083SXin LI #endif
72ada6f083SXin LI
73dc2c7305SBill Fenner /*
7404fb2745SSam Leffler * Setting O_BINARY on DOS/Windows is a bit tricky
7504fb2745SSam Leffler */
76ada6f083SXin LI #if defined(_WIN32)
77ee2dd488SSam Leffler #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
7804fb2745SSam Leffler #elif defined(MSDOS)
7904fb2745SSam Leffler #if defined(__HIGHC__)
8004fb2745SSam Leffler #define SET_BINMODE(f) setmode(f, O_BINARY)
8104fb2745SSam Leffler #else
8204fb2745SSam Leffler #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
8304fb2745SSam Leffler #endif
8404fb2745SSam Leffler #endif
8504fb2745SSam Leffler
86feb4ecdbSBruce M Simpson static int
sf_getnonblock(pcap_t * p _U_)87b00ab754SHans Petter Selasky sf_getnonblock(pcap_t *p _U_)
88feb4ecdbSBruce M Simpson {
89feb4ecdbSBruce M Simpson /*
90feb4ecdbSBruce M Simpson * This is a savefile, not a live capture file, so never say
91feb4ecdbSBruce M Simpson * it's in non-blocking mode.
92feb4ecdbSBruce M Simpson */
93feb4ecdbSBruce M Simpson return (0);
94feb4ecdbSBruce M Simpson }
95feb4ecdbSBruce M Simpson
96feb4ecdbSBruce M Simpson static int
sf_setnonblock(pcap_t * p,int nonblock _U_)97b00ab754SHans Petter Selasky sf_setnonblock(pcap_t *p, int nonblock _U_)
98feb4ecdbSBruce M Simpson {
99feb4ecdbSBruce M Simpson /*
100d1e87331SXin LI * This is a savefile, not a live capture file, so reject
101d1e87331SXin LI * requests to put it in non-blocking mode. (If it's a
102d1e87331SXin LI * pipe, it could be put in non-blocking mode, but that
103d1e87331SXin LI * would significantly complicate the code to read packets,
104d1e87331SXin LI * as it would have to handle reading partial packets and
105d1e87331SXin LI * keeping the state of the read.)
106feb4ecdbSBruce M Simpson */
1076f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
108d1e87331SXin LI "Savefiles cannot be put into non-blocking mode");
109d1e87331SXin LI return (-1);
110feb4ecdbSBruce M Simpson }
111feb4ecdbSBruce M Simpson
112feb4ecdbSBruce M Simpson static int
sf_cant_set_rfmon(pcap_t * p _U_)1136f9cba8fSJoseph Mingrone sf_cant_set_rfmon(pcap_t *p _U_)
1146f9cba8fSJoseph Mingrone {
1156f9cba8fSJoseph Mingrone /*
1166f9cba8fSJoseph Mingrone * This is a savefile, not a device on which you can capture,
1176f9cba8fSJoseph Mingrone * so never say it supports being put into monitor mode.
1186f9cba8fSJoseph Mingrone */
1196f9cba8fSJoseph Mingrone return (0);
1206f9cba8fSJoseph Mingrone }
1216f9cba8fSJoseph Mingrone
1226f9cba8fSJoseph Mingrone static int
sf_stats(pcap_t * p,struct pcap_stat * ps _U_)123b00ab754SHans Petter Selasky sf_stats(pcap_t *p, struct pcap_stat *ps _U_)
124feb4ecdbSBruce M Simpson {
1256f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
126feb4ecdbSBruce M Simpson "Statistics aren't available from savefiles");
127feb4ecdbSBruce M Simpson return (-1);
128feb4ecdbSBruce M Simpson }
129feb4ecdbSBruce M Simpson
130ada6f083SXin LI #ifdef _WIN32
131ada6f083SXin LI static struct pcap_stat *
sf_stats_ex(pcap_t * p,int * size _U_)1326f9cba8fSJoseph Mingrone sf_stats_ex(pcap_t *p, int *size _U_)
133ada6f083SXin LI {
1346f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
135ada6f083SXin LI "Statistics aren't available from savefiles");
136ada6f083SXin LI return (NULL);
137ada6f083SXin LI }
138ada6f083SXin LI
139a8e07101SRui Paulo static int
sf_setbuff(pcap_t * p,int dim _U_)1406f9cba8fSJoseph Mingrone sf_setbuff(pcap_t *p, int dim _U_)
141a8e07101SRui Paulo {
1426f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
143a8e07101SRui Paulo "The kernel buffer size cannot be set while reading from a file");
144a8e07101SRui Paulo return (-1);
145a8e07101SRui Paulo }
146a8e07101SRui Paulo
147a8e07101SRui Paulo static int
sf_setmode(pcap_t * p,int mode _U_)1486f9cba8fSJoseph Mingrone sf_setmode(pcap_t *p, int mode _U_)
149a8e07101SRui Paulo {
1506f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
151a8e07101SRui Paulo "impossible to set mode while reading from a file");
152a8e07101SRui Paulo return (-1);
153a8e07101SRui Paulo }
154a8e07101SRui Paulo
155a8e07101SRui Paulo static int
sf_setmintocopy(pcap_t * p,int size _U_)1566f9cba8fSJoseph Mingrone sf_setmintocopy(pcap_t *p, int size _U_)
157a8e07101SRui Paulo {
1586f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
159a8e07101SRui Paulo "The mintocopy parameter cannot be set while reading from a file");
160a8e07101SRui Paulo return (-1);
161a8e07101SRui Paulo }
162ada6f083SXin LI
163ada6f083SXin LI static HANDLE
sf_getevent(pcap_t * pcap)164ada6f083SXin LI sf_getevent(pcap_t *pcap)
165ada6f083SXin LI {
1666f9cba8fSJoseph Mingrone (void)snprintf(pcap->errbuf, sizeof(pcap->errbuf),
167ada6f083SXin LI "The read event cannot be retrieved while reading from a file");
168ada6f083SXin LI return (INVALID_HANDLE_VALUE);
169ada6f083SXin LI }
170ada6f083SXin LI
171ada6f083SXin LI static int
sf_oid_get_request(pcap_t * p,bpf_u_int32 oid _U_,void * data _U_,size_t * lenp _U_)172ada6f083SXin LI sf_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
173ada6f083SXin LI size_t *lenp _U_)
174ada6f083SXin LI {
1756f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
176ada6f083SXin LI "An OID get request cannot be performed on a file");
177ada6f083SXin LI return (PCAP_ERROR);
178ada6f083SXin LI }
179ada6f083SXin LI
180ada6f083SXin LI static int
sf_oid_set_request(pcap_t * p,bpf_u_int32 oid _U_,const void * data _U_,size_t * lenp _U_)181ada6f083SXin LI sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
182ada6f083SXin LI size_t *lenp _U_)
183ada6f083SXin LI {
1846f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
185ada6f083SXin LI "An OID set request cannot be performed on a file");
186ada6f083SXin LI return (PCAP_ERROR);
187ada6f083SXin LI }
188ada6f083SXin LI
189ada6f083SXin LI static u_int
sf_sendqueue_transmit(pcap_t * p,pcap_send_queue * queue _U_,int sync _U_)1906f9cba8fSJoseph Mingrone sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
191ada6f083SXin LI {
192*afdbf109SJoseph Mingrone pcapint_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
193ada6f083SXin LI PCAP_ERRBUF_SIZE);
194ada6f083SXin LI return (0);
195ada6f083SXin LI }
196ada6f083SXin LI
197ada6f083SXin LI static int
sf_setuserbuffer(pcap_t * p,int size _U_)1986f9cba8fSJoseph Mingrone sf_setuserbuffer(pcap_t *p, int size _U_)
199ada6f083SXin LI {
2006f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
201ada6f083SXin LI "The user buffer cannot be set when reading from a file");
202ada6f083SXin LI return (-1);
203ada6f083SXin LI }
204ada6f083SXin LI
205ada6f083SXin LI static int
sf_live_dump(pcap_t * p,char * filename _U_,int maxsize _U_,int maxpacks _U_)2066f9cba8fSJoseph Mingrone sf_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
207ada6f083SXin LI {
2086f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
209ada6f083SXin LI "Live packet dumping cannot be performed when reading from a file");
210ada6f083SXin LI return (-1);
211ada6f083SXin LI }
212ada6f083SXin LI
213ada6f083SXin LI static int
sf_live_dump_ended(pcap_t * p,int sync _U_)2146f9cba8fSJoseph Mingrone sf_live_dump_ended(pcap_t *p, int sync _U_)
215ada6f083SXin LI {
2166f9cba8fSJoseph Mingrone snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
217ada6f083SXin LI "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
218ada6f083SXin LI return (-1);
219ada6f083SXin LI }
220ada6f083SXin LI
221ada6f083SXin LI static PAirpcapHandle
sf_get_airpcap_handle(pcap_t * pcap _U_)2226f9cba8fSJoseph Mingrone sf_get_airpcap_handle(pcap_t *pcap _U_)
223ada6f083SXin LI {
224ada6f083SXin LI return (NULL);
225ada6f083SXin LI }
226a8e07101SRui Paulo #endif
227a8e07101SRui Paulo
22804fb2745SSam Leffler static int
sf_inject(pcap_t * p,const void * buf _U_,int size _U_)2296f9cba8fSJoseph Mingrone sf_inject(pcap_t *p, const void *buf _U_, int size _U_)
23004fb2745SSam Leffler {
231*afdbf109SJoseph Mingrone pcapint_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
23204fb2745SSam Leffler PCAP_ERRBUF_SIZE);
23304fb2745SSam Leffler return (-1);
23404fb2745SSam Leffler }
23504fb2745SSam Leffler
236ee2dd488SSam Leffler /*
237ee2dd488SSam Leffler * Set direction flag: Which packets do we accept on a forwarding
238ee2dd488SSam Leffler * single device? IN, OUT or both?
239ee2dd488SSam Leffler */
240ee2dd488SSam Leffler static int
sf_setdirection(pcap_t * p,pcap_direction_t d _U_)241b00ab754SHans Petter Selasky sf_setdirection(pcap_t *p, pcap_direction_t d _U_)
242ee2dd488SSam Leffler {
2436f9cba8fSJoseph Mingrone snprintf(p->errbuf, sizeof(p->errbuf),
244ee2dd488SSam Leffler "Setting direction is not supported on savefiles");
245ee2dd488SSam Leffler return (-1);
246ee2dd488SSam Leffler }
247ee2dd488SSam Leffler
248681ed54cSXin LI void
pcapint_sf_cleanup(pcap_t * p)249*afdbf109SJoseph Mingrone pcapint_sf_cleanup(pcap_t *p)
250feb4ecdbSBruce M Simpson {
251681ed54cSXin LI if (p->rfile != stdin)
252681ed54cSXin LI (void)fclose(p->rfile);
253a0ee43a1SRui Paulo if (p->buffer != NULL)
254a0ee43a1SRui Paulo free(p->buffer);
255d1e87331SXin LI pcap_freecode(&p->fcode);
256feb4ecdbSBruce M Simpson }
257feb4ecdbSBruce M Simpson
2586f9cba8fSJoseph Mingrone #ifdef _WIN32
2596f9cba8fSJoseph Mingrone /*
2606f9cba8fSJoseph Mingrone * Wrapper for fopen() and _wfopen().
2616f9cba8fSJoseph Mingrone *
2626f9cba8fSJoseph Mingrone * If we're in UTF-8 mode, map the pathname from UTF-8 to UTF-16LE and
2636f9cba8fSJoseph Mingrone * call _wfopen().
2646f9cba8fSJoseph Mingrone *
2656f9cba8fSJoseph Mingrone * If we're not, just use fopen(); that'll treat it as being in the
2666f9cba8fSJoseph Mingrone * local code page.
2676f9cba8fSJoseph Mingrone */
2686f9cba8fSJoseph Mingrone FILE *
pcapint_charset_fopen(const char * path,const char * mode)269*afdbf109SJoseph Mingrone pcapint_charset_fopen(const char *path, const char *mode)
2706f9cba8fSJoseph Mingrone {
2716f9cba8fSJoseph Mingrone wchar_t *utf16_path;
2726f9cba8fSJoseph Mingrone #define MAX_MODE_LEN 16
2736f9cba8fSJoseph Mingrone wchar_t utf16_mode[MAX_MODE_LEN+1];
2746f9cba8fSJoseph Mingrone int i;
2756f9cba8fSJoseph Mingrone char c;
2766f9cba8fSJoseph Mingrone FILE *fp;
2776f9cba8fSJoseph Mingrone int save_errno;
2786f9cba8fSJoseph Mingrone
279*afdbf109SJoseph Mingrone if (pcapint_utf_8_mode) {
2806f9cba8fSJoseph Mingrone /*
2816f9cba8fSJoseph Mingrone * Map from UTF-8 to UTF-16LE.
2826f9cba8fSJoseph Mingrone * Fail if there are invalid characters in the input
2836f9cba8fSJoseph Mingrone * string, rather than converting them to REPLACEMENT
2846f9cba8fSJoseph Mingrone * CHARACTER; the latter is appropriate for strings
2856f9cba8fSJoseph Mingrone * to be displayed to the user, but for file names
2866f9cba8fSJoseph Mingrone * you just want the attempt to open the file to fail.
2876f9cba8fSJoseph Mingrone */
2886f9cba8fSJoseph Mingrone utf16_path = cp_to_utf_16le(CP_UTF8, path,
2896f9cba8fSJoseph Mingrone MB_ERR_INVALID_CHARS);
2906f9cba8fSJoseph Mingrone if (utf16_path == NULL) {
2916f9cba8fSJoseph Mingrone /*
2926f9cba8fSJoseph Mingrone * Error. Assume errno has been set.
2936f9cba8fSJoseph Mingrone *
2946f9cba8fSJoseph Mingrone * XXX - what about Windows errors?
2956f9cba8fSJoseph Mingrone */
2966f9cba8fSJoseph Mingrone return (NULL);
2976f9cba8fSJoseph Mingrone }
2986f9cba8fSJoseph Mingrone
2996f9cba8fSJoseph Mingrone /*
3006f9cba8fSJoseph Mingrone * Now convert the mode to UTF-16LE as well.
3016f9cba8fSJoseph Mingrone * We assume the mode is ASCII, and that
3026f9cba8fSJoseph Mingrone * it's short, so that's easy.
3036f9cba8fSJoseph Mingrone */
3046f9cba8fSJoseph Mingrone for (i = 0; (c = *mode) != '\0'; i++, mode++) {
3056f9cba8fSJoseph Mingrone if (c > 0x7F) {
3066f9cba8fSJoseph Mingrone /* Not an ASCII character; fail with EINVAL. */
3076f9cba8fSJoseph Mingrone free(utf16_path);
3086f9cba8fSJoseph Mingrone errno = EINVAL;
3096f9cba8fSJoseph Mingrone return (NULL);
3106f9cba8fSJoseph Mingrone }
3116f9cba8fSJoseph Mingrone if (i >= MAX_MODE_LEN) {
3126f9cba8fSJoseph Mingrone /* The mode string is longer than we allow. */
3136f9cba8fSJoseph Mingrone free(utf16_path);
3146f9cba8fSJoseph Mingrone errno = EINVAL;
3156f9cba8fSJoseph Mingrone return (NULL);
3166f9cba8fSJoseph Mingrone }
3176f9cba8fSJoseph Mingrone utf16_mode[i] = c;
3186f9cba8fSJoseph Mingrone }
3196f9cba8fSJoseph Mingrone utf16_mode[i] = '\0';
3206f9cba8fSJoseph Mingrone
3216f9cba8fSJoseph Mingrone /*
3226f9cba8fSJoseph Mingrone * OK, we have UTF-16LE strings; hand them to
3236f9cba8fSJoseph Mingrone * _wfopen().
3246f9cba8fSJoseph Mingrone */
3256f9cba8fSJoseph Mingrone fp = _wfopen(utf16_path, utf16_mode);
3266f9cba8fSJoseph Mingrone
3276f9cba8fSJoseph Mingrone /*
3286f9cba8fSJoseph Mingrone * Make sure freeing the UTF-16LE string doesn't
3296f9cba8fSJoseph Mingrone * overwrite the error code we got from _wfopen().
3306f9cba8fSJoseph Mingrone */
3316f9cba8fSJoseph Mingrone save_errno = errno;
3326f9cba8fSJoseph Mingrone free(utf16_path);
3336f9cba8fSJoseph Mingrone errno = save_errno;
3346f9cba8fSJoseph Mingrone
3356f9cba8fSJoseph Mingrone return (fp);
3366f9cba8fSJoseph Mingrone } else {
3376f9cba8fSJoseph Mingrone /*
3386f9cba8fSJoseph Mingrone * This takes strings in the local code page as an
3396f9cba8fSJoseph Mingrone * argument.
3406f9cba8fSJoseph Mingrone */
3416f9cba8fSJoseph Mingrone return (fopen(path, mode));
3426f9cba8fSJoseph Mingrone }
3436f9cba8fSJoseph Mingrone }
3446f9cba8fSJoseph Mingrone #endif
3456f9cba8fSJoseph Mingrone
3468cf6c252SPaul Traina pcap_t *
pcap_open_offline_with_tstamp_precision(const char * fname,u_int precision,char * errbuf)347681ed54cSXin LI pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
348681ed54cSXin LI char *errbuf)
3498cf6c252SPaul Traina {
35004fb2745SSam Leffler FILE *fp;
35104fb2745SSam Leffler pcap_t *p;
35204fb2745SSam Leffler
353ada6f083SXin LI if (fname == NULL) {
3546f9cba8fSJoseph Mingrone snprintf(errbuf, PCAP_ERRBUF_SIZE,
355ada6f083SXin LI "A null pointer was supplied as the file name");
356ada6f083SXin LI return (NULL);
357ada6f083SXin LI }
35804fb2745SSam Leffler if (fname[0] == '-' && fname[1] == '\0')
359ee2dd488SSam Leffler {
36004fb2745SSam Leffler fp = stdin;
3616f9cba8fSJoseph Mingrone if (fp == NULL) {
3626f9cba8fSJoseph Mingrone snprintf(errbuf, PCAP_ERRBUF_SIZE,
3636f9cba8fSJoseph Mingrone "The standard input is not open");
3646f9cba8fSJoseph Mingrone return (NULL);
3656f9cba8fSJoseph Mingrone }
366ada6f083SXin LI #if defined(_WIN32) || defined(MSDOS)
367ee2dd488SSam Leffler /*
368ee2dd488SSam Leffler * We're reading from the standard input, so put it in binary
369ee2dd488SSam Leffler * mode, as savefiles are binary files.
370ee2dd488SSam Leffler */
371ee2dd488SSam Leffler SET_BINMODE(fp);
372ee2dd488SSam Leffler #endif
373ee2dd488SSam Leffler }
37404fb2745SSam Leffler else {
375b00ab754SHans Petter Selasky /*
376*afdbf109SJoseph Mingrone * Use pcapint_charset_fopen(); on Windows, it tests whether we're
3776f9cba8fSJoseph Mingrone * in "local code page" or "UTF-8" mode, and treats the
3786f9cba8fSJoseph Mingrone * pathname appropriately, and on other platforms, it just
3796f9cba8fSJoseph Mingrone * wraps fopen().
3806f9cba8fSJoseph Mingrone *
381b00ab754SHans Petter Selasky * "b" is supported as of C90, so *all* UN*Xes should
3826f9cba8fSJoseph Mingrone * support it, even though it does nothing. For MS-DOS,
3836f9cba8fSJoseph Mingrone * we again need it.
384b00ab754SHans Petter Selasky */
385*afdbf109SJoseph Mingrone fp = pcapint_charset_fopen(fname, "rb");
38604fb2745SSam Leffler if (fp == NULL) {
387*afdbf109SJoseph Mingrone pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
388b00ab754SHans Petter Selasky errno, "%s", fname);
38904fb2745SSam Leffler return (NULL);
39004fb2745SSam Leffler }
39104fb2745SSam Leffler }
392681ed54cSXin LI p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf);
39304fb2745SSam Leffler if (p == NULL) {
39404fb2745SSam Leffler if (fp != stdin)
39504fb2745SSam Leffler fclose(fp);
39604fb2745SSam Leffler }
39704fb2745SSam Leffler return (p);
39804fb2745SSam Leffler }
39904fb2745SSam Leffler
400681ed54cSXin LI pcap_t *
pcap_open_offline(const char * fname,char * errbuf)401681ed54cSXin LI pcap_open_offline(const char *fname, char *errbuf)
402681ed54cSXin LI {
403681ed54cSXin LI return (pcap_open_offline_with_tstamp_precision(fname,
404681ed54cSXin LI PCAP_TSTAMP_PRECISION_MICRO, errbuf));
405681ed54cSXin LI }
406681ed54cSXin LI
407ada6f083SXin LI #ifdef _WIN32
pcap_hopen_offline_with_tstamp_precision(intptr_t osfd,u_int precision,char * errbuf)408681ed54cSXin LI pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
409681ed54cSXin LI char *errbuf)
410a8e07101SRui Paulo {
411a8e07101SRui Paulo int fd;
412a8e07101SRui Paulo FILE *file;
413a8e07101SRui Paulo
414a8e07101SRui Paulo fd = _open_osfhandle(osfd, _O_RDONLY);
415a8e07101SRui Paulo if ( fd < 0 )
416a8e07101SRui Paulo {
417*afdbf109SJoseph Mingrone pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
418b00ab754SHans Petter Selasky errno, "_open_osfhandle");
419a8e07101SRui Paulo return NULL;
420a8e07101SRui Paulo }
421a8e07101SRui Paulo
422a8e07101SRui Paulo file = _fdopen(fd, "rb");
423a8e07101SRui Paulo if ( file == NULL )
424a8e07101SRui Paulo {
425*afdbf109SJoseph Mingrone pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
426b00ab754SHans Petter Selasky errno, "_fdopen");
42757e22627SCy Schubert _close(fd);
428a8e07101SRui Paulo return NULL;
429a8e07101SRui Paulo }
430a8e07101SRui Paulo
431681ed54cSXin LI return pcap_fopen_offline_with_tstamp_precision(file, precision,
432681ed54cSXin LI errbuf);
433681ed54cSXin LI }
434681ed54cSXin LI
pcap_hopen_offline(intptr_t osfd,char * errbuf)435681ed54cSXin LI pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
436681ed54cSXin LI {
437681ed54cSXin LI return pcap_hopen_offline_with_tstamp_precision(osfd,
438681ed54cSXin LI PCAP_TSTAMP_PRECISION_MICRO, errbuf);
439a8e07101SRui Paulo }
440a8e07101SRui Paulo #endif
441a8e07101SRui Paulo
44257e22627SCy Schubert /*
44357e22627SCy Schubert * Given a link-layer header type and snapshot length, return a
44457e22627SCy Schubert * snapshot length to use when reading the file; it's guaranteed
44557e22627SCy Schubert * to be > 0 and <= INT_MAX.
44657e22627SCy Schubert *
44757e22627SCy Schubert * XXX - the only reason why we limit it to <= INT_MAX is so that
44857e22627SCy Schubert * it fits in p->snapshot, and the only reason that p->snapshot is
44957e22627SCy Schubert * signed is that pcap_snapshot() returns an int, not an unsigned int.
45057e22627SCy Schubert */
45157e22627SCy Schubert bpf_u_int32
pcapint_adjust_snapshot(bpf_u_int32 linktype,bpf_u_int32 snaplen)452*afdbf109SJoseph Mingrone pcapint_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
45357e22627SCy Schubert {
45457e22627SCy Schubert if (snaplen == 0 || snaplen > INT_MAX) {
45557e22627SCy Schubert /*
45657e22627SCy Schubert * Bogus snapshot length; use the maximum for this
45757e22627SCy Schubert * link-layer type as a fallback.
45857e22627SCy Schubert *
45957e22627SCy Schubert * XXX - we don't clamp snapshot lengths that are
46057e22627SCy Schubert * <= INT_MAX but > max_snaplen_for_dlt(linktype),
46157e22627SCy Schubert * so a capture file could cause us to allocate
46257e22627SCy Schubert * a Really Big Buffer.
46357e22627SCy Schubert */
46457e22627SCy Schubert snaplen = max_snaplen_for_dlt(linktype);
46557e22627SCy Schubert }
46657e22627SCy Schubert return snaplen;
46757e22627SCy Schubert }
46857e22627SCy Schubert
46957e22627SCy Schubert static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
470a0ee43a1SRui Paulo pcap_check_header,
471a0ee43a1SRui Paulo pcap_ng_check_header
472a0ee43a1SRui Paulo };
473a0ee43a1SRui Paulo
474a0ee43a1SRui Paulo #define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0])
475a0ee43a1SRui Paulo
476ada6f083SXin LI #ifdef _WIN32
477a8e07101SRui Paulo static
478a8e07101SRui Paulo #endif
47904fb2745SSam Leffler pcap_t *
pcap_fopen_offline_with_tstamp_precision(FILE * fp,u_int precision,char * errbuf)480681ed54cSXin LI pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
481681ed54cSXin LI char *errbuf)
48204fb2745SSam Leffler {
4838cf6c252SPaul Traina register pcap_t *p;
48457e22627SCy Schubert uint8_t magic[4];
485a0ee43a1SRui Paulo size_t amt_read;
486a0ee43a1SRui Paulo u_int i;
487681ed54cSXin LI int err;
4888cf6c252SPaul Traina
489a0ee43a1SRui Paulo /*
4906f9cba8fSJoseph Mingrone * Fail if we were passed a NULL fp.
4916f9cba8fSJoseph Mingrone *
4926f9cba8fSJoseph Mingrone * That shouldn't happen if we're opening with a path name, but
4936f9cba8fSJoseph Mingrone * it could happen if buggy code is opening with a FILE * and
4946f9cba8fSJoseph Mingrone * didn't bother to make sure the FILE * isn't null.
4956f9cba8fSJoseph Mingrone */
4966f9cba8fSJoseph Mingrone if (fp == NULL) {
4976f9cba8fSJoseph Mingrone snprintf(errbuf, PCAP_ERRBUF_SIZE,
4986f9cba8fSJoseph Mingrone "Null FILE * pointer provided to savefile open routine");
4996f9cba8fSJoseph Mingrone return (NULL);
5006f9cba8fSJoseph Mingrone }
5016f9cba8fSJoseph Mingrone
5026f9cba8fSJoseph Mingrone /*
503a0ee43a1SRui Paulo * Read the first 4 bytes of the file; the network analyzer dump
504b00ab754SHans Petter Selasky * file formats we support (pcap and pcapng), and several other
505a0ee43a1SRui Paulo * formats we might support in the future (such as snoop, DOS and
506a0ee43a1SRui Paulo * Windows Sniffer, and Microsoft Network Monitor) all have magic
507a0ee43a1SRui Paulo * numbers that are unique in their first 4 bytes.
508a0ee43a1SRui Paulo */
50957e22627SCy Schubert amt_read = fread(&magic, 1, sizeof(magic), fp);
510a0ee43a1SRui Paulo if (amt_read != sizeof(magic)) {
51104fb2745SSam Leffler if (ferror(fp)) {
512*afdbf109SJoseph Mingrone pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
513b00ab754SHans Petter Selasky errno, "error reading dump file");
51404fb2745SSam Leffler } else {
5156f9cba8fSJoseph Mingrone snprintf(errbuf, PCAP_ERRBUF_SIZE,
5166f9cba8fSJoseph Mingrone "truncated dump file; tried to read %zu file header bytes, only got %zu",
51757e22627SCy Schubert sizeof(magic), amt_read);
5188cf6c252SPaul Traina }
519681ed54cSXin LI return (NULL);
5208cf6c252SPaul Traina }
521a0ee43a1SRui Paulo
522dc2c7305SBill Fenner /*
523a0ee43a1SRui Paulo * Try all file types.
524dc2c7305SBill Fenner */
525a0ee43a1SRui Paulo for (i = 0; i < N_FILE_TYPES; i++) {
526681ed54cSXin LI p = (*check_headers[i])(magic, fp, precision, errbuf, &err);
527681ed54cSXin LI if (p != NULL) {
528681ed54cSXin LI /* Yup, that's it. */
529681ed54cSXin LI goto found;
530681ed54cSXin LI }
531681ed54cSXin LI if (err) {
532ef96d74fSMax Laier /*
533a0ee43a1SRui Paulo * Error trying to read the header.
534ef96d74fSMax Laier */
535681ed54cSXin LI return (NULL);
536ef96d74fSMax Laier }
537a0ee43a1SRui Paulo }
538a0ee43a1SRui Paulo
539a0ee43a1SRui Paulo /*
540a0ee43a1SRui Paulo * Well, who knows what this mess is....
541a0ee43a1SRui Paulo */
5426f9cba8fSJoseph Mingrone snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
543681ed54cSXin LI return (NULL);
544a0ee43a1SRui Paulo
545a0ee43a1SRui Paulo found:
546681ed54cSXin LI p->rfile = fp;
5478cf6c252SPaul Traina
54804fb2745SSam Leffler /* Padding only needed for live capture fcode */
54904fb2745SSam Leffler p->fddipad = 0;
5508cf6c252SPaul Traina
551ada6f083SXin LI #if !defined(_WIN32) && !defined(MSDOS)
552feb4ecdbSBruce M Simpson /*
553feb4ecdbSBruce M Simpson * You can do "select()" and "poll()" on plain files on most
554feb4ecdbSBruce M Simpson * platforms, and should be able to do so on pipes.
555feb4ecdbSBruce M Simpson *
556feb4ecdbSBruce M Simpson * You can't do "select()" on anything other than sockets in
557feb4ecdbSBruce M Simpson * Windows, so, on Win32 systems, we don't have "selectable_fd".
558feb4ecdbSBruce M Simpson */
559feb4ecdbSBruce M Simpson p->selectable_fd = fileno(fp);
560feb4ecdbSBruce M Simpson #endif
561feb4ecdbSBruce M Simpson
5626f9cba8fSJoseph Mingrone p->can_set_rfmon_op = sf_cant_set_rfmon;
563*afdbf109SJoseph Mingrone p->read_op = pcapint_offline_read;
56404fb2745SSam Leffler p->inject_op = sf_inject;
565*afdbf109SJoseph Mingrone p->setfilter_op = pcapint_install_bpf_program;
566ee2dd488SSam Leffler p->setdirection_op = sf_setdirection;
567feb4ecdbSBruce M Simpson p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
568feb4ecdbSBruce M Simpson p->getnonblock_op = sf_getnonblock;
569feb4ecdbSBruce M Simpson p->setnonblock_op = sf_setnonblock;
570feb4ecdbSBruce M Simpson p->stats_op = sf_stats;
571ada6f083SXin LI #ifdef _WIN32
572ada6f083SXin LI p->stats_ex_op = sf_stats_ex;
573a8e07101SRui Paulo p->setbuff_op = sf_setbuff;
574a8e07101SRui Paulo p->setmode_op = sf_setmode;
575a8e07101SRui Paulo p->setmintocopy_op = sf_setmintocopy;
576ada6f083SXin LI p->getevent_op = sf_getevent;
577ada6f083SXin LI p->oid_get_request_op = sf_oid_get_request;
578ada6f083SXin LI p->oid_set_request_op = sf_oid_set_request;
579ada6f083SXin LI p->sendqueue_transmit_op = sf_sendqueue_transmit;
580ada6f083SXin LI p->setuserbuffer_op = sf_setuserbuffer;
581ada6f083SXin LI p->live_dump_op = sf_live_dump;
582ada6f083SXin LI p->live_dump_ended_op = sf_live_dump_ended;
583ada6f083SXin LI p->get_airpcap_handle_op = sf_get_airpcap_handle;
584a8e07101SRui Paulo #endif
585681ed54cSXin LI
586681ed54cSXin LI /*
587681ed54cSXin LI * For offline captures, the standard one-shot callback can
588681ed54cSXin LI * be used for pcap_next()/pcap_next_ex().
589681ed54cSXin LI */
590*afdbf109SJoseph Mingrone p->oneshot_callback = pcapint_oneshot;
591681ed54cSXin LI
592ada6f083SXin LI /*
5936f9cba8fSJoseph Mingrone * Default breakloop operation.
5946f9cba8fSJoseph Mingrone */
595*afdbf109SJoseph Mingrone p->breakloop_op = pcapint_breakloop_common;
5966f9cba8fSJoseph Mingrone
5976f9cba8fSJoseph Mingrone /*
598ada6f083SXin LI * Savefiles never require special BPF code generation.
599ada6f083SXin LI */
600ada6f083SXin LI p->bpf_codegen_flags = 0;
601ada6f083SXin LI
602a8e07101SRui Paulo p->activated = 1;
603feb4ecdbSBruce M Simpson
6048cf6c252SPaul Traina return (p);
605681ed54cSXin LI }
606681ed54cSXin LI
6076f9cba8fSJoseph Mingrone /*
6086f9cba8fSJoseph Mingrone * This isn't needed on Windows; we #define pcap_fopen_offline() as
6096f9cba8fSJoseph Mingrone * a wrapper around pcap_hopen_offline(), and we don't call it from
6106f9cba8fSJoseph Mingrone * inside this file, so it's unused.
6116f9cba8fSJoseph Mingrone */
6126f9cba8fSJoseph Mingrone #ifndef _WIN32
613681ed54cSXin LI pcap_t *
pcap_fopen_offline(FILE * fp,char * errbuf)614681ed54cSXin LI pcap_fopen_offline(FILE *fp, char *errbuf)
615681ed54cSXin LI {
616681ed54cSXin LI return (pcap_fopen_offline_with_tstamp_precision(fp,
617681ed54cSXin LI PCAP_TSTAMP_PRECISION_MICRO, errbuf));
6188cf6c252SPaul Traina }
6196f9cba8fSJoseph Mingrone #endif
6208cf6c252SPaul Traina
6218cf6c252SPaul Traina /*
622a0ee43a1SRui Paulo * Read packets from a capture file, and call the callback for each
623a0ee43a1SRui Paulo * packet.
6248cf6c252SPaul Traina * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
6258cf6c252SPaul Traina */
6268cf6c252SPaul Traina int
pcapint_offline_read(pcap_t * p,int cnt,pcap_handler callback,u_char * user)627*afdbf109SJoseph Mingrone pcapint_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
6288cf6c252SPaul Traina {
62904fb2745SSam Leffler struct bpf_insn *fcode;
6308cf6c252SPaul Traina int n = 0;
631a0ee43a1SRui Paulo u_char *data;
6328cf6c252SPaul Traina
6336f9cba8fSJoseph Mingrone /*
6346f9cba8fSJoseph Mingrone * This can conceivably process more than INT_MAX packets,
6356f9cba8fSJoseph Mingrone * which would overflow the packet count, causing it either
6366f9cba8fSJoseph Mingrone * to look like a negative number, and thus cause us to
6376f9cba8fSJoseph Mingrone * return a value that looks like an error, or overflow
6386f9cba8fSJoseph Mingrone * back into positive territory, and thus cause us to
6396f9cba8fSJoseph Mingrone * return a too-low count.
6406f9cba8fSJoseph Mingrone *
6416f9cba8fSJoseph Mingrone * Therefore, if the packet count is unlimited, we clip
6426f9cba8fSJoseph Mingrone * it at INT_MAX; this routine is not expected to
6436f9cba8fSJoseph Mingrone * process packets indefinitely, so that's not an issue.
6446f9cba8fSJoseph Mingrone */
6456f9cba8fSJoseph Mingrone if (PACKET_COUNT_IS_UNLIMITED(cnt))
6466f9cba8fSJoseph Mingrone cnt = INT_MAX;
6476f9cba8fSJoseph Mingrone
6486f9cba8fSJoseph Mingrone for (;;) {
6498cf6c252SPaul Traina struct pcap_pkthdr h;
6506f9cba8fSJoseph Mingrone int status;
6518cf6c252SPaul Traina
652feb4ecdbSBruce M Simpson /*
653feb4ecdbSBruce M Simpson * Has "pcap_breakloop()" been called?
654feb4ecdbSBruce M Simpson * If so, return immediately - if we haven't read any
655feb4ecdbSBruce M Simpson * packets, clear the flag and return -2 to indicate
656feb4ecdbSBruce M Simpson * that we were told to break out of the loop, otherwise
657feb4ecdbSBruce M Simpson * leave the flag set, so that the *next* call will break
658feb4ecdbSBruce M Simpson * out of the loop without having read any packets, and
659feb4ecdbSBruce M Simpson * return the number of packets we've processed so far.
660feb4ecdbSBruce M Simpson */
661feb4ecdbSBruce M Simpson if (p->break_loop) {
662feb4ecdbSBruce M Simpson if (n == 0) {
663feb4ecdbSBruce M Simpson p->break_loop = 0;
664feb4ecdbSBruce M Simpson return (-2);
665feb4ecdbSBruce M Simpson } else
666feb4ecdbSBruce M Simpson return (n);
667feb4ecdbSBruce M Simpson }
668feb4ecdbSBruce M Simpson
669681ed54cSXin LI status = p->next_packet_op(p, &h, &data);
6706f9cba8fSJoseph Mingrone if (status < 0) {
6716f9cba8fSJoseph Mingrone /*
6726f9cba8fSJoseph Mingrone * Error. Pass it back to the caller.
6736f9cba8fSJoseph Mingrone */
6748cf6c252SPaul Traina return (status);
6758cf6c252SPaul Traina }
6766f9cba8fSJoseph Mingrone if (status == 0) {
6776f9cba8fSJoseph Mingrone /*
6786f9cba8fSJoseph Mingrone * EOF. Nothing more to process;
6796f9cba8fSJoseph Mingrone */
6806f9cba8fSJoseph Mingrone break;
6816f9cba8fSJoseph Mingrone }
6828cf6c252SPaul Traina
6836f9cba8fSJoseph Mingrone /*
6846f9cba8fSJoseph Mingrone * OK, we've read a packet; run it through the filter
6856f9cba8fSJoseph Mingrone * and, if it passes, process it.
6866f9cba8fSJoseph Mingrone */
68704fb2745SSam Leffler if ((fcode = p->fcode.bf_insns) == NULL ||
688*afdbf109SJoseph Mingrone pcapint_filter(fcode, data, h.len, h.caplen)) {
689a0ee43a1SRui Paulo (*callback)(user, &h, data);
6906f9cba8fSJoseph Mingrone n++; /* count the packet */
6916f9cba8fSJoseph Mingrone if (n >= cnt)
6928cf6c252SPaul Traina break;
6938cf6c252SPaul Traina }
6948cf6c252SPaul Traina }
6958cf6c252SPaul Traina /*XXX this breaks semantics tcpslice expects */
6968cf6c252SPaul Traina return (n);
6978cf6c252SPaul Traina }
698