1 1.8 christos /* $NetBSD: savefile.c,v 1.8 2024/09/02 15:33:38 christos Exp $ */ 2 1.2 christos 3 1.1 christos /* 4 1.1 christos * Copyright (c) 1993, 1994, 1995, 1996, 1997 5 1.1 christos * The Regents of the University of California. All rights reserved. 6 1.1 christos * 7 1.1 christos * Redistribution and use in source and binary forms, with or without 8 1.1 christos * modification, are permitted provided that: (1) source code distributions 9 1.1 christos * retain the above copyright notice and this paragraph in its entirety, (2) 10 1.1 christos * distributions including binary code include the above copyright notice and 11 1.1 christos * this paragraph in its entirety in the documentation or other materials 12 1.1 christos * provided with the distribution, and (3) all advertising materials mentioning 13 1.1 christos * features or use of this software display the following acknowledgement: 14 1.1 christos * ``This product includes software developed by the University of California, 15 1.1 christos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 1.1 christos * the University nor the names of its contributors may be used to endorse 17 1.1 christos * or promote products derived from this software without specific prior 18 1.1 christos * written permission. 19 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 1.1 christos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 1.1 christos * 23 1.1 christos * savefile.c - supports offline use of tcpdump 24 1.1 christos * Extraction/creation by Jeffrey Mogul, DECWRL 25 1.1 christos * Modified by Steve McCanne, LBL. 26 1.1 christos * 27 1.1 christos * Used to save the received packet headers, after filtering, to 28 1.1 christos * a file, and then read them later. 29 1.1 christos * The first record in the file contains saved values for the machine 30 1.1 christos * dependent values so we can print the dump file on any architecture. 31 1.1 christos */ 32 1.1 christos 33 1.2 christos #include <sys/cdefs.h> 34 1.8 christos __RCSID("$NetBSD: savefile.c,v 1.8 2024/09/02 15:33:38 christos Exp $"); 35 1.1 christos 36 1.5 christos #include <config.h> 37 1.1 christos 38 1.5 christos #include <pcap-types.h> 39 1.4 christos #ifdef _WIN32 40 1.5 christos #include <io.h> 41 1.5 christos #include <fcntl.h> 42 1.4 christos #endif /* _WIN32 */ 43 1.1 christos 44 1.1 christos #include <errno.h> 45 1.1 christos #include <memory.h> 46 1.1 christos #include <stdio.h> 47 1.1 christos #include <stdlib.h> 48 1.1 christos #include <string.h> 49 1.6 christos #include <limits.h> /* for INT_MAX */ 50 1.1 christos 51 1.1 christos #include "pcap-int.h" 52 1.1 christos 53 1.1 christos #ifdef HAVE_OS_PROTO_H 54 1.1 christos #include "os-proto.h" 55 1.1 christos #endif 56 1.1 christos 57 1.1 christos #include "sf-pcap.h" 58 1.5 christos #include "sf-pcapng.h" 59 1.6 christos #include "pcap-common.h" 60 1.7 christos #include "charconv.h" 61 1.1 christos 62 1.4 christos #ifdef _WIN32 63 1.4 christos /* 64 1.7 christos * This isn't exported on Windows, because it would only work if both 65 1.6 christos * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise, 66 1.6 christos * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it 67 1.4 christos * could be different if they're using different versions of the C runtime. 68 1.4 christos * 69 1.7 christos * Instead, pcap/pcap.h defines it as a macro that wraps the hopen version, 70 1.7 christos * with the wrapper calling _fileno() and _get_osfhandle() themselves, 71 1.7 christos * so that it convert the appropriate CRT version's FILE structure to 72 1.4 christos * a HANDLE (which is OS-defined, not CRT-defined, and is part of the Win32 73 1.4 christos * and Win64 ABIs). 74 1.4 christos */ 75 1.4 christos static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *); 76 1.4 christos #endif 77 1.4 christos 78 1.1 christos /* 79 1.1 christos * Setting O_BINARY on DOS/Windows is a bit tricky 80 1.1 christos */ 81 1.4 christos #if defined(_WIN32) 82 1.1 christos #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY) 83 1.1 christos #elif defined(MSDOS) 84 1.1 christos #if defined(__HIGHC__) 85 1.1 christos #define SET_BINMODE(f) setmode(f, O_BINARY) 86 1.1 christos #else 87 1.1 christos #define SET_BINMODE(f) setmode(fileno(f), O_BINARY) 88 1.1 christos #endif 89 1.1 christos #endif 90 1.1 christos 91 1.1 christos static int 92 1.5 christos sf_getnonblock(pcap_t *p _U_) 93 1.1 christos { 94 1.1 christos /* 95 1.1 christos * This is a savefile, not a live capture file, so never say 96 1.1 christos * it's in non-blocking mode. 97 1.1 christos */ 98 1.1 christos return (0); 99 1.1 christos } 100 1.1 christos 101 1.1 christos static int 102 1.5 christos sf_setnonblock(pcap_t *p, int nonblock _U_) 103 1.1 christos { 104 1.1 christos /* 105 1.2 christos * This is a savefile, not a live capture file, so reject 106 1.2 christos * requests to put it in non-blocking mode. (If it's a 107 1.2 christos * pipe, it could be put in non-blocking mode, but that 108 1.2 christos * would significantly complicate the code to read packets, 109 1.2 christos * as it would have to handle reading partial packets and 110 1.2 christos * keeping the state of the read.) 111 1.1 christos */ 112 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 113 1.2 christos "Savefiles cannot be put into non-blocking mode"); 114 1.2 christos return (-1); 115 1.1 christos } 116 1.1 christos 117 1.1 christos static int 118 1.7 christos sf_cant_set_rfmon(pcap_t *p _U_) 119 1.7 christos { 120 1.7 christos /* 121 1.7 christos * This is a savefile, not a device on which you can capture, 122 1.7 christos * so never say it supports being put into monitor mode. 123 1.7 christos */ 124 1.7 christos return (0); 125 1.7 christos } 126 1.7 christos 127 1.7 christos static int 128 1.5 christos sf_stats(pcap_t *p, struct pcap_stat *ps _U_) 129 1.1 christos { 130 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 131 1.1 christos "Statistics aren't available from savefiles"); 132 1.1 christos return (-1); 133 1.1 christos } 134 1.1 christos 135 1.4 christos #ifdef _WIN32 136 1.4 christos static struct pcap_stat * 137 1.7 christos sf_stats_ex(pcap_t *p, int *size _U_) 138 1.4 christos { 139 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 140 1.4 christos "Statistics aren't available from savefiles"); 141 1.4 christos return (NULL); 142 1.4 christos } 143 1.4 christos 144 1.1 christos static int 145 1.7 christos sf_setbuff(pcap_t *p, int dim _U_) 146 1.1 christos { 147 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 148 1.1 christos "The kernel buffer size cannot be set while reading from a file"); 149 1.1 christos return (-1); 150 1.1 christos } 151 1.1 christos 152 1.1 christos static int 153 1.7 christos sf_setmode(pcap_t *p, int mode _U_) 154 1.1 christos { 155 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 156 1.1 christos "impossible to set mode while reading from a file"); 157 1.1 christos return (-1); 158 1.1 christos } 159 1.1 christos 160 1.1 christos static int 161 1.7 christos sf_setmintocopy(pcap_t *p, int size _U_) 162 1.1 christos { 163 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 164 1.1 christos "The mintocopy parameter cannot be set while reading from a file"); 165 1.1 christos return (-1); 166 1.1 christos } 167 1.4 christos 168 1.4 christos static HANDLE 169 1.4 christos sf_getevent(pcap_t *pcap) 170 1.4 christos { 171 1.7 christos (void)snprintf(pcap->errbuf, sizeof(pcap->errbuf), 172 1.4 christos "The read event cannot be retrieved while reading from a file"); 173 1.4 christos return (INVALID_HANDLE_VALUE); 174 1.4 christos } 175 1.4 christos 176 1.4 christos static int 177 1.4 christos sf_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, 178 1.4 christos size_t *lenp _U_) 179 1.4 christos { 180 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 181 1.4 christos "An OID get request cannot be performed on a file"); 182 1.4 christos return (PCAP_ERROR); 183 1.4 christos } 184 1.4 christos 185 1.4 christos static int 186 1.4 christos sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, 187 1.4 christos size_t *lenp _U_) 188 1.4 christos { 189 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 190 1.4 christos "An OID set request cannot be performed on a file"); 191 1.4 christos return (PCAP_ERROR); 192 1.4 christos } 193 1.4 christos 194 1.4 christos static u_int 195 1.7 christos sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) 196 1.4 christos { 197 1.8 christos pcapint_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", 198 1.4 christos PCAP_ERRBUF_SIZE); 199 1.4 christos return (0); 200 1.4 christos } 201 1.4 christos 202 1.4 christos static int 203 1.7 christos sf_setuserbuffer(pcap_t *p, int size _U_) 204 1.4 christos { 205 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 206 1.4 christos "The user buffer cannot be set when reading from a file"); 207 1.4 christos return (-1); 208 1.4 christos } 209 1.4 christos 210 1.4 christos static int 211 1.7 christos sf_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_) 212 1.4 christos { 213 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 214 1.4 christos "Live packet dumping cannot be performed when reading from a file"); 215 1.4 christos return (-1); 216 1.4 christos } 217 1.4 christos 218 1.4 christos static int 219 1.7 christos sf_live_dump_ended(pcap_t *p, int sync _U_) 220 1.4 christos { 221 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 222 1.4 christos "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); 223 1.4 christos return (-1); 224 1.4 christos } 225 1.4 christos 226 1.4 christos static PAirpcapHandle 227 1.7 christos sf_get_airpcap_handle(pcap_t *pcap _U_) 228 1.4 christos { 229 1.4 christos return (NULL); 230 1.4 christos } 231 1.1 christos #endif 232 1.1 christos 233 1.1 christos static int 234 1.1 christos sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_) 235 1.1 christos { 236 1.8 christos pcapint_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", 237 1.1 christos PCAP_ERRBUF_SIZE); 238 1.1 christos return (-1); 239 1.1 christos } 240 1.1 christos 241 1.1 christos /* 242 1.1 christos * Set direction flag: Which packets do we accept on a forwarding 243 1.1 christos * single device? IN, OUT or both? 244 1.1 christos */ 245 1.1 christos static int 246 1.5 christos sf_setdirection(pcap_t *p, pcap_direction_t d _U_) 247 1.1 christos { 248 1.7 christos snprintf(p->errbuf, sizeof(p->errbuf), 249 1.1 christos "Setting direction is not supported on savefiles"); 250 1.1 christos return (-1); 251 1.1 christos } 252 1.1 christos 253 1.2 christos void 254 1.8 christos pcapint_sf_cleanup(pcap_t *p) 255 1.1 christos { 256 1.2 christos if (p->rfile != stdin) 257 1.2 christos (void)fclose(p->rfile); 258 1.1 christos if (p->buffer != NULL) 259 1.1 christos free(p->buffer); 260 1.2 christos pcap_freecode(&p->fcode); 261 1.1 christos } 262 1.1 christos 263 1.7 christos #ifdef _WIN32 264 1.7 christos /* 265 1.7 christos * Wrapper for fopen() and _wfopen(). 266 1.7 christos * 267 1.7 christos * If we're in UTF-8 mode, map the pathname from UTF-8 to UTF-16LE and 268 1.7 christos * call _wfopen(). 269 1.7 christos * 270 1.7 christos * If we're not, just use fopen(); that'll treat it as being in the 271 1.7 christos * local code page. 272 1.7 christos */ 273 1.7 christos FILE * 274 1.8 christos pcapint_charset_fopen(const char *path, const char *mode) 275 1.7 christos { 276 1.7 christos wchar_t *utf16_path; 277 1.7 christos #define MAX_MODE_LEN 16 278 1.7 christos wchar_t utf16_mode[MAX_MODE_LEN+1]; 279 1.7 christos int i; 280 1.7 christos char c; 281 1.7 christos FILE *fp; 282 1.7 christos int save_errno; 283 1.7 christos 284 1.8 christos if (pcapint_utf_8_mode) { 285 1.7 christos /* 286 1.7 christos * Map from UTF-8 to UTF-16LE. 287 1.7 christos * Fail if there are invalid characters in the input 288 1.7 christos * string, rather than converting them to REPLACEMENT 289 1.7 christos * CHARACTER; the latter is appropriate for strings 290 1.7 christos * to be displayed to the user, but for file names 291 1.7 christos * you just want the attempt to open the file to fail. 292 1.7 christos */ 293 1.7 christos utf16_path = cp_to_utf_16le(CP_UTF8, path, 294 1.7 christos MB_ERR_INVALID_CHARS); 295 1.7 christos if (utf16_path == NULL) { 296 1.7 christos /* 297 1.7 christos * Error. Assume errno has been set. 298 1.7 christos * 299 1.7 christos * XXX - what about Windows errors? 300 1.7 christos */ 301 1.7 christos return (NULL); 302 1.7 christos } 303 1.7 christos 304 1.7 christos /* 305 1.7 christos * Now convert the mode to UTF-16LE as well. 306 1.7 christos * We assume the mode is ASCII, and that 307 1.7 christos * it's short, so that's easy. 308 1.7 christos */ 309 1.7 christos for (i = 0; (c = *mode) != '\0'; i++, mode++) { 310 1.7 christos if (c > 0x7F) { 311 1.7 christos /* Not an ASCII character; fail with EINVAL. */ 312 1.7 christos free(utf16_path); 313 1.7 christos errno = EINVAL; 314 1.7 christos return (NULL); 315 1.7 christos } 316 1.7 christos if (i >= MAX_MODE_LEN) { 317 1.7 christos /* The mode string is longer than we allow. */ 318 1.7 christos free(utf16_path); 319 1.7 christos errno = EINVAL; 320 1.7 christos return (NULL); 321 1.7 christos } 322 1.7 christos utf16_mode[i] = c; 323 1.7 christos } 324 1.7 christos utf16_mode[i] = '\0'; 325 1.7 christos 326 1.7 christos /* 327 1.7 christos * OK, we have UTF-16LE strings; hand them to 328 1.7 christos * _wfopen(). 329 1.7 christos */ 330 1.7 christos fp = _wfopen(utf16_path, utf16_mode); 331 1.7 christos 332 1.7 christos /* 333 1.7 christos * Make sure freeing the UTF-16LE string doesn't 334 1.7 christos * overwrite the error code we got from _wfopen(). 335 1.7 christos */ 336 1.7 christos save_errno = errno; 337 1.7 christos free(utf16_path); 338 1.7 christos errno = save_errno; 339 1.7 christos 340 1.7 christos return (fp); 341 1.7 christos } else { 342 1.7 christos /* 343 1.7 christos * This takes strings in the local code page as an 344 1.7 christos * argument. 345 1.7 christos */ 346 1.7 christos return (fopen(path, mode)); 347 1.7 christos } 348 1.7 christos } 349 1.7 christos #endif 350 1.7 christos 351 1.1 christos pcap_t * 352 1.2 christos pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision, 353 1.4 christos char *errbuf) 354 1.1 christos { 355 1.1 christos FILE *fp; 356 1.1 christos pcap_t *p; 357 1.1 christos 358 1.4 christos if (fname == NULL) { 359 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, 360 1.4 christos "A null pointer was supplied as the file name"); 361 1.4 christos return (NULL); 362 1.4 christos } 363 1.1 christos if (fname[0] == '-' && fname[1] == '\0') 364 1.1 christos { 365 1.1 christos fp = stdin; 366 1.7 christos if (fp == NULL) { 367 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, 368 1.7 christos "The standard input is not open"); 369 1.7 christos return (NULL); 370 1.7 christos } 371 1.4 christos #if defined(_WIN32) || defined(MSDOS) 372 1.1 christos /* 373 1.1 christos * We're reading from the standard input, so put it in binary 374 1.1 christos * mode, as savefiles are binary files. 375 1.1 christos */ 376 1.1 christos SET_BINMODE(fp); 377 1.1 christos #endif 378 1.1 christos } 379 1.1 christos else { 380 1.5 christos /* 381 1.8 christos * Use pcapint_charset_fopen(); on Windows, it tests whether we're 382 1.7 christos * in "local code page" or "UTF-8" mode, and treats the 383 1.7 christos * pathname appropriately, and on other platforms, it just 384 1.7 christos * wraps fopen(). 385 1.7 christos * 386 1.5 christos * "b" is supported as of C90, so *all* UN*Xes should 387 1.7 christos * support it, even though it does nothing. For MS-DOS, 388 1.7 christos * we again need it. 389 1.5 christos */ 390 1.8 christos fp = pcapint_charset_fopen(fname, "rb"); 391 1.1 christos if (fp == NULL) { 392 1.8 christos pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 393 1.5 christos errno, "%s", fname); 394 1.1 christos return (NULL); 395 1.1 christos } 396 1.1 christos } 397 1.2 christos p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf); 398 1.1 christos if (p == NULL) { 399 1.1 christos if (fp != stdin) 400 1.1 christos fclose(fp); 401 1.1 christos } 402 1.1 christos return (p); 403 1.1 christos } 404 1.1 christos 405 1.2 christos pcap_t * 406 1.2 christos pcap_open_offline(const char *fname, char *errbuf) 407 1.2 christos { 408 1.2 christos return (pcap_open_offline_with_tstamp_precision(fname, 409 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf)); 410 1.2 christos } 411 1.2 christos 412 1.4 christos #ifdef _WIN32 413 1.2 christos pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision, 414 1.2 christos char *errbuf) 415 1.1 christos { 416 1.1 christos int fd; 417 1.1 christos FILE *file; 418 1.1 christos 419 1.1 christos fd = _open_osfhandle(osfd, _O_RDONLY); 420 1.3 christos if ( fd < 0 ) 421 1.1 christos { 422 1.8 christos pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 423 1.5 christos errno, "_open_osfhandle"); 424 1.1 christos return NULL; 425 1.1 christos } 426 1.1 christos 427 1.1 christos file = _fdopen(fd, "rb"); 428 1.3 christos if ( file == NULL ) 429 1.1 christos { 430 1.8 christos pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 431 1.5 christos errno, "_fdopen"); 432 1.6 christos _close(fd); 433 1.1 christos return NULL; 434 1.1 christos } 435 1.1 christos 436 1.2 christos return pcap_fopen_offline_with_tstamp_precision(file, precision, 437 1.2 christos errbuf); 438 1.2 christos } 439 1.2 christos 440 1.2 christos pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf) 441 1.2 christos { 442 1.2 christos return pcap_hopen_offline_with_tstamp_precision(osfd, 443 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf); 444 1.1 christos } 445 1.1 christos #endif 446 1.1 christos 447 1.6 christos /* 448 1.6 christos * Given a link-layer header type and snapshot length, return a 449 1.6 christos * snapshot length to use when reading the file; it's guaranteed 450 1.6 christos * to be > 0 and <= INT_MAX. 451 1.6 christos * 452 1.6 christos * XXX - the only reason why we limit it to <= INT_MAX is so that 453 1.6 christos * it fits in p->snapshot, and the only reason that p->snapshot is 454 1.6 christos * signed is that pcap_snapshot() returns an int, not an unsigned int. 455 1.6 christos */ 456 1.6 christos bpf_u_int32 457 1.8 christos pcapint_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen) 458 1.6 christos { 459 1.6 christos if (snaplen == 0 || snaplen > INT_MAX) { 460 1.6 christos /* 461 1.6 christos * Bogus snapshot length; use the maximum for this 462 1.6 christos * link-layer type as a fallback. 463 1.6 christos * 464 1.6 christos * XXX - we don't clamp snapshot lengths that are 465 1.6 christos * <= INT_MAX but > max_snaplen_for_dlt(linktype), 466 1.6 christos * so a capture file could cause us to allocate 467 1.6 christos * a Really Big Buffer. 468 1.6 christos */ 469 1.6 christos snaplen = max_snaplen_for_dlt(linktype); 470 1.6 christos } 471 1.6 christos return snaplen; 472 1.6 christos } 473 1.6 christos 474 1.6 christos static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = { 475 1.1 christos pcap_check_header, 476 1.1 christos pcap_ng_check_header 477 1.1 christos }; 478 1.1 christos 479 1.1 christos #define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0]) 480 1.1 christos 481 1.4 christos #ifdef _WIN32 482 1.1 christos static 483 1.1 christos #endif 484 1.1 christos pcap_t * 485 1.2 christos pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, 486 1.2 christos char *errbuf) 487 1.1 christos { 488 1.1 christos register pcap_t *p; 489 1.6 christos uint8_t magic[4]; 490 1.1 christos size_t amt_read; 491 1.1 christos u_int i; 492 1.2 christos int err; 493 1.1 christos 494 1.1 christos /* 495 1.7 christos * Fail if we were passed a NULL fp. 496 1.7 christos * 497 1.7 christos * That shouldn't happen if we're opening with a path name, but 498 1.7 christos * it could happen if buggy code is opening with a FILE * and 499 1.7 christos * didn't bother to make sure the FILE * isn't null. 500 1.7 christos */ 501 1.7 christos if (fp == NULL) { 502 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, 503 1.7 christos "Null FILE * pointer provided to savefile open routine"); 504 1.7 christos return (NULL); 505 1.7 christos } 506 1.7 christos 507 1.7 christos /* 508 1.1 christos * Read the first 4 bytes of the file; the network analyzer dump 509 1.5 christos * file formats we support (pcap and pcapng), and several other 510 1.1 christos * formats we might support in the future (such as snoop, DOS and 511 1.1 christos * Windows Sniffer, and Microsoft Network Monitor) all have magic 512 1.1 christos * numbers that are unique in their first 4 bytes. 513 1.1 christos */ 514 1.6 christos amt_read = fread(&magic, 1, sizeof(magic), fp); 515 1.1 christos if (amt_read != sizeof(magic)) { 516 1.1 christos if (ferror(fp)) { 517 1.8 christos pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 518 1.5 christos errno, "error reading dump file"); 519 1.1 christos } else { 520 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, 521 1.7 christos "truncated dump file; tried to read %zu file header bytes, only got %zu", 522 1.6 christos sizeof(magic), amt_read); 523 1.1 christos } 524 1.2 christos return (NULL); 525 1.1 christos } 526 1.1 christos 527 1.1 christos /* 528 1.1 christos * Try all file types. 529 1.1 christos */ 530 1.1 christos for (i = 0; i < N_FILE_TYPES; i++) { 531 1.2 christos p = (*check_headers[i])(magic, fp, precision, errbuf, &err); 532 1.2 christos if (p != NULL) { 533 1.2 christos /* Yup, that's it. */ 534 1.2 christos goto found; 535 1.2 christos } 536 1.2 christos if (err) { 537 1.1 christos /* 538 1.1 christos * Error trying to read the header. 539 1.1 christos */ 540 1.2 christos return (NULL); 541 1.1 christos } 542 1.1 christos } 543 1.1 christos 544 1.1 christos /* 545 1.1 christos * Well, who knows what this mess is.... 546 1.1 christos */ 547 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format"); 548 1.2 christos return (NULL); 549 1.1 christos 550 1.1 christos found: 551 1.2 christos p->rfile = fp; 552 1.1 christos 553 1.1 christos /* Padding only needed for live capture fcode */ 554 1.1 christos p->fddipad = 0; 555 1.1 christos 556 1.4 christos #if !defined(_WIN32) && !defined(MSDOS) 557 1.1 christos /* 558 1.1 christos * You can do "select()" and "poll()" on plain files on most 559 1.1 christos * platforms, and should be able to do so on pipes. 560 1.1 christos * 561 1.1 christos * You can't do "select()" on anything other than sockets in 562 1.1 christos * Windows, so, on Win32 systems, we don't have "selectable_fd". 563 1.1 christos */ 564 1.1 christos p->selectable_fd = fileno(fp); 565 1.1 christos #endif 566 1.1 christos 567 1.7 christos p->can_set_rfmon_op = sf_cant_set_rfmon; 568 1.8 christos p->read_op = pcapint_offline_read; 569 1.1 christos p->inject_op = sf_inject; 570 1.8 christos p->setfilter_op = pcapint_install_bpf_program; 571 1.1 christos p->setdirection_op = sf_setdirection; 572 1.1 christos p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ 573 1.1 christos p->getnonblock_op = sf_getnonblock; 574 1.1 christos p->setnonblock_op = sf_setnonblock; 575 1.1 christos p->stats_op = sf_stats; 576 1.4 christos #ifdef _WIN32 577 1.4 christos p->stats_ex_op = sf_stats_ex; 578 1.1 christos p->setbuff_op = sf_setbuff; 579 1.1 christos p->setmode_op = sf_setmode; 580 1.1 christos p->setmintocopy_op = sf_setmintocopy; 581 1.4 christos p->getevent_op = sf_getevent; 582 1.4 christos p->oid_get_request_op = sf_oid_get_request; 583 1.4 christos p->oid_set_request_op = sf_oid_set_request; 584 1.4 christos p->sendqueue_transmit_op = sf_sendqueue_transmit; 585 1.4 christos p->setuserbuffer_op = sf_setuserbuffer; 586 1.4 christos p->live_dump_op = sf_live_dump; 587 1.4 christos p->live_dump_ended_op = sf_live_dump_ended; 588 1.4 christos p->get_airpcap_handle_op = sf_get_airpcap_handle; 589 1.1 christos #endif 590 1.2 christos 591 1.2 christos /* 592 1.2 christos * For offline captures, the standard one-shot callback can 593 1.2 christos * be used for pcap_next()/pcap_next_ex(). 594 1.2 christos */ 595 1.8 christos p->oneshot_callback = pcapint_oneshot; 596 1.2 christos 597 1.3 christos /* 598 1.7 christos * Default breakloop operation. 599 1.7 christos */ 600 1.8 christos p->breakloop_op = pcapint_breakloop_common; 601 1.7 christos 602 1.7 christos /* 603 1.3 christos * Savefiles never require special BPF code generation. 604 1.3 christos */ 605 1.3 christos p->bpf_codegen_flags = 0; 606 1.3 christos 607 1.1 christos p->activated = 1; 608 1.1 christos 609 1.1 christos return (p); 610 1.2 christos } 611 1.2 christos 612 1.7 christos /* 613 1.7 christos * This isn't needed on Windows; we #define pcap_fopen_offline() as 614 1.7 christos * a wrapper around pcap_hopen_offline(), and we don't call it from 615 1.7 christos * inside this file, so it's unused. 616 1.7 christos */ 617 1.7 christos #ifndef _WIN32 618 1.2 christos pcap_t * 619 1.2 christos pcap_fopen_offline(FILE *fp, char *errbuf) 620 1.2 christos { 621 1.2 christos return (pcap_fopen_offline_with_tstamp_precision(fp, 622 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf)); 623 1.1 christos } 624 1.7 christos #endif 625 1.1 christos 626 1.1 christos /* 627 1.1 christos * Read packets from a capture file, and call the callback for each 628 1.1 christos * packet. 629 1.1 christos * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 630 1.1 christos */ 631 1.1 christos int 632 1.8 christos pcapint_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 633 1.1 christos { 634 1.1 christos struct bpf_insn *fcode; 635 1.1 christos int n = 0; 636 1.1 christos u_char *data; 637 1.1 christos 638 1.7 christos /* 639 1.7 christos * This can conceivably process more than INT_MAX packets, 640 1.7 christos * which would overflow the packet count, causing it either 641 1.7 christos * to look like a negative number, and thus cause us to 642 1.7 christos * return a value that looks like an error, or overflow 643 1.7 christos * back into positive territory, and thus cause us to 644 1.7 christos * return a too-low count. 645 1.7 christos * 646 1.7 christos * Therefore, if the packet count is unlimited, we clip 647 1.7 christos * it at INT_MAX; this routine is not expected to 648 1.7 christos * process packets indefinitely, so that's not an issue. 649 1.7 christos */ 650 1.7 christos if (PACKET_COUNT_IS_UNLIMITED(cnt)) 651 1.7 christos cnt = INT_MAX; 652 1.7 christos 653 1.7 christos for (;;) { 654 1.1 christos struct pcap_pkthdr h; 655 1.7 christos int status; 656 1.1 christos 657 1.1 christos /* 658 1.1 christos * Has "pcap_breakloop()" been called? 659 1.1 christos * If so, return immediately - if we haven't read any 660 1.1 christos * packets, clear the flag and return -2 to indicate 661 1.1 christos * that we were told to break out of the loop, otherwise 662 1.1 christos * leave the flag set, so that the *next* call will break 663 1.1 christos * out of the loop without having read any packets, and 664 1.1 christos * return the number of packets we've processed so far. 665 1.1 christos */ 666 1.1 christos if (p->break_loop) { 667 1.1 christos if (n == 0) { 668 1.1 christos p->break_loop = 0; 669 1.1 christos return (-2); 670 1.1 christos } else 671 1.1 christos return (n); 672 1.1 christos } 673 1.1 christos 674 1.2 christos status = p->next_packet_op(p, &h, &data); 675 1.7 christos if (status < 0) { 676 1.7 christos /* 677 1.7 christos * Error. Pass it back to the caller. 678 1.7 christos */ 679 1.1 christos return (status); 680 1.1 christos } 681 1.7 christos if (status == 0) { 682 1.7 christos /* 683 1.7 christos * EOF. Nothing more to process; 684 1.7 christos */ 685 1.7 christos break; 686 1.7 christos } 687 1.1 christos 688 1.7 christos /* 689 1.7 christos * OK, we've read a packet; run it through the filter 690 1.7 christos * and, if it passes, process it. 691 1.7 christos */ 692 1.1 christos if ((fcode = p->fcode.bf_insns) == NULL || 693 1.8 christos pcapint_filter(fcode, data, h.len, h.caplen)) { 694 1.1 christos (*callback)(user, &h, data); 695 1.7 christos n++; /* count the packet */ 696 1.7 christos if (n >= cnt) 697 1.1 christos break; 698 1.1 christos } 699 1.1 christos } 700 1.1 christos /*XXX this breaks semantics tcpslice expects */ 701 1.1 christos return (n); 702 1.1 christos } 703