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