savefile.c revision 162012
117683Spst/* 239291Sfenner * Copyright (c) 1993, 1994, 1995, 1996, 1997 317683Spst * The Regents of the University of California. All rights reserved. 417683Spst * 517683Spst * Redistribution and use in source and binary forms, with or without 617683Spst * modification, are permitted provided that: (1) source code distributions 717683Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817683Spst * distributions including binary code include the above copyright notice and 917683Spst * this paragraph in its entirety in the documentation or other materials 1017683Spst * provided with the distribution, and (3) all advertising materials mentioning 1117683Spst * features or use of this software display the following acknowledgement: 1217683Spst * ``This product includes software developed by the University of California, 1317683Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417683Spst * the University nor the names of its contributors may be used to endorse 1517683Spst * or promote products derived from this software without specific prior 1617683Spst * written permission. 1717683Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817683Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917683Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2026175Sfenner * 2117683Spst * savefile.c - supports offline use of tcpdump 2217683Spst * Extraction/creation by Jeffrey Mogul, DECWRL 2317683Spst * Modified by Steve McCanne, LBL. 2417683Spst * 2517683Spst * Used to save the received packet headers, after filtering, to 2617683Spst * a file, and then read them later. 2717683Spst * The first record in the file contains saved values for the machine 2817683Spst * dependent values so we can print the dump file on any architecture. 2917683Spst */ 3017683Spst 3126175Sfenner#ifndef lint 32127664Sbmsstatic const char rcsid[] _U_ = 33162012Ssam "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.126.2.13 2005/08/29 21:05:45 guy Exp $ (LBL)"; 3426175Sfenner#endif 3526175Sfenner 3675107Sfenner#ifdef HAVE_CONFIG_H 3775107Sfenner#include "config.h" 3875107Sfenner#endif 3975107Sfenner 4017683Spst#include <errno.h> 4117683Spst#include <memory.h> 4217683Spst#include <stdio.h> 4317683Spst#include <stdlib.h> 4475107Sfenner#include <string.h> 4517683Spst 4617683Spst#include "pcap-int.h" 4717683Spst 4817683Spst#ifdef HAVE_OS_PROTO_H 4917683Spst#include "os-proto.h" 5017683Spst#endif 5117683Spst 52146768Ssam/* 53146768Ssam * Standard libpcap format. 54146768Ssam */ 55146768Ssam#define TCPDUMP_MAGIC 0xa1b2c3d4 5617683Spst 5717683Spst/* 58146768Ssam * Alexey Kuznetzov's modified libpcap format. 59146768Ssam */ 60146768Ssam#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34 61146768Ssam 62146768Ssam/* 63146768Ssam * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt> 64146768Ssam * for another modified format. 65146768Ssam */ 66146768Ssam#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd 67146768Ssam 68146768Ssam/* 69146768Ssam * Navtel Communcations' format, with nanosecond timestamps, 70146768Ssam * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>. 71146768Ssam */ 72146768Ssam#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d 73146768Ssam 74146768Ssam/* 75162012Ssam * Normal libpcap format, except for seconds/nanoseconds timestamps, 76162012Ssam * as per a request by Ulf Lamping <ulf.lamping@web.de> 77162012Ssam */ 78162012Ssam#define NSEC_TCPDUMP_MAGIC 0xa1b23c4d 79162012Ssam 80162012Ssam/* 8117683Spst * We use the "receiver-makes-right" approach to byte order, 8217683Spst * because time is at a premium when we are writing the file. 8317683Spst * In other words, the pcap_file_header and pcap_pkthdr, 8417683Spst * records are written in host byte order. 85127664Sbms * Note that the bytes of packet data are written out in the order in 86127664Sbms * which they were received, so multi-byte fields in packets are not 87127664Sbms * written in host byte order, they're written in whatever order the 88127664Sbms * sending machine put them in. 8917683Spst * 9017683Spst * ntoh[ls] aren't sufficient because we might need to swap on a big-endian 9117683Spst * machine (if the file was written in little-end order). 9217683Spst */ 9317683Spst#define SWAPLONG(y) \ 9417683Spst((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 9517683Spst#define SWAPSHORT(y) \ 9626175Sfenner ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) 9717683Spst 9817683Spst#define SFERR_TRUNC 1 9917683Spst#define SFERR_BADVERSION 2 10017683Spst#define SFERR_BADF 3 10117683Spst#define SFERR_EOF 4 /* not really an error, just a status */ 10217683Spst 10375107Sfenner/* 104146768Ssam * Setting O_BINARY on DOS/Windows is a bit tricky 105146768Ssam */ 106146768Ssam#if defined(WIN32) 107147894Ssam #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY) 108146768Ssam#elif defined(MSDOS) 109146768Ssam #if defined(__HIGHC__) 110146768Ssam #define SET_BINMODE(f) setmode(f, O_BINARY) 111146768Ssam #else 112146768Ssam #define SET_BINMODE(f) setmode(fileno(f), O_BINARY) 113146768Ssam #endif 114146768Ssam#endif 115146768Ssam 116146768Ssam/* 11775107Sfenner * We don't write DLT_* values to the capture file header, because 11875107Sfenner * they're not the same on all platforms. 11975107Sfenner * 12075107Sfenner * Unfortunately, the various flavors of BSD have not always used the same 12175107Sfenner * numerical values for the same data types, and various patches to 12275107Sfenner * libpcap for non-BSD OSes have added their own DLT_* codes for link 12375107Sfenner * layer encapsulation types seen on those OSes, and those codes have had, 12475107Sfenner * in some cases, values that were also used, on other platforms, for other 12575107Sfenner * link layer encapsulation types. 12675107Sfenner * 12775107Sfenner * This means that capture files of a type whose numerical DLT_* code 12875107Sfenner * means different things on different BSDs, or with different versions 12975107Sfenner * of libpcap, can't always be read on systems other than those like 13075107Sfenner * the one running on the machine on which the capture was made. 13175107Sfenner * 13275107Sfenner * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes 13375107Sfenner * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* 13475107Sfenner * codes to DLT_* codes when reading a savefile header. 13575107Sfenner * 13675107Sfenner * For those DLT_* codes that have, as far as we know, the same values on 13775107Sfenner * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as 13875107Sfenner * DLT_xxx; that way, captures of those types can still be read by 13975107Sfenner * versions of libpcap that map LINKTYPE_* values to DLT_* values, and 14075107Sfenner * captures of those types written by versions of libpcap that map DLT_ 14175107Sfenner * values to LINKTYPE_ values can still be read by older versions 14275107Sfenner * of libpcap. 14375107Sfenner * 14475107Sfenner * The other LINKTYPE_* codes are given values starting at 100, in the 14575107Sfenner * hopes that no DLT_* code will be given one of those values. 14675107Sfenner * 14775107Sfenner * In order to ensure that a given LINKTYPE_* code's value will refer to 14875107Sfenner * the same encapsulation type on all platforms, you should not allocate 14975107Sfenner * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". 15075107Sfenner * The tcpdump developers will allocate a value for you, and will not 15175107Sfenner * subsequently allocate it to anybody else; that value will be added to 15275107Sfenner * the "pcap.h" in the tcpdump.org CVS repository, so that a future 15375107Sfenner * libpcap release will include it. 15475107Sfenner * 15575107Sfenner * You should, if possible, also contribute patches to libpcap and tcpdump 15675107Sfenner * to handle the new encapsulation type, so that they can also be checked 15775107Sfenner * into the tcpdump.org CVS repository and so that they will appear in 15875107Sfenner * future libpcap and tcpdump releases. 159127664Sbms * 160127664Sbms * Do *NOT* assume that any values after the largest value in this file 161127664Sbms * are available; you might not have the most up-to-date version of this 162127664Sbms * file, and new values after that one might have been assigned. Also, 163127664Sbms * do *NOT* use any values below 100 - those might already have been 164127664Sbms * taken by one (or more!) organizations. 16575107Sfenner */ 16675107Sfenner#define LINKTYPE_NULL DLT_NULL 16775107Sfenner#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ 16875107Sfenner#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ 16975107Sfenner#define LINKTYPE_AX25 DLT_AX25 17075107Sfenner#define LINKTYPE_PRONET DLT_PRONET 17175107Sfenner#define LINKTYPE_CHAOS DLT_CHAOS 17275107Sfenner#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ 173127664Sbms#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ 17475107Sfenner#define LINKTYPE_SLIP DLT_SLIP 17575107Sfenner#define LINKTYPE_PPP DLT_PPP 17675107Sfenner#define LINKTYPE_FDDI DLT_FDDI 17775107Sfenner 17875107Sfenner/* 17975107Sfenner * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 18075107Sfenner * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol 18175107Sfenner * field) at the beginning of the packet. 18275107Sfenner * 18375107Sfenner * This is for use when there is always such a header; the address field 18475107Sfenner * might be 0xff, for regular PPP, or it might be an address field for Cisco 18575107Sfenner * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco 18675107Sfenner * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. 18775107Sfenner * 18875107Sfenner * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that 18975107Sfenner * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL 19075107Sfenner * captures will be written out with a link type that NetBSD's tcpdump 19175107Sfenner * can read. 19275107Sfenner */ 19375107Sfenner#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ 19475107Sfenner 19598530Sfenner#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ 19698530Sfenner 197127664Sbms#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */ 198127664Sbms 19975107Sfenner#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ 20075107Sfenner#define LINKTYPE_RAW 101 /* raw IP */ 20175107Sfenner#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ 20275107Sfenner#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ 20375107Sfenner#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ 20498530Sfenner#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ 20575107Sfenner#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ 206127664Sbms#define LINKTYPE_FRELAY 107 /* Frame Relay */ 20798530Sfenner#define LINKTYPE_LOOP 108 /* OpenBSD loopback */ 208127664Sbms#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ 20975107Sfenner 210127664Sbms/* 211127664Sbms * These three types are reserved for future use. 212127664Sbms */ 213127664Sbms#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ 214127664Sbms#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ 215127664Sbms#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ 216127664Sbms 21798530Sfenner#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ 21898530Sfenner#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ 21998530Sfenner#define LINKTYPE_ECONET 115 /* Acorn Econet */ 22098530Sfenner 221127664Sbms/* 222127664Sbms * Reserved for use with OpenBSD ipfilter. 223127664Sbms */ 224127664Sbms#define LINKTYPE_IPFILTER 116 225127664Sbms 226127664Sbms#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ 22798530Sfenner#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ 22898530Sfenner#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ 22998530Sfenner#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ 23098530Sfenner 23175107Sfenner/* 232127664Sbms * Reserved for Siemens HiPath HDLC. 23375107Sfenner */ 234127664Sbms#define LINKTYPE_HHDLC 121 23575107Sfenner 236127664Sbms#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ 237127664Sbms#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ 238127664Sbms 239127664Sbms/* 240127664Sbms * Reserved as per request from Kent Dahlgren <kent@praesum.com> 241127664Sbms * for private use. 242127664Sbms */ 243127664Sbms#define LINKTYPE_RIO 124 /* RapidIO */ 244127664Sbms#define LINKTYPE_PCI_EXP 125 /* PCI Express */ 245127664Sbms#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ 246127664Sbms 247127664Sbms#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ 248127664Sbms 249127664Sbms/* 250127664Sbms * Reserved for the TZSP encapsulation, as per request from 251127664Sbms * Chris Waters <chris.waters@networkchemistry.com> 252127664Sbms * TZSP is a generic encapsulation for any other link type, 253127664Sbms * which includes a means to include meta-information 254127664Sbms * with the packet, e.g. signal strength and channel 255127664Sbms * for 802.11 packets. 256127664Sbms */ 257127664Sbms#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ 258127664Sbms 259127664Sbms#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ 260127664Sbms 261127664Sbms/* 262127664Sbms * Juniper-private data link types, as per request from 263127664Sbms * Hannes Gredler <hannes@juniper.net>. The corresponding 264127664Sbms * DLT_s are used for passing on chassis-internal 265127664Sbms * metainformation such as QOS profiles, etc.. 266127664Sbms */ 267127664Sbms#define LINKTYPE_JUNIPER_MLPPP 130 268127664Sbms#define LINKTYPE_JUNIPER_MLFR 131 269127664Sbms#define LINKTYPE_JUNIPER_ES 132 270127664Sbms#define LINKTYPE_JUNIPER_GGSN 133 271127664Sbms#define LINKTYPE_JUNIPER_MFR 134 272127664Sbms#define LINKTYPE_JUNIPER_ATM2 135 273127664Sbms#define LINKTYPE_JUNIPER_SERVICES 136 274127664Sbms#define LINKTYPE_JUNIPER_ATM1 137 275127664Sbms 276127664Sbms#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */ 277127664Sbms 278147894Ssam#define LINKTYPE_MTP2_WITH_PHDR 139 279147894Ssam#define LINKTYPE_MTP2 140 280147894Ssam#define LINKTYPE_MTP3 141 281147894Ssam#define LINKTYPE_SCCP 142 282127664Sbms 283127664Sbms#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */ 284127664Sbms 285127664Sbms#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */ 286127664Sbms 287127664Sbms/* 288127664Sbms * Reserved for IBM SP switch and IBM Next Federation switch. 289127664Sbms */ 290127664Sbms#define LINKTYPE_IBM_SP 145 291127664Sbms#define LINKTYPE_IBM_SN 146 292127664Sbms 293127664Sbms/* 294127664Sbms * Reserved for private use. If you have some link-layer header type 295127664Sbms * that you want to use within your organization, with the capture files 296127664Sbms * using that link-layer header type not ever be sent outside your 297127664Sbms * organization, you can use these values. 298127664Sbms * 299127664Sbms * No libpcap release will use these for any purpose, nor will any 300127664Sbms * tcpdump release use them, either. 301127664Sbms * 302127664Sbms * Do *NOT* use these in capture files that you expect anybody not using 303127664Sbms * your private versions of capture-file-reading tools to read; in 304127664Sbms * particular, do *NOT* use them in products, otherwise you may find that 305127664Sbms * people won't be able to use tcpdump, or snort, or Ethereal, or... to 306127664Sbms * read capture files from your firewall/intrusion detection/traffic 307127664Sbms * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value, 308127664Sbms * and you may also find that the developers of those applications will 309127664Sbms * not accept patches to let them read those files. 310127664Sbms * 311127664Sbms * Also, do not use them if somebody might send you a capture using them 312127664Sbms * for *their* private type and tools using them for *your* private type 313127664Sbms * would have to read them. 314127664Sbms * 315127664Sbms * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ 316127664Sbms * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type 317127664Sbms * you're given. 318127664Sbms */ 319127664Sbms#define LINKTYPE_USER0 147 320127664Sbms#define LINKTYPE_USER1 148 321127664Sbms#define LINKTYPE_USER2 149 322127664Sbms#define LINKTYPE_USER3 150 323127664Sbms#define LINKTYPE_USER4 151 324127664Sbms#define LINKTYPE_USER5 152 325127664Sbms#define LINKTYPE_USER6 153 326127664Sbms#define LINKTYPE_USER7 154 327127664Sbms#define LINKTYPE_USER8 155 328127664Sbms#define LINKTYPE_USER9 156 329127664Sbms#define LINKTYPE_USER10 157 330127664Sbms#define LINKTYPE_USER11 158 331127664Sbms#define LINKTYPE_USER12 159 332127664Sbms#define LINKTYPE_USER13 160 333127664Sbms#define LINKTYPE_USER14 161 334127664Sbms#define LINKTYPE_USER15 162 335127664Sbms 336127664Sbms/* 337127664Sbms * For future use with 802.11 captures - defined by AbsoluteValue 338127664Sbms * Systems to store a number of bits of link-layer information 339127664Sbms * including radio information: 340127664Sbms * 341127664Sbms * http://www.shaftnet.org/~pizza/software/capturefrm.txt 342127664Sbms * 343127664Sbms * but could and arguably should also be used by non-AVS Linux 344127664Sbms * 802.11 drivers; that may happen in the future. 345127664Sbms */ 346127664Sbms#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ 347127664Sbms 348127664Sbms/* 349127664Sbms * Juniper-private data link type, as per request from 350127664Sbms * Hannes Gredler <hannes@juniper.net>. The corresponding 351127664Sbms * DLT_s are used for passing on chassis-internal 352127664Sbms * metainformation such as QOS profiles, etc.. 353127664Sbms */ 354127664Sbms#define LINKTYPE_JUNIPER_MONITOR 164 355127664Sbms 356146768Ssam/* 357146768Ssam * Reserved for BACnet MS/TP. 358146768Ssam */ 359146768Ssam#define LINKTYPE_BACNET_MS_TP 165 360146768Ssam 361146768Ssam/* 362146768Ssam * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>. 363146768Ssam * 364146768Ssam * This is used in some OSes to allow a kernel socket filter to distinguish 365146768Ssam * between incoming and outgoing packets, on a socket intended to 366146768Ssam * supply pppd with outgoing packets so it can do dial-on-demand and 367146768Ssam * hangup-on-lack-of-demand; incoming packets are filtered out so they 368146768Ssam * don't cause pppd to hold the connection up (you don't want random 369146768Ssam * input packets such as port scans, packets from old lost connections, 370146768Ssam * etc. to force the connection to stay up). 371146768Ssam * 372146768Ssam * The first byte of the PPP header (0xff03) is modified to accomodate 373146768Ssam * the direction - 0x00 = IN, 0x01 = OUT. 374146768Ssam */ 375146768Ssam#define LINKTYPE_PPP_PPPD 166 376146768Ssam 377146768Ssam/* 378146768Ssam * Juniper-private data link type, as per request from 379146768Ssam * Hannes Gredler <hannes@juniper.net>. The DLT_s are used 380146768Ssam * for passing on chassis-internal metainformation such as 381146768Ssam * QOS profiles, cookies, etc.. 382146768Ssam */ 383146768Ssam#define LINKTYPE_JUNIPER_PPPOE 167 384146768Ssam#define LINKTYPE_JUNIPER_PPPOE_ATM 168 385146768Ssam 386146768Ssam#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */ 387146768Ssam#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ 388146768Ssam#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */ 389146768Ssam 390146768Ssam/* 391146768Ssam * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line 392146768Ssam * monitoring equipment. 393146768Ssam */ 394146768Ssam#define LINKTYPE_GCOM_T1E1 172 395146768Ssam#define LINKTYPE_GCOM_SERIAL 173 396146768Ssam 397146768Ssam/* 398146768Ssam * Juniper-private data link type, as per request from 399146768Ssam * Hannes Gredler <hannes@juniper.net>. The DLT_ is used 400146768Ssam * for internal communication to Physical Interface Cards (PIC) 401146768Ssam */ 402146768Ssam#define LINKTYPE_JUNIPER_PIC_PEER 174 403146768Ssam 404146768Ssam/* 405146768Ssam * Link types requested by Gregor Maier <gregor@endace.com> of Endace 406146768Ssam * Measurement Systems. They add an ERF header (see 407146768Ssam * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of 408146768Ssam * the link-layer header. 409146768Ssam */ 410146768Ssam#define LINKTYPE_ERF_ETH 175 /* Ethernet */ 411146768Ssam#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */ 412146768Ssam 413147894Ssam/* 414147894Ssam * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD 415147894Ssam * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header 416147894Ssam * includes additional information before the LAPD header, so it's 417147894Ssam * not necessarily a generic LAPD header. 418147894Ssam */ 419147894Ssam#define LINKTYPE_LINUX_LAPD 177 420147894Ssam 421162012Ssam/* 422162012Ssam * Juniper-private data link type, as per request from 423162012Ssam * Hannes Gredler <hannes@juniper.net>. 424162012Ssam * The Link Types are used for prepending meta-information 425162012Ssam * like interface index, interface name 426162012Ssam * before standard Ethernet, PPP, Frelay & C-HDLC Frames 427162012Ssam */ 428162012Ssam#define LINKTYPE_JUNIPER_ETHER 178 429162012Ssam#define LINKTYPE_JUNIPER_PPP 179 430162012Ssam#define LINKTYPE_JUNIPER_FRELAY 180 431162012Ssam#define LINKTYPE_JUNIPER_CHDLC 181 432162012Ssam 43375107Sfennerstatic struct linktype_map { 43475107Sfenner int dlt; 43575107Sfenner int linktype; 43675107Sfenner} map[] = { 43775107Sfenner /* 43875107Sfenner * These DLT_* codes have LINKTYPE_* codes with values identical 43975107Sfenner * to the values of the corresponding DLT_* code. 44075107Sfenner */ 44175107Sfenner { DLT_NULL, LINKTYPE_NULL }, 44275107Sfenner { DLT_EN10MB, LINKTYPE_ETHERNET }, 44375107Sfenner { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, 44475107Sfenner { DLT_AX25, LINKTYPE_AX25 }, 44575107Sfenner { DLT_PRONET, LINKTYPE_PRONET }, 44675107Sfenner { DLT_CHAOS, LINKTYPE_CHAOS }, 44775107Sfenner { DLT_IEEE802, LINKTYPE_TOKEN_RING }, 44875107Sfenner { DLT_ARCNET, LINKTYPE_ARCNET }, 44975107Sfenner { DLT_SLIP, LINKTYPE_SLIP }, 45075107Sfenner { DLT_PPP, LINKTYPE_PPP }, 45175107Sfenner { DLT_FDDI, LINKTYPE_FDDI }, 45275107Sfenner 45375107Sfenner /* 45475107Sfenner * These DLT_* codes have different values on different 45575107Sfenner * platforms; we map them to LINKTYPE_* codes that 45675107Sfenner * have values that should never be equal to any DLT_* 45775107Sfenner * code. 45875107Sfenner */ 459127664Sbms#ifdef DLT_FR 460127664Sbms /* BSD/OS Frame Relay */ 461127664Sbms { DLT_FR, LINKTYPE_FRELAY }, 462127664Sbms#endif 463127664Sbms 464127664Sbms { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, 46575107Sfenner { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, 46675107Sfenner { DLT_RAW, LINKTYPE_RAW }, 46775107Sfenner { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, 46875107Sfenner { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, 46975107Sfenner 47075107Sfenner /* BSD/OS Cisco HDLC */ 47175107Sfenner { DLT_C_HDLC, LINKTYPE_C_HDLC }, 47275107Sfenner 47375107Sfenner /* 47475107Sfenner * These DLT_* codes are not on all platforms, but, so far, 47575107Sfenner * there don't appear to be any platforms that define 47675107Sfenner * other codes with those values; we map them to 47775107Sfenner * different LINKTYPE_* values anyway, just in case. 47875107Sfenner */ 47975107Sfenner 48075107Sfenner /* Linux ATM Classical IP */ 48175107Sfenner { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, 48275107Sfenner 48375107Sfenner /* NetBSD sync/async serial PPP (or Cisco HDLC) */ 48475107Sfenner { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, 48575107Sfenner 48698530Sfenner /* NetBSD PPP over Ethernet */ 48798530Sfenner { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, 48898530Sfenner 48975107Sfenner /* IEEE 802.11 wireless */ 49075107Sfenner { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, 49175107Sfenner 492127664Sbms /* Frame Relay */ 493127664Sbms { DLT_FRELAY, LINKTYPE_FRELAY }, 494127664Sbms 49575107Sfenner /* OpenBSD loopback */ 49675107Sfenner { DLT_LOOP, LINKTYPE_LOOP }, 49775107Sfenner 49875107Sfenner /* Linux cooked socket capture */ 49975107Sfenner { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, 50075107Sfenner 50198530Sfenner /* Apple LocalTalk hardware */ 50298530Sfenner { DLT_LTALK, LINKTYPE_LTALK }, 50398530Sfenner 50498530Sfenner /* Acorn Econet */ 50598530Sfenner { DLT_ECONET, LINKTYPE_ECONET }, 50698530Sfenner 507127664Sbms /* OpenBSD DLT_PFLOG */ 508127664Sbms { DLT_PFLOG, LINKTYPE_PFLOG }, 509127664Sbms 51098530Sfenner /* For Cisco-internal use */ 51198530Sfenner { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, 51298530Sfenner 51398530Sfenner /* Prism II monitor-mode header plus 802.11 header */ 51498530Sfenner { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, 51598530Sfenner 51698530Sfenner /* FreeBSD Aironet driver stuff */ 51798530Sfenner { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, 51898530Sfenner 519127664Sbms /* Siemens HiPath HDLC */ 520127664Sbms { DLT_HHDLC, LINKTYPE_HHDLC }, 521127664Sbms 522127664Sbms /* RFC 2625 IP-over-Fibre Channel */ 523127664Sbms { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, 524127664Sbms 525127664Sbms /* Solaris+SunATM */ 526127664Sbms { DLT_SUNATM, LINKTYPE_SUNATM }, 527127664Sbms 528127664Sbms /* RapidIO */ 529127664Sbms { DLT_RIO, LINKTYPE_RIO }, 530127664Sbms 531127664Sbms /* PCI Express */ 532127664Sbms { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, 533127664Sbms 534127664Sbms /* Xilinx Aurora link layer */ 535127664Sbms { DLT_AURORA, LINKTYPE_AURORA }, 536127664Sbms 537127664Sbms /* 802.11 plus BSD radio header */ 538127664Sbms { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, 539127664Sbms 540127664Sbms /* Tazmen Sniffer Protocol */ 541127664Sbms { DLT_TZSP, LINKTYPE_TZSP }, 542127664Sbms 543127664Sbms /* Arcnet with Linux-style link-layer headers */ 544127664Sbms { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, 545127664Sbms 546127664Sbms /* Juniper-internal chassis encapsulation */ 547127664Sbms { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP }, 548127664Sbms { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR }, 549127664Sbms { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES }, 550127664Sbms { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN }, 551127664Sbms { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR }, 552127664Sbms { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 }, 553127664Sbms { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES }, 554127664Sbms { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 }, 555127664Sbms 556127664Sbms /* Apple IP-over-IEEE 1394 cooked header */ 557127664Sbms { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 }, 558127664Sbms 559147894Ssam /* SS7 */ 560147894Ssam { DLT_MTP2_WITH_PHDR, LINKTYPE_MTP2_WITH_PHDR }, 561147894Ssam { DLT_MTP2, LINKTYPE_MTP2 }, 562147894Ssam { DLT_MTP3, LINKTYPE_MTP3 }, 563147894Ssam { DLT_SCCP, LINKTYPE_SCCP }, 564147894Ssam 565127664Sbms /* DOCSIS MAC frames */ 566127664Sbms { DLT_DOCSIS, LINKTYPE_DOCSIS }, 567127664Sbms 568127664Sbms /* IrDA IrLAP packets + Linux-cooked header */ 569127664Sbms { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA }, 570127664Sbms 571127664Sbms /* IBM SP and Next Federation switches */ 572127664Sbms { DLT_IBM_SP, LINKTYPE_IBM_SP }, 573127664Sbms { DLT_IBM_SN, LINKTYPE_IBM_SN }, 574127664Sbms 575127664Sbms /* 802.11 plus AVS radio header */ 576127664Sbms { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS }, 577127664Sbms 57875107Sfenner /* 57975107Sfenner * Any platform that defines additional DLT_* codes should: 58075107Sfenner * 58175107Sfenner * request a LINKTYPE_* code and value from tcpdump.org, 58275107Sfenner * as per the above; 58375107Sfenner * 58475107Sfenner * add, in their version of libpcap, an entry to map 58575107Sfenner * those DLT_* codes to the corresponding LINKTYPE_* 58675107Sfenner * code; 58775107Sfenner * 58875107Sfenner * redefine, in their "net/bpf.h", any DLT_* values 58975107Sfenner * that collide with the values used by their additional 59075107Sfenner * DLT_* codes, to remove those collisions (but without 59175107Sfenner * making them collide with any of the LINKTYPE_* 59275107Sfenner * values equal to 50 or above; they should also avoid 59375107Sfenner * defining DLT_* values that collide with those 59475107Sfenner * LINKTYPE_* values, either). 59575107Sfenner */ 596127664Sbms 597146768Ssam /* Juniper-internal chassis encapsulation */ 598146768Ssam { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR }, 599146768Ssam 600146768Ssam /* BACnet MS/TP */ 601146768Ssam { DLT_BACNET_MS_TP, LINKTYPE_BACNET_MS_TP }, 602146768Ssam 603146768Ssam /* PPP for pppd, with direction flag in the PPP header */ 604146768Ssam { DLT_PPP_PPPD, LINKTYPE_PPP_PPPD}, 605146768Ssam 606146768Ssam /* Juniper-internal chassis encapsulation */ 607146768Ssam { DLT_JUNIPER_PPPOE, LINKTYPE_JUNIPER_PPPOE }, 608146768Ssam { DLT_JUNIPER_PPPOE_ATM,LINKTYPE_JUNIPER_PPPOE_ATM }, 609146768Ssam 610146768Ssam /* GPRS LLC */ 611146768Ssam { DLT_GPRS_LLC, LINKTYPE_GPRS_LLC }, 612146768Ssam 613146768Ssam /* Transparent Generic Framing Procedure (ITU-T G.7041/Y.1303) */ 614146768Ssam { DLT_GPF_T, LINKTYPE_GPF_T }, 615146768Ssam 616146768Ssam /* Framed Generic Framing Procedure (ITU-T G.7041/Y.1303) */ 617146768Ssam { DLT_GPF_F, LINKTYPE_GPF_F }, 618146768Ssam 619146768Ssam { DLT_GCOM_T1E1, LINKTYPE_GCOM_T1E1 }, 620146768Ssam { DLT_GCOM_SERIAL, LINKTYPE_GCOM_SERIAL }, 621146768Ssam 622127664Sbms /* Juniper-internal chassis encapsulation */ 623146768Ssam { DLT_JUNIPER_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER }, 624127664Sbms 625146768Ssam /* Endace types */ 626146768Ssam { DLT_ERF_ETH, LINKTYPE_ERF_ETH }, 627146768Ssam { DLT_ERF_POS, LINKTYPE_ERF_POS }, 628146768Ssam 629147894Ssam /* viSDN LAPD */ 630147894Ssam { DLT_LINUX_LAPD, LINKTYPE_LINUX_LAPD }, 631147894Ssam 632162012Ssam /* Juniper meta-information before Ether, PPP, Frame Relay, C-HDLC Frames */ 633162012Ssam { DLT_JUNIPER_ETHER, LINKTYPE_JUNIPER_ETHER }, 634162012Ssam { DLT_JUNIPER_PPP, LINKTYPE_JUNIPER_PPP }, 635162012Ssam { DLT_JUNIPER_FRELAY, LINKTYPE_JUNIPER_FRELAY }, 636162012Ssam { DLT_JUNIPER_CHDLC, LINKTYPE_JUNIPER_CHDLC }, 637162012Ssam 638162012Ssam 63975107Sfenner { -1, -1 } 64075107Sfenner}; 64175107Sfenner 64217683Spststatic int 64375107Sfennerdlt_to_linktype(int dlt) 64475107Sfenner{ 64575107Sfenner int i; 64675107Sfenner 64775107Sfenner for (i = 0; map[i].dlt != -1; i++) { 64875107Sfenner if (map[i].dlt == dlt) 64975107Sfenner return (map[i].linktype); 65075107Sfenner } 65175107Sfenner 65275107Sfenner /* 65375107Sfenner * If we don't have a mapping for this DLT_ code, return an 65475107Sfenner * error; that means that the table above needs to have an 65575107Sfenner * entry added. 65675107Sfenner */ 65775107Sfenner return (-1); 65875107Sfenner} 65975107Sfenner 66075107Sfennerstatic int 66175107Sfennerlinktype_to_dlt(int linktype) 66275107Sfenner{ 66375107Sfenner int i; 66475107Sfenner 66575107Sfenner for (i = 0; map[i].linktype != -1; i++) { 66675107Sfenner if (map[i].linktype == linktype) 66775107Sfenner return (map[i].dlt); 66875107Sfenner } 66975107Sfenner 67075107Sfenner /* 67175107Sfenner * If we don't have an entry for this link type, return 67275107Sfenner * the link type value; it may be a DLT_ value from an 67375107Sfenner * older version of libpcap. 67475107Sfenner */ 67575107Sfenner return linktype; 67675107Sfenner} 67775107Sfenner 67875107Sfennerstatic int 67917683Spstsf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) 68017683Spst{ 68117683Spst struct pcap_file_header hdr; 68217683Spst 68317683Spst hdr.magic = TCPDUMP_MAGIC; 68417683Spst hdr.version_major = PCAP_VERSION_MAJOR; 68517683Spst hdr.version_minor = PCAP_VERSION_MINOR; 68617683Spst 68717683Spst hdr.thiszone = thiszone; 68817683Spst hdr.snaplen = snaplen; 68917683Spst hdr.sigfigs = 0; 69017683Spst hdr.linktype = linktype; 69117683Spst 69217683Spst if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 69317683Spst return (-1); 69417683Spst 69517683Spst return (0); 69617683Spst} 69717683Spst 69817683Spststatic void 69917683Spstswap_hdr(struct pcap_file_header *hp) 70017683Spst{ 70117683Spst hp->version_major = SWAPSHORT(hp->version_major); 70217683Spst hp->version_minor = SWAPSHORT(hp->version_minor); 70317683Spst hp->thiszone = SWAPLONG(hp->thiszone); 70417683Spst hp->sigfigs = SWAPLONG(hp->sigfigs); 70517683Spst hp->snaplen = SWAPLONG(hp->snaplen); 70617683Spst hp->linktype = SWAPLONG(hp->linktype); 70717683Spst} 70817683Spst 709127664Sbmsstatic int 710127664Sbmssf_getnonblock(pcap_t *p, char *errbuf) 711127664Sbms{ 712127664Sbms /* 713127664Sbms * This is a savefile, not a live capture file, so never say 714127664Sbms * it's in non-blocking mode. 715127664Sbms */ 716127664Sbms return (0); 717127664Sbms} 718127664Sbms 719127664Sbmsstatic int 720127664Sbmssf_setnonblock(pcap_t *p, int nonblock, char *errbuf) 721127664Sbms{ 722127664Sbms /* 723127664Sbms * This is a savefile, not a live capture file, so ignore 724127664Sbms * requests to put it in non-blocking mode. 725127664Sbms */ 726127664Sbms return (0); 727127664Sbms} 728127664Sbms 729127664Sbmsstatic int 730127664Sbmssf_stats(pcap_t *p, struct pcap_stat *ps) 731127664Sbms{ 732127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 733127664Sbms "Statistics aren't available from savefiles"); 734127664Sbms return (-1); 735127664Sbms} 736127664Sbms 737146768Ssamstatic int 738146768Ssamsf_inject(pcap_t *p, const void *buf _U_, size_t size _U_) 739146768Ssam{ 740146768Ssam strlcpy(p->errbuf, "Sending packets isn't supported on savefiles", 741146768Ssam PCAP_ERRBUF_SIZE); 742146768Ssam return (-1); 743146768Ssam} 744146768Ssam 745147894Ssam/* 746147894Ssam * Set direction flag: Which packets do we accept on a forwarding 747147894Ssam * single device? IN, OUT or both? 748147894Ssam */ 749147894Ssamstatic int 750162012Ssamsf_setdirection(pcap_t *p, pcap_direction_t d) 751147894Ssam{ 752147894Ssam snprintf(p->errbuf, sizeof(p->errbuf), 753147894Ssam "Setting direction is not supported on savefiles"); 754147894Ssam return (-1); 755147894Ssam} 756147894Ssam 757127664Sbmsstatic void 758127664Sbmssf_close(pcap_t *p) 759127664Sbms{ 760127664Sbms if (p->sf.rfile != stdin) 761127664Sbms (void)fclose(p->sf.rfile); 762127664Sbms if (p->sf.base != NULL) 763127664Sbms free(p->sf.base); 764127664Sbms} 765127664Sbms 76617683Spstpcap_t * 76739291Sfennerpcap_open_offline(const char *fname, char *errbuf) 76817683Spst{ 769146768Ssam FILE *fp; 770146768Ssam pcap_t *p; 771146768Ssam 772146768Ssam if (fname[0] == '-' && fname[1] == '\0') 773147894Ssam { 774146768Ssam fp = stdin; 775147894Ssam#if defined(WIN32) || defined(MSDOS) 776147894Ssam /* 777147894Ssam * We're reading from the standard input, so put it in binary 778147894Ssam * mode, as savefiles are binary files. 779147894Ssam */ 780147894Ssam SET_BINMODE(fp); 781147894Ssam#endif 782147894Ssam } 783146768Ssam else { 784146768Ssam#if !defined(WIN32) && !defined(MSDOS) 785146768Ssam fp = fopen(fname, "r"); 786146768Ssam#else 787146768Ssam fp = fopen(fname, "rb"); 788146768Ssam#endif 789146768Ssam if (fp == NULL) { 790146768Ssam snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, 791146768Ssam pcap_strerror(errno)); 792146768Ssam return (NULL); 793146768Ssam } 794146768Ssam } 795146768Ssam p = pcap_fopen_offline(fp, errbuf); 796146768Ssam if (p == NULL) { 797146768Ssam if (fp != stdin) 798146768Ssam fclose(fp); 799146768Ssam } 800146768Ssam return (p); 801146768Ssam} 802146768Ssam 803146768Ssampcap_t * 804146768Ssampcap_fopen_offline(FILE *fp, char *errbuf) 805146768Ssam{ 80617683Spst register pcap_t *p; 80717683Spst struct pcap_file_header hdr; 808146768Ssam size_t amt_read; 80975107Sfenner bpf_u_int32 magic; 81017683Spst int linklen; 81117683Spst 81217683Spst p = (pcap_t *)malloc(sizeof(*p)); 81317683Spst if (p == NULL) { 81475107Sfenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 81517683Spst return (NULL); 81617683Spst } 81717683Spst 81817683Spst memset((char *)p, 0, sizeof(*p)); 81917683Spst 820146768Ssam amt_read = fread((char *)&hdr, 1, sizeof(hdr), fp); 821146768Ssam if (amt_read != sizeof(hdr)) { 822146768Ssam if (ferror(fp)) { 823146768Ssam snprintf(errbuf, PCAP_ERRBUF_SIZE, 824146768Ssam "error reading dump file: %s", 82575107Sfenner pcap_strerror(errno)); 826146768Ssam } else { 827146768Ssam snprintf(errbuf, PCAP_ERRBUF_SIZE, 828146768Ssam "truncated dump file; tried to read %lu file header bytes, only got %lu", 829146768Ssam (unsigned long)sizeof(hdr), 830146768Ssam (unsigned long)amt_read); 83117683Spst } 83217683Spst goto bad; 83317683Spst } 83475107Sfenner magic = hdr.magic; 835146768Ssam if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) { 83675107Sfenner magic = SWAPLONG(magic); 837146768Ssam if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) { 83875107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, 83975107Sfenner "bad dump file format"); 84017683Spst goto bad; 84117683Spst } 84217683Spst p->sf.swapped = 1; 84317683Spst swap_hdr(&hdr); 84417683Spst } 845146768Ssam if (magic == KUZNETZOV_TCPDUMP_MAGIC) { 84675107Sfenner /* 84775107Sfenner * XXX - the patch that's in some versions of libpcap 848146768Ssam * changes the packet header but not the magic number, 849146768Ssam * and some other versions with this magic number have 850146768Ssam * some extra debugging information in the packet header; 85175107Sfenner * we'd have to use some hacks^H^H^H^H^Hheuristics to 852146768Ssam * detect those variants. 853146768Ssam * 854146768Ssam * Ethereal does that, but it does so by trying to read 855146768Ssam * the first two packets of the file with each of the 856146768Ssam * record header formats. That currently means it seeks 857146768Ssam * backwards and retries the reads, which doesn't work 858146768Ssam * on pipes. We want to be able to read from a pipe, so 859146768Ssam * that strategy won't work; we'd have to buffer some 860146768Ssam * data ourselves and read from that buffer in order to 861146768Ssam * make that work. 86275107Sfenner */ 86375107Sfenner p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 86475107Sfenner } else 86575107Sfenner p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); 86617683Spst if (hdr.version_major < PCAP_VERSION_MAJOR) { 86775107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); 86817683Spst goto bad; 86917683Spst } 87017683Spst p->tzoff = hdr.thiszone; 87117683Spst p->snapshot = hdr.snaplen; 87275107Sfenner p->linktype = linktype_to_dlt(hdr.linktype); 87317683Spst p->sf.rfile = fp; 874127664Sbms#ifndef WIN32 87517683Spst p->bufsize = hdr.snaplen; 876127664Sbms#else 877127664Sbms /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ 878127664Sbms p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); 879127664Sbms#endif 88017683Spst 88117683Spst /* Align link header as required for proper data alignment */ 88217683Spst /* XXX should handle all types */ 88317683Spst switch (p->linktype) { 88417683Spst 88517683Spst case DLT_EN10MB: 88617683Spst linklen = 14; 88717683Spst break; 88817683Spst 88917683Spst case DLT_FDDI: 89017683Spst linklen = 13 + 8; /* fddi_header + llc */ 89117683Spst break; 89217683Spst 89317683Spst case DLT_NULL: 89417683Spst default: 89517683Spst linklen = 0; 89617683Spst break; 89717683Spst } 89817683Spst 89975107Sfenner if (p->bufsize < 0) 90075107Sfenner p->bufsize = BPF_MAXBUFSIZE; 90117683Spst p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); 90275107Sfenner if (p->sf.base == NULL) { 90375107Sfenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 90475107Sfenner goto bad; 90575107Sfenner } 90617683Spst p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); 90717683Spst p->sf.version_major = hdr.version_major; 90817683Spst p->sf.version_minor = hdr.version_minor; 90917683Spst#ifdef PCAP_FDDIPAD 910146768Ssam /* Padding only needed for live capture fcode */ 911146768Ssam p->fddipad = 0; 91217683Spst#endif 91317683Spst 914127664Sbms /* 915127664Sbms * We interchanged the caplen and len fields at version 2.3, 916127664Sbms * in order to match the bpf header layout. But unfortunately 917127664Sbms * some files were written with version 2.3 in their headers 918127664Sbms * but without the interchanged fields. 919127664Sbms * 920127664Sbms * In addition, DG/UX tcpdump writes out files with a version 921127664Sbms * number of 543.0, and with the caplen and len fields in the 922127664Sbms * pre-2.3 order. 923127664Sbms */ 924127664Sbms switch (hdr.version_major) { 925127664Sbms 926127664Sbms case 2: 927127664Sbms if (hdr.version_minor < 3) 928127664Sbms p->sf.lengths_swapped = SWAPPED; 929127664Sbms else if (hdr.version_minor == 3) 930127664Sbms p->sf.lengths_swapped = MAYBE_SWAPPED; 931127664Sbms else 932127664Sbms p->sf.lengths_swapped = NOT_SWAPPED; 933127664Sbms break; 934127664Sbms 935127664Sbms case 543: 936127664Sbms p->sf.lengths_swapped = SWAPPED; 937127664Sbms break; 938127664Sbms 939127664Sbms default: 940127664Sbms p->sf.lengths_swapped = NOT_SWAPPED; 941127664Sbms break; 942127664Sbms } 943127664Sbms 944146768Ssam#if !defined(WIN32) && !defined(MSDOS) 945127664Sbms /* 946127664Sbms * You can do "select()" and "poll()" on plain files on most 947127664Sbms * platforms, and should be able to do so on pipes. 948127664Sbms * 949127664Sbms * You can't do "select()" on anything other than sockets in 950127664Sbms * Windows, so, on Win32 systems, we don't have "selectable_fd". 951127664Sbms */ 952127664Sbms p->selectable_fd = fileno(fp); 953127664Sbms#endif 954127664Sbms 955127664Sbms p->read_op = pcap_offline_read; 956146768Ssam p->inject_op = sf_inject; 957127664Sbms p->setfilter_op = install_bpf_program; 958147894Ssam p->setdirection_op = sf_setdirection; 959127664Sbms p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ 960127664Sbms p->getnonblock_op = sf_getnonblock; 961127664Sbms p->setnonblock_op = sf_setnonblock; 962127664Sbms p->stats_op = sf_stats; 963127664Sbms p->close_op = sf_close; 964127664Sbms 96517683Spst return (p); 96617683Spst bad: 96717683Spst free(p); 96817683Spst return (NULL); 96917683Spst} 97017683Spst 97117683Spst/* 97217683Spst * Read sf_readfile and return the next packet. Return the header in hdr 97317683Spst * and the contents in buf. Return 0 on success, SFERR_EOF if there were 97417683Spst * no more packets, and SFERR_TRUNC if a partial packet was encountered. 97517683Spst */ 97617683Spststatic int 977127664Sbmssf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) 97817683Spst{ 97975107Sfenner struct pcap_sf_patched_pkthdr sf_hdr; 98017683Spst FILE *fp = p->sf.rfile; 981127664Sbms size_t amt_read; 982127664Sbms bpf_u_int32 t; 98317683Spst 98475107Sfenner /* 98575107Sfenner * Read the packet header; the structure we use as a buffer 98675107Sfenner * is the longer structure for files generated by the patched 98775107Sfenner * libpcap, but if the file has the magic number for an 98875107Sfenner * unpatched libpcap we only read as many bytes as the regular 98975107Sfenner * header has. 99075107Sfenner */ 991127664Sbms amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp); 992127664Sbms if (amt_read != p->sf.hdrsize) { 993127664Sbms if (ferror(fp)) { 994127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 995127664Sbms "error reading dump file: %s", 996127664Sbms pcap_strerror(errno)); 997127664Sbms return (-1); 998127664Sbms } else { 999127664Sbms if (amt_read != 0) { 1000127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1001127664Sbms "truncated dump file; tried to read %d header bytes, only got %lu", 1002127664Sbms p->sf.hdrsize, (unsigned long)amt_read); 1003127664Sbms return (-1); 1004127664Sbms } 1005127664Sbms /* EOF */ 1006127664Sbms return (1); 1007127664Sbms } 100817683Spst } 100917683Spst 101017683Spst if (p->sf.swapped) { 101117683Spst /* these were written in opposite byte order */ 101256889Sfenner hdr->caplen = SWAPLONG(sf_hdr.caplen); 101356889Sfenner hdr->len = SWAPLONG(sf_hdr.len); 101456889Sfenner hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 101556889Sfenner hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 101656889Sfenner } else { 101756889Sfenner hdr->caplen = sf_hdr.caplen; 101856889Sfenner hdr->len = sf_hdr.len; 101956889Sfenner hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 102056889Sfenner hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 102117683Spst } 1022127664Sbms /* Swap the caplen and len fields, if necessary. */ 1023127664Sbms switch (p->sf.lengths_swapped) { 1024127664Sbms 1025127664Sbms case NOT_SWAPPED: 1026127664Sbms break; 1027127664Sbms 1028127664Sbms case MAYBE_SWAPPED: 1029127664Sbms if (hdr->caplen <= hdr->len) { 1030127664Sbms /* 1031127664Sbms * The captured length is <= the actual length, 1032127664Sbms * so presumably they weren't swapped. 1033127664Sbms */ 1034127664Sbms break; 1035127664Sbms } 1036127664Sbms /* FALLTHROUGH */ 1037127664Sbms 1038127664Sbms case SWAPPED: 1039127664Sbms t = hdr->caplen; 104017683Spst hdr->caplen = hdr->len; 104117683Spst hdr->len = t; 1042127664Sbms break; 104317683Spst } 104417683Spst 104517683Spst if (hdr->caplen > buflen) { 104617683Spst /* 104717683Spst * This can happen due to Solaris 2.3 systems tripping 104817683Spst * over the BUFMOD problem and not setting the snapshot 104917683Spst * correctly in the savefile header. If the caplen isn't 105017683Spst * grossly wrong, try to salvage. 105117683Spst */ 105217683Spst static u_char *tp = NULL; 1053127664Sbms static size_t tsize = 0; 105417683Spst 105526175Sfenner if (hdr->caplen > 65535) { 105675107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 105775107Sfenner "bogus savefile header"); 105826175Sfenner return (-1); 105926175Sfenner } 106075107Sfenner 106117683Spst if (tsize < hdr->caplen) { 106217683Spst tsize = ((hdr->caplen + 1023) / 1024) * 1024; 106317683Spst if (tp != NULL) 106417683Spst free((u_char *)tp); 106517683Spst tp = (u_char *)malloc(tsize); 106617683Spst if (tp == NULL) { 106726175Sfenner tsize = 0; 106875107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 106975107Sfenner "BUFMOD hack malloc"); 107017683Spst return (-1); 107117683Spst } 107217683Spst } 1073127664Sbms amt_read = fread((char *)tp, 1, hdr->caplen, fp); 1074127664Sbms if (amt_read != hdr->caplen) { 1075127664Sbms if (ferror(fp)) { 1076127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1077127664Sbms "error reading dump file: %s", 1078127664Sbms pcap_strerror(errno)); 1079127664Sbms } else { 1080127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1081127664Sbms "truncated dump file; tried to read %u captured bytes, only got %lu", 1082127664Sbms hdr->caplen, (unsigned long)amt_read); 1083127664Sbms } 108417683Spst return (-1); 108517683Spst } 108626175Sfenner /* 108726175Sfenner * We can only keep up to buflen bytes. Since caplen > buflen 108826175Sfenner * is exactly how we got here, we know we can only keep the 108926175Sfenner * first buflen bytes and must drop the remainder. Adjust 109026175Sfenner * caplen accordingly, so we don't get confused later as 109126175Sfenner * to how many bytes we have to play with. 109226175Sfenner */ 109326175Sfenner hdr->caplen = buflen; 109417683Spst memcpy((char *)buf, (char *)tp, buflen); 109517683Spst 109617683Spst } else { 109717683Spst /* read the packet itself */ 1098127664Sbms amt_read = fread((char *)buf, 1, hdr->caplen, fp); 1099127664Sbms if (amt_read != hdr->caplen) { 1100127664Sbms if (ferror(fp)) { 1101127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1102127664Sbms "error reading dump file: %s", 1103127664Sbms pcap_strerror(errno)); 1104127664Sbms } else { 1105127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1106127664Sbms "truncated dump file; tried to read %u captured bytes, only got %lu", 1107127664Sbms hdr->caplen, (unsigned long)amt_read); 1108127664Sbms } 110917683Spst return (-1); 111017683Spst } 111117683Spst } 111217683Spst return (0); 111317683Spst} 111417683Spst 111517683Spst/* 111617683Spst * Print out packets stored in the file initialized by sf_read_init(). 111717683Spst * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 111817683Spst */ 111917683Spstint 112017683Spstpcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 112117683Spst{ 1122146768Ssam struct bpf_insn *fcode; 112317683Spst int status = 0; 112417683Spst int n = 0; 112517683Spst 112617683Spst while (status == 0) { 112717683Spst struct pcap_pkthdr h; 112817683Spst 1129127664Sbms /* 1130127664Sbms * Has "pcap_breakloop()" been called? 1131127664Sbms * If so, return immediately - if we haven't read any 1132127664Sbms * packets, clear the flag and return -2 to indicate 1133127664Sbms * that we were told to break out of the loop, otherwise 1134127664Sbms * leave the flag set, so that the *next* call will break 1135127664Sbms * out of the loop without having read any packets, and 1136127664Sbms * return the number of packets we've processed so far. 1137127664Sbms */ 1138127664Sbms if (p->break_loop) { 1139127664Sbms if (n == 0) { 1140127664Sbms p->break_loop = 0; 1141127664Sbms return (-2); 1142127664Sbms } else 1143127664Sbms return (n); 1144127664Sbms } 1145127664Sbms 114617683Spst status = sf_next_packet(p, &h, p->buffer, p->bufsize); 114717683Spst if (status) { 114817683Spst if (status == 1) 114917683Spst return (0); 115017683Spst return (status); 115117683Spst } 115217683Spst 1153146768Ssam if ((fcode = p->fcode.bf_insns) == NULL || 115417683Spst bpf_filter(fcode, p->buffer, h.len, h.caplen)) { 115517683Spst (*callback)(user, &h, p->buffer); 115617683Spst if (++n >= cnt && cnt > 0) 115717683Spst break; 115817683Spst } 115917683Spst } 116017683Spst /*XXX this breaks semantics tcpslice expects */ 116117683Spst return (n); 116217683Spst} 116317683Spst 116417683Spst/* 116517683Spst * Output a packet to the initialized dump file. 116617683Spst */ 116717683Spstvoid 116817683Spstpcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 116917683Spst{ 117017683Spst register FILE *f; 117156889Sfenner struct pcap_sf_pkthdr sf_hdr; 117217683Spst 117317683Spst f = (FILE *)user; 117456889Sfenner sf_hdr.ts.tv_sec = h->ts.tv_sec; 117556889Sfenner sf_hdr.ts.tv_usec = h->ts.tv_usec; 117656889Sfenner sf_hdr.caplen = h->caplen; 117756889Sfenner sf_hdr.len = h->len; 117817683Spst /* XXX we should check the return status */ 117956889Sfenner (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 118017683Spst (void)fwrite((char *)sp, h->caplen, 1, f); 118117683Spst} 118217683Spst 1183146768Ssamstatic pcap_dumper_t * 1184146768Ssampcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) 1185146768Ssam{ 1186146768Ssam 1187146768Ssam#if defined(WIN32) || defined(MSDOS) 1188146768Ssam /* 1189146768Ssam * If we're writing to the standard output, put it in binary 1190146768Ssam * mode, as savefiles are binary files. 1191146768Ssam * 1192146768Ssam * Otherwise, we turn off buffering. 1193146768Ssam * XXX - why? And why not on the standard output? 1194146768Ssam */ 1195146768Ssam if (f == stdout) 1196146768Ssam SET_BINMODE(f); 1197146768Ssam else 1198146768Ssam setbuf(f, NULL); 1199146768Ssam#endif 1200146768Ssam if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) { 1201146768Ssam snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", 1202146768Ssam fname, pcap_strerror(errno)); 1203146768Ssam if (f != stdout) 1204146768Ssam (void)fclose(f); 1205146768Ssam return (NULL); 1206146768Ssam } 1207146768Ssam return ((pcap_dumper_t *)f); 1208146768Ssam} 1209146768Ssam 121017683Spst/* 121117683Spst * Initialize so that sf_write() will output to the file named 'fname'. 121217683Spst */ 121317683Spstpcap_dumper_t * 121439291Sfennerpcap_dump_open(pcap_t *p, const char *fname) 121517683Spst{ 121617683Spst FILE *f; 121775107Sfenner int linktype; 121875107Sfenner 121975107Sfenner linktype = dlt_to_linktype(p->linktype); 122075107Sfenner if (linktype == -1) { 122175107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 122275107Sfenner "%s: link-layer type %d isn't supported in savefiles", 122375107Sfenner fname, linktype); 122475107Sfenner return (NULL); 122575107Sfenner } 122675107Sfenner 1227127664Sbms if (fname[0] == '-' && fname[1] == '\0') { 122817683Spst f = stdout; 1229146768Ssam fname = "standard output"; 1230127664Sbms } else { 1231146768Ssam#if !defined(WIN32) && !defined(MSDOS) 123217683Spst f = fopen(fname, "w"); 1233127664Sbms#else 1234127664Sbms f = fopen(fname, "wb"); 1235127664Sbms#endif 123617683Spst if (f == NULL) { 123775107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 123817683Spst fname, pcap_strerror(errno)); 123917683Spst return (NULL); 124017683Spst } 124117683Spst } 1242146768Ssam return (pcap_setup_dump(p, linktype, f, fname)); 124317683Spst} 124417683Spst 1245146768Ssam/* 1246146768Ssam * Initialize so that sf_write() will output to the given stream. 1247146768Ssam */ 1248146768Ssampcap_dumper_t * 1249146768Ssampcap_dump_fopen(pcap_t *p, FILE *f) 1250146768Ssam{ 1251146768Ssam int linktype; 1252146768Ssam 1253146768Ssam linktype = dlt_to_linktype(p->linktype); 1254146768Ssam if (linktype == -1) { 1255146768Ssam snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1256146768Ssam "stream: link-layer type %d isn't supported in savefiles", 1257146768Ssam linktype); 1258146768Ssam return (NULL); 1259146768Ssam } 1260146768Ssam 1261146768Ssam return (pcap_setup_dump(p, linktype, f, "stream")); 1262146768Ssam} 1263146768Ssam 1264127664SbmsFILE * 1265127664Sbmspcap_dump_file(pcap_dumper_t *p) 1266127664Sbms{ 1267127664Sbms return ((FILE *)p); 1268127664Sbms} 1269127664Sbms 1270147894Ssamlong 1271147894Ssampcap_dump_ftell(pcap_dumper_t *p) 1272147894Ssam{ 1273147894Ssam return (ftell((FILE *)p)); 1274147894Ssam} 1275147894Ssam 1276127664Sbmsint 1277127664Sbmspcap_dump_flush(pcap_dumper_t *p) 1278127664Sbms{ 1279127664Sbms 1280127664Sbms if (fflush((FILE *)p) == EOF) 1281127664Sbms return (-1); 1282127664Sbms else 1283127664Sbms return (0); 1284127664Sbms} 1285127664Sbms 128617683Spstvoid 128717683Spstpcap_dump_close(pcap_dumper_t *p) 128817683Spst{ 128917683Spst 129017683Spst#ifdef notyet 129117683Spst if (ferror((FILE *)p)) 129217683Spst return-an-error; 129317683Spst /* XXX should check return from fclose() too */ 129417683Spst#endif 129517683Spst (void)fclose((FILE *)p); 129617683Spst} 1297