summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/savefile.c
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2004-03-31 09:07:39 +0000
committerbms <bms@FreeBSD.org>2004-03-31 09:07:39 +0000
commitda13a5a9d72229b2a6026a49b9977934bdef13ed (patch)
treeb024e287db2b122351a0e433fbc33120af98a9eb /contrib/libpcap/savefile.c
parent34111fdf72727e35d5c81dc576ce3f5a87c9ef84 (diff)
downloadFreeBSD-src-da13a5a9d72229b2a6026a49b9977934bdef13ed.zip
FreeBSD-src-da13a5a9d72229b2a6026a49b9977934bdef13ed.tar.gz
Import libpcap 0.8.3, from http://www.tcpdump.org/releases/libpcap-0.8.3.tar.gz
Diffstat (limited to 'contrib/libpcap/savefile.c')
-rw-r--r--contrib/libpcap/savefile.c476
1 files changed, 433 insertions, 43 deletions
diff --git a/contrib/libpcap/savefile.c b/contrib/libpcap/savefile.c
index f952a19..cc307bd 100644
--- a/contrib/libpcap/savefile.c
+++ b/contrib/libpcap/savefile.c
@@ -29,23 +29,19 @@
*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.55 2001/11/28 07:16:53 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/time.h>
-
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include "pcap-int.h"
@@ -61,7 +57,10 @@ static const char rcsid[] =
* because time is at a premium when we are writing the file.
* In other words, the pcap_file_header and pcap_pkthdr,
* records are written in host byte order.
- * Note that the packets are always written in network byte order.
+ * Note that the bytes of packet data are written out in the order in
+ * which they were received, so multi-byte fields in packets are not
+ * written in host byte order, they're written in whatever order the
+ * sending machine put them in.
*
* ntoh[ls] aren't sufficient because we might need to swap on a big-endian
* machine (if the file was written in little-end order).
@@ -119,6 +118,12 @@ static const char rcsid[] =
* to handle the new encapsulation type, so that they can also be checked
* into the tcpdump.org CVS repository and so that they will appear in
* future libpcap and tcpdump releases.
+ *
+ * Do *NOT* assume that any values after the largest value in this file
+ * are available; you might not have the most up-to-date version of this
+ * file, and new values after that one might have been assigned. Also,
+ * do *NOT* use any values below 100 - those might already have been
+ * taken by one (or more!) organizations.
*/
#define LINKTYPE_NULL DLT_NULL
#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
@@ -127,7 +132,7 @@ static const char rcsid[] =
#define LINKTYPE_PRONET DLT_PRONET
#define LINKTYPE_CHAOS DLT_CHAOS
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
-#define LINKTYPE_ARCNET DLT_ARCNET
+#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */
#define LINKTYPE_SLIP DLT_SLIP
#define LINKTYPE_PPP DLT_PPP
#define LINKTYPE_FDDI DLT_FDDI
@@ -151,6 +156,13 @@ static const char rcsid[] =
#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
+/*
+ * This isn't supported in libpcap 0.8[.x], but is supported in the
+ * current CVS version; we include it here to note that it's not available
+ * for anybody else to use.
+ */
+#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
+
#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
#define LINKTYPE_RAW 101 /* raw IP */
#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
@@ -158,26 +170,160 @@ static const char rcsid[] =
#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
+#define LINKTYPE_FRELAY 107 /* Frame Relay */
#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
+#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
+
+/*
+ * These three types are reserved for future use.
+ */
+#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
+#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
+#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
#define LINKTYPE_ECONET 115 /* Acorn Econet */
+/*
+ * Reserved for use with OpenBSD ipfilter.
+ */
+#define LINKTYPE_IPFILTER 116
+
+#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */
#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */
/*
- * These types are reserved for future use.
+ * Reserved for Siemens HiPath HDLC.
*/
-#define LINKTYPE_FR 107 /* BSD/OS Frame Relay */
-#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
-#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
-#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
-#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
-#define LINKTYPE_IPFILTER 116 /* IP Filter capture files */
-#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
+#define LINKTYPE_HHDLC 121
+
+#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
+#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
+
+/*
+ * Reserved as per request from Kent Dahlgren <kent@praesum.com>
+ * for private use.
+ */
+#define LINKTYPE_RIO 124 /* RapidIO */
+#define LINKTYPE_PCI_EXP 125 /* PCI Express */
+#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
+
+#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
+
+/*
+ * Reserved for the TZSP encapsulation, as per request from
+ * Chris Waters <chris.waters@networkchemistry.com>
+ * TZSP is a generic encapsulation for any other link type,
+ * which includes a means to include meta-information
+ * with the packet, e.g. signal strength and channel
+ * for 802.11 packets.
+ */
+#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */
+
+#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */
+
+/*
+ * Juniper-private data link types, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MLPPP 130
+#define LINKTYPE_JUNIPER_MLFR 131
+#define LINKTYPE_JUNIPER_ES 132
+#define LINKTYPE_JUNIPER_GGSN 133
+#define LINKTYPE_JUNIPER_MFR 134
+#define LINKTYPE_JUNIPER_ATM2 135
+#define LINKTYPE_JUNIPER_SERVICES 136
+#define LINKTYPE_JUNIPER_ATM1 137
+
+#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
+
+#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */
+#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */
+#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */
+#define LINKTYPE_RAWSS7_SCCP 142
+
+/*
+ * This isn't supported in libpcap 0.8[.x], but is supported in the
+ * current CVS version; we include it here to note that it's not available
+ * for anybody else to use.
+ */
+#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */
+
+#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */
+
+/*
+ * Reserved for IBM SP switch and IBM Next Federation switch.
+ */
+#define LINKTYPE_IBM_SP 145
+#define LINKTYPE_IBM_SN 146
+
+/*
+ * Reserved for private use. If you have some link-layer header type
+ * that you want to use within your organization, with the capture files
+ * using that link-layer header type not ever be sent outside your
+ * organization, you can use these values.
+ *
+ * No libpcap release will use these for any purpose, nor will any
+ * tcpdump release use them, either.
+ *
+ * Do *NOT* use these in capture files that you expect anybody not using
+ * your private versions of capture-file-reading tools to read; in
+ * particular, do *NOT* use them in products, otherwise you may find that
+ * people won't be able to use tcpdump, or snort, or Ethereal, or... to
+ * read capture files from your firewall/intrusion detection/traffic
+ * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value,
+ * and you may also find that the developers of those applications will
+ * not accept patches to let them read those files.
+ *
+ * Also, do not use them if somebody might send you a capture using them
+ * for *their* private type and tools using them for *your* private type
+ * would have to read them.
+ *
+ * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_
+ * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type
+ * you're given.
+ */
+#define LINKTYPE_USER0 147
+#define LINKTYPE_USER1 148
+#define LINKTYPE_USER2 149
+#define LINKTYPE_USER3 150
+#define LINKTYPE_USER4 151
+#define LINKTYPE_USER5 152
+#define LINKTYPE_USER6 153
+#define LINKTYPE_USER7 154
+#define LINKTYPE_USER8 155
+#define LINKTYPE_USER9 156
+#define LINKTYPE_USER10 157
+#define LINKTYPE_USER11 158
+#define LINKTYPE_USER12 159
+#define LINKTYPE_USER13 160
+#define LINKTYPE_USER14 161
+#define LINKTYPE_USER15 162
+
+/*
+ * For future use with 802.11 captures - defined by AbsoluteValue
+ * Systems to store a number of bits of link-layer information
+ * including radio information:
+ *
+ * http://www.shaftnet.org/~pizza/software/capturefrm.txt
+ *
+ * but could and arguably should also be used by non-AVS Linux
+ * 802.11 drivers; that may happen in the future.
+ */
+#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MONITOR 164
static struct linktype_map {
int dlt;
@@ -205,6 +351,12 @@ static struct linktype_map {
* have values that should never be equal to any DLT_*
* code.
*/
+#ifdef DLT_FR
+ /* BSD/OS Frame Relay */
+ { DLT_FR, LINKTYPE_FRELAY },
+#endif
+
+ { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
@@ -232,6 +384,9 @@ static struct linktype_map {
/* IEEE 802.11 wireless */
{ DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
+ /* Frame Relay */
+ { DLT_FRELAY, LINKTYPE_FRELAY },
+
/* OpenBSD loopback */
{ DLT_LOOP, LINKTYPE_LOOP },
@@ -244,6 +399,9 @@ static struct linktype_map {
/* Acorn Econet */
{ DLT_ECONET, LINKTYPE_ECONET },
+ /* OpenBSD DLT_PFLOG */
+ { DLT_PFLOG, LINKTYPE_PFLOG },
+
/* For Cisco-internal use */
{ DLT_CISCO_IOS, LINKTYPE_CISCO_IOS },
@@ -253,6 +411,59 @@ static struct linktype_map {
/* FreeBSD Aironet driver stuff */
{ DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER },
+ /* Siemens HiPath HDLC */
+ { DLT_HHDLC, LINKTYPE_HHDLC },
+
+ /* RFC 2625 IP-over-Fibre Channel */
+ { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC },
+
+ /* Solaris+SunATM */
+ { DLT_SUNATM, LINKTYPE_SUNATM },
+
+ /* RapidIO */
+ { DLT_RIO, LINKTYPE_RIO },
+
+ /* PCI Express */
+ { DLT_PCI_EXP, LINKTYPE_PCI_EXP },
+
+ /* Xilinx Aurora link layer */
+ { DLT_AURORA, LINKTYPE_AURORA },
+
+ /* 802.11 plus BSD radio header */
+ { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO },
+
+ /* Tazmen Sniffer Protocol */
+ { DLT_TZSP, LINKTYPE_TZSP },
+
+ /* Arcnet with Linux-style link-layer headers */
+ { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX },
+
+ /* Juniper-internal chassis encapsulation */
+ { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP },
+ { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR },
+ { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES },
+ { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN },
+ { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR },
+ { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 },
+ { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
+ { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 },
+
+ /* Apple IP-over-IEEE 1394 cooked header */
+ { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
+
+ /* DOCSIS MAC frames */
+ { DLT_DOCSIS, LINKTYPE_DOCSIS },
+
+ /* IrDA IrLAP packets + Linux-cooked header */
+ { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA },
+
+ /* IBM SP and Next Federation switches */
+ { DLT_IBM_SP, LINKTYPE_IBM_SP },
+ { DLT_IBM_SN, LINKTYPE_IBM_SN },
+
+ /* 802.11 plus AVS radio header */
+ { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS },
+
/*
* Any platform that defines additional DLT_* codes should:
*
@@ -271,6 +482,10 @@ static struct linktype_map {
* defining DLT_* values that collide with those
* LINKTYPE_* values, either).
*/
+
+ /* Juniper-internal chassis encapsulation */
+ { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
+
{ -1, -1 }
};
@@ -341,6 +556,43 @@ swap_hdr(struct pcap_file_header *hp)
hp->linktype = SWAPLONG(hp->linktype);
}
+static int
+sf_getnonblock(pcap_t *p, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so never say
+ * it's in non-blocking mode.
+ */
+ return (0);
+}
+
+static int
+sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so ignore
+ * requests to put it in non-blocking mode.
+ */
+ return (0);
+}
+
+static int
+sf_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from savefiles");
+ return (-1);
+}
+
+static void
+sf_close(pcap_t *p)
+{
+ if (p->sf.rfile != stdin)
+ (void)fclose(p->sf.rfile);
+ if (p->sf.base != NULL)
+ free(p->sf.base);
+}
+
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
@@ -357,15 +609,15 @@ pcap_open_offline(const char *fname, char *errbuf)
}
memset((char *)p, 0, sizeof(*p));
- /*
- * Set this field so we don't close stdin in pcap_close!
- */
- p->fd = -1;
if (fname[0] == '-' && fname[1] == '\0')
fp = stdin;
else {
+#ifndef WIN32
fp = fopen(fname, "r");
+#else
+ fp = fopen(fname, "rb");
+#endif
if (fp == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
pcap_strerror(errno));
@@ -406,7 +658,12 @@ pcap_open_offline(const char *fname, char *errbuf)
p->snapshot = hdr.snaplen;
p->linktype = linktype_to_dlt(hdr.linktype);
p->sf.rfile = fp;
+#ifndef WIN32
p->bufsize = hdr.snaplen;
+#else
+ /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
+ p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
+#endif
/* Align link header as required for proper data alignment */
/* XXX should handle all types */
@@ -441,8 +698,59 @@ pcap_open_offline(const char *fname, char *errbuf)
pcap_fddipad = 0;
#endif
+ /*
+ * We interchanged the caplen and len fields at version 2.3,
+ * in order to match the bpf header layout. But unfortunately
+ * some files were written with version 2.3 in their headers
+ * but without the interchanged fields.
+ *
+ * In addition, DG/UX tcpdump writes out files with a version
+ * number of 543.0, and with the caplen and len fields in the
+ * pre-2.3 order.
+ */
+ switch (hdr.version_major) {
+
+ case 2:
+ if (hdr.version_minor < 3)
+ p->sf.lengths_swapped = SWAPPED;
+ else if (hdr.version_minor == 3)
+ p->sf.lengths_swapped = MAYBE_SWAPPED;
+ else
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+
+ case 543:
+ p->sf.lengths_swapped = SWAPPED;
+ break;
+
+ default:
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+ }
+
+#ifndef WIN32
+ /*
+ * You can do "select()" and "poll()" on plain files on most
+ * platforms, and should be able to do so on pipes.
+ *
+ * You can't do "select()" on anything other than sockets in
+ * Windows, so, on Win32 systems, we don't have "selectable_fd".
+ */
+ p->selectable_fd = fileno(fp);
+#endif
+
+ p->read_op = pcap_offline_read;
+ p->setfilter_op = install_bpf_program;
+ p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
+ p->getnonblock_op = sf_getnonblock;
+ p->setnonblock_op = sf_setnonblock;
+ p->stats_op = sf_stats;
+ p->close_op = sf_close;
+
return (p);
bad:
+ if(fp)
+ fclose(fp);
free(p);
return (NULL);
}
@@ -453,10 +761,12 @@ pcap_open_offline(const char *fname, char *errbuf)
* no more packets, and SFERR_TRUNC if a partial packet was encountered.
*/
static int
-sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
+sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
{
struct pcap_sf_patched_pkthdr sf_hdr;
FILE *fp = p->sf.rfile;
+ size_t amt_read;
+ bpf_u_int32 t;
/*
* Read the packet header; the structure we use as a buffer
@@ -465,9 +775,23 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
* unpatched libpcap we only read as many bytes as the regular
* header has.
*/
- if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) {
- /* probably an EOF, though could be a truncated packet */
- return (1);
+ amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
+ if (amt_read != p->sf.hdrsize) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1);
+ } else {
+ if (amt_read != 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %d header bytes, only got %lu",
+ p->sf.hdrsize, (unsigned long)amt_read);
+ return (-1);
+ }
+ /* EOF */
+ return (1);
+ }
}
if (p->sf.swapped) {
@@ -482,17 +806,27 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
}
- /*
- * We interchanged the caplen and len fields at version 2.3,
- * in order to match the bpf header layout. But unfortunately
- * some files were written with version 2.3 in their headers
- * but without the interchanged fields.
- */
- if (p->sf.version_minor < 3 ||
- (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
- int t = hdr->caplen;
+ /* Swap the caplen and len fields, if necessary. */
+ switch (p->sf.lengths_swapped) {
+
+ case NOT_SWAPPED:
+ break;
+
+ case MAYBE_SWAPPED:
+ if (hdr->caplen <= hdr->len) {
+ /*
+ * The captured length is <= the actual length,
+ * so presumably they weren't swapped.
+ */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case SWAPPED:
+ t = hdr->caplen;
hdr->caplen = hdr->len;
hdr->len = t;
+ break;
}
if (hdr->caplen > buflen) {
@@ -503,7 +837,7 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
* grossly wrong, try to salvage.
*/
static u_char *tp = NULL;
- static int tsize = 0;
+ static size_t tsize = 0;
if (hdr->caplen > 65535) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -523,9 +857,17 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
return (-1);
}
}
- if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file");
+ amt_read = fread((char *)tp, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
return (-1);
}
/*
@@ -540,10 +882,17 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
} else {
/* read the packet itself */
-
- if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file");
+ amt_read = fread((char *)buf, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
return (-1);
}
}
@@ -564,6 +913,23 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
while (status == 0) {
struct pcap_pkthdr h;
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return -2 to indicate
+ * that we were told to break out of the loop, otherwise
+ * leave the flag set, so that the *next* call will break
+ * out of the loop without having read any packets, and
+ * return the number of packets we've processed so far.
+ */
+ if (p->break_loop) {
+ if (n == 0) {
+ p->break_loop = 0;
+ return (-2);
+ } else
+ return (n);
+ }
+
status = sf_next_packet(p, &h, p->buffer, p->bufsize);
if (status) {
if (status == 1)
@@ -618,10 +984,18 @@ pcap_dump_open(pcap_t *p, const char *fname)
return (NULL);
}
- if (fname[0] == '-' && fname[1] == '\0')
+ if (fname[0] == '-' && fname[1] == '\0') {
f = stdout;
- else {
+#ifdef WIN32
+ _setmode(_fileno(f), _O_BINARY);
+#endif
+ } else {
+#ifndef WIN32
f = fopen(fname, "w");
+#else
+ f = fopen(fname, "wb");
+ setbuf(f, NULL); /* XXX - why? */
+#endif
if (f == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
@@ -632,6 +1006,22 @@ pcap_dump_open(pcap_t *p, const char *fname)
return ((pcap_dumper_t *)f);
}
+FILE *
+pcap_dump_file(pcap_dumper_t *p)
+{
+ return ((FILE *)p);
+}
+
+int
+pcap_dump_flush(pcap_dumper_t *p)
+{
+
+ if (fflush((FILE *)p) == EOF)
+ return (-1);
+ else
+ return (0);
+}
+
void
pcap_dump_close(pcap_dumper_t *p)
{
OpenPOWER on IntegriCloud