summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/savefile.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/savefile.c')
-rw-r--r--contrib/libpcap/savefile.c298
1 files changed, 249 insertions, 49 deletions
diff --git a/contrib/libpcap/savefile.c b/contrib/libpcap/savefile.c
index cc307bd..0a739fa 100644
--- a/contrib/libpcap/savefile.c
+++ b/contrib/libpcap/savefile.c
@@ -30,7 +30,7 @@
#ifndef lint
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)";
+ "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.126 2005/02/08 20:03:16 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -49,8 +49,27 @@ static const char rcsid[] _U_ =
#include "os-proto.h"
#endif
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
+/*
+ * Standard libpcap format.
+ */
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/*
+ * Alexey Kuznetzov's modified libpcap format.
+ */
+#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
+
+/*
+ * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
+ * for another modified format.
+ */
+#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
+
+/*
+ * Navtel Communcations' format, with nanosecond timestamps,
+ * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
+ */
+#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
/*
* We use the "receiver-makes-right" approach to byte order,
@@ -76,6 +95,19 @@ static const char rcsid[] _U_ =
#define SFERR_EOF 4 /* not really an error, just a status */
/*
+ * Setting O_BINARY on DOS/Windows is a bit tricky
+ */
+#if defined(WIN32)
+ #define SET_BINMODE(f) _setmode(fileno(f), O_BINARY)
+#elif defined(MSDOS)
+ #if defined(__HIGHC__)
+ #define SET_BINMODE(f) setmode(f, O_BINARY)
+ #else
+ #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
+ #endif
+#endif
+
+/*
* We don't write DLT_* values to the capture file header, because
* they're not the same on all platforms.
*
@@ -156,11 +188,6 @@ static const char rcsid[] _U_ =
#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 */
@@ -247,11 +274,6 @@ static const char rcsid[] _U_ =
#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 */
@@ -325,6 +347,63 @@ static const char rcsid[] _U_ =
*/
#define LINKTYPE_JUNIPER_MONITOR 164
+/*
+ * Reserved for BACnet MS/TP.
+ */
+#define LINKTYPE_BACNET_MS_TP 165
+
+/*
+ * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
+ *
+ * This is used in some OSes to allow a kernel socket filter to distinguish
+ * between incoming and outgoing packets, on a socket intended to
+ * supply pppd with outgoing packets so it can do dial-on-demand and
+ * hangup-on-lack-of-demand; incoming packets are filtered out so they
+ * don't cause pppd to hold the connection up (you don't want random
+ * input packets such as port scans, packets from old lost connections,
+ * etc. to force the connection to stay up).
+ *
+ * The first byte of the PPP header (0xff03) is modified to accomodate
+ * the direction - 0x00 = IN, 0x01 = OUT.
+ */
+#define LINKTYPE_PPP_PPPD 166
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
+ * for passing on chassis-internal metainformation such as
+ * QOS profiles, cookies, etc..
+ */
+#define LINKTYPE_JUNIPER_PPPOE 167
+#define LINKTYPE_JUNIPER_PPPOE_ATM 168
+
+#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
+#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
+#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
+
+/*
+ * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
+ * monitoring equipment.
+ */
+#define LINKTYPE_GCOM_T1E1 172
+#define LINKTYPE_GCOM_SERIAL 173
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_ is used
+ * for internal communication to Physical Interface Cards (PIC)
+ */
+#define LINKTYPE_JUNIPER_PIC_PEER 174
+
+/*
+ * Link types requested by Gregor Maier <gregor@endace.com> of Endace
+ * Measurement Systems. They add an ERF header (see
+ * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
+ * the link-layer header.
+ */
+#define LINKTYPE_ERF_ETH 175 /* Ethernet */
+#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */
+
static struct linktype_map {
int dlt;
int linktype;
@@ -483,8 +562,37 @@ static struct linktype_map {
* LINKTYPE_* values, either).
*/
+ /* Juniper-internal chassis encapsulation */
+ { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
+
+ /* BACnet MS/TP */
+ { DLT_BACNET_MS_TP, LINKTYPE_BACNET_MS_TP },
+
+ /* PPP for pppd, with direction flag in the PPP header */
+ { DLT_PPP_PPPD, LINKTYPE_PPP_PPPD},
+
+ /* Juniper-internal chassis encapsulation */
+ { DLT_JUNIPER_PPPOE, LINKTYPE_JUNIPER_PPPOE },
+ { DLT_JUNIPER_PPPOE_ATM,LINKTYPE_JUNIPER_PPPOE_ATM },
+
+ /* GPRS LLC */
+ { DLT_GPRS_LLC, LINKTYPE_GPRS_LLC },
+
+ /* Transparent Generic Framing Procedure (ITU-T G.7041/Y.1303) */
+ { DLT_GPF_T, LINKTYPE_GPF_T },
+
+ /* Framed Generic Framing Procedure (ITU-T G.7041/Y.1303) */
+ { DLT_GPF_F, LINKTYPE_GPF_F },
+
+ { DLT_GCOM_T1E1, LINKTYPE_GCOM_T1E1 },
+ { DLT_GCOM_SERIAL, LINKTYPE_GCOM_SERIAL },
+
/* Juniper-internal chassis encapsulation */
- { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
+ { DLT_JUNIPER_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER },
+
+ /* Endace types */
+ { DLT_ERF_ETH, LINKTYPE_ERF_ETH },
+ { DLT_ERF_POS, LINKTYPE_ERF_POS },
{ -1, -1 }
};
@@ -584,6 +692,14 @@ sf_stats(pcap_t *p, struct pcap_stat *ps)
return (-1);
}
+static int
+sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
+{
+ strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
+ PCAP_ERRBUF_SIZE);
+ return (-1);
+}
+
static void
sf_close(pcap_t *p)
{
@@ -596,9 +712,37 @@ sf_close(pcap_t *p)
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
+ FILE *fp;
+ pcap_t *p;
+
+ if (fname[0] == '-' && fname[1] == '\0')
+ fp = stdin;
+ else {
+#if !defined(WIN32) && !defined(MSDOS)
+ fp = fopen(fname, "r");
+#else
+ fp = fopen(fname, "rb");
+#endif
+ if (fp == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ p = pcap_fopen_offline(fp, errbuf);
+ if (p == NULL) {
+ if (fp != stdin)
+ fclose(fp);
+ }
+ return (p);
+}
+
+pcap_t *
+pcap_fopen_offline(FILE *fp, char *errbuf)
+{
register pcap_t *p;
- register FILE *fp;
struct pcap_file_header hdr;
+ size_t amt_read;
bpf_u_int32 magic;
int linklen;
@@ -610,29 +754,24 @@ pcap_open_offline(const char *fname, char *errbuf)
memset((char *)p, 0, sizeof(*p));
- 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,
+ amt_read = fread((char *)&hdr, 1, sizeof(hdr), fp);
+ if (amt_read != sizeof(hdr)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
pcap_strerror(errno));
- goto bad;
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu file header bytes, only got %lu",
+ (unsigned long)sizeof(hdr),
+ (unsigned long)amt_read);
}
- }
- if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
- pcap_strerror(errno));
goto bad;
}
magic = hdr.magic;
- if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
magic = SWAPLONG(magic);
- if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bad dump file format");
goto bad;
@@ -640,12 +779,23 @@ pcap_open_offline(const char *fname, char *errbuf)
p->sf.swapped = 1;
swap_hdr(&hdr);
}
- if (magic == PATCHED_TCPDUMP_MAGIC) {
+ if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
/*
* XXX - the patch that's in some versions of libpcap
- * changes the packet header but not the magic number;
+ * changes the packet header but not the magic number,
+ * and some other versions with this magic number have
+ * some extra debugging information in the packet header;
* we'd have to use some hacks^H^H^H^H^Hheuristics to
- * detect that.
+ * detect those variants.
+ *
+ * Ethereal does that, but it does so by trying to read
+ * the first two packets of the file with each of the
+ * record header formats. That currently means it seeks
+ * backwards and retries the reads, which doesn't work
+ * on pipes. We want to be able to read from a pipe, so
+ * that strategy won't work; we'd have to buffer some
+ * data ourselves and read from that buffer in order to
+ * make that work.
*/
p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
} else
@@ -694,8 +844,8 @@ pcap_open_offline(const char *fname, char *errbuf)
p->sf.version_major = hdr.version_major;
p->sf.version_minor = hdr.version_minor;
#ifdef PCAP_FDDIPAD
- /* XXX padding only needed for kernel fcode */
- pcap_fddipad = 0;
+ /* Padding only needed for live capture fcode */
+ p->fddipad = 0;
#endif
/*
@@ -728,7 +878,7 @@ pcap_open_offline(const char *fname, char *errbuf)
break;
}
-#ifndef WIN32
+#if !defined(WIN32) && !defined(MSDOS)
/*
* You can do "select()" and "poll()" on plain files on most
* platforms, and should be able to do so on pipes.
@@ -740,6 +890,7 @@ pcap_open_offline(const char *fname, char *errbuf)
#endif
p->read_op = pcap_offline_read;
+ p->inject_op = sf_inject;
p->setfilter_op = install_bpf_program;
p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
p->getnonblock_op = sf_getnonblock;
@@ -747,10 +898,17 @@ pcap_open_offline(const char *fname, char *errbuf)
p->stats_op = sf_stats;
p->close_op = sf_close;
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * If we're reading from the standard input, put it in binary
+ * mode, as savefiles are binary files.
+ */
+ if (fp == stdin)
+ SET_BINMODE(fp);
+#endif
+
return (p);
bad:
- if(fp)
- fclose(fp);
free(p);
return (NULL);
}
@@ -906,7 +1064,7 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
int
pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
- struct bpf_insn *fcode = p->fcode.bf_insns;
+ struct bpf_insn *fcode;
int status = 0;
int n = 0;
@@ -937,7 +1095,7 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return (status);
}
- if (fcode == NULL ||
+ if ((fcode = p->fcode.bf_insns) == NULL ||
bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
(*callback)(user, &h, p->buffer);
if (++n >= cnt && cnt > 0)
@@ -967,6 +1125,33 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
(void)fwrite((char *)sp, h->caplen, 1, f);
}
+static pcap_dumper_t *
+pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
+{
+
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * If we're writing to the standard output, put it in binary
+ * mode, as savefiles are binary files.
+ *
+ * Otherwise, we turn off buffering.
+ * XXX - why? And why not on the standard output?
+ */
+ if (f == stdout)
+ SET_BINMODE(f);
+ else
+ setbuf(f, NULL);
+#endif
+ if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
+ fname, pcap_strerror(errno));
+ if (f != stdout)
+ (void)fclose(f);
+ return (NULL);
+ }
+ return ((pcap_dumper_t *)f);
+}
+
/*
* Initialize so that sf_write() will output to the file named 'fname'.
*/
@@ -986,15 +1171,12 @@ pcap_dump_open(pcap_t *p, const char *fname)
if (fname[0] == '-' && fname[1] == '\0') {
f = stdout;
-#ifdef WIN32
- _setmode(_fileno(f), _O_BINARY);
-#endif
+ fname = "standard output";
} else {
-#ifndef WIN32
+#if !defined(WIN32) && !defined(MSDOS)
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",
@@ -1002,8 +1184,26 @@ pcap_dump_open(pcap_t *p, const char *fname)
return (NULL);
}
}
- (void)sf_write_header(f, linktype, p->tzoff, p->snapshot);
- return ((pcap_dumper_t *)f);
+ return (pcap_setup_dump(p, linktype, f, fname));
+}
+
+/*
+ * Initialize so that sf_write() will output to the given stream.
+ */
+pcap_dumper_t *
+pcap_dump_fopen(pcap_t *p, FILE *f)
+{
+ int linktype;
+
+ linktype = dlt_to_linktype(p->linktype);
+ if (linktype == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "stream: link-layer type %d isn't supported in savefiles",
+ linktype);
+ return (NULL);
+ }
+
+ return (pcap_setup_dump(p, linktype, f, "stream"));
}
FILE *
OpenPOWER on IntegriCloud