1 /* $NetBSD: savefile.c,v 1.6 2019/10/01 16:02:12 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * savefile.c - supports offline use of tcpdump 24 * Extraction/creation by Jeffrey Mogul, DECWRL 25 * Modified by Steve McCanne, LBL. 26 * 27 * Used to save the received packet headers, after filtering, to 28 * a file, and then read them later. 29 * The first record in the file contains saved values for the machine 30 * dependent values so we can print the dump file on any architecture. 31 */ 32 33 #include <sys/cdefs.h> 34 __RCSID("$NetBSD: savefile.c,v 1.6 2019/10/01 16:02:12 christos Exp $"); 35 36 #ifdef HAVE_CONFIG_H 37 #include <config.h> 38 #endif 39 40 #include <pcap-types.h> 41 #ifdef _WIN32 42 #include <io.h> 43 #include <fcntl.h> 44 #endif /* _WIN32 */ 45 46 #include <errno.h> 47 #include <memory.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <limits.h> /* for INT_MAX */ 52 53 #include "pcap-int.h" 54 55 #ifdef HAVE_OS_PROTO_H 56 #include "os-proto.h" 57 #endif 58 59 #include "sf-pcap.h" 60 #include "sf-pcapng.h" 61 #include "pcap-common.h" 62 63 #ifdef _WIN32 64 /* 65 * These aren't exported on Windows, because they would only work if both 66 * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise, 67 * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it 68 * could be different if they're using different versions of the C runtime. 69 * 70 * Instead, pcap/pcap.h defines them as macros that wrap the hopen versions, 71 * with the wrappers calling _fileno() and _get_osfhandle() themselves, 72 * so that they convert the appropriate CRT version's FILE structure to 73 * a HANDLE (which is OS-defined, not CRT-defined, and is part of the Win32 74 * and Win64 ABIs). 75 */ 76 static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *); 77 static pcap_t *pcap_fopen_offline(FILE *, char *); 78 #endif 79 80 /* 81 * Setting O_BINARY on DOS/Windows is a bit tricky 82 */ 83 #if defined(_WIN32) 84 #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY) 85 #elif defined(MSDOS) 86 #if defined(__HIGHC__) 87 #define SET_BINMODE(f) setmode(f, O_BINARY) 88 #else 89 #define SET_BINMODE(f) setmode(fileno(f), O_BINARY) 90 #endif 91 #endif 92 93 static int 94 sf_getnonblock(pcap_t *p _U_) 95 { 96 /* 97 * This is a savefile, not a live capture file, so never say 98 * it's in non-blocking mode. 99 */ 100 return (0); 101 } 102 103 static int 104 sf_setnonblock(pcap_t *p, int nonblock _U_) 105 { 106 /* 107 * This is a savefile, not a live capture file, so reject 108 * requests to put it in non-blocking mode. (If it's a 109 * pipe, it could be put in non-blocking mode, but that 110 * would significantly complicate the code to read packets, 111 * as it would have to handle reading partial packets and 112 * keeping the state of the read.) 113 */ 114 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 115 "Savefiles cannot be put into non-blocking mode"); 116 return (-1); 117 } 118 119 static int 120 sf_stats(pcap_t *p, struct pcap_stat *ps _U_) 121 { 122 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 123 "Statistics aren't available from savefiles"); 124 return (-1); 125 } 126 127 #ifdef _WIN32 128 static struct pcap_stat * 129 sf_stats_ex(pcap_t *p, int *size) 130 { 131 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 132 "Statistics aren't available from savefiles"); 133 return (NULL); 134 } 135 136 static int 137 sf_setbuff(pcap_t *p, int dim) 138 { 139 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 140 "The kernel buffer size cannot be set while reading from a file"); 141 return (-1); 142 } 143 144 static int 145 sf_setmode(pcap_t *p, int mode) 146 { 147 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 148 "impossible to set mode while reading from a file"); 149 return (-1); 150 } 151 152 static int 153 sf_setmintocopy(pcap_t *p, int size) 154 { 155 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 156 "The mintocopy parameter cannot be set while reading from a file"); 157 return (-1); 158 } 159 160 static HANDLE 161 sf_getevent(pcap_t *pcap) 162 { 163 (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), 164 "The read event cannot be retrieved while reading from a file"); 165 return (INVALID_HANDLE_VALUE); 166 } 167 168 static int 169 sf_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, 170 size_t *lenp _U_) 171 { 172 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 173 "An OID get request cannot be performed on a file"); 174 return (PCAP_ERROR); 175 } 176 177 static int 178 sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, 179 size_t *lenp _U_) 180 { 181 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 182 "An OID set request cannot be performed on a file"); 183 return (PCAP_ERROR); 184 } 185 186 static u_int 187 sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync) 188 { 189 pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", 190 PCAP_ERRBUF_SIZE); 191 return (0); 192 } 193 194 static int 195 sf_setuserbuffer(pcap_t *p, int size) 196 { 197 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 198 "The user buffer cannot be set when reading from a file"); 199 return (-1); 200 } 201 202 static int 203 sf_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks) 204 { 205 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 206 "Live packet dumping cannot be performed when reading from a file"); 207 return (-1); 208 } 209 210 static int 211 sf_live_dump_ended(pcap_t *p, int sync) 212 { 213 pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 214 "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); 215 return (-1); 216 } 217 218 static PAirpcapHandle 219 sf_get_airpcap_handle(pcap_t *pcap) 220 { 221 return (NULL); 222 } 223 #endif 224 225 static int 226 sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_) 227 { 228 pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", 229 PCAP_ERRBUF_SIZE); 230 return (-1); 231 } 232 233 /* 234 * Set direction flag: Which packets do we accept on a forwarding 235 * single device? IN, OUT or both? 236 */ 237 static int 238 sf_setdirection(pcap_t *p, pcap_direction_t d _U_) 239 { 240 pcap_snprintf(p->errbuf, sizeof(p->errbuf), 241 "Setting direction is not supported on savefiles"); 242 return (-1); 243 } 244 245 void 246 sf_cleanup(pcap_t *p) 247 { 248 if (p->rfile != stdin) 249 (void)fclose(p->rfile); 250 if (p->buffer != NULL) 251 free(p->buffer); 252 pcap_freecode(&p->fcode); 253 } 254 255 pcap_t * 256 pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision, 257 char *errbuf) 258 { 259 FILE *fp; 260 pcap_t *p; 261 262 if (fname == NULL) { 263 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 264 "A null pointer was supplied as the file name"); 265 return (NULL); 266 } 267 if (fname[0] == '-' && fname[1] == '\0') 268 { 269 fp = stdin; 270 #if defined(_WIN32) || defined(MSDOS) 271 /* 272 * We're reading from the standard input, so put it in binary 273 * mode, as savefiles are binary files. 274 */ 275 SET_BINMODE(fp); 276 #endif 277 } 278 else { 279 /* 280 * "b" is supported as of C90, so *all* UN*Xes should 281 * support it, even though it does nothing. It's 282 * required on Windows, as the file is a binary file 283 * and must be read in binary mode. 284 */ 285 fp = fopen(fname, "rb"); 286 if (fp == NULL) { 287 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 288 errno, "%s", fname); 289 return (NULL); 290 } 291 } 292 p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf); 293 if (p == NULL) { 294 if (fp != stdin) 295 fclose(fp); 296 } 297 return (p); 298 } 299 300 pcap_t * 301 pcap_open_offline(const char *fname, char *errbuf) 302 { 303 return (pcap_open_offline_with_tstamp_precision(fname, 304 PCAP_TSTAMP_PRECISION_MICRO, errbuf)); 305 } 306 307 #ifdef _WIN32 308 pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision, 309 char *errbuf) 310 { 311 int fd; 312 FILE *file; 313 314 fd = _open_osfhandle(osfd, _O_RDONLY); 315 if ( fd < 0 ) 316 { 317 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 318 errno, "_open_osfhandle"); 319 return NULL; 320 } 321 322 file = _fdopen(fd, "rb"); 323 if ( file == NULL ) 324 { 325 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 326 errno, "_fdopen"); 327 _close(fd); 328 return NULL; 329 } 330 331 return pcap_fopen_offline_with_tstamp_precision(file, precision, 332 errbuf); 333 } 334 335 pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf) 336 { 337 return pcap_hopen_offline_with_tstamp_precision(osfd, 338 PCAP_TSTAMP_PRECISION_MICRO, errbuf); 339 } 340 #endif 341 342 /* 343 * Given a link-layer header type and snapshot length, return a 344 * snapshot length to use when reading the file; it's guaranteed 345 * to be > 0 and <= INT_MAX. 346 * 347 * XXX - the only reason why we limit it to <= INT_MAX is so that 348 * it fits in p->snapshot, and the only reason that p->snapshot is 349 * signed is that pcap_snapshot() returns an int, not an unsigned int. 350 */ 351 bpf_u_int32 352 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen) 353 { 354 if (snaplen == 0 || snaplen > INT_MAX) { 355 /* 356 * Bogus snapshot length; use the maximum for this 357 * link-layer type as a fallback. 358 * 359 * XXX - we don't clamp snapshot lengths that are 360 * <= INT_MAX but > max_snaplen_for_dlt(linktype), 361 * so a capture file could cause us to allocate 362 * a Really Big Buffer. 363 */ 364 snaplen = max_snaplen_for_dlt(linktype); 365 } 366 return snaplen; 367 } 368 369 static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = { 370 pcap_check_header, 371 pcap_ng_check_header 372 }; 373 374 #define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0]) 375 376 #ifdef _WIN32 377 static 378 #endif 379 pcap_t * 380 pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision, 381 char *errbuf) 382 { 383 register pcap_t *p; 384 uint8_t magic[4]; 385 size_t amt_read; 386 u_int i; 387 int err; 388 389 /* 390 * Read the first 4 bytes of the file; the network analyzer dump 391 * file formats we support (pcap and pcapng), and several other 392 * formats we might support in the future (such as snoop, DOS and 393 * Windows Sniffer, and Microsoft Network Monitor) all have magic 394 * numbers that are unique in their first 4 bytes. 395 */ 396 amt_read = fread(&magic, 1, sizeof(magic), fp); 397 if (amt_read != sizeof(magic)) { 398 if (ferror(fp)) { 399 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 400 errno, "error reading dump file"); 401 } else { 402 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 403 "truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize, 404 sizeof(magic), amt_read); 405 } 406 return (NULL); 407 } 408 409 /* 410 * Try all file types. 411 */ 412 for (i = 0; i < N_FILE_TYPES; i++) { 413 p = (*check_headers[i])(magic, fp, precision, errbuf, &err); 414 if (p != NULL) { 415 /* Yup, that's it. */ 416 goto found; 417 } 418 if (err) { 419 /* 420 * Error trying to read the header. 421 */ 422 return (NULL); 423 } 424 } 425 426 /* 427 * Well, who knows what this mess is.... 428 */ 429 pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format"); 430 return (NULL); 431 432 found: 433 p->rfile = fp; 434 435 /* Padding only needed for live capture fcode */ 436 p->fddipad = 0; 437 438 #if !defined(_WIN32) && !defined(MSDOS) 439 /* 440 * You can do "select()" and "poll()" on plain files on most 441 * platforms, and should be able to do so on pipes. 442 * 443 * You can't do "select()" on anything other than sockets in 444 * Windows, so, on Win32 systems, we don't have "selectable_fd". 445 */ 446 p->selectable_fd = fileno(fp); 447 #endif 448 449 p->read_op = pcap_offline_read; 450 p->inject_op = sf_inject; 451 p->setfilter_op = install_bpf_program; 452 p->setdirection_op = sf_setdirection; 453 p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ 454 p->getnonblock_op = sf_getnonblock; 455 p->setnonblock_op = sf_setnonblock; 456 p->stats_op = sf_stats; 457 #ifdef _WIN32 458 p->stats_ex_op = sf_stats_ex; 459 p->setbuff_op = sf_setbuff; 460 p->setmode_op = sf_setmode; 461 p->setmintocopy_op = sf_setmintocopy; 462 p->getevent_op = sf_getevent; 463 p->oid_get_request_op = sf_oid_get_request; 464 p->oid_set_request_op = sf_oid_set_request; 465 p->sendqueue_transmit_op = sf_sendqueue_transmit; 466 p->setuserbuffer_op = sf_setuserbuffer; 467 p->live_dump_op = sf_live_dump; 468 p->live_dump_ended_op = sf_live_dump_ended; 469 p->get_airpcap_handle_op = sf_get_airpcap_handle; 470 #endif 471 472 /* 473 * For offline captures, the standard one-shot callback can 474 * be used for pcap_next()/pcap_next_ex(). 475 */ 476 p->oneshot_callback = pcap_oneshot; 477 478 /* 479 * Savefiles never require special BPF code generation. 480 */ 481 p->bpf_codegen_flags = 0; 482 483 p->activated = 1; 484 485 return (p); 486 } 487 488 #ifdef _WIN32 489 static 490 #endif 491 pcap_t * 492 pcap_fopen_offline(FILE *fp, char *errbuf) 493 { 494 return (pcap_fopen_offline_with_tstamp_precision(fp, 495 PCAP_TSTAMP_PRECISION_MICRO, errbuf)); 496 } 497 498 /* 499 * Read packets from a capture file, and call the callback for each 500 * packet. 501 * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 502 */ 503 int 504 pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 505 { 506 struct bpf_insn *fcode; 507 int status = 0; 508 int n = 0; 509 u_char *data; 510 511 while (status == 0) { 512 struct pcap_pkthdr h; 513 514 /* 515 * Has "pcap_breakloop()" been called? 516 * If so, return immediately - if we haven't read any 517 * packets, clear the flag and return -2 to indicate 518 * that we were told to break out of the loop, otherwise 519 * leave the flag set, so that the *next* call will break 520 * out of the loop without having read any packets, and 521 * return the number of packets we've processed so far. 522 */ 523 if (p->break_loop) { 524 if (n == 0) { 525 p->break_loop = 0; 526 return (-2); 527 } else 528 return (n); 529 } 530 531 status = p->next_packet_op(p, &h, &data); 532 if (status) { 533 if (status == 1) 534 return (0); 535 return (status); 536 } 537 538 if ((fcode = p->fcode.bf_insns) == NULL || 539 bpf_filter(fcode, data, h.len, h.caplen)) { 540 (*callback)(user, &h, data); 541 if (++n >= cnt && cnt > 0) 542 break; 543 } 544 } 545 /*XXX this breaks semantics tcpslice expects */ 546 return (n); 547 } 548