Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

savefile.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1993, 1994, 1995, 1996, 1997
00003  *  The Regents of the University of California.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that: (1) source code distributions
00007  * retain the above copyright notice and this paragraph in its entirety, (2)
00008  * distributions including binary code include the above copyright notice and
00009  * this paragraph in its entirety in the documentation or other materials
00010  * provided with the distribution, and (3) all advertising materials mentioning
00011  * features or use of this software display the following acknowledgement:
00012  * ``This product includes software developed by the University of California,
00013  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
00014  * the University nor the names of its contributors may be used to endorse
00015  * or promote products derived from this software without specific prior
00016  * written permission.
00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00020  *
00021  * savefile.c - supports offline use of tcpdump
00022  *  Extraction/creation by Jeffrey Mogul, DECWRL
00023  *  Modified by Steve McCanne, LBL.
00024  *
00025  * Used to save the received packet headers, after filtering, to
00026  * a file, and then read them later.
00027  * The first record in the file contains saved values for the machine
00028  * dependent values so we can print the dump file on any architecture.
00029  */
00030 
00031 #ifndef lint
00032 static const char rcsid[] _U_ =
00033     "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.100 2003/12/21 21:58:50 guy Exp $ (LBL)";
00034 #endif
00035 
00036 #ifdef HAVE_CONFIG_H
00037 #include "config.h"
00038 #endif
00039 
00040 #include <errno.h>
00041 #include <memory.h>
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 
00046 #include "pcap-int.h"
00047 
00048 #ifdef HAVE_OS_PROTO_H
00049 #include "os-proto.h"
00050 #endif
00051 
00052 #define TCPDUMP_MAGIC 0xa1b2c3d4
00053 #define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
00054 
00055 /*
00056  * We use the "receiver-makes-right" approach to byte order,
00057  * because time is at a premium when we are writing the file.
00058  * In other words, the pcap_file_header and pcap_pkthdr,
00059  * records are written in host byte order.
00060  * Note that the bytes of packet data are written out in the order in
00061  * which they were received, so multi-byte fields in packets are not
00062  * written in host byte order, they're written in whatever order the
00063  * sending machine put them in.
00064  *
00065  * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
00066  * machine (if the file was written in little-end order).
00067  */
00068 #define SWAPLONG(y) \
00069 ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
00070 #define SWAPSHORT(y) \
00071     ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
00072 
00073 #define SFERR_TRUNC     1
00074 #define SFERR_BADVERSION    2
00075 #define SFERR_BADF      3
00076 #define SFERR_EOF       4 /* not really an error, just a status */
00077 
00078 /*
00079  * We don't write DLT_* values to the capture file header, because
00080  * they're not the same on all platforms.
00081  *
00082  * Unfortunately, the various flavors of BSD have not always used the same
00083  * numerical values for the same data types, and various patches to
00084  * libpcap for non-BSD OSes have added their own DLT_* codes for link
00085  * layer encapsulation types seen on those OSes, and those codes have had,
00086  * in some cases, values that were also used, on other platforms, for other
00087  * link layer encapsulation types.
00088  *
00089  * This means that capture files of a type whose numerical DLT_* code
00090  * means different things on different BSDs, or with different versions
00091  * of libpcap, can't always be read on systems other than those like
00092  * the one running on the machine on which the capture was made.
00093  *
00094  * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
00095  * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
00096  * codes to DLT_* codes when reading a savefile header.
00097  *
00098  * For those DLT_* codes that have, as far as we know, the same values on
00099  * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
00100  * DLT_xxx; that way, captures of those types can still be read by
00101  * versions of libpcap that map LINKTYPE_* values to DLT_* values, and
00102  * captures of those types written by versions of libpcap that map DLT_
00103  * values to LINKTYPE_ values can still be read by older versions
00104  * of libpcap.
00105  *
00106  * The other LINKTYPE_* codes are given values starting at 100, in the
00107  * hopes that no DLT_* code will be given one of those values.
00108  *
00109  * In order to ensure that a given LINKTYPE_* code's value will refer to
00110  * the same encapsulation type on all platforms, you should not allocate
00111  * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org".
00112  * The tcpdump developers will allocate a value for you, and will not
00113  * subsequently allocate it to anybody else; that value will be added to
00114  * the "pcap.h" in the tcpdump.org CVS repository, so that a future
00115  * libpcap release will include it.
00116  *
00117  * You should, if possible, also contribute patches to libpcap and tcpdump
00118  * to handle the new encapsulation type, so that they can also be checked
00119  * into the tcpdump.org CVS repository and so that they will appear in
00120  * future libpcap and tcpdump releases.
00121  */
00122 #define LINKTYPE_NULL       DLT_NULL
00123 #define LINKTYPE_ETHERNET   DLT_EN10MB  /* also for 100Mb and up */
00124 #define LINKTYPE_EXP_ETHERNET   DLT_EN3MB   /* 3Mb experimental Ethernet */
00125 #define LINKTYPE_AX25       DLT_AX25
00126 #define LINKTYPE_PRONET     DLT_PRONET
00127 #define LINKTYPE_CHAOS      DLT_CHAOS
00128 #define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
00129 #define LINKTYPE_ARCNET     DLT_ARCNET  /* BSD-style headers */
00130 #define LINKTYPE_SLIP       DLT_SLIP
00131 #define LINKTYPE_PPP        DLT_PPP
00132 #define LINKTYPE_FDDI       DLT_FDDI
00133 
00134 /*
00135  * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
00136  * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
00137  * field) at the beginning of the packet.
00138  *
00139  * This is for use when there is always such a header; the address field
00140  * might be 0xff, for regular PPP, or it might be an address field for Cisco
00141  * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
00142  * HDLC").  This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
00143  *
00144  * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that
00145  * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL
00146  * captures will be written out with a link type that NetBSD's tcpdump
00147  * can read.
00148  */
00149 #define LINKTYPE_PPP_HDLC   50      /* PPP in HDLC-like framing */
00150 
00151 #define LINKTYPE_PPP_ETHER  51      /* NetBSD PPP-over-Ethernet */
00152 
00153 #define LINKTYPE_ATM_RFC1483    100     /* LLC/SNAP-encapsulated ATM */
00154 #define LINKTYPE_RAW        101     /* raw IP */
00155 #define LINKTYPE_SLIP_BSDOS 102     /* BSD/OS SLIP BPF header */
00156 #define LINKTYPE_PPP_BSDOS  103     /* BSD/OS PPP BPF header */
00157 #define LINKTYPE_C_HDLC     104     /* Cisco HDLC */
00158 #define LINKTYPE_IEEE802_11 105     /* IEEE 802.11 (wireless) */
00159 #define LINKTYPE_ATM_CLIP   106     /* Linux Classical IP over ATM */
00160 #define LINKTYPE_FRELAY     107     /* Frame Relay */
00161 #define LINKTYPE_LOOP       108     /* OpenBSD loopback */
00162 #define LINKTYPE_ENC        109     /* OpenBSD IPSEC enc */
00163 
00164 #define LINKTYPE_LINUX_SLL  113     /* Linux cooked socket capture */
00165 #define LINKTYPE_LTALK      114     /* Apple LocalTalk hardware */
00166 #define LINKTYPE_ECONET     115     /* Acorn Econet */
00167 
00168 #define LINKTYPE_PFLOG      117     /* OpenBSD DLT_PFLOG */
00169 #define LINKTYPE_CISCO_IOS  118     /* For Cisco-internal use */
00170 #define LINKTYPE_PRISM_HEADER   119     /* 802.11+Prism II monitor mode */
00171 #define LINKTYPE_AIRONET_HEADER 120     /* FreeBSD Aironet driver stuff */
00172 #define LINKTYPE_IP_OVER_FC 122     /* RFC 2625 IP-over-Fibre Channel */
00173 #define LINKTYPE_SUNATM     123     /* Solaris+SunATM */
00174 
00175 #define LINKTYPE_IEEE802_11_RADIO 127       /* 802.11 plus WLAN header */
00176 
00177 #define LINKTYPE_TZSP       128     /* Tazmen Sniffer Protocol */
00178 
00179 #define LINKTYPE_ARCNET_LINUX   129     /* Linux-style headers */
00180 
00181 #define LINKTYPE_JUNIPER_MLPPP  130     /* Juniper-internal chassis encapsulation */
00182 #define LINKTYPE_JUNIPER_MLFR   131
00183 #define LINKTYPE_JUNIPER_ES     132
00184 #define LINKTYPE_JUNIPER_GGSN   133
00185 #define LINKTYPE_JUNIPER_MFR    134
00186 #define LINKTYPE_JUNIPER_ATM2   135
00187 #define LINKTYPE_JUNIPER_SERVICES 136
00188 #define LINKTYPE_JUNIPER_ATM1   137
00189 
00190 #define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
00191 
00192 #define LINKTYPE_RAWSS7         139             /* see rawss7.h for */
00193 #define LINKTYPE_RAWSS7_MTP2    140         /* information  on these */
00194 #define LINKTYPE_RAWSS7_MTP3    141             /* definitions */
00195 #define LINKTYPE_RAWSS7_SCCP    142
00196 
00197 #define LINKTYPE_DOCSIS     143     /* DOCSIS MAC frames */
00198 
00199 #define LINKTYPE_LINUX_IRDA 144     /* Linux-IrDA */
00200 
00201 /*
00202  * These types are reserved for future use.
00203  */
00204 #define LINKTYPE_LANE8023   110     /* ATM LANE + 802.3 */
00205 #define LINKTYPE_HIPPI      111     /* NetBSD HIPPI */
00206 #define LINKTYPE_HDLC       112     /* NetBSD HDLC framing */
00207 #define LINKTYPE_IPFILTER   116     /* IP Filter capture files */
00208 #define LINKTYPE_HHDLC      121     /* Siemens HiPath HDLC */
00209 #define LINKTYPE_RIO        124     /* RapidIO */
00210 #define LINKTYPE_PCI_EXP    125     /* PCI Express */
00211 #define LINKTYPE_AURORA     126     /* Xilinx Aurora link layer */
00212 #define LINKTYPE_IBM_SP     145     /* IBM SP switch */
00213 #define LINKTYPE_IBM_SN     146     /* IBM Next Federation switch */
00214 
00215 static struct linktype_map {
00216     int dlt;
00217     int linktype;
00218 } map[] = {
00219     /*
00220      * These DLT_* codes have LINKTYPE_* codes with values identical
00221      * to the values of the corresponding DLT_* code.
00222      */
00223     { DLT_NULL,     LINKTYPE_NULL },
00224     { DLT_EN10MB,       LINKTYPE_ETHERNET },
00225     { DLT_EN3MB,        LINKTYPE_EXP_ETHERNET },
00226     { DLT_AX25,     LINKTYPE_AX25 },
00227     { DLT_PRONET,       LINKTYPE_PRONET },
00228     { DLT_CHAOS,        LINKTYPE_CHAOS },
00229     { DLT_IEEE802,      LINKTYPE_TOKEN_RING },
00230     { DLT_ARCNET,       LINKTYPE_ARCNET },
00231     { DLT_SLIP,     LINKTYPE_SLIP },
00232     { DLT_PPP,      LINKTYPE_PPP },
00233     { DLT_FDDI,     LINKTYPE_FDDI },
00234 
00235     /*
00236      * These DLT_* codes have different values on different
00237      * platforms; we map them to LINKTYPE_* codes that
00238      * have values that should never be equal to any DLT_*
00239      * code.
00240      */
00241 #ifdef DLT_FR
00242     /* BSD/OS Frame Relay */
00243     { DLT_FR,       LINKTYPE_FRELAY },
00244 #endif
00245     { DLT_ATM_RFC1483,  LINKTYPE_ATM_RFC1483 },
00246     { DLT_RAW,      LINKTYPE_RAW },
00247     { DLT_SLIP_BSDOS,   LINKTYPE_SLIP_BSDOS },
00248     { DLT_PPP_BSDOS,    LINKTYPE_PPP_BSDOS },
00249 
00250     /* BSD/OS Cisco HDLC */
00251     { DLT_C_HDLC,       LINKTYPE_C_HDLC },
00252 
00253     /*
00254      * These DLT_* codes are not on all platforms, but, so far,
00255      * there don't appear to be any platforms that define
00256      * other codes with those values; we map them to
00257      * different LINKTYPE_* values anyway, just in case.
00258      */
00259 
00260     /* Linux ATM Classical IP */
00261     { DLT_ATM_CLIP,     LINKTYPE_ATM_CLIP },
00262 
00263     /* NetBSD sync/async serial PPP (or Cisco HDLC) */
00264     { DLT_PPP_SERIAL,   LINKTYPE_PPP_HDLC },
00265 
00266     /* NetBSD PPP over Ethernet */
00267     { DLT_PPP_ETHER,    LINKTYPE_PPP_ETHER },
00268 
00269     /* IEEE 802.11 wireless */
00270     { DLT_IEEE802_11,   LINKTYPE_IEEE802_11 },
00271 
00272     /* Frame Relay */
00273     { DLT_FRELAY,       LINKTYPE_FRELAY },
00274 
00275     /* OpenBSD loopback */
00276     { DLT_LOOP,     LINKTYPE_LOOP },
00277 
00278     /* Linux cooked socket capture */
00279     { DLT_LINUX_SLL,    LINKTYPE_LINUX_SLL },
00280 
00281     /* Apple LocalTalk hardware */
00282     { DLT_LTALK,        LINKTYPE_LTALK },
00283 
00284     /* Acorn Econet */
00285     { DLT_ECONET,       LINKTYPE_ECONET },
00286 
00287     /* OpenBSD DLT_PFLOG */
00288     { DLT_PFLOG,        LINKTYPE_PFLOG },
00289 
00290     /* For Cisco-internal use */
00291     { DLT_CISCO_IOS,    LINKTYPE_CISCO_IOS },
00292 
00293     /* Prism II monitor-mode header plus 802.11 header */
00294     { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER },
00295 
00296     /* FreeBSD Aironet driver stuff */
00297     { DLT_AIRONET_HEADER,   LINKTYPE_AIRONET_HEADER },
00298 
00299     /* Siemens HiPath HDLC */
00300     { DLT_HHDLC,        LINKTYPE_HHDLC },
00301 
00302     /* RFC 2625 IP-over-Fibre Channel */
00303     { DLT_IP_OVER_FC,   LINKTYPE_IP_OVER_FC },
00304 
00305     /* Solaris+SunATM */
00306     { DLT_SUNATM,       LINKTYPE_SUNATM },
00307 
00308     /* RapidIO */
00309     { DLT_RIO,      LINKTYPE_RIO },
00310 
00311     /* PCI Express */
00312     { DLT_PCI_EXP,      LINKTYPE_PCI_EXP },
00313 
00314     /* Xilinx Aurora link layer */
00315     { DLT_AURORA,       LINKTYPE_AURORA },
00316 
00317     /* 802.11 plus WLAN header */
00318     { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO },
00319 
00320     /* Tazmen Sniffer Protocol */
00321     { DLT_TZSP,     LINKTYPE_TZSP },
00322 
00323     /* Arcnet with Linux-style link-layer headers */
00324     { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX },
00325 
00326         /* Juniper-internal chassis encapsulation */
00327         { DLT_JUNIPER_MLPPP,    LINKTYPE_JUNIPER_MLPPP },
00328         { DLT_JUNIPER_MLFR,     LINKTYPE_JUNIPER_MLFR },
00329         { DLT_JUNIPER_ES,       LINKTYPE_JUNIPER_ES },
00330         { DLT_JUNIPER_GGSN,     LINKTYPE_JUNIPER_GGSN },
00331         { DLT_JUNIPER_MFR,      LINKTYPE_JUNIPER_MFR },
00332         { DLT_JUNIPER_ATM2,     LINKTYPE_JUNIPER_ATM2 },
00333         { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
00334         { DLT_JUNIPER_ATM1,     LINKTYPE_JUNIPER_ATM1 },
00335 
00336     /* Apple IP-over-IEEE 1394 cooked header */
00337     { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
00338 
00339     /* DOCSIS MAC frames */
00340     { DLT_DOCSIS,       LINKTYPE_DOCSIS },
00341 
00342     /* IrDA IrLAP packets + Linux-cooked header */
00343     { DLT_LINUX_IRDA,   LINKTYPE_LINUX_IRDA },
00344 
00345     /* IBM SP and Next Federation switches */
00346     { DLT_IBM_SP,       LINKTYPE_IBM_SP },
00347     { DLT_IBM_SN,       LINKTYPE_IBM_SN },
00348 
00349     /*
00350      * Any platform that defines additional DLT_* codes should:
00351      *
00352      *  request a LINKTYPE_* code and value from tcpdump.org,
00353      *  as per the above;
00354      *
00355      *  add, in their version of libpcap, an entry to map
00356      *  those DLT_* codes to the corresponding LINKTYPE_*
00357      *  code;
00358      *
00359      *  redefine, in their "net/bpf.h", any DLT_* values
00360      *  that collide with the values used by their additional
00361      *  DLT_* codes, to remove those collisions (but without
00362      *  making them collide with any of the LINKTYPE_*
00363      *  values equal to 50 or above; they should also avoid
00364      *  defining DLT_* values that collide with those
00365      *  LINKTYPE_* values, either).
00366      */
00367     { -1,           -1 }
00368 };
00369 
00370 static int
00371 dlt_to_linktype(int dlt)
00372 {
00373     int i;
00374 
00375     for (i = 0; map[i].dlt != -1; i++) {
00376         if (map[i].dlt == dlt)
00377             return (map[i].linktype);
00378     }
00379 
00380     /*
00381      * If we don't have a mapping for this DLT_ code, return an
00382      * error; that means that the table above needs to have an
00383      * entry added.
00384      */
00385     return (-1);
00386 }
00387 
00388 static int
00389 linktype_to_dlt(int linktype)
00390 {
00391     int i;
00392 
00393     for (i = 0; map[i].linktype != -1; i++) {
00394         if (map[i].linktype == linktype)
00395             return (map[i].dlt);
00396     }
00397 
00398     /*
00399      * If we don't have an entry for this link type, return
00400      * the link type value; it may be a DLT_ value from an
00401      * older version of libpcap.
00402      */
00403     return linktype;
00404 }
00405 
00406 static int
00407 sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
00408 {
00409     struct pcap_file_header hdr;
00410 
00411     hdr.magic = TCPDUMP_MAGIC;
00412     hdr.version_major = PCAP_VERSION_MAJOR;
00413     hdr.version_minor = PCAP_VERSION_MINOR;
00414 
00415     hdr.thiszone = thiszone;
00416     hdr.snaplen = snaplen;
00417     hdr.sigfigs = 0;
00418     hdr.linktype = linktype;
00419 
00420     if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
00421         return (-1);
00422 
00423     return (0);
00424 }
00425 
00426 static void
00427 swap_hdr(struct pcap_file_header *hp)
00428 {
00429     hp->version_major = SWAPSHORT(hp->version_major);
00430     hp->version_minor = SWAPSHORT(hp->version_minor);
00431     hp->thiszone = SWAPLONG(hp->thiszone);
00432     hp->sigfigs = SWAPLONG(hp->sigfigs);
00433     hp->snaplen = SWAPLONG(hp->snaplen);
00434     hp->linktype = SWAPLONG(hp->linktype);
00435 }
00436 
00437 static int
00438 sf_getnonblock(pcap_t *p, char *errbuf)
00439 {
00440     /*
00441      * This is a savefile, not a live capture file, so never say
00442      * it's in non-blocking mode.
00443      */
00444     return (0);
00445 }
00446 
00447 static int
00448 sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
00449 {
00450     /*
00451      * This is a savefile, not a live capture file, so ignore
00452      * requests to put it in non-blocking mode.
00453      */
00454     return (0);
00455 }
00456 
00457 static int
00458 sf_stats(pcap_t *p, struct pcap_stat *ps)
00459 {
00460     snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00461         "Statistics aren't available from savefiles");
00462     return (-1);
00463 }
00464 
00465 static void
00466 sf_close(pcap_t *p)
00467 {
00468     if (p->sf.rfile != stdin)
00469         (void)fclose(p->sf.rfile);
00470     if (p->sf.base != NULL)
00471         free(p->sf.base);
00472 }
00473 
00474 pcap_t *
00475 pcap_open_offline(const char *fname, char *errbuf)
00476 {
00477     register pcap_t *p;
00478     register FILE *fp;
00479     struct pcap_file_header hdr;
00480     bpf_u_int32 magic;
00481     int linklen;
00482 
00483     p = (pcap_t *)malloc(sizeof(*p));
00484     if (p == NULL) {
00485         strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
00486         return (NULL);
00487     }
00488 
00489     memset((char *)p, 0, sizeof(*p));
00490 
00491     if (fname[0] == '-' && fname[1] == '\0')
00492         fp = stdin;
00493     else {
00494 #ifndef WIN32
00495         fp = fopen(fname, "r");
00496 #else
00497         fp = fopen(fname, "rb");
00498 #endif
00499         if (fp == NULL) {
00500             snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
00501                 pcap_strerror(errno));
00502             goto bad;
00503         }
00504     }
00505     if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
00506         snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
00507             pcap_strerror(errno));
00508         goto bad;
00509     }
00510     magic = hdr.magic;
00511     if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
00512         magic = SWAPLONG(magic);
00513         if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
00514             snprintf(errbuf, PCAP_ERRBUF_SIZE,
00515                 "bad dump file format");
00516             goto bad;
00517         }
00518         p->sf.swapped = 1;
00519         swap_hdr(&hdr);
00520     }
00521     if (magic == PATCHED_TCPDUMP_MAGIC) {
00522         /*
00523          * XXX - the patch that's in some versions of libpcap
00524          * changes the packet header but not the magic number;
00525          * we'd have to use some hacks^H^H^H^H^Hheuristics to
00526          * detect that.
00527          */
00528         p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
00529     } else
00530         p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
00531     if (hdr.version_major < PCAP_VERSION_MAJOR) {
00532         snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
00533         goto bad;
00534     }
00535     p->tzoff = hdr.thiszone;
00536     p->snapshot = hdr.snaplen;
00537     p->linktype = linktype_to_dlt(hdr.linktype);
00538     p->sf.rfile = fp;
00539 #ifndef WIN32
00540     p->bufsize = hdr.snaplen;
00541 #else
00542     /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
00543     p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
00544 #endif
00545 
00546     /* Align link header as required for proper data alignment */
00547     /* XXX should handle all types */
00548     switch (p->linktype) {
00549 
00550     case DLT_EN10MB:
00551         linklen = 14;
00552         break;
00553 
00554     case DLT_FDDI:
00555         linklen = 13 + 8;   /* fddi_header + llc */
00556         break;
00557 
00558     case DLT_NULL:
00559     default:
00560         linklen = 0;
00561         break;
00562     }
00563 
00564     if (p->bufsize < 0)
00565         p->bufsize = BPF_MAXBUFSIZE;
00566     p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
00567     if (p->sf.base == NULL) {
00568         strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE);
00569         goto bad;
00570     }
00571     p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
00572     p->sf.version_major = hdr.version_major;
00573     p->sf.version_minor = hdr.version_minor;
00574 #ifdef PCAP_FDDIPAD
00575     /* XXX padding only needed for kernel fcode */
00576     pcap_fddipad = 0;
00577 #endif
00578 
00579     /*
00580      * We interchanged the caplen and len fields at version 2.3,
00581      * in order to match the bpf header layout.  But unfortunately
00582      * some files were written with version 2.3 in their headers
00583      * but without the interchanged fields.
00584      *
00585      * In addition, DG/UX tcpdump writes out files with a version
00586      * number of 543.0, and with the caplen and len fields in the
00587      * pre-2.3 order.
00588      */
00589     switch (hdr.version_major) {
00590 
00591     case 2:
00592         if (hdr.version_minor < 3)
00593             p->sf.lengths_swapped = SWAPPED;
00594         else if (hdr.version_minor == 3)
00595             p->sf.lengths_swapped = MAYBE_SWAPPED;
00596         else
00597             p->sf.lengths_swapped = NOT_SWAPPED;
00598         break;
00599 
00600     case 543:
00601         p->sf.lengths_swapped = SWAPPED;
00602         break;
00603 
00604     default:
00605         p->sf.lengths_swapped = NOT_SWAPPED;
00606         break;
00607     }
00608 
00609 #ifndef WIN32
00610     /*
00611      * You can do "select()" and "poll()" on plain files on most
00612      * platforms, and should be able to do so on pipes.
00613      *
00614      * You can't do "select()" on anything other than sockets in
00615      * Windows, so, on Win32 systems, we don't have "selectable_fd".
00616      */
00617     p->selectable_fd = fileno(fp);
00618 #endif
00619 
00620     p->read_op = pcap_offline_read;
00621     p->setfilter_op = install_bpf_program;
00622     p->set_datalink_op = NULL;  /* we don't support munging link-layer headers */
00623     p->getnonblock_op = sf_getnonblock;
00624     p->setnonblock_op = sf_setnonblock;
00625     p->stats_op = sf_stats;
00626     p->close_op = sf_close;
00627 
00628     return (p);
00629  bad:
00630     if(fp)
00631         fclose(fp);
00632     free(p);
00633     return (NULL);
00634 }
00635 
00636 /*
00637  * Read sf_readfile and return the next packet.  Return the header in hdr
00638  * and the contents in buf.  Return 0 on success, SFERR_EOF if there were
00639  * no more packets, and SFERR_TRUNC if a partial packet was encountered.
00640  */
00641 static int
00642 sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
00643 {
00644     struct pcap_sf_patched_pkthdr sf_hdr;
00645     FILE *fp = p->sf.rfile;
00646     size_t amt_read;
00647     bpf_u_int32 t;
00648 
00649     /*
00650      * Read the packet header; the structure we use as a buffer
00651      * is the longer structure for files generated by the patched
00652      * libpcap, but if the file has the magic number for an
00653      * unpatched libpcap we only read as many bytes as the regular
00654      * header has.
00655      */
00656     amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
00657     if (amt_read != p->sf.hdrsize) {
00658         if (ferror(fp)) {
00659             snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00660                 "error reading dump file: %s",
00661                 pcap_strerror(errno));
00662             return (-1);
00663         } else {
00664             if (amt_read != 0) {
00665                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00666                     "truncated dump file; tried to read %d header bytes, only got %lu",
00667                     p->sf.hdrsize, (unsigned long)amt_read);
00668                 return (-1);
00669             }
00670             /* EOF */
00671             return (1);
00672         }
00673     }
00674 
00675     if (p->sf.swapped) {
00676         /* these were written in opposite byte order */
00677         hdr->caplen = SWAPLONG(sf_hdr.caplen);
00678         hdr->len = SWAPLONG(sf_hdr.len);
00679         hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
00680         hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
00681     } else {
00682         hdr->caplen = sf_hdr.caplen;
00683         hdr->len = sf_hdr.len;
00684         hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
00685         hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
00686     }
00687     /* Swap the caplen and len fields, if necessary. */
00688     switch (p->sf.lengths_swapped) {
00689 
00690     case NOT_SWAPPED:
00691         break;
00692 
00693     case MAYBE_SWAPPED:
00694         if (hdr->caplen <= hdr->len) {
00695             /*
00696              * The captured length is <= the actual length,
00697              * so presumably they weren't swapped.
00698              */
00699             break;
00700         }
00701         /* FALLTHROUGH */
00702 
00703     case SWAPPED:
00704         t = hdr->caplen;
00705         hdr->caplen = hdr->len;
00706         hdr->len = t;
00707         break;
00708     }
00709 
00710     if (hdr->caplen > buflen) {
00711         /*
00712          * This can happen due to Solaris 2.3 systems tripping
00713          * over the BUFMOD problem and not setting the snapshot
00714          * correctly in the savefile header.  If the caplen isn't
00715          * grossly wrong, try to salvage.
00716          */
00717         static u_char *tp = NULL;
00718         static size_t tsize = 0;
00719 
00720         if (hdr->caplen > 65535) {
00721             snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00722                 "bogus savefile header");
00723             return (-1);
00724         }
00725 
00726         if (tsize < hdr->caplen) {
00727             tsize = ((hdr->caplen + 1023) / 1024) * 1024;
00728             if (tp != NULL)
00729                 free((u_char *)tp);
00730             tp = (u_char *)malloc(tsize);
00731             if (tp == NULL) {
00732                 tsize = 0;
00733                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00734                     "BUFMOD hack malloc");
00735                 return (-1);
00736             }
00737         }
00738         amt_read = fread((char *)tp, 1, hdr->caplen, fp);
00739         if (amt_read != hdr->caplen) {
00740             if (ferror(fp)) {
00741                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00742                     "error reading dump file: %s",
00743                     pcap_strerror(errno));
00744             } else {
00745                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00746                     "truncated dump file; tried to read %u captured bytes, only got %lu",
00747                     hdr->caplen, (unsigned long)amt_read);
00748             }
00749             return (-1);
00750         }
00751         /*
00752          * We can only keep up to buflen bytes.  Since caplen > buflen
00753          * is exactly how we got here, we know we can only keep the
00754          * first buflen bytes and must drop the remainder.  Adjust
00755          * caplen accordingly, so we don't get confused later as
00756          * to how many bytes we have to play with.
00757          */
00758         hdr->caplen = buflen;
00759         memcpy((char *)buf, (char *)tp, buflen);
00760 
00761     } else {
00762         /* read the packet itself */
00763         amt_read = fread((char *)buf, 1, hdr->caplen, fp);
00764         if (amt_read != hdr->caplen) {
00765             if (ferror(fp)) {
00766                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00767                     "error reading dump file: %s",
00768                     pcap_strerror(errno));
00769             } else {
00770                 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00771                     "truncated dump file; tried to read %u captured bytes, only got %lu",
00772                     hdr->caplen, (unsigned long)amt_read);
00773             }
00774             return (-1);
00775         }
00776     }
00777     return (0);
00778 }
00779 
00780 /*
00781  * Print out packets stored in the file initialized by sf_read_init().
00782  * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
00783  */
00784 int
00785 pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
00786 {
00787     struct bpf_insn *fcode = p->fcode.bf_insns;
00788     int status = 0;
00789     int n = 0;
00790 
00791 #ifdef HAVE_REMOTE
00792     static int samp_npkt;               // parameter needed for sampling, whtn '1 out of N' method has been requested
00793     static struct timeval samp_time;    // parameter needed for sampling, whtn '1 every N ms' method has been requested
00794 #endif /* HAVE_REMOTE */
00795 
00796 
00797     while (status == 0) {
00798         struct pcap_pkthdr h;
00799 
00800         /*
00801          * Has "pcap_breakloop()" been called?
00802          * If so, return immediately - if we haven't read any
00803          * packets, clear the flag and return -2 to indicate
00804          * that we were told to break out of the loop, otherwise
00805          * leave the flag set, so that the *next* call will break
00806          * out of the loop without having read any packets, and
00807          * return the number of packets we've processed so far.
00808          */
00809         if (p->break_loop) {
00810             if (n == 0) {
00811                 p->break_loop = 0;
00812                 return (-2);
00813             } else
00814                 return (n);
00815         }
00816 
00817         status = sf_next_packet(p, &h, p->buffer, p->bufsize);
00818         if (status) {
00819             if (status == 1)
00820                 return (0);
00821             return (status);
00822         }
00823 
00824         if (fcode == NULL ||
00825             bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
00826 
00827 #ifdef HAVE_REMOTE
00828             if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N)
00829             {
00830                 samp_npkt= (samp_npkt + 1) % p->rmt_samp.value;
00831 
00832                 // Discard all packets that are not '1 out of N'
00833                 if (samp_npkt != 0)
00834                     continue;
00835             }
00836 
00837             if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS)
00838             {
00839                 // Check if the timestamp of the arrived packet is smaller than our target time
00840                 if ( (h.ts.tv_sec < samp_time.tv_sec) ||
00841                         ( (h.ts.tv_sec == samp_time.tv_sec) && (h.ts.tv_usec < samp_time.tv_usec) ) )
00842                     continue;
00843 
00844                 // The arrived packet is suitable for being sent to the remote host
00845                 // So, let's update the target time
00846                 samp_time.tv_usec= h.ts.tv_usec + p->rmt_samp.value * 1000;
00847                 if (samp_time.tv_usec > 1000000)
00848                 {
00849                     samp_time.tv_sec= h.ts.tv_sec + samp_time.tv_usec / 1000000;
00850                     samp_time.tv_usec= samp_time.tv_usec % 1000000;
00851                 }
00852 
00853             }
00854 #endif /* HAVE_REMOTE */
00855 
00856             (*callback)(user, &h, p->buffer);
00857             if (++n >= cnt && cnt > 0)
00858                 break;
00859         }
00860     }
00861     /*XXX this breaks semantics tcpslice expects */
00862     return (n);
00863 }
00864 
00865 /*
00866  * Output a packet to the initialized dump file.
00867  */
00868 void
00869 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
00870 {
00871     register FILE *f;
00872     struct pcap_sf_pkthdr sf_hdr;
00873 
00874     f = (FILE *)user;
00875     sf_hdr.ts.tv_sec  = h->ts.tv_sec;
00876     sf_hdr.ts.tv_usec = h->ts.tv_usec;
00877     sf_hdr.caplen     = h->caplen;
00878     sf_hdr.len        = h->len;
00879     /* XXX we should check the return status */
00880     (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
00881     (void)fwrite((char *)sp, h->caplen, 1, f);
00882 }
00883 
00884 /*
00885  * Initialize so that sf_write() will output to the file named 'fname'.
00886  */
00887 pcap_dumper_t *
00888 pcap_dump_open(pcap_t *p, const char *fname)
00889 {
00890     FILE *f;
00891     int linktype;
00892 
00893     linktype = dlt_to_linktype(p->linktype);
00894     if (linktype == -1) {
00895         snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
00896             "%s: link-layer type %d isn't supported in savefiles",
00897             fname, linktype);
00898         return (NULL);
00899     }
00900 
00901     if (fname[0] == '-' && fname[1] == '\0') {
00902         f = stdout;
00903 #ifdef WIN32
00904         _setmode(_fileno(f), _O_BINARY);
00905 #endif
00906     } else {
00907 #ifndef WIN32
00908         f = fopen(fname, "w");
00909 #else
00910         f = fopen(fname, "wb");
00911 #endif
00912         if (f == NULL) {
00913             snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
00914                 fname, pcap_strerror(errno));
00915             return (NULL);
00916         }
00917 #ifdef WIN32
00918         setbuf(f, NULL);
00919 #endif
00920 
00921     }
00922     (void)sf_write_header(f, linktype, p->tzoff, p->snapshot);
00923     return ((pcap_dumper_t *)f);
00924 }
00925 
00926 FILE *
00927 pcap_dump_file(pcap_dumper_t *p)
00928 {
00929     return ((FILE *)p);
00930 }
00931 
00932 int
00933 pcap_dump_flush(pcap_dumper_t *p)
00934 {
00935 
00936     if (fflush((FILE *)p) == EOF)
00937         return (-1);
00938     else
00939         return (0);
00940 }
00941 
00942 void
00943 pcap_dump_close(pcap_dumper_t *p)
00944 {
00945 
00946 #ifdef notyet
00947     if (ferror((FILE *)p))
00948         return-an-error;
00949     /* XXX should check return from fclose() too */
00950 #endif
00951     (void)fclose((FILE *)p);
00952 }

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.