savefile.c revision 127664
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_ = 33127664Sbms "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 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 5217683Spst#define TCPDUMP_MAGIC 0xa1b2c3d4 5375107Sfenner#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 5417683Spst 5517683Spst/* 5617683Spst * We use the "receiver-makes-right" approach to byte order, 5717683Spst * because time is at a premium when we are writing the file. 5817683Spst * In other words, the pcap_file_header and pcap_pkthdr, 5917683Spst * records are written in host byte order. 60127664Sbms * Note that the bytes of packet data are written out in the order in 61127664Sbms * which they were received, so multi-byte fields in packets are not 62127664Sbms * written in host byte order, they're written in whatever order the 63127664Sbms * sending machine put them in. 6417683Spst * 6517683Spst * ntoh[ls] aren't sufficient because we might need to swap on a big-endian 6617683Spst * machine (if the file was written in little-end order). 6717683Spst */ 6817683Spst#define SWAPLONG(y) \ 6917683Spst((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 7017683Spst#define SWAPSHORT(y) \ 7126175Sfenner ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) 7217683Spst 7317683Spst#define SFERR_TRUNC 1 7417683Spst#define SFERR_BADVERSION 2 7517683Spst#define SFERR_BADF 3 7617683Spst#define SFERR_EOF 4 /* not really an error, just a status */ 7717683Spst 7875107Sfenner/* 7975107Sfenner * We don't write DLT_* values to the capture file header, because 8075107Sfenner * they're not the same on all platforms. 8175107Sfenner * 8275107Sfenner * Unfortunately, the various flavors of BSD have not always used the same 8375107Sfenner * numerical values for the same data types, and various patches to 8475107Sfenner * libpcap for non-BSD OSes have added their own DLT_* codes for link 8575107Sfenner * layer encapsulation types seen on those OSes, and those codes have had, 8675107Sfenner * in some cases, values that were also used, on other platforms, for other 8775107Sfenner * link layer encapsulation types. 8875107Sfenner * 8975107Sfenner * This means that capture files of a type whose numerical DLT_* code 9075107Sfenner * means different things on different BSDs, or with different versions 9175107Sfenner * of libpcap, can't always be read on systems other than those like 9275107Sfenner * the one running on the machine on which the capture was made. 9375107Sfenner * 9475107Sfenner * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes 9575107Sfenner * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* 9675107Sfenner * codes to DLT_* codes when reading a savefile header. 9775107Sfenner * 9875107Sfenner * For those DLT_* codes that have, as far as we know, the same values on 9975107Sfenner * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as 10075107Sfenner * DLT_xxx; that way, captures of those types can still be read by 10175107Sfenner * versions of libpcap that map LINKTYPE_* values to DLT_* values, and 10275107Sfenner * captures of those types written by versions of libpcap that map DLT_ 10375107Sfenner * values to LINKTYPE_ values can still be read by older versions 10475107Sfenner * of libpcap. 10575107Sfenner * 10675107Sfenner * The other LINKTYPE_* codes are given values starting at 100, in the 10775107Sfenner * hopes that no DLT_* code will be given one of those values. 10875107Sfenner * 10975107Sfenner * In order to ensure that a given LINKTYPE_* code's value will refer to 11075107Sfenner * the same encapsulation type on all platforms, you should not allocate 11175107Sfenner * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". 11275107Sfenner * The tcpdump developers will allocate a value for you, and will not 11375107Sfenner * subsequently allocate it to anybody else; that value will be added to 11475107Sfenner * the "pcap.h" in the tcpdump.org CVS repository, so that a future 11575107Sfenner * libpcap release will include it. 11675107Sfenner * 11775107Sfenner * You should, if possible, also contribute patches to libpcap and tcpdump 11875107Sfenner * to handle the new encapsulation type, so that they can also be checked 11975107Sfenner * into the tcpdump.org CVS repository and so that they will appear in 12075107Sfenner * future libpcap and tcpdump releases. 121127664Sbms * 122127664Sbms * Do *NOT* assume that any values after the largest value in this file 123127664Sbms * are available; you might not have the most up-to-date version of this 124127664Sbms * file, and new values after that one might have been assigned. Also, 125127664Sbms * do *NOT* use any values below 100 - those might already have been 126127664Sbms * taken by one (or more!) organizations. 12775107Sfenner */ 12875107Sfenner#define LINKTYPE_NULL DLT_NULL 12975107Sfenner#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ 13075107Sfenner#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ 13175107Sfenner#define LINKTYPE_AX25 DLT_AX25 13275107Sfenner#define LINKTYPE_PRONET DLT_PRONET 13375107Sfenner#define LINKTYPE_CHAOS DLT_CHAOS 13475107Sfenner#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ 135127664Sbms#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ 13675107Sfenner#define LINKTYPE_SLIP DLT_SLIP 13775107Sfenner#define LINKTYPE_PPP DLT_PPP 13875107Sfenner#define LINKTYPE_FDDI DLT_FDDI 13975107Sfenner 14075107Sfenner/* 14175107Sfenner * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 14275107Sfenner * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol 14375107Sfenner * field) at the beginning of the packet. 14475107Sfenner * 14575107Sfenner * This is for use when there is always such a header; the address field 14675107Sfenner * might be 0xff, for regular PPP, or it might be an address field for Cisco 14775107Sfenner * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco 14875107Sfenner * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. 14975107Sfenner * 15075107Sfenner * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that 15175107Sfenner * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL 15275107Sfenner * captures will be written out with a link type that NetBSD's tcpdump 15375107Sfenner * can read. 15475107Sfenner */ 15575107Sfenner#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ 15675107Sfenner 15798530Sfenner#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ 15898530Sfenner 159127664Sbms/* 160127664Sbms * This isn't supported in libpcap 0.8[.x], but is supported in the 161127664Sbms * current CVS version; we include it here to note that it's not available 162127664Sbms * for anybody else to use. 163127664Sbms */ 164127664Sbms#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */ 165127664Sbms 16675107Sfenner#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ 16775107Sfenner#define LINKTYPE_RAW 101 /* raw IP */ 16875107Sfenner#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ 16975107Sfenner#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ 17075107Sfenner#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ 17198530Sfenner#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ 17275107Sfenner#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ 173127664Sbms#define LINKTYPE_FRELAY 107 /* Frame Relay */ 17498530Sfenner#define LINKTYPE_LOOP 108 /* OpenBSD loopback */ 175127664Sbms#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ 17675107Sfenner 177127664Sbms/* 178127664Sbms * These three types are reserved for future use. 179127664Sbms */ 180127664Sbms#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ 181127664Sbms#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ 182127664Sbms#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ 183127664Sbms 18498530Sfenner#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ 18598530Sfenner#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ 18698530Sfenner#define LINKTYPE_ECONET 115 /* Acorn Econet */ 18798530Sfenner 188127664Sbms/* 189127664Sbms * Reserved for use with OpenBSD ipfilter. 190127664Sbms */ 191127664Sbms#define LINKTYPE_IPFILTER 116 192127664Sbms 193127664Sbms#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ 19498530Sfenner#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ 19598530Sfenner#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ 19698530Sfenner#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ 19798530Sfenner 19875107Sfenner/* 199127664Sbms * Reserved for Siemens HiPath HDLC. 20075107Sfenner */ 201127664Sbms#define LINKTYPE_HHDLC 121 20275107Sfenner 203127664Sbms#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ 204127664Sbms#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ 205127664Sbms 206127664Sbms/* 207127664Sbms * Reserved as per request from Kent Dahlgren <kent@praesum.com> 208127664Sbms * for private use. 209127664Sbms */ 210127664Sbms#define LINKTYPE_RIO 124 /* RapidIO */ 211127664Sbms#define LINKTYPE_PCI_EXP 125 /* PCI Express */ 212127664Sbms#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ 213127664Sbms 214127664Sbms#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ 215127664Sbms 216127664Sbms/* 217127664Sbms * Reserved for the TZSP encapsulation, as per request from 218127664Sbms * Chris Waters <chris.waters@networkchemistry.com> 219127664Sbms * TZSP is a generic encapsulation for any other link type, 220127664Sbms * which includes a means to include meta-information 221127664Sbms * with the packet, e.g. signal strength and channel 222127664Sbms * for 802.11 packets. 223127664Sbms */ 224127664Sbms#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ 225127664Sbms 226127664Sbms#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ 227127664Sbms 228127664Sbms/* 229127664Sbms * Juniper-private data link types, as per request from 230127664Sbms * Hannes Gredler <hannes@juniper.net>. The corresponding 231127664Sbms * DLT_s are used for passing on chassis-internal 232127664Sbms * metainformation such as QOS profiles, etc.. 233127664Sbms */ 234127664Sbms#define LINKTYPE_JUNIPER_MLPPP 130 235127664Sbms#define LINKTYPE_JUNIPER_MLFR 131 236127664Sbms#define LINKTYPE_JUNIPER_ES 132 237127664Sbms#define LINKTYPE_JUNIPER_GGSN 133 238127664Sbms#define LINKTYPE_JUNIPER_MFR 134 239127664Sbms#define LINKTYPE_JUNIPER_ATM2 135 240127664Sbms#define LINKTYPE_JUNIPER_SERVICES 136 241127664Sbms#define LINKTYPE_JUNIPER_ATM1 137 242127664Sbms 243127664Sbms#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */ 244127664Sbms 245127664Sbms#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */ 246127664Sbms#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */ 247127664Sbms#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */ 248127664Sbms#define LINKTYPE_RAWSS7_SCCP 142 249127664Sbms 250127664Sbms/* 251127664Sbms * This isn't supported in libpcap 0.8[.x], but is supported in the 252127664Sbms * current CVS version; we include it here to note that it's not available 253127664Sbms * for anybody else to use. 254127664Sbms */ 255127664Sbms#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */ 256127664Sbms 257127664Sbms#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */ 258127664Sbms 259127664Sbms/* 260127664Sbms * Reserved for IBM SP switch and IBM Next Federation switch. 261127664Sbms */ 262127664Sbms#define LINKTYPE_IBM_SP 145 263127664Sbms#define LINKTYPE_IBM_SN 146 264127664Sbms 265127664Sbms/* 266127664Sbms * Reserved for private use. If you have some link-layer header type 267127664Sbms * that you want to use within your organization, with the capture files 268127664Sbms * using that link-layer header type not ever be sent outside your 269127664Sbms * organization, you can use these values. 270127664Sbms * 271127664Sbms * No libpcap release will use these for any purpose, nor will any 272127664Sbms * tcpdump release use them, either. 273127664Sbms * 274127664Sbms * Do *NOT* use these in capture files that you expect anybody not using 275127664Sbms * your private versions of capture-file-reading tools to read; in 276127664Sbms * particular, do *NOT* use them in products, otherwise you may find that 277127664Sbms * people won't be able to use tcpdump, or snort, or Ethereal, or... to 278127664Sbms * read capture files from your firewall/intrusion detection/traffic 279127664Sbms * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value, 280127664Sbms * and you may also find that the developers of those applications will 281127664Sbms * not accept patches to let them read those files. 282127664Sbms * 283127664Sbms * Also, do not use them if somebody might send you a capture using them 284127664Sbms * for *their* private type and tools using them for *your* private type 285127664Sbms * would have to read them. 286127664Sbms * 287127664Sbms * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ 288127664Sbms * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type 289127664Sbms * you're given. 290127664Sbms */ 291127664Sbms#define LINKTYPE_USER0 147 292127664Sbms#define LINKTYPE_USER1 148 293127664Sbms#define LINKTYPE_USER2 149 294127664Sbms#define LINKTYPE_USER3 150 295127664Sbms#define LINKTYPE_USER4 151 296127664Sbms#define LINKTYPE_USER5 152 297127664Sbms#define LINKTYPE_USER6 153 298127664Sbms#define LINKTYPE_USER7 154 299127664Sbms#define LINKTYPE_USER8 155 300127664Sbms#define LINKTYPE_USER9 156 301127664Sbms#define LINKTYPE_USER10 157 302127664Sbms#define LINKTYPE_USER11 158 303127664Sbms#define LINKTYPE_USER12 159 304127664Sbms#define LINKTYPE_USER13 160 305127664Sbms#define LINKTYPE_USER14 161 306127664Sbms#define LINKTYPE_USER15 162 307127664Sbms 308127664Sbms/* 309127664Sbms * For future use with 802.11 captures - defined by AbsoluteValue 310127664Sbms * Systems to store a number of bits of link-layer information 311127664Sbms * including radio information: 312127664Sbms * 313127664Sbms * http://www.shaftnet.org/~pizza/software/capturefrm.txt 314127664Sbms * 315127664Sbms * but could and arguably should also be used by non-AVS Linux 316127664Sbms * 802.11 drivers; that may happen in the future. 317127664Sbms */ 318127664Sbms#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ 319127664Sbms 320127664Sbms/* 321127664Sbms * Juniper-private data link type, as per request from 322127664Sbms * Hannes Gredler <hannes@juniper.net>. The corresponding 323127664Sbms * DLT_s are used for passing on chassis-internal 324127664Sbms * metainformation such as QOS profiles, etc.. 325127664Sbms */ 326127664Sbms#define LINKTYPE_JUNIPER_MONITOR 164 327127664Sbms 32875107Sfennerstatic struct linktype_map { 32975107Sfenner int dlt; 33075107Sfenner int linktype; 33175107Sfenner} map[] = { 33275107Sfenner /* 33375107Sfenner * These DLT_* codes have LINKTYPE_* codes with values identical 33475107Sfenner * to the values of the corresponding DLT_* code. 33575107Sfenner */ 33675107Sfenner { DLT_NULL, LINKTYPE_NULL }, 33775107Sfenner { DLT_EN10MB, LINKTYPE_ETHERNET }, 33875107Sfenner { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, 33975107Sfenner { DLT_AX25, LINKTYPE_AX25 }, 34075107Sfenner { DLT_PRONET, LINKTYPE_PRONET }, 34175107Sfenner { DLT_CHAOS, LINKTYPE_CHAOS }, 34275107Sfenner { DLT_IEEE802, LINKTYPE_TOKEN_RING }, 34375107Sfenner { DLT_ARCNET, LINKTYPE_ARCNET }, 34475107Sfenner { DLT_SLIP, LINKTYPE_SLIP }, 34575107Sfenner { DLT_PPP, LINKTYPE_PPP }, 34675107Sfenner { DLT_FDDI, LINKTYPE_FDDI }, 34775107Sfenner 34875107Sfenner /* 34975107Sfenner * These DLT_* codes have different values on different 35075107Sfenner * platforms; we map them to LINKTYPE_* codes that 35175107Sfenner * have values that should never be equal to any DLT_* 35275107Sfenner * code. 35375107Sfenner */ 354127664Sbms#ifdef DLT_FR 355127664Sbms /* BSD/OS Frame Relay */ 356127664Sbms { DLT_FR, LINKTYPE_FRELAY }, 357127664Sbms#endif 358127664Sbms 359127664Sbms { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, 36075107Sfenner { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, 36175107Sfenner { DLT_RAW, LINKTYPE_RAW }, 36275107Sfenner { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, 36375107Sfenner { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, 36475107Sfenner 36575107Sfenner /* BSD/OS Cisco HDLC */ 36675107Sfenner { DLT_C_HDLC, LINKTYPE_C_HDLC }, 36775107Sfenner 36875107Sfenner /* 36975107Sfenner * These DLT_* codes are not on all platforms, but, so far, 37075107Sfenner * there don't appear to be any platforms that define 37175107Sfenner * other codes with those values; we map them to 37275107Sfenner * different LINKTYPE_* values anyway, just in case. 37375107Sfenner */ 37475107Sfenner 37575107Sfenner /* Linux ATM Classical IP */ 37675107Sfenner { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, 37775107Sfenner 37875107Sfenner /* NetBSD sync/async serial PPP (or Cisco HDLC) */ 37975107Sfenner { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, 38075107Sfenner 38198530Sfenner /* NetBSD PPP over Ethernet */ 38298530Sfenner { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, 38398530Sfenner 38475107Sfenner /* IEEE 802.11 wireless */ 38575107Sfenner { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, 38675107Sfenner 387127664Sbms /* Frame Relay */ 388127664Sbms { DLT_FRELAY, LINKTYPE_FRELAY }, 389127664Sbms 39075107Sfenner /* OpenBSD loopback */ 39175107Sfenner { DLT_LOOP, LINKTYPE_LOOP }, 39275107Sfenner 39375107Sfenner /* Linux cooked socket capture */ 39475107Sfenner { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, 39575107Sfenner 39698530Sfenner /* Apple LocalTalk hardware */ 39798530Sfenner { DLT_LTALK, LINKTYPE_LTALK }, 39898530Sfenner 39998530Sfenner /* Acorn Econet */ 40098530Sfenner { DLT_ECONET, LINKTYPE_ECONET }, 40198530Sfenner 402127664Sbms /* OpenBSD DLT_PFLOG */ 403127664Sbms { DLT_PFLOG, LINKTYPE_PFLOG }, 404127664Sbms 40598530Sfenner /* For Cisco-internal use */ 40698530Sfenner { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, 40798530Sfenner 40898530Sfenner /* Prism II monitor-mode header plus 802.11 header */ 40998530Sfenner { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, 41098530Sfenner 41198530Sfenner /* FreeBSD Aironet driver stuff */ 41298530Sfenner { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, 41398530Sfenner 414127664Sbms /* Siemens HiPath HDLC */ 415127664Sbms { DLT_HHDLC, LINKTYPE_HHDLC }, 416127664Sbms 417127664Sbms /* RFC 2625 IP-over-Fibre Channel */ 418127664Sbms { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, 419127664Sbms 420127664Sbms /* Solaris+SunATM */ 421127664Sbms { DLT_SUNATM, LINKTYPE_SUNATM }, 422127664Sbms 423127664Sbms /* RapidIO */ 424127664Sbms { DLT_RIO, LINKTYPE_RIO }, 425127664Sbms 426127664Sbms /* PCI Express */ 427127664Sbms { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, 428127664Sbms 429127664Sbms /* Xilinx Aurora link layer */ 430127664Sbms { DLT_AURORA, LINKTYPE_AURORA }, 431127664Sbms 432127664Sbms /* 802.11 plus BSD radio header */ 433127664Sbms { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, 434127664Sbms 435127664Sbms /* Tazmen Sniffer Protocol */ 436127664Sbms { DLT_TZSP, LINKTYPE_TZSP }, 437127664Sbms 438127664Sbms /* Arcnet with Linux-style link-layer headers */ 439127664Sbms { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, 440127664Sbms 441127664Sbms /* Juniper-internal chassis encapsulation */ 442127664Sbms { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP }, 443127664Sbms { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR }, 444127664Sbms { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES }, 445127664Sbms { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN }, 446127664Sbms { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR }, 447127664Sbms { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 }, 448127664Sbms { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES }, 449127664Sbms { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 }, 450127664Sbms 451127664Sbms /* Apple IP-over-IEEE 1394 cooked header */ 452127664Sbms { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 }, 453127664Sbms 454127664Sbms /* DOCSIS MAC frames */ 455127664Sbms { DLT_DOCSIS, LINKTYPE_DOCSIS }, 456127664Sbms 457127664Sbms /* IrDA IrLAP packets + Linux-cooked header */ 458127664Sbms { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA }, 459127664Sbms 460127664Sbms /* IBM SP and Next Federation switches */ 461127664Sbms { DLT_IBM_SP, LINKTYPE_IBM_SP }, 462127664Sbms { DLT_IBM_SN, LINKTYPE_IBM_SN }, 463127664Sbms 464127664Sbms /* 802.11 plus AVS radio header */ 465127664Sbms { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS }, 466127664Sbms 46775107Sfenner /* 46875107Sfenner * Any platform that defines additional DLT_* codes should: 46975107Sfenner * 47075107Sfenner * request a LINKTYPE_* code and value from tcpdump.org, 47175107Sfenner * as per the above; 47275107Sfenner * 47375107Sfenner * add, in their version of libpcap, an entry to map 47475107Sfenner * those DLT_* codes to the corresponding LINKTYPE_* 47575107Sfenner * code; 47675107Sfenner * 47775107Sfenner * redefine, in their "net/bpf.h", any DLT_* values 47875107Sfenner * that collide with the values used by their additional 47975107Sfenner * DLT_* codes, to remove those collisions (but without 48075107Sfenner * making them collide with any of the LINKTYPE_* 48175107Sfenner * values equal to 50 or above; they should also avoid 48275107Sfenner * defining DLT_* values that collide with those 48375107Sfenner * LINKTYPE_* values, either). 48475107Sfenner */ 485127664Sbms 486127664Sbms /* Juniper-internal chassis encapsulation */ 487127664Sbms { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR }, 488127664Sbms 48975107Sfenner { -1, -1 } 49075107Sfenner}; 49175107Sfenner 49217683Spststatic int 49375107Sfennerdlt_to_linktype(int dlt) 49475107Sfenner{ 49575107Sfenner int i; 49675107Sfenner 49775107Sfenner for (i = 0; map[i].dlt != -1; i++) { 49875107Sfenner if (map[i].dlt == dlt) 49975107Sfenner return (map[i].linktype); 50075107Sfenner } 50175107Sfenner 50275107Sfenner /* 50375107Sfenner * If we don't have a mapping for this DLT_ code, return an 50475107Sfenner * error; that means that the table above needs to have an 50575107Sfenner * entry added. 50675107Sfenner */ 50775107Sfenner return (-1); 50875107Sfenner} 50975107Sfenner 51075107Sfennerstatic int 51175107Sfennerlinktype_to_dlt(int linktype) 51275107Sfenner{ 51375107Sfenner int i; 51475107Sfenner 51575107Sfenner for (i = 0; map[i].linktype != -1; i++) { 51675107Sfenner if (map[i].linktype == linktype) 51775107Sfenner return (map[i].dlt); 51875107Sfenner } 51975107Sfenner 52075107Sfenner /* 52175107Sfenner * If we don't have an entry for this link type, return 52275107Sfenner * the link type value; it may be a DLT_ value from an 52375107Sfenner * older version of libpcap. 52475107Sfenner */ 52575107Sfenner return linktype; 52675107Sfenner} 52775107Sfenner 52875107Sfennerstatic int 52917683Spstsf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) 53017683Spst{ 53117683Spst struct pcap_file_header hdr; 53217683Spst 53317683Spst hdr.magic = TCPDUMP_MAGIC; 53417683Spst hdr.version_major = PCAP_VERSION_MAJOR; 53517683Spst hdr.version_minor = PCAP_VERSION_MINOR; 53617683Spst 53717683Spst hdr.thiszone = thiszone; 53817683Spst hdr.snaplen = snaplen; 53917683Spst hdr.sigfigs = 0; 54017683Spst hdr.linktype = linktype; 54117683Spst 54217683Spst if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 54317683Spst return (-1); 54417683Spst 54517683Spst return (0); 54617683Spst} 54717683Spst 54817683Spststatic void 54917683Spstswap_hdr(struct pcap_file_header *hp) 55017683Spst{ 55117683Spst hp->version_major = SWAPSHORT(hp->version_major); 55217683Spst hp->version_minor = SWAPSHORT(hp->version_minor); 55317683Spst hp->thiszone = SWAPLONG(hp->thiszone); 55417683Spst hp->sigfigs = SWAPLONG(hp->sigfigs); 55517683Spst hp->snaplen = SWAPLONG(hp->snaplen); 55617683Spst hp->linktype = SWAPLONG(hp->linktype); 55717683Spst} 55817683Spst 559127664Sbmsstatic int 560127664Sbmssf_getnonblock(pcap_t *p, char *errbuf) 561127664Sbms{ 562127664Sbms /* 563127664Sbms * This is a savefile, not a live capture file, so never say 564127664Sbms * it's in non-blocking mode. 565127664Sbms */ 566127664Sbms return (0); 567127664Sbms} 568127664Sbms 569127664Sbmsstatic int 570127664Sbmssf_setnonblock(pcap_t *p, int nonblock, char *errbuf) 571127664Sbms{ 572127664Sbms /* 573127664Sbms * This is a savefile, not a live capture file, so ignore 574127664Sbms * requests to put it in non-blocking mode. 575127664Sbms */ 576127664Sbms return (0); 577127664Sbms} 578127664Sbms 579127664Sbmsstatic int 580127664Sbmssf_stats(pcap_t *p, struct pcap_stat *ps) 581127664Sbms{ 582127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 583127664Sbms "Statistics aren't available from savefiles"); 584127664Sbms return (-1); 585127664Sbms} 586127664Sbms 587127664Sbmsstatic void 588127664Sbmssf_close(pcap_t *p) 589127664Sbms{ 590127664Sbms if (p->sf.rfile != stdin) 591127664Sbms (void)fclose(p->sf.rfile); 592127664Sbms if (p->sf.base != NULL) 593127664Sbms free(p->sf.base); 594127664Sbms} 595127664Sbms 59617683Spstpcap_t * 59739291Sfennerpcap_open_offline(const char *fname, char *errbuf) 59817683Spst{ 59917683Spst register pcap_t *p; 60017683Spst register FILE *fp; 60117683Spst struct pcap_file_header hdr; 60275107Sfenner bpf_u_int32 magic; 60317683Spst int linklen; 60417683Spst 60517683Spst p = (pcap_t *)malloc(sizeof(*p)); 60617683Spst if (p == NULL) { 60775107Sfenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 60817683Spst return (NULL); 60917683Spst } 61017683Spst 61117683Spst memset((char *)p, 0, sizeof(*p)); 61217683Spst 61317683Spst if (fname[0] == '-' && fname[1] == '\0') 61417683Spst fp = stdin; 61517683Spst else { 616127664Sbms#ifndef WIN32 61717683Spst fp = fopen(fname, "r"); 618127664Sbms#else 619127664Sbms fp = fopen(fname, "rb"); 620127664Sbms#endif 62117683Spst if (fp == NULL) { 62275107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, 62375107Sfenner pcap_strerror(errno)); 62417683Spst goto bad; 62517683Spst } 62617683Spst } 62717683Spst if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { 62875107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", 62975107Sfenner pcap_strerror(errno)); 63017683Spst goto bad; 63117683Spst } 63275107Sfenner magic = hdr.magic; 63375107Sfenner if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 63475107Sfenner magic = SWAPLONG(magic); 63575107Sfenner if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 63675107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, 63775107Sfenner "bad dump file format"); 63817683Spst goto bad; 63917683Spst } 64017683Spst p->sf.swapped = 1; 64117683Spst swap_hdr(&hdr); 64217683Spst } 64375107Sfenner if (magic == PATCHED_TCPDUMP_MAGIC) { 64475107Sfenner /* 64575107Sfenner * XXX - the patch that's in some versions of libpcap 64675107Sfenner * changes the packet header but not the magic number; 64775107Sfenner * we'd have to use some hacks^H^H^H^H^Hheuristics to 64875107Sfenner * detect that. 64975107Sfenner */ 65075107Sfenner p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 65175107Sfenner } else 65275107Sfenner p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); 65317683Spst if (hdr.version_major < PCAP_VERSION_MAJOR) { 65475107Sfenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); 65517683Spst goto bad; 65617683Spst } 65717683Spst p->tzoff = hdr.thiszone; 65817683Spst p->snapshot = hdr.snaplen; 65975107Sfenner p->linktype = linktype_to_dlt(hdr.linktype); 66017683Spst p->sf.rfile = fp; 661127664Sbms#ifndef WIN32 66217683Spst p->bufsize = hdr.snaplen; 663127664Sbms#else 664127664Sbms /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ 665127664Sbms p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); 666127664Sbms#endif 66717683Spst 66817683Spst /* Align link header as required for proper data alignment */ 66917683Spst /* XXX should handle all types */ 67017683Spst switch (p->linktype) { 67117683Spst 67217683Spst case DLT_EN10MB: 67317683Spst linklen = 14; 67417683Spst break; 67517683Spst 67617683Spst case DLT_FDDI: 67717683Spst linklen = 13 + 8; /* fddi_header + llc */ 67817683Spst break; 67917683Spst 68017683Spst case DLT_NULL: 68117683Spst default: 68217683Spst linklen = 0; 68317683Spst break; 68417683Spst } 68517683Spst 68675107Sfenner if (p->bufsize < 0) 68775107Sfenner p->bufsize = BPF_MAXBUFSIZE; 68817683Spst p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); 68975107Sfenner if (p->sf.base == NULL) { 69075107Sfenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 69175107Sfenner goto bad; 69275107Sfenner } 69317683Spst p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); 69417683Spst p->sf.version_major = hdr.version_major; 69517683Spst p->sf.version_minor = hdr.version_minor; 69617683Spst#ifdef PCAP_FDDIPAD 69717683Spst /* XXX padding only needed for kernel fcode */ 69817683Spst pcap_fddipad = 0; 69917683Spst#endif 70017683Spst 701127664Sbms /* 702127664Sbms * We interchanged the caplen and len fields at version 2.3, 703127664Sbms * in order to match the bpf header layout. But unfortunately 704127664Sbms * some files were written with version 2.3 in their headers 705127664Sbms * but without the interchanged fields. 706127664Sbms * 707127664Sbms * In addition, DG/UX tcpdump writes out files with a version 708127664Sbms * number of 543.0, and with the caplen and len fields in the 709127664Sbms * pre-2.3 order. 710127664Sbms */ 711127664Sbms switch (hdr.version_major) { 712127664Sbms 713127664Sbms case 2: 714127664Sbms if (hdr.version_minor < 3) 715127664Sbms p->sf.lengths_swapped = SWAPPED; 716127664Sbms else if (hdr.version_minor == 3) 717127664Sbms p->sf.lengths_swapped = MAYBE_SWAPPED; 718127664Sbms else 719127664Sbms p->sf.lengths_swapped = NOT_SWAPPED; 720127664Sbms break; 721127664Sbms 722127664Sbms case 543: 723127664Sbms p->sf.lengths_swapped = SWAPPED; 724127664Sbms break; 725127664Sbms 726127664Sbms default: 727127664Sbms p->sf.lengths_swapped = NOT_SWAPPED; 728127664Sbms break; 729127664Sbms } 730127664Sbms 731127664Sbms#ifndef WIN32 732127664Sbms /* 733127664Sbms * You can do "select()" and "poll()" on plain files on most 734127664Sbms * platforms, and should be able to do so on pipes. 735127664Sbms * 736127664Sbms * You can't do "select()" on anything other than sockets in 737127664Sbms * Windows, so, on Win32 systems, we don't have "selectable_fd". 738127664Sbms */ 739127664Sbms p->selectable_fd = fileno(fp); 740127664Sbms#endif 741127664Sbms 742127664Sbms p->read_op = pcap_offline_read; 743127664Sbms p->setfilter_op = install_bpf_program; 744127664Sbms p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ 745127664Sbms p->getnonblock_op = sf_getnonblock; 746127664Sbms p->setnonblock_op = sf_setnonblock; 747127664Sbms p->stats_op = sf_stats; 748127664Sbms p->close_op = sf_close; 749127664Sbms 75017683Spst return (p); 75117683Spst bad: 752127664Sbms if(fp) 753127664Sbms fclose(fp); 75417683Spst free(p); 75517683Spst return (NULL); 75617683Spst} 75717683Spst 75817683Spst/* 75917683Spst * Read sf_readfile and return the next packet. Return the header in hdr 76017683Spst * and the contents in buf. Return 0 on success, SFERR_EOF if there were 76117683Spst * no more packets, and SFERR_TRUNC if a partial packet was encountered. 76217683Spst */ 76317683Spststatic int 764127664Sbmssf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) 76517683Spst{ 76675107Sfenner struct pcap_sf_patched_pkthdr sf_hdr; 76717683Spst FILE *fp = p->sf.rfile; 768127664Sbms size_t amt_read; 769127664Sbms bpf_u_int32 t; 77017683Spst 77175107Sfenner /* 77275107Sfenner * Read the packet header; the structure we use as a buffer 77375107Sfenner * is the longer structure for files generated by the patched 77475107Sfenner * libpcap, but if the file has the magic number for an 77575107Sfenner * unpatched libpcap we only read as many bytes as the regular 77675107Sfenner * header has. 77775107Sfenner */ 778127664Sbms amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp); 779127664Sbms if (amt_read != p->sf.hdrsize) { 780127664Sbms if (ferror(fp)) { 781127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 782127664Sbms "error reading dump file: %s", 783127664Sbms pcap_strerror(errno)); 784127664Sbms return (-1); 785127664Sbms } else { 786127664Sbms if (amt_read != 0) { 787127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 788127664Sbms "truncated dump file; tried to read %d header bytes, only got %lu", 789127664Sbms p->sf.hdrsize, (unsigned long)amt_read); 790127664Sbms return (-1); 791127664Sbms } 792127664Sbms /* EOF */ 793127664Sbms return (1); 794127664Sbms } 79517683Spst } 79617683Spst 79717683Spst if (p->sf.swapped) { 79817683Spst /* these were written in opposite byte order */ 79956889Sfenner hdr->caplen = SWAPLONG(sf_hdr.caplen); 80056889Sfenner hdr->len = SWAPLONG(sf_hdr.len); 80156889Sfenner hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 80256889Sfenner hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 80356889Sfenner } else { 80456889Sfenner hdr->caplen = sf_hdr.caplen; 80556889Sfenner hdr->len = sf_hdr.len; 80656889Sfenner hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 80756889Sfenner hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 80817683Spst } 809127664Sbms /* Swap the caplen and len fields, if necessary. */ 810127664Sbms switch (p->sf.lengths_swapped) { 811127664Sbms 812127664Sbms case NOT_SWAPPED: 813127664Sbms break; 814127664Sbms 815127664Sbms case MAYBE_SWAPPED: 816127664Sbms if (hdr->caplen <= hdr->len) { 817127664Sbms /* 818127664Sbms * The captured length is <= the actual length, 819127664Sbms * so presumably they weren't swapped. 820127664Sbms */ 821127664Sbms break; 822127664Sbms } 823127664Sbms /* FALLTHROUGH */ 824127664Sbms 825127664Sbms case SWAPPED: 826127664Sbms t = hdr->caplen; 82717683Spst hdr->caplen = hdr->len; 82817683Spst hdr->len = t; 829127664Sbms break; 83017683Spst } 83117683Spst 83217683Spst if (hdr->caplen > buflen) { 83317683Spst /* 83417683Spst * This can happen due to Solaris 2.3 systems tripping 83517683Spst * over the BUFMOD problem and not setting the snapshot 83617683Spst * correctly in the savefile header. If the caplen isn't 83717683Spst * grossly wrong, try to salvage. 83817683Spst */ 83917683Spst static u_char *tp = NULL; 840127664Sbms static size_t tsize = 0; 84117683Spst 84226175Sfenner if (hdr->caplen > 65535) { 84375107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 84475107Sfenner "bogus savefile header"); 84526175Sfenner return (-1); 84626175Sfenner } 84775107Sfenner 84817683Spst if (tsize < hdr->caplen) { 84917683Spst tsize = ((hdr->caplen + 1023) / 1024) * 1024; 85017683Spst if (tp != NULL) 85117683Spst free((u_char *)tp); 85217683Spst tp = (u_char *)malloc(tsize); 85317683Spst if (tp == NULL) { 85426175Sfenner tsize = 0; 85575107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 85675107Sfenner "BUFMOD hack malloc"); 85717683Spst return (-1); 85817683Spst } 85917683Spst } 860127664Sbms amt_read = fread((char *)tp, 1, hdr->caplen, fp); 861127664Sbms if (amt_read != hdr->caplen) { 862127664Sbms if (ferror(fp)) { 863127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 864127664Sbms "error reading dump file: %s", 865127664Sbms pcap_strerror(errno)); 866127664Sbms } else { 867127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 868127664Sbms "truncated dump file; tried to read %u captured bytes, only got %lu", 869127664Sbms hdr->caplen, (unsigned long)amt_read); 870127664Sbms } 87117683Spst return (-1); 87217683Spst } 87326175Sfenner /* 87426175Sfenner * We can only keep up to buflen bytes. Since caplen > buflen 87526175Sfenner * is exactly how we got here, we know we can only keep the 87626175Sfenner * first buflen bytes and must drop the remainder. Adjust 87726175Sfenner * caplen accordingly, so we don't get confused later as 87826175Sfenner * to how many bytes we have to play with. 87926175Sfenner */ 88026175Sfenner hdr->caplen = buflen; 88117683Spst memcpy((char *)buf, (char *)tp, buflen); 88217683Spst 88317683Spst } else { 88417683Spst /* read the packet itself */ 885127664Sbms amt_read = fread((char *)buf, 1, hdr->caplen, fp); 886127664Sbms if (amt_read != hdr->caplen) { 887127664Sbms if (ferror(fp)) { 888127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 889127664Sbms "error reading dump file: %s", 890127664Sbms pcap_strerror(errno)); 891127664Sbms } else { 892127664Sbms snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 893127664Sbms "truncated dump file; tried to read %u captured bytes, only got %lu", 894127664Sbms hdr->caplen, (unsigned long)amt_read); 895127664Sbms } 89617683Spst return (-1); 89717683Spst } 89817683Spst } 89917683Spst return (0); 90017683Spst} 90117683Spst 90217683Spst/* 90317683Spst * Print out packets stored in the file initialized by sf_read_init(). 90417683Spst * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 90517683Spst */ 90617683Spstint 90717683Spstpcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 90817683Spst{ 90917683Spst struct bpf_insn *fcode = p->fcode.bf_insns; 91017683Spst int status = 0; 91117683Spst int n = 0; 91217683Spst 91317683Spst while (status == 0) { 91417683Spst struct pcap_pkthdr h; 91517683Spst 916127664Sbms /* 917127664Sbms * Has "pcap_breakloop()" been called? 918127664Sbms * If so, return immediately - if we haven't read any 919127664Sbms * packets, clear the flag and return -2 to indicate 920127664Sbms * that we were told to break out of the loop, otherwise 921127664Sbms * leave the flag set, so that the *next* call will break 922127664Sbms * out of the loop without having read any packets, and 923127664Sbms * return the number of packets we've processed so far. 924127664Sbms */ 925127664Sbms if (p->break_loop) { 926127664Sbms if (n == 0) { 927127664Sbms p->break_loop = 0; 928127664Sbms return (-2); 929127664Sbms } else 930127664Sbms return (n); 931127664Sbms } 932127664Sbms 93317683Spst status = sf_next_packet(p, &h, p->buffer, p->bufsize); 93417683Spst if (status) { 93517683Spst if (status == 1) 93617683Spst return (0); 93717683Spst return (status); 93817683Spst } 93917683Spst 94017683Spst if (fcode == NULL || 94117683Spst bpf_filter(fcode, p->buffer, h.len, h.caplen)) { 94217683Spst (*callback)(user, &h, p->buffer); 94317683Spst if (++n >= cnt && cnt > 0) 94417683Spst break; 94517683Spst } 94617683Spst } 94717683Spst /*XXX this breaks semantics tcpslice expects */ 94817683Spst return (n); 94917683Spst} 95017683Spst 95117683Spst/* 95217683Spst * Output a packet to the initialized dump file. 95317683Spst */ 95417683Spstvoid 95517683Spstpcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 95617683Spst{ 95717683Spst register FILE *f; 95856889Sfenner struct pcap_sf_pkthdr sf_hdr; 95917683Spst 96017683Spst f = (FILE *)user; 96156889Sfenner sf_hdr.ts.tv_sec = h->ts.tv_sec; 96256889Sfenner sf_hdr.ts.tv_usec = h->ts.tv_usec; 96356889Sfenner sf_hdr.caplen = h->caplen; 96456889Sfenner sf_hdr.len = h->len; 96517683Spst /* XXX we should check the return status */ 96656889Sfenner (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 96717683Spst (void)fwrite((char *)sp, h->caplen, 1, f); 96817683Spst} 96917683Spst 97017683Spst/* 97117683Spst * Initialize so that sf_write() will output to the file named 'fname'. 97217683Spst */ 97317683Spstpcap_dumper_t * 97439291Sfennerpcap_dump_open(pcap_t *p, const char *fname) 97517683Spst{ 97617683Spst FILE *f; 97775107Sfenner int linktype; 97875107Sfenner 97975107Sfenner linktype = dlt_to_linktype(p->linktype); 98075107Sfenner if (linktype == -1) { 98175107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 98275107Sfenner "%s: link-layer type %d isn't supported in savefiles", 98375107Sfenner fname, linktype); 98475107Sfenner return (NULL); 98575107Sfenner } 98675107Sfenner 987127664Sbms if (fname[0] == '-' && fname[1] == '\0') { 98817683Spst f = stdout; 989127664Sbms#ifdef WIN32 990127664Sbms _setmode(_fileno(f), _O_BINARY); 991127664Sbms#endif 992127664Sbms } else { 993127664Sbms#ifndef WIN32 99417683Spst f = fopen(fname, "w"); 995127664Sbms#else 996127664Sbms f = fopen(fname, "wb"); 997127664Sbms setbuf(f, NULL); /* XXX - why? */ 998127664Sbms#endif 99917683Spst if (f == NULL) { 100075107Sfenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 100117683Spst fname, pcap_strerror(errno)); 100217683Spst return (NULL); 100317683Spst } 100417683Spst } 100575107Sfenner (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); 100617683Spst return ((pcap_dumper_t *)f); 100717683Spst} 100817683Spst 1009127664SbmsFILE * 1010127664Sbmspcap_dump_file(pcap_dumper_t *p) 1011127664Sbms{ 1012127664Sbms return ((FILE *)p); 1013127664Sbms} 1014127664Sbms 1015127664Sbmsint 1016127664Sbmspcap_dump_flush(pcap_dumper_t *p) 1017127664Sbms{ 1018127664Sbms 1019127664Sbms if (fflush((FILE *)p) == EOF) 1020127664Sbms return (-1); 1021127664Sbms else 1022127664Sbms return (0); 1023127664Sbms} 1024127664Sbms 102517683Spstvoid 102617683Spstpcap_dump_close(pcap_dumper_t *p) 102717683Spst{ 102817683Spst 102917683Spst#ifdef notyet 103017683Spst if (ferror((FILE *)p)) 103117683Spst return-an-error; 103217683Spst /* XXX should check return from fclose() too */ 103317683Spst#endif 103417683Spst (void)fclose((FILE *)p); 103517683Spst} 1036