18cf6c252SPaul Traina /* 2a4b5b39fSBill Fenner * Copyright (c) 1993, 1994, 1995, 1996, 1997 38cf6c252SPaul Traina * The Regents of the University of California. All rights reserved. 48cf6c252SPaul Traina * 58cf6c252SPaul Traina * Redistribution and use in source and binary forms, with or without 68cf6c252SPaul Traina * modification, are permitted provided that: (1) source code distributions 78cf6c252SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 88cf6c252SPaul Traina * distributions including binary code include the above copyright notice and 98cf6c252SPaul Traina * this paragraph in its entirety in the documentation or other materials 108cf6c252SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 118cf6c252SPaul Traina * features or use of this software display the following acknowledgement: 128cf6c252SPaul Traina * ``This product includes software developed by the University of California, 138cf6c252SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 148cf6c252SPaul Traina * the University nor the names of its contributors may be used to endorse 158cf6c252SPaul Traina * or promote products derived from this software without specific prior 168cf6c252SPaul Traina * written permission. 178cf6c252SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 188cf6c252SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 198cf6c252SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 203052b236SBill Fenner * 218cf6c252SPaul Traina * savefile.c - supports offline use of tcpdump 228cf6c252SPaul Traina * Extraction/creation by Jeffrey Mogul, DECWRL 238cf6c252SPaul Traina * Modified by Steve McCanne, LBL. 248cf6c252SPaul Traina * 258cf6c252SPaul Traina * Used to save the received packet headers, after filtering, to 268cf6c252SPaul Traina * a file, and then read them later. 278cf6c252SPaul Traina * The first record in the file contains saved values for the machine 288cf6c252SPaul Traina * dependent values so we can print the dump file on any architecture. 298cf6c252SPaul Traina */ 308cf6c252SPaul Traina 313052b236SBill Fenner #ifndef lint 32feb4ecdbSBruce M Simpson static const char rcsid[] _U_ = 33feb4ecdbSBruce M Simpson "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp $ (LBL)"; 34dc2c7305SBill Fenner #endif 35dc2c7305SBill Fenner 36dc2c7305SBill Fenner #ifdef HAVE_CONFIG_H 37dc2c7305SBill Fenner #include "config.h" 383052b236SBill Fenner #endif 393052b236SBill Fenner 408cf6c252SPaul Traina #include <errno.h> 418cf6c252SPaul Traina #include <memory.h> 428cf6c252SPaul Traina #include <stdio.h> 438cf6c252SPaul Traina #include <stdlib.h> 44dc2c7305SBill Fenner #include <string.h> 458cf6c252SPaul Traina 468cf6c252SPaul Traina #include "pcap-int.h" 478cf6c252SPaul Traina 488cf6c252SPaul Traina #ifdef HAVE_OS_PROTO_H 498cf6c252SPaul Traina #include "os-proto.h" 508cf6c252SPaul Traina #endif 518cf6c252SPaul Traina 528cf6c252SPaul Traina #define TCPDUMP_MAGIC 0xa1b2c3d4 53dc2c7305SBill Fenner #define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 548cf6c252SPaul Traina 558cf6c252SPaul Traina /* 568cf6c252SPaul Traina * We use the "receiver-makes-right" approach to byte order, 578cf6c252SPaul Traina * because time is at a premium when we are writing the file. 588cf6c252SPaul Traina * In other words, the pcap_file_header and pcap_pkthdr, 598cf6c252SPaul Traina * records are written in host byte order. 60feb4ecdbSBruce M Simpson * Note that the bytes of packet data are written out in the order in 61feb4ecdbSBruce M Simpson * which they were received, so multi-byte fields in packets are not 62feb4ecdbSBruce M Simpson * written in host byte order, they're written in whatever order the 63feb4ecdbSBruce M Simpson * sending machine put them in. 648cf6c252SPaul Traina * 658cf6c252SPaul Traina * ntoh[ls] aren't sufficient because we might need to swap on a big-endian 668cf6c252SPaul Traina * machine (if the file was written in little-end order). 678cf6c252SPaul Traina */ 688cf6c252SPaul Traina #define SWAPLONG(y) \ 698cf6c252SPaul Traina ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) 708cf6c252SPaul Traina #define SWAPSHORT(y) \ 713052b236SBill Fenner ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) 728cf6c252SPaul Traina 738cf6c252SPaul Traina #define SFERR_TRUNC 1 748cf6c252SPaul Traina #define SFERR_BADVERSION 2 758cf6c252SPaul Traina #define SFERR_BADF 3 768cf6c252SPaul Traina #define SFERR_EOF 4 /* not really an error, just a status */ 778cf6c252SPaul Traina 78dc2c7305SBill Fenner /* 79dc2c7305SBill Fenner * We don't write DLT_* values to the capture file header, because 80dc2c7305SBill Fenner * they're not the same on all platforms. 81dc2c7305SBill Fenner * 82dc2c7305SBill Fenner * Unfortunately, the various flavors of BSD have not always used the same 83dc2c7305SBill Fenner * numerical values for the same data types, and various patches to 84dc2c7305SBill Fenner * libpcap for non-BSD OSes have added their own DLT_* codes for link 85dc2c7305SBill Fenner * layer encapsulation types seen on those OSes, and those codes have had, 86dc2c7305SBill Fenner * in some cases, values that were also used, on other platforms, for other 87dc2c7305SBill Fenner * link layer encapsulation types. 88dc2c7305SBill Fenner * 89dc2c7305SBill Fenner * This means that capture files of a type whose numerical DLT_* code 90dc2c7305SBill Fenner * means different things on different BSDs, or with different versions 91dc2c7305SBill Fenner * of libpcap, can't always be read on systems other than those like 92dc2c7305SBill Fenner * the one running on the machine on which the capture was made. 93dc2c7305SBill Fenner * 94dc2c7305SBill Fenner * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes 95dc2c7305SBill Fenner * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* 96dc2c7305SBill Fenner * codes to DLT_* codes when reading a savefile header. 97dc2c7305SBill Fenner * 98dc2c7305SBill Fenner * For those DLT_* codes that have, as far as we know, the same values on 99dc2c7305SBill Fenner * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as 100dc2c7305SBill Fenner * DLT_xxx; that way, captures of those types can still be read by 101dc2c7305SBill Fenner * versions of libpcap that map LINKTYPE_* values to DLT_* values, and 102dc2c7305SBill Fenner * captures of those types written by versions of libpcap that map DLT_ 103dc2c7305SBill Fenner * values to LINKTYPE_ values can still be read by older versions 104dc2c7305SBill Fenner * of libpcap. 105dc2c7305SBill Fenner * 106dc2c7305SBill Fenner * The other LINKTYPE_* codes are given values starting at 100, in the 107dc2c7305SBill Fenner * hopes that no DLT_* code will be given one of those values. 108dc2c7305SBill Fenner * 109dc2c7305SBill Fenner * In order to ensure that a given LINKTYPE_* code's value will refer to 110dc2c7305SBill Fenner * the same encapsulation type on all platforms, you should not allocate 111dc2c7305SBill Fenner * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". 112dc2c7305SBill Fenner * The tcpdump developers will allocate a value for you, and will not 113dc2c7305SBill Fenner * subsequently allocate it to anybody else; that value will be added to 114dc2c7305SBill Fenner * the "pcap.h" in the tcpdump.org CVS repository, so that a future 115dc2c7305SBill Fenner * libpcap release will include it. 116dc2c7305SBill Fenner * 117dc2c7305SBill Fenner * You should, if possible, also contribute patches to libpcap and tcpdump 118dc2c7305SBill Fenner * to handle the new encapsulation type, so that they can also be checked 119dc2c7305SBill Fenner * into the tcpdump.org CVS repository and so that they will appear in 120dc2c7305SBill Fenner * future libpcap and tcpdump releases. 121feb4ecdbSBruce M Simpson * 122feb4ecdbSBruce M Simpson * Do *NOT* assume that any values after the largest value in this file 123feb4ecdbSBruce M Simpson * are available; you might not have the most up-to-date version of this 124feb4ecdbSBruce M Simpson * file, and new values after that one might have been assigned. Also, 125feb4ecdbSBruce M Simpson * do *NOT* use any values below 100 - those might already have been 126feb4ecdbSBruce M Simpson * taken by one (or more!) organizations. 127dc2c7305SBill Fenner */ 128dc2c7305SBill Fenner #define LINKTYPE_NULL DLT_NULL 129dc2c7305SBill Fenner #define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ 130dc2c7305SBill Fenner #define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ 131dc2c7305SBill Fenner #define LINKTYPE_AX25 DLT_AX25 132dc2c7305SBill Fenner #define LINKTYPE_PRONET DLT_PRONET 133dc2c7305SBill Fenner #define LINKTYPE_CHAOS DLT_CHAOS 134dc2c7305SBill Fenner #define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ 135feb4ecdbSBruce M Simpson #define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ 136dc2c7305SBill Fenner #define LINKTYPE_SLIP DLT_SLIP 137dc2c7305SBill Fenner #define LINKTYPE_PPP DLT_PPP 138dc2c7305SBill Fenner #define LINKTYPE_FDDI DLT_FDDI 139dc2c7305SBill Fenner 140dc2c7305SBill Fenner /* 141dc2c7305SBill Fenner * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 142dc2c7305SBill Fenner * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol 143dc2c7305SBill Fenner * field) at the beginning of the packet. 144dc2c7305SBill Fenner * 145dc2c7305SBill Fenner * This is for use when there is always such a header; the address field 146dc2c7305SBill Fenner * might be 0xff, for regular PPP, or it might be an address field for Cisco 147dc2c7305SBill Fenner * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco 148dc2c7305SBill Fenner * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. 149dc2c7305SBill Fenner * 150dc2c7305SBill Fenner * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that 151dc2c7305SBill Fenner * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL 152dc2c7305SBill Fenner * captures will be written out with a link type that NetBSD's tcpdump 153dc2c7305SBill Fenner * can read. 154dc2c7305SBill Fenner */ 155dc2c7305SBill Fenner #define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ 156dc2c7305SBill Fenner 1570a94d38fSBill Fenner #define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ 1580a94d38fSBill Fenner 159feb4ecdbSBruce M Simpson /* 160feb4ecdbSBruce M Simpson * This isn't supported in libpcap 0.8[.x], but is supported in the 161feb4ecdbSBruce M Simpson * current CVS version; we include it here to note that it's not available 162feb4ecdbSBruce M Simpson * for anybody else to use. 163feb4ecdbSBruce M Simpson */ 164feb4ecdbSBruce M Simpson #define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */ 165feb4ecdbSBruce M Simpson 166dc2c7305SBill Fenner #define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ 167dc2c7305SBill Fenner #define LINKTYPE_RAW 101 /* raw IP */ 168dc2c7305SBill Fenner #define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ 169dc2c7305SBill Fenner #define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ 170dc2c7305SBill Fenner #define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ 1710a94d38fSBill Fenner #define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ 172dc2c7305SBill Fenner #define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ 173feb4ecdbSBruce M Simpson #define LINKTYPE_FRELAY 107 /* Frame Relay */ 1740a94d38fSBill Fenner #define LINKTYPE_LOOP 108 /* OpenBSD loopback */ 175feb4ecdbSBruce M Simpson #define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ 176feb4ecdbSBruce M Simpson 177feb4ecdbSBruce M Simpson /* 178feb4ecdbSBruce M Simpson * These three types are reserved for future use. 179feb4ecdbSBruce M Simpson */ 180feb4ecdbSBruce M Simpson #define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ 181feb4ecdbSBruce M Simpson #define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ 182feb4ecdbSBruce M Simpson #define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ 1830a94d38fSBill Fenner 1840a94d38fSBill Fenner #define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ 1850a94d38fSBill Fenner #define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ 1860a94d38fSBill Fenner #define LINKTYPE_ECONET 115 /* Acorn Econet */ 1870a94d38fSBill Fenner 188feb4ecdbSBruce M Simpson /* 189feb4ecdbSBruce M Simpson * Reserved for use with OpenBSD ipfilter. 190feb4ecdbSBruce M Simpson */ 191feb4ecdbSBruce M Simpson #define LINKTYPE_IPFILTER 116 192feb4ecdbSBruce M Simpson 193feb4ecdbSBruce M Simpson #define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ 1940a94d38fSBill Fenner #define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ 1950a94d38fSBill Fenner #define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ 1960a94d38fSBill Fenner #define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ 197dc2c7305SBill Fenner 198dc2c7305SBill Fenner /* 199feb4ecdbSBruce M Simpson * Reserved for Siemens HiPath HDLC. 200dc2c7305SBill Fenner */ 201feb4ecdbSBruce M Simpson #define LINKTYPE_HHDLC 121 202feb4ecdbSBruce M Simpson 203feb4ecdbSBruce M Simpson #define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ 204feb4ecdbSBruce M Simpson #define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ 205feb4ecdbSBruce M Simpson 206feb4ecdbSBruce M Simpson /* 207feb4ecdbSBruce M Simpson * Reserved as per request from Kent Dahlgren <kent@praesum.com> 208feb4ecdbSBruce M Simpson * for private use. 209feb4ecdbSBruce M Simpson */ 210feb4ecdbSBruce M Simpson #define LINKTYPE_RIO 124 /* RapidIO */ 211feb4ecdbSBruce M Simpson #define LINKTYPE_PCI_EXP 125 /* PCI Express */ 212feb4ecdbSBruce M Simpson #define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ 213feb4ecdbSBruce M Simpson 214feb4ecdbSBruce M Simpson #define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ 215feb4ecdbSBruce M Simpson 216feb4ecdbSBruce M Simpson /* 217feb4ecdbSBruce M Simpson * Reserved for the TZSP encapsulation, as per request from 218feb4ecdbSBruce M Simpson * Chris Waters <chris.waters@networkchemistry.com> 219feb4ecdbSBruce M Simpson * TZSP is a generic encapsulation for any other link type, 220feb4ecdbSBruce M Simpson * which includes a means to include meta-information 221feb4ecdbSBruce M Simpson * with the packet, e.g. signal strength and channel 222feb4ecdbSBruce M Simpson * for 802.11 packets. 223feb4ecdbSBruce M Simpson */ 224feb4ecdbSBruce M Simpson #define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ 225feb4ecdbSBruce M Simpson 226feb4ecdbSBruce M Simpson #define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ 227feb4ecdbSBruce M Simpson 228feb4ecdbSBruce M Simpson /* 229feb4ecdbSBruce M Simpson * Juniper-private data link types, as per request from 230feb4ecdbSBruce M Simpson * Hannes Gredler <hannes@juniper.net>. The corresponding 231feb4ecdbSBruce M Simpson * DLT_s are used for passing on chassis-internal 232feb4ecdbSBruce M Simpson * metainformation such as QOS profiles, etc.. 233feb4ecdbSBruce M Simpson */ 234feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_MLPPP 130 235feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_MLFR 131 236feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_ES 132 237feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_GGSN 133 238feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_MFR 134 239feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_ATM2 135 240feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_SERVICES 136 241feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_ATM1 137 242feb4ecdbSBruce M Simpson 243feb4ecdbSBruce M Simpson #define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */ 244feb4ecdbSBruce M Simpson 245feb4ecdbSBruce M Simpson #define LINKTYPE_RAWSS7 139 /* see rawss7.h for */ 246feb4ecdbSBruce M Simpson #define LINKTYPE_RAWSS7_MTP2 140 /* information on these */ 247feb4ecdbSBruce M Simpson #define LINKTYPE_RAWSS7_MTP3 141 /* definitions */ 248feb4ecdbSBruce M Simpson #define LINKTYPE_RAWSS7_SCCP 142 249feb4ecdbSBruce M Simpson 250feb4ecdbSBruce M Simpson /* 251feb4ecdbSBruce M Simpson * This isn't supported in libpcap 0.8[.x], but is supported in the 252feb4ecdbSBruce M Simpson * current CVS version; we include it here to note that it's not available 253feb4ecdbSBruce M Simpson * for anybody else to use. 254feb4ecdbSBruce M Simpson */ 255feb4ecdbSBruce M Simpson #define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */ 256feb4ecdbSBruce M Simpson 257feb4ecdbSBruce M Simpson #define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */ 258feb4ecdbSBruce M Simpson 259feb4ecdbSBruce M Simpson /* 260feb4ecdbSBruce M Simpson * Reserved for IBM SP switch and IBM Next Federation switch. 261feb4ecdbSBruce M Simpson */ 262feb4ecdbSBruce M Simpson #define LINKTYPE_IBM_SP 145 263feb4ecdbSBruce M Simpson #define LINKTYPE_IBM_SN 146 264feb4ecdbSBruce M Simpson 265feb4ecdbSBruce M Simpson /* 266feb4ecdbSBruce M Simpson * Reserved for private use. If you have some link-layer header type 267feb4ecdbSBruce M Simpson * that you want to use within your organization, with the capture files 268feb4ecdbSBruce M Simpson * using that link-layer header type not ever be sent outside your 269feb4ecdbSBruce M Simpson * organization, you can use these values. 270feb4ecdbSBruce M Simpson * 271feb4ecdbSBruce M Simpson * No libpcap release will use these for any purpose, nor will any 272feb4ecdbSBruce M Simpson * tcpdump release use them, either. 273feb4ecdbSBruce M Simpson * 274feb4ecdbSBruce M Simpson * Do *NOT* use these in capture files that you expect anybody not using 275feb4ecdbSBruce M Simpson * your private versions of capture-file-reading tools to read; in 276feb4ecdbSBruce M Simpson * particular, do *NOT* use them in products, otherwise you may find that 277feb4ecdbSBruce M Simpson * people won't be able to use tcpdump, or snort, or Ethereal, or... to 278feb4ecdbSBruce M Simpson * read capture files from your firewall/intrusion detection/traffic 279feb4ecdbSBruce M Simpson * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value, 280feb4ecdbSBruce M Simpson * and you may also find that the developers of those applications will 281feb4ecdbSBruce M Simpson * not accept patches to let them read those files. 282feb4ecdbSBruce M Simpson * 283feb4ecdbSBruce M Simpson * Also, do not use them if somebody might send you a capture using them 284feb4ecdbSBruce M Simpson * for *their* private type and tools using them for *your* private type 285feb4ecdbSBruce M Simpson * would have to read them. 286feb4ecdbSBruce M Simpson * 287feb4ecdbSBruce M Simpson * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ 288feb4ecdbSBruce M Simpson * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type 289feb4ecdbSBruce M Simpson * you're given. 290feb4ecdbSBruce M Simpson */ 291feb4ecdbSBruce M Simpson #define LINKTYPE_USER0 147 292feb4ecdbSBruce M Simpson #define LINKTYPE_USER1 148 293feb4ecdbSBruce M Simpson #define LINKTYPE_USER2 149 294feb4ecdbSBruce M Simpson #define LINKTYPE_USER3 150 295feb4ecdbSBruce M Simpson #define LINKTYPE_USER4 151 296feb4ecdbSBruce M Simpson #define LINKTYPE_USER5 152 297feb4ecdbSBruce M Simpson #define LINKTYPE_USER6 153 298feb4ecdbSBruce M Simpson #define LINKTYPE_USER7 154 299feb4ecdbSBruce M Simpson #define LINKTYPE_USER8 155 300feb4ecdbSBruce M Simpson #define LINKTYPE_USER9 156 301feb4ecdbSBruce M Simpson #define LINKTYPE_USER10 157 302feb4ecdbSBruce M Simpson #define LINKTYPE_USER11 158 303feb4ecdbSBruce M Simpson #define LINKTYPE_USER12 159 304feb4ecdbSBruce M Simpson #define LINKTYPE_USER13 160 305feb4ecdbSBruce M Simpson #define LINKTYPE_USER14 161 306feb4ecdbSBruce M Simpson #define LINKTYPE_USER15 162 307feb4ecdbSBruce M Simpson 308feb4ecdbSBruce M Simpson /* 309feb4ecdbSBruce M Simpson * For future use with 802.11 captures - defined by AbsoluteValue 310feb4ecdbSBruce M Simpson * Systems to store a number of bits of link-layer information 311feb4ecdbSBruce M Simpson * including radio information: 312feb4ecdbSBruce M Simpson * 313feb4ecdbSBruce M Simpson * http://www.shaftnet.org/~pizza/software/capturefrm.txt 314feb4ecdbSBruce M Simpson * 315feb4ecdbSBruce M Simpson * but could and arguably should also be used by non-AVS Linux 316feb4ecdbSBruce M Simpson * 802.11 drivers; that may happen in the future. 317feb4ecdbSBruce M Simpson */ 318feb4ecdbSBruce M Simpson #define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ 319feb4ecdbSBruce M Simpson 320feb4ecdbSBruce M Simpson /* 321feb4ecdbSBruce M Simpson * Juniper-private data link type, as per request from 322feb4ecdbSBruce M Simpson * Hannes Gredler <hannes@juniper.net>. The corresponding 323feb4ecdbSBruce M Simpson * DLT_s are used for passing on chassis-internal 324feb4ecdbSBruce M Simpson * metainformation such as QOS profiles, etc.. 325feb4ecdbSBruce M Simpson */ 326feb4ecdbSBruce M Simpson #define LINKTYPE_JUNIPER_MONITOR 164 327dc2c7305SBill Fenner 328dc2c7305SBill Fenner static struct linktype_map { 329dc2c7305SBill Fenner int dlt; 330dc2c7305SBill Fenner int linktype; 331dc2c7305SBill Fenner } map[] = { 332dc2c7305SBill Fenner /* 333dc2c7305SBill Fenner * These DLT_* codes have LINKTYPE_* codes with values identical 334dc2c7305SBill Fenner * to the values of the corresponding DLT_* code. 335dc2c7305SBill Fenner */ 336dc2c7305SBill Fenner { DLT_NULL, LINKTYPE_NULL }, 337dc2c7305SBill Fenner { DLT_EN10MB, LINKTYPE_ETHERNET }, 338dc2c7305SBill Fenner { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, 339dc2c7305SBill Fenner { DLT_AX25, LINKTYPE_AX25 }, 340dc2c7305SBill Fenner { DLT_PRONET, LINKTYPE_PRONET }, 341dc2c7305SBill Fenner { DLT_CHAOS, LINKTYPE_CHAOS }, 342dc2c7305SBill Fenner { DLT_IEEE802, LINKTYPE_TOKEN_RING }, 343dc2c7305SBill Fenner { DLT_ARCNET, LINKTYPE_ARCNET }, 344dc2c7305SBill Fenner { DLT_SLIP, LINKTYPE_SLIP }, 345dc2c7305SBill Fenner { DLT_PPP, LINKTYPE_PPP }, 346dc2c7305SBill Fenner { DLT_FDDI, LINKTYPE_FDDI }, 347dc2c7305SBill Fenner 348dc2c7305SBill Fenner /* 349dc2c7305SBill Fenner * These DLT_* codes have different values on different 350dc2c7305SBill Fenner * platforms; we map them to LINKTYPE_* codes that 351dc2c7305SBill Fenner * have values that should never be equal to any DLT_* 352dc2c7305SBill Fenner * code. 353dc2c7305SBill Fenner */ 354feb4ecdbSBruce M Simpson #ifdef DLT_FR 355feb4ecdbSBruce M Simpson /* BSD/OS Frame Relay */ 356feb4ecdbSBruce M Simpson { DLT_FR, LINKTYPE_FRELAY }, 357feb4ecdbSBruce M Simpson #endif 358feb4ecdbSBruce M Simpson 359feb4ecdbSBruce M Simpson { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, 360dc2c7305SBill Fenner { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, 361dc2c7305SBill Fenner { DLT_RAW, LINKTYPE_RAW }, 362dc2c7305SBill Fenner { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, 363dc2c7305SBill Fenner { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, 364dc2c7305SBill Fenner 365dc2c7305SBill Fenner /* BSD/OS Cisco HDLC */ 366dc2c7305SBill Fenner { DLT_C_HDLC, LINKTYPE_C_HDLC }, 367dc2c7305SBill Fenner 368dc2c7305SBill Fenner /* 369dc2c7305SBill Fenner * These DLT_* codes are not on all platforms, but, so far, 370dc2c7305SBill Fenner * there don't appear to be any platforms that define 371dc2c7305SBill Fenner * other codes with those values; we map them to 372dc2c7305SBill Fenner * different LINKTYPE_* values anyway, just in case. 373dc2c7305SBill Fenner */ 374dc2c7305SBill Fenner 375dc2c7305SBill Fenner /* Linux ATM Classical IP */ 376dc2c7305SBill Fenner { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, 377dc2c7305SBill Fenner 378dc2c7305SBill Fenner /* NetBSD sync/async serial PPP (or Cisco HDLC) */ 379dc2c7305SBill Fenner { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, 380dc2c7305SBill Fenner 3810a94d38fSBill Fenner /* NetBSD PPP over Ethernet */ 3820a94d38fSBill Fenner { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, 3830a94d38fSBill Fenner 384dc2c7305SBill Fenner /* IEEE 802.11 wireless */ 385dc2c7305SBill Fenner { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, 386dc2c7305SBill Fenner 387feb4ecdbSBruce M Simpson /* Frame Relay */ 388feb4ecdbSBruce M Simpson { DLT_FRELAY, LINKTYPE_FRELAY }, 389feb4ecdbSBruce M Simpson 390dc2c7305SBill Fenner /* OpenBSD loopback */ 391dc2c7305SBill Fenner { DLT_LOOP, LINKTYPE_LOOP }, 392dc2c7305SBill Fenner 393dc2c7305SBill Fenner /* Linux cooked socket capture */ 394dc2c7305SBill Fenner { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, 395dc2c7305SBill Fenner 3960a94d38fSBill Fenner /* Apple LocalTalk hardware */ 3970a94d38fSBill Fenner { DLT_LTALK, LINKTYPE_LTALK }, 3980a94d38fSBill Fenner 3990a94d38fSBill Fenner /* Acorn Econet */ 4000a94d38fSBill Fenner { DLT_ECONET, LINKTYPE_ECONET }, 4010a94d38fSBill Fenner 402feb4ecdbSBruce M Simpson /* OpenBSD DLT_PFLOG */ 403feb4ecdbSBruce M Simpson { DLT_PFLOG, LINKTYPE_PFLOG }, 404feb4ecdbSBruce M Simpson 4050a94d38fSBill Fenner /* For Cisco-internal use */ 4060a94d38fSBill Fenner { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, 4070a94d38fSBill Fenner 4080a94d38fSBill Fenner /* Prism II monitor-mode header plus 802.11 header */ 4090a94d38fSBill Fenner { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, 4100a94d38fSBill Fenner 4110a94d38fSBill Fenner /* FreeBSD Aironet driver stuff */ 4120a94d38fSBill Fenner { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, 4130a94d38fSBill Fenner 414feb4ecdbSBruce M Simpson /* Siemens HiPath HDLC */ 415feb4ecdbSBruce M Simpson { DLT_HHDLC, LINKTYPE_HHDLC }, 416feb4ecdbSBruce M Simpson 417feb4ecdbSBruce M Simpson /* RFC 2625 IP-over-Fibre Channel */ 418feb4ecdbSBruce M Simpson { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, 419feb4ecdbSBruce M Simpson 420feb4ecdbSBruce M Simpson /* Solaris+SunATM */ 421feb4ecdbSBruce M Simpson { DLT_SUNATM, LINKTYPE_SUNATM }, 422feb4ecdbSBruce M Simpson 423feb4ecdbSBruce M Simpson /* RapidIO */ 424feb4ecdbSBruce M Simpson { DLT_RIO, LINKTYPE_RIO }, 425feb4ecdbSBruce M Simpson 426feb4ecdbSBruce M Simpson /* PCI Express */ 427feb4ecdbSBruce M Simpson { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, 428feb4ecdbSBruce M Simpson 429feb4ecdbSBruce M Simpson /* Xilinx Aurora link layer */ 430feb4ecdbSBruce M Simpson { DLT_AURORA, LINKTYPE_AURORA }, 431feb4ecdbSBruce M Simpson 432feb4ecdbSBruce M Simpson /* 802.11 plus BSD radio header */ 433feb4ecdbSBruce M Simpson { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, 434feb4ecdbSBruce M Simpson 435feb4ecdbSBruce M Simpson /* Tazmen Sniffer Protocol */ 436feb4ecdbSBruce M Simpson { DLT_TZSP, LINKTYPE_TZSP }, 437feb4ecdbSBruce M Simpson 438feb4ecdbSBruce M Simpson /* Arcnet with Linux-style link-layer headers */ 439feb4ecdbSBruce M Simpson { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, 440feb4ecdbSBruce M Simpson 441feb4ecdbSBruce M Simpson /* Juniper-internal chassis encapsulation */ 442feb4ecdbSBruce M Simpson { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP }, 443feb4ecdbSBruce M Simpson { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR }, 444feb4ecdbSBruce M Simpson { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES }, 445feb4ecdbSBruce M Simpson { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN }, 446feb4ecdbSBruce M Simpson { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR }, 447feb4ecdbSBruce M Simpson { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 }, 448feb4ecdbSBruce M Simpson { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES }, 449feb4ecdbSBruce M Simpson { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 }, 450feb4ecdbSBruce M Simpson 451feb4ecdbSBruce M Simpson /* Apple IP-over-IEEE 1394 cooked header */ 452feb4ecdbSBruce M Simpson { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 }, 453feb4ecdbSBruce M Simpson 454feb4ecdbSBruce M Simpson /* DOCSIS MAC frames */ 455feb4ecdbSBruce M Simpson { DLT_DOCSIS, LINKTYPE_DOCSIS }, 456feb4ecdbSBruce M Simpson 457feb4ecdbSBruce M Simpson /* IrDA IrLAP packets + Linux-cooked header */ 458feb4ecdbSBruce M Simpson { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA }, 459feb4ecdbSBruce M Simpson 460feb4ecdbSBruce M Simpson /* IBM SP and Next Federation switches */ 461feb4ecdbSBruce M Simpson { DLT_IBM_SP, LINKTYPE_IBM_SP }, 462feb4ecdbSBruce M Simpson { DLT_IBM_SN, LINKTYPE_IBM_SN }, 463feb4ecdbSBruce M Simpson 464feb4ecdbSBruce M Simpson /* 802.11 plus AVS radio header */ 465feb4ecdbSBruce M Simpson { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS }, 466feb4ecdbSBruce M Simpson 467dc2c7305SBill Fenner /* 468dc2c7305SBill Fenner * Any platform that defines additional DLT_* codes should: 469dc2c7305SBill Fenner * 470dc2c7305SBill Fenner * request a LINKTYPE_* code and value from tcpdump.org, 471dc2c7305SBill Fenner * as per the above; 472dc2c7305SBill Fenner * 473dc2c7305SBill Fenner * add, in their version of libpcap, an entry to map 474dc2c7305SBill Fenner * those DLT_* codes to the corresponding LINKTYPE_* 475dc2c7305SBill Fenner * code; 476dc2c7305SBill Fenner * 477dc2c7305SBill Fenner * redefine, in their "net/bpf.h", any DLT_* values 478dc2c7305SBill Fenner * that collide with the values used by their additional 479dc2c7305SBill Fenner * DLT_* codes, to remove those collisions (but without 480dc2c7305SBill Fenner * making them collide with any of the LINKTYPE_* 481dc2c7305SBill Fenner * values equal to 50 or above; they should also avoid 482dc2c7305SBill Fenner * defining DLT_* values that collide with those 483dc2c7305SBill Fenner * LINKTYPE_* values, either). 484dc2c7305SBill Fenner */ 485feb4ecdbSBruce M Simpson 486feb4ecdbSBruce M Simpson /* Juniper-internal chassis encapsulation */ 487feb4ecdbSBruce M Simpson { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR }, 488feb4ecdbSBruce M Simpson 489dc2c7305SBill Fenner { -1, -1 } 490dc2c7305SBill Fenner }; 491dc2c7305SBill Fenner 492dc2c7305SBill Fenner static int 493dc2c7305SBill Fenner dlt_to_linktype(int dlt) 494dc2c7305SBill Fenner { 495dc2c7305SBill Fenner int i; 496dc2c7305SBill Fenner 497dc2c7305SBill Fenner for (i = 0; map[i].dlt != -1; i++) { 498dc2c7305SBill Fenner if (map[i].dlt == dlt) 499dc2c7305SBill Fenner return (map[i].linktype); 500dc2c7305SBill Fenner } 501dc2c7305SBill Fenner 502dc2c7305SBill Fenner /* 503dc2c7305SBill Fenner * If we don't have a mapping for this DLT_ code, return an 504dc2c7305SBill Fenner * error; that means that the table above needs to have an 505dc2c7305SBill Fenner * entry added. 506dc2c7305SBill Fenner */ 507dc2c7305SBill Fenner return (-1); 508dc2c7305SBill Fenner } 509dc2c7305SBill Fenner 510dc2c7305SBill Fenner static int 511dc2c7305SBill Fenner linktype_to_dlt(int linktype) 512dc2c7305SBill Fenner { 513dc2c7305SBill Fenner int i; 514dc2c7305SBill Fenner 515dc2c7305SBill Fenner for (i = 0; map[i].linktype != -1; i++) { 516dc2c7305SBill Fenner if (map[i].linktype == linktype) 517dc2c7305SBill Fenner return (map[i].dlt); 518dc2c7305SBill Fenner } 519dc2c7305SBill Fenner 520dc2c7305SBill Fenner /* 521dc2c7305SBill Fenner * If we don't have an entry for this link type, return 522dc2c7305SBill Fenner * the link type value; it may be a DLT_ value from an 523dc2c7305SBill Fenner * older version of libpcap. 524dc2c7305SBill Fenner */ 525dc2c7305SBill Fenner return linktype; 526dc2c7305SBill Fenner } 527dc2c7305SBill Fenner 5288cf6c252SPaul Traina static int 5298cf6c252SPaul Traina sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) 5308cf6c252SPaul Traina { 5318cf6c252SPaul Traina struct pcap_file_header hdr; 5328cf6c252SPaul Traina 5338cf6c252SPaul Traina hdr.magic = TCPDUMP_MAGIC; 5348cf6c252SPaul Traina hdr.version_major = PCAP_VERSION_MAJOR; 5358cf6c252SPaul Traina hdr.version_minor = PCAP_VERSION_MINOR; 5368cf6c252SPaul Traina 5378cf6c252SPaul Traina hdr.thiszone = thiszone; 5388cf6c252SPaul Traina hdr.snaplen = snaplen; 5398cf6c252SPaul Traina hdr.sigfigs = 0; 5408cf6c252SPaul Traina hdr.linktype = linktype; 5418cf6c252SPaul Traina 5428cf6c252SPaul Traina if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) 5438cf6c252SPaul Traina return (-1); 5448cf6c252SPaul Traina 5458cf6c252SPaul Traina return (0); 5468cf6c252SPaul Traina } 5478cf6c252SPaul Traina 5488cf6c252SPaul Traina static void 5498cf6c252SPaul Traina swap_hdr(struct pcap_file_header *hp) 5508cf6c252SPaul Traina { 5518cf6c252SPaul Traina hp->version_major = SWAPSHORT(hp->version_major); 5528cf6c252SPaul Traina hp->version_minor = SWAPSHORT(hp->version_minor); 5538cf6c252SPaul Traina hp->thiszone = SWAPLONG(hp->thiszone); 5548cf6c252SPaul Traina hp->sigfigs = SWAPLONG(hp->sigfigs); 5558cf6c252SPaul Traina hp->snaplen = SWAPLONG(hp->snaplen); 5568cf6c252SPaul Traina hp->linktype = SWAPLONG(hp->linktype); 5578cf6c252SPaul Traina } 5588cf6c252SPaul Traina 559feb4ecdbSBruce M Simpson static int 560feb4ecdbSBruce M Simpson sf_getnonblock(pcap_t *p, char *errbuf) 561feb4ecdbSBruce M Simpson { 562feb4ecdbSBruce M Simpson /* 563feb4ecdbSBruce M Simpson * This is a savefile, not a live capture file, so never say 564feb4ecdbSBruce M Simpson * it's in non-blocking mode. 565feb4ecdbSBruce M Simpson */ 566feb4ecdbSBruce M Simpson return (0); 567feb4ecdbSBruce M Simpson } 568feb4ecdbSBruce M Simpson 569feb4ecdbSBruce M Simpson static int 570feb4ecdbSBruce M Simpson sf_setnonblock(pcap_t *p, int nonblock, char *errbuf) 571feb4ecdbSBruce M Simpson { 572feb4ecdbSBruce M Simpson /* 573feb4ecdbSBruce M Simpson * This is a savefile, not a live capture file, so ignore 574feb4ecdbSBruce M Simpson * requests to put it in non-blocking mode. 575feb4ecdbSBruce M Simpson */ 576feb4ecdbSBruce M Simpson return (0); 577feb4ecdbSBruce M Simpson } 578feb4ecdbSBruce M Simpson 579feb4ecdbSBruce M Simpson static int 580feb4ecdbSBruce M Simpson sf_stats(pcap_t *p, struct pcap_stat *ps) 581feb4ecdbSBruce M Simpson { 582feb4ecdbSBruce M Simpson snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 583feb4ecdbSBruce M Simpson "Statistics aren't available from savefiles"); 584feb4ecdbSBruce M Simpson return (-1); 585feb4ecdbSBruce M Simpson } 586feb4ecdbSBruce M Simpson 587feb4ecdbSBruce M Simpson static void 588feb4ecdbSBruce M Simpson sf_close(pcap_t *p) 589feb4ecdbSBruce M Simpson { 590feb4ecdbSBruce M Simpson if (p->sf.rfile != stdin) 591feb4ecdbSBruce M Simpson (void)fclose(p->sf.rfile); 592feb4ecdbSBruce M Simpson if (p->sf.base != NULL) 593feb4ecdbSBruce M Simpson free(p->sf.base); 594feb4ecdbSBruce M Simpson } 595feb4ecdbSBruce M Simpson 5968cf6c252SPaul Traina pcap_t * 597a4b5b39fSBill Fenner pcap_open_offline(const char *fname, char *errbuf) 5988cf6c252SPaul Traina { 5998cf6c252SPaul Traina register pcap_t *p; 6008cf6c252SPaul Traina register FILE *fp; 6018cf6c252SPaul Traina struct pcap_file_header hdr; 602dc2c7305SBill Fenner bpf_u_int32 magic; 6038cf6c252SPaul Traina int linklen; 6048cf6c252SPaul Traina 6058cf6c252SPaul Traina p = (pcap_t *)malloc(sizeof(*p)); 6068cf6c252SPaul Traina if (p == NULL) { 607dc2c7305SBill Fenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 6088cf6c252SPaul Traina return (NULL); 6098cf6c252SPaul Traina } 6108cf6c252SPaul Traina 6118cf6c252SPaul Traina memset((char *)p, 0, sizeof(*p)); 6128cf6c252SPaul Traina 6138cf6c252SPaul Traina if (fname[0] == '-' && fname[1] == '\0') 6148cf6c252SPaul Traina fp = stdin; 6158cf6c252SPaul Traina else { 616feb4ecdbSBruce M Simpson #ifndef WIN32 6178cf6c252SPaul Traina fp = fopen(fname, "r"); 618feb4ecdbSBruce M Simpson #else 619feb4ecdbSBruce M Simpson fp = fopen(fname, "rb"); 620feb4ecdbSBruce M Simpson #endif 6218cf6c252SPaul Traina if (fp == NULL) { 622dc2c7305SBill Fenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, 623dc2c7305SBill Fenner pcap_strerror(errno)); 6248cf6c252SPaul Traina goto bad; 6258cf6c252SPaul Traina } 6268cf6c252SPaul Traina } 6278cf6c252SPaul Traina if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { 628dc2c7305SBill Fenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", 629dc2c7305SBill Fenner pcap_strerror(errno)); 6308cf6c252SPaul Traina goto bad; 6318cf6c252SPaul Traina } 632dc2c7305SBill Fenner magic = hdr.magic; 633dc2c7305SBill Fenner if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 634dc2c7305SBill Fenner magic = SWAPLONG(magic); 635dc2c7305SBill Fenner if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { 636dc2c7305SBill Fenner snprintf(errbuf, PCAP_ERRBUF_SIZE, 637dc2c7305SBill Fenner "bad dump file format"); 6388cf6c252SPaul Traina goto bad; 6398cf6c252SPaul Traina } 6408cf6c252SPaul Traina p->sf.swapped = 1; 6418cf6c252SPaul Traina swap_hdr(&hdr); 6428cf6c252SPaul Traina } 643dc2c7305SBill Fenner if (magic == PATCHED_TCPDUMP_MAGIC) { 644dc2c7305SBill Fenner /* 645dc2c7305SBill Fenner * XXX - the patch that's in some versions of libpcap 646dc2c7305SBill Fenner * changes the packet header but not the magic number; 647dc2c7305SBill Fenner * we'd have to use some hacks^H^H^H^H^Hheuristics to 648dc2c7305SBill Fenner * detect that. 649dc2c7305SBill Fenner */ 650dc2c7305SBill Fenner p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); 651dc2c7305SBill Fenner } else 652dc2c7305SBill Fenner p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); 6538cf6c252SPaul Traina if (hdr.version_major < PCAP_VERSION_MAJOR) { 654dc2c7305SBill Fenner snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); 6558cf6c252SPaul Traina goto bad; 6568cf6c252SPaul Traina } 6578cf6c252SPaul Traina p->tzoff = hdr.thiszone; 6588cf6c252SPaul Traina p->snapshot = hdr.snaplen; 659dc2c7305SBill Fenner p->linktype = linktype_to_dlt(hdr.linktype); 6608cf6c252SPaul Traina p->sf.rfile = fp; 661feb4ecdbSBruce M Simpson #ifndef WIN32 6628cf6c252SPaul Traina p->bufsize = hdr.snaplen; 663feb4ecdbSBruce M Simpson #else 664feb4ecdbSBruce M Simpson /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ 665feb4ecdbSBruce M Simpson p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); 666feb4ecdbSBruce M Simpson #endif 6678cf6c252SPaul Traina 6688cf6c252SPaul Traina /* Align link header as required for proper data alignment */ 6698cf6c252SPaul Traina /* XXX should handle all types */ 6708cf6c252SPaul Traina switch (p->linktype) { 6718cf6c252SPaul Traina 6728cf6c252SPaul Traina case DLT_EN10MB: 6738cf6c252SPaul Traina linklen = 14; 6748cf6c252SPaul Traina break; 6758cf6c252SPaul Traina 6768cf6c252SPaul Traina case DLT_FDDI: 6778cf6c252SPaul Traina linklen = 13 + 8; /* fddi_header + llc */ 6788cf6c252SPaul Traina break; 6798cf6c252SPaul Traina 6808cf6c252SPaul Traina case DLT_NULL: 6818cf6c252SPaul Traina default: 6828cf6c252SPaul Traina linklen = 0; 6838cf6c252SPaul Traina break; 6848cf6c252SPaul Traina } 6858cf6c252SPaul Traina 686dc2c7305SBill Fenner if (p->bufsize < 0) 687dc2c7305SBill Fenner p->bufsize = BPF_MAXBUFSIZE; 6888cf6c252SPaul Traina p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); 689dc2c7305SBill Fenner if (p->sf.base == NULL) { 690dc2c7305SBill Fenner strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); 691dc2c7305SBill Fenner goto bad; 692dc2c7305SBill Fenner } 6938cf6c252SPaul Traina p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); 6948cf6c252SPaul Traina p->sf.version_major = hdr.version_major; 6958cf6c252SPaul Traina p->sf.version_minor = hdr.version_minor; 6968cf6c252SPaul Traina #ifdef PCAP_FDDIPAD 6978cf6c252SPaul Traina /* XXX padding only needed for kernel fcode */ 6988cf6c252SPaul Traina pcap_fddipad = 0; 6998cf6c252SPaul Traina #endif 7008cf6c252SPaul Traina 701feb4ecdbSBruce M Simpson /* 702feb4ecdbSBruce M Simpson * We interchanged the caplen and len fields at version 2.3, 703feb4ecdbSBruce M Simpson * in order to match the bpf header layout. But unfortunately 704feb4ecdbSBruce M Simpson * some files were written with version 2.3 in their headers 705feb4ecdbSBruce M Simpson * but without the interchanged fields. 706feb4ecdbSBruce M Simpson * 707feb4ecdbSBruce M Simpson * In addition, DG/UX tcpdump writes out files with a version 708feb4ecdbSBruce M Simpson * number of 543.0, and with the caplen and len fields in the 709feb4ecdbSBruce M Simpson * pre-2.3 order. 710feb4ecdbSBruce M Simpson */ 711feb4ecdbSBruce M Simpson switch (hdr.version_major) { 712feb4ecdbSBruce M Simpson 713feb4ecdbSBruce M Simpson case 2: 714feb4ecdbSBruce M Simpson if (hdr.version_minor < 3) 715feb4ecdbSBruce M Simpson p->sf.lengths_swapped = SWAPPED; 716feb4ecdbSBruce M Simpson else if (hdr.version_minor == 3) 717feb4ecdbSBruce M Simpson p->sf.lengths_swapped = MAYBE_SWAPPED; 718feb4ecdbSBruce M Simpson else 719feb4ecdbSBruce M Simpson p->sf.lengths_swapped = NOT_SWAPPED; 720feb4ecdbSBruce M Simpson break; 721feb4ecdbSBruce M Simpson 722feb4ecdbSBruce M Simpson case 543: 723feb4ecdbSBruce M Simpson p->sf.lengths_swapped = SWAPPED; 724feb4ecdbSBruce M Simpson break; 725feb4ecdbSBruce M Simpson 726feb4ecdbSBruce M Simpson default: 727feb4ecdbSBruce M Simpson p->sf.lengths_swapped = NOT_SWAPPED; 728feb4ecdbSBruce M Simpson break; 729feb4ecdbSBruce M Simpson } 730feb4ecdbSBruce M Simpson 731feb4ecdbSBruce M Simpson #ifndef WIN32 732feb4ecdbSBruce M Simpson /* 733feb4ecdbSBruce M Simpson * You can do "select()" and "poll()" on plain files on most 734feb4ecdbSBruce M Simpson * platforms, and should be able to do so on pipes. 735feb4ecdbSBruce M Simpson * 736feb4ecdbSBruce M Simpson * You can't do "select()" on anything other than sockets in 737feb4ecdbSBruce M Simpson * Windows, so, on Win32 systems, we don't have "selectable_fd". 738feb4ecdbSBruce M Simpson */ 739feb4ecdbSBruce M Simpson p->selectable_fd = fileno(fp); 740feb4ecdbSBruce M Simpson #endif 741feb4ecdbSBruce M Simpson 742feb4ecdbSBruce M Simpson p->read_op = pcap_offline_read; 743feb4ecdbSBruce M Simpson p->setfilter_op = install_bpf_program; 744feb4ecdbSBruce M Simpson p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ 745feb4ecdbSBruce M Simpson p->getnonblock_op = sf_getnonblock; 746feb4ecdbSBruce M Simpson p->setnonblock_op = sf_setnonblock; 747feb4ecdbSBruce M Simpson p->stats_op = sf_stats; 748feb4ecdbSBruce M Simpson p->close_op = sf_close; 749feb4ecdbSBruce M Simpson 7508cf6c252SPaul Traina return (p); 7518cf6c252SPaul Traina bad: 752feb4ecdbSBruce M Simpson if(fp) 753feb4ecdbSBruce M Simpson fclose(fp); 7548cf6c252SPaul Traina free(p); 7558cf6c252SPaul Traina return (NULL); 7568cf6c252SPaul Traina } 7578cf6c252SPaul Traina 7588cf6c252SPaul Traina /* 7598cf6c252SPaul Traina * Read sf_readfile and return the next packet. Return the header in hdr 7608cf6c252SPaul Traina * and the contents in buf. Return 0 on success, SFERR_EOF if there were 7618cf6c252SPaul Traina * no more packets, and SFERR_TRUNC if a partial packet was encountered. 7628cf6c252SPaul Traina */ 7638cf6c252SPaul Traina static int 764feb4ecdbSBruce M Simpson sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) 7658cf6c252SPaul Traina { 766dc2c7305SBill Fenner struct pcap_sf_patched_pkthdr sf_hdr; 7678cf6c252SPaul Traina FILE *fp = p->sf.rfile; 768feb4ecdbSBruce M Simpson size_t amt_read; 769feb4ecdbSBruce M Simpson bpf_u_int32 t; 7708cf6c252SPaul Traina 771dc2c7305SBill Fenner /* 772dc2c7305SBill Fenner * Read the packet header; the structure we use as a buffer 773dc2c7305SBill Fenner * is the longer structure for files generated by the patched 774dc2c7305SBill Fenner * libpcap, but if the file has the magic number for an 775dc2c7305SBill Fenner * unpatched libpcap we only read as many bytes as the regular 776dc2c7305SBill Fenner * header has. 777dc2c7305SBill Fenner */ 778feb4ecdbSBruce M Simpson amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp); 779feb4ecdbSBruce M Simpson if (amt_read != p->sf.hdrsize) { 780feb4ecdbSBruce M Simpson if (ferror(fp)) { 781feb4ecdbSBruce M Simpson snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 782feb4ecdbSBruce M Simpson "error reading dump file: %s", 783feb4ecdbSBruce M Simpson pcap_strerror(errno)); 784feb4ecdbSBruce M Simpson return (-1); 785feb4ecdbSBruce M Simpson } else { 786feb4ecdbSBruce M Simpson if (amt_read != 0) { 787feb4ecdbSBruce M Simpson snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 788feb4ecdbSBruce M Simpson "truncated dump file; tried to read %d header bytes, only got %lu", 789feb4ecdbSBruce M Simpson p->sf.hdrsize, (unsigned long)amt_read); 790feb4ecdbSBruce M Simpson return (-1); 791feb4ecdbSBruce M Simpson } 792feb4ecdbSBruce M Simpson /* EOF */ 7938cf6c252SPaul Traina return (1); 7948cf6c252SPaul Traina } 795feb4ecdbSBruce M Simpson } 7968cf6c252SPaul Traina 7978cf6c252SPaul Traina if (p->sf.swapped) { 7988cf6c252SPaul Traina /* these were written in opposite byte order */ 7998751327cSBill Fenner hdr->caplen = SWAPLONG(sf_hdr.caplen); 8008751327cSBill Fenner hdr->len = SWAPLONG(sf_hdr.len); 8018751327cSBill Fenner hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); 8028751327cSBill Fenner hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); 8038751327cSBill Fenner } else { 8048751327cSBill Fenner hdr->caplen = sf_hdr.caplen; 8058751327cSBill Fenner hdr->len = sf_hdr.len; 8068751327cSBill Fenner hdr->ts.tv_sec = sf_hdr.ts.tv_sec; 8078751327cSBill Fenner hdr->ts.tv_usec = sf_hdr.ts.tv_usec; 8088cf6c252SPaul Traina } 809feb4ecdbSBruce M Simpson /* Swap the caplen and len fields, if necessary. */ 810feb4ecdbSBruce M Simpson switch (p->sf.lengths_swapped) { 811feb4ecdbSBruce M Simpson 812feb4ecdbSBruce M Simpson case NOT_SWAPPED: 813feb4ecdbSBruce M Simpson break; 814feb4ecdbSBruce M Simpson 815feb4ecdbSBruce M Simpson case MAYBE_SWAPPED: 816feb4ecdbSBruce M Simpson if (hdr->caplen <= hdr->len) { 8178cf6c252SPaul Traina /* 818feb4ecdbSBruce M Simpson * The captured length is <= the actual length, 819feb4ecdbSBruce M Simpson * so presumably they weren't swapped. 8208cf6c252SPaul Traina */ 821feb4ecdbSBruce M Simpson break; 822feb4ecdbSBruce M Simpson } 823feb4ecdbSBruce M Simpson /* FALLTHROUGH */ 824feb4ecdbSBruce M Simpson 825feb4ecdbSBruce M Simpson case SWAPPED: 826feb4ecdbSBruce M Simpson t = hdr->caplen; 8278cf6c252SPaul Traina hdr->caplen = hdr->len; 8288cf6c252SPaul Traina hdr->len = t; 829feb4ecdbSBruce M Simpson break; 8308cf6c252SPaul Traina } 8318cf6c252SPaul Traina 8328cf6c252SPaul Traina if (hdr->caplen > buflen) { 8338cf6c252SPaul Traina /* 8348cf6c252SPaul Traina * This can happen due to Solaris 2.3 systems tripping 8358cf6c252SPaul Traina * over the BUFMOD problem and not setting the snapshot 8368cf6c252SPaul Traina * correctly in the savefile header. If the caplen isn't 8378cf6c252SPaul Traina * grossly wrong, try to salvage. 8388cf6c252SPaul Traina */ 8398cf6c252SPaul Traina static u_char *tp = NULL; 840feb4ecdbSBruce M Simpson static size_t tsize = 0; 8418cf6c252SPaul Traina 8423052b236SBill Fenner if (hdr->caplen > 65535) { 843dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 844dc2c7305SBill Fenner "bogus savefile header"); 8453052b236SBill Fenner return (-1); 8463052b236SBill Fenner } 847dc2c7305SBill Fenner 8488cf6c252SPaul Traina if (tsize < hdr->caplen) { 8498cf6c252SPaul Traina tsize = ((hdr->caplen + 1023) / 1024) * 1024; 8508cf6c252SPaul Traina if (tp != NULL) 8518cf6c252SPaul Traina free((u_char *)tp); 8528cf6c252SPaul Traina tp = (u_char *)malloc(tsize); 8538cf6c252SPaul Traina if (tp == NULL) { 8543052b236SBill Fenner tsize = 0; 855dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 856dc2c7305SBill Fenner "BUFMOD hack malloc"); 8578cf6c252SPaul Traina return (-1); 8588cf6c252SPaul Traina } 8598cf6c252SPaul Traina } 860feb4ecdbSBruce M Simpson amt_read = fread((char *)tp, 1, hdr->caplen, fp); 861feb4ecdbSBruce M Simpson if (amt_read != hdr->caplen) { 862feb4ecdbSBruce M Simpson if (ferror(fp)) { 863dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 864feb4ecdbSBruce M Simpson "error reading dump file: %s", 865feb4ecdbSBruce M Simpson pcap_strerror(errno)); 866feb4ecdbSBruce M Simpson } else { 867feb4ecdbSBruce M Simpson snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 868feb4ecdbSBruce M Simpson "truncated dump file; tried to read %u captured bytes, only got %lu", 869feb4ecdbSBruce M Simpson hdr->caplen, (unsigned long)amt_read); 870feb4ecdbSBruce M Simpson } 8718cf6c252SPaul Traina return (-1); 8728cf6c252SPaul Traina } 8733052b236SBill Fenner /* 8743052b236SBill Fenner * We can only keep up to buflen bytes. Since caplen > buflen 8753052b236SBill Fenner * is exactly how we got here, we know we can only keep the 8763052b236SBill Fenner * first buflen bytes and must drop the remainder. Adjust 8773052b236SBill Fenner * caplen accordingly, so we don't get confused later as 8783052b236SBill Fenner * to how many bytes we have to play with. 8793052b236SBill Fenner */ 8803052b236SBill Fenner hdr->caplen = buflen; 8818cf6c252SPaul Traina memcpy((char *)buf, (char *)tp, buflen); 8828cf6c252SPaul Traina 8838cf6c252SPaul Traina } else { 8848cf6c252SPaul Traina /* read the packet itself */ 885feb4ecdbSBruce M Simpson amt_read = fread((char *)buf, 1, hdr->caplen, fp); 886feb4ecdbSBruce M Simpson if (amt_read != hdr->caplen) { 887feb4ecdbSBruce M Simpson if (ferror(fp)) { 888dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 889feb4ecdbSBruce M Simpson "error reading dump file: %s", 890feb4ecdbSBruce M Simpson pcap_strerror(errno)); 891feb4ecdbSBruce M Simpson } else { 892feb4ecdbSBruce M Simpson snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 893feb4ecdbSBruce M Simpson "truncated dump file; tried to read %u captured bytes, only got %lu", 894feb4ecdbSBruce M Simpson hdr->caplen, (unsigned long)amt_read); 895feb4ecdbSBruce M Simpson } 8968cf6c252SPaul Traina return (-1); 8978cf6c252SPaul Traina } 8988cf6c252SPaul Traina } 8998cf6c252SPaul Traina return (0); 9008cf6c252SPaul Traina } 9018cf6c252SPaul Traina 9028cf6c252SPaul Traina /* 9038cf6c252SPaul Traina * Print out packets stored in the file initialized by sf_read_init(). 9048cf6c252SPaul Traina * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. 9058cf6c252SPaul Traina */ 9068cf6c252SPaul Traina int 9078cf6c252SPaul Traina pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 9088cf6c252SPaul Traina { 9098cf6c252SPaul Traina struct bpf_insn *fcode = p->fcode.bf_insns; 9108cf6c252SPaul Traina int status = 0; 9118cf6c252SPaul Traina int n = 0; 9128cf6c252SPaul Traina 9138cf6c252SPaul Traina while (status == 0) { 9148cf6c252SPaul Traina struct pcap_pkthdr h; 9158cf6c252SPaul Traina 916feb4ecdbSBruce M Simpson /* 917feb4ecdbSBruce M Simpson * Has "pcap_breakloop()" been called? 918feb4ecdbSBruce M Simpson * If so, return immediately - if we haven't read any 919feb4ecdbSBruce M Simpson * packets, clear the flag and return -2 to indicate 920feb4ecdbSBruce M Simpson * that we were told to break out of the loop, otherwise 921feb4ecdbSBruce M Simpson * leave the flag set, so that the *next* call will break 922feb4ecdbSBruce M Simpson * out of the loop without having read any packets, and 923feb4ecdbSBruce M Simpson * return the number of packets we've processed so far. 924feb4ecdbSBruce M Simpson */ 925feb4ecdbSBruce M Simpson if (p->break_loop) { 926feb4ecdbSBruce M Simpson if (n == 0) { 927feb4ecdbSBruce M Simpson p->break_loop = 0; 928feb4ecdbSBruce M Simpson return (-2); 929feb4ecdbSBruce M Simpson } else 930feb4ecdbSBruce M Simpson return (n); 931feb4ecdbSBruce M Simpson } 932feb4ecdbSBruce M Simpson 9338cf6c252SPaul Traina status = sf_next_packet(p, &h, p->buffer, p->bufsize); 9348cf6c252SPaul Traina if (status) { 9358cf6c252SPaul Traina if (status == 1) 9368cf6c252SPaul Traina return (0); 9378cf6c252SPaul Traina return (status); 9388cf6c252SPaul Traina } 9398cf6c252SPaul Traina 9408cf6c252SPaul Traina if (fcode == NULL || 9418cf6c252SPaul Traina bpf_filter(fcode, p->buffer, h.len, h.caplen)) { 9428cf6c252SPaul Traina (*callback)(user, &h, p->buffer); 9438cf6c252SPaul Traina if (++n >= cnt && cnt > 0) 9448cf6c252SPaul Traina break; 9458cf6c252SPaul Traina } 9468cf6c252SPaul Traina } 9478cf6c252SPaul Traina /*XXX this breaks semantics tcpslice expects */ 9488cf6c252SPaul Traina return (n); 9498cf6c252SPaul Traina } 9508cf6c252SPaul Traina 9518cf6c252SPaul Traina /* 9528cf6c252SPaul Traina * Output a packet to the initialized dump file. 9538cf6c252SPaul Traina */ 9548cf6c252SPaul Traina void 9558cf6c252SPaul Traina pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 9568cf6c252SPaul Traina { 9578cf6c252SPaul Traina register FILE *f; 9588751327cSBill Fenner struct pcap_sf_pkthdr sf_hdr; 9598cf6c252SPaul Traina 9608cf6c252SPaul Traina f = (FILE *)user; 9618751327cSBill Fenner sf_hdr.ts.tv_sec = h->ts.tv_sec; 9628751327cSBill Fenner sf_hdr.ts.tv_usec = h->ts.tv_usec; 9638751327cSBill Fenner sf_hdr.caplen = h->caplen; 9648751327cSBill Fenner sf_hdr.len = h->len; 9658cf6c252SPaul Traina /* XXX we should check the return status */ 9668751327cSBill Fenner (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); 9678cf6c252SPaul Traina (void)fwrite((char *)sp, h->caplen, 1, f); 9688cf6c252SPaul Traina } 9698cf6c252SPaul Traina 9708cf6c252SPaul Traina /* 9718cf6c252SPaul Traina * Initialize so that sf_write() will output to the file named 'fname'. 9728cf6c252SPaul Traina */ 9738cf6c252SPaul Traina pcap_dumper_t * 974a4b5b39fSBill Fenner pcap_dump_open(pcap_t *p, const char *fname) 9758cf6c252SPaul Traina { 9768cf6c252SPaul Traina FILE *f; 977dc2c7305SBill Fenner int linktype; 978dc2c7305SBill Fenner 979dc2c7305SBill Fenner linktype = dlt_to_linktype(p->linktype); 980dc2c7305SBill Fenner if (linktype == -1) { 981dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 982dc2c7305SBill Fenner "%s: link-layer type %d isn't supported in savefiles", 983dc2c7305SBill Fenner fname, linktype); 984dc2c7305SBill Fenner return (NULL); 985dc2c7305SBill Fenner } 986dc2c7305SBill Fenner 987feb4ecdbSBruce M Simpson if (fname[0] == '-' && fname[1] == '\0') { 9888cf6c252SPaul Traina f = stdout; 989feb4ecdbSBruce M Simpson #ifdef WIN32 990feb4ecdbSBruce M Simpson _setmode(_fileno(f), _O_BINARY); 991feb4ecdbSBruce M Simpson #endif 992feb4ecdbSBruce M Simpson } else { 993feb4ecdbSBruce M Simpson #ifndef WIN32 9948cf6c252SPaul Traina f = fopen(fname, "w"); 995feb4ecdbSBruce M Simpson #else 996feb4ecdbSBruce M Simpson f = fopen(fname, "wb"); 997feb4ecdbSBruce M Simpson setbuf(f, NULL); /* XXX - why? */ 998feb4ecdbSBruce M Simpson #endif 9998cf6c252SPaul Traina if (f == NULL) { 1000dc2c7305SBill Fenner snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", 10018cf6c252SPaul Traina fname, pcap_strerror(errno)); 10028cf6c252SPaul Traina return (NULL); 10038cf6c252SPaul Traina } 10048cf6c252SPaul Traina } 1005dc2c7305SBill Fenner (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); 10068cf6c252SPaul Traina return ((pcap_dumper_t *)f); 10078cf6c252SPaul Traina } 10088cf6c252SPaul Traina 1009feb4ecdbSBruce M Simpson FILE * 1010feb4ecdbSBruce M Simpson pcap_dump_file(pcap_dumper_t *p) 1011feb4ecdbSBruce M Simpson { 1012feb4ecdbSBruce M Simpson return ((FILE *)p); 1013feb4ecdbSBruce M Simpson } 1014feb4ecdbSBruce M Simpson 1015feb4ecdbSBruce M Simpson int 1016feb4ecdbSBruce M Simpson pcap_dump_flush(pcap_dumper_t *p) 1017feb4ecdbSBruce M Simpson { 1018feb4ecdbSBruce M Simpson 1019feb4ecdbSBruce M Simpson if (fflush((FILE *)p) == EOF) 1020feb4ecdbSBruce M Simpson return (-1); 1021feb4ecdbSBruce M Simpson else 1022feb4ecdbSBruce M Simpson return (0); 1023feb4ecdbSBruce M Simpson } 1024feb4ecdbSBruce M Simpson 10258cf6c252SPaul Traina void 10268cf6c252SPaul Traina pcap_dump_close(pcap_dumper_t *p) 10278cf6c252SPaul Traina { 10288cf6c252SPaul Traina 10298cf6c252SPaul Traina #ifdef notyet 10308cf6c252SPaul Traina if (ferror((FILE *)p)) 10318cf6c252SPaul Traina return-an-error; 10328cf6c252SPaul Traina /* XXX should check return from fclose() too */ 10338cf6c252SPaul Traina #endif 10348cf6c252SPaul Traina (void)fclose((FILE *)p); 10358cf6c252SPaul Traina } 1036