aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.common3
-rw-r--r--capture_loop.c79
-rw-r--r--capture_loop.h8
-rw-r--r--pcapio.c186
-rw-r--r--pcapio.h44
-rw-r--r--ringbuffer.c39
-rw-r--r--ringbuffer.h7
-rw-r--r--tethereal.c146
8 files changed, 375 insertions, 137 deletions
diff --git a/Makefile.common b/Makefile.common
index eb21e63005..f27e41f4e8 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -58,6 +58,7 @@ ETHEREAL_COMMON_SRC = \
packet-range.c \
print.c \
ps.c \
+ pcapio.c \
ringbuffer.c \
timestats.c \
util.c \
@@ -81,6 +82,7 @@ ETHEREAL_COMMON_INCLUDES = \
fileset.h \
isprint.h \
packet-range.h \
+ pcapio.h \
print.h \
ps.h \
register.h \
@@ -221,6 +223,7 @@ dumpcap_SOURCES = \
clopts_common.c \
conditions.c \
dumpcap.c \
+ pcapio.c \
ringbuffer.c \
tempfile.c \
version_info.c
diff --git a/capture_loop.c b/capture_loop.c
index 986f8974d2..dc4eb74c51 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -68,8 +68,7 @@
#include <pcap.h>
-#include "wiretap/wtap.h"
-#include "wiretap/wtap-capture.h"
+#include "pcapio.h"
#include "capture-pcap-util.h"
@@ -640,7 +639,7 @@ gboolean capture_loop_open_input(capture_options *capture_opts, loop_data *ld, c
}
-/* open the capture input file (pcap or capture pipe) */
+/* close the capture input file (pcap or capture pipe) */
static void capture_loop_close_input(loop_data *ld) {
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_close_input");
@@ -746,14 +745,14 @@ gboolean capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, const
}
-/* open the wiretap part of the capture output file */
-gboolean capture_loop_init_wiretap_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len) {
+/* set up to write to the already-opened capture output file/files */
+gboolean capture_loop_init_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len) {
int pcap_encap;
int file_snaplen;
int err;
- g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_init_wiretap_output");
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_init_output");
/* get packet encapsulation type and snaplen */
#ifndef _WIN32
@@ -768,22 +767,15 @@ gboolean capture_loop_init_wiretap_output(capture_options *capture_opts, int sav
}
/* Set up to write to the capture file. */
- ld->wtap_linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
- if (ld->wtap_linktype == WTAP_ENCAP_UNKNOWN) {
- g_snprintf(errmsg, errmsg_len,
- "The network you're capturing from is of a type"
- " that (T)Ethereal doesn't support (data link type %d).", pcap_encap);
- return FALSE;
- }
+ ld->linktype = pcap_encap;
if (capture_opts->multi_files_on) {
- ld->wtap_pdh = ringbuf_init_wtap_dump_fdopen(WTAP_FILE_PCAP, ld->wtap_linktype,
- file_snaplen, &err);
+ ld->pdh = ringbuf_init_libpcap_fdopen(ld->linktype, file_snaplen, &err);
} else {
- ld->wtap_pdh = wtap_dump_fdopen(save_file_fd, WTAP_FILE_PCAP,
- ld->wtap_linktype, file_snaplen, FALSE /* compressed */, &err);
+ ld->pdh = libpcap_fdopen(save_file_fd, ld->linktype, file_snaplen,
+ &ld->bytes_written, &err);
}
- if (ld->wtap_pdh == NULL) {
+ if (ld->pdh == NULL) {
/* We couldn't set up to write to the capture file. */
/* XXX - use cf_open_error_message from tethereal instead? */
switch (err) {
@@ -824,9 +816,9 @@ gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld,
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_close_output");
if (capture_opts->multi_files_on) {
- return ringbuf_wtap_dump_close(&capture_opts->save_file, err_close);
+ return ringbuf_libpcap_dump_close(&capture_opts->save_file, err_close);
} else {
- return wtap_dump_close(ld->wtap_pdh, err_close);
+ return libpcap_dump_close(ld->pdh, err_close);
}
}
@@ -1129,7 +1121,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
ld.wtap_linktype = WTAP_ENCAP_UNKNOWN;
ld.pcap_err = FALSE;
ld.from_cap_pipe = FALSE;
- ld.wtap_pdh = NULL;
+ ld.pdh = NULL;
#ifndef _WIN32
ld.cap_pipe_fd = -1;
#endif
@@ -1168,8 +1160,8 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
goto error;
}
- /* open the wiretap part of the output file (the output file is already open) */
- if (!capture_loop_init_wiretap_output(capture_opts, save_file_fd, &ld, errmsg, sizeof(errmsg))) {
+ /* set up to write to the already-opened capture output file/files */
+ if (!capture_loop_init_output(capture_opts, save_file_fd, &ld, errmsg, sizeof(errmsg))) {
goto error;
}
@@ -1186,7 +1178,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
message to our parent so that they'll open the capture file and
update its windows to indicate that we have a live capture in
progress. */
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
sync_pipe_filename_to_parent(capture_opts->save_file);
/* initialize capture stop (and alike) conditions */
@@ -1233,7 +1225,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* check capture size condition */
if (cnd_autostop_size != NULL && cnd_eval(cnd_autostop_size,
- (guint32)wtap_get_bytes_dumped(ld.wtap_pdh))){
+ (guint32)ld.bytes_written)){
/* Capture size limit reached, do we have another file? */
if (capture_opts->multi_files_on) {
if (cnd_autostop_files != NULL && cnd_eval(cnd_autostop_files, ++autostop_files)) {
@@ -1243,15 +1235,15 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &save_file_fd, &ld.err)) {
+ if (ringbuf_switch_file(&ld.pdh, &capture_opts->save_file, &save_file_fd, &ld.err)) {
/* File switch succeeded: reset the conditions */
cnd_reset(cnd_autostop_size);
if (cnd_file_duration) {
cnd_reset(cnd_file_duration);
}
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
- inpkts_to_sync_pipe = 0;
+ inpkts_to_sync_pipe = 0;
sync_pipe_filename_to_parent(capture_opts->save_file);
} else {
/* File switch failed: stop here */
@@ -1265,7 +1257,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
} /* cnd_autostop_size */
if (capture_opts->output_to_pipe) {
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
}
} /* inpkts */
@@ -1285,10 +1277,10 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* Let the parent process know. */
if (inpkts_to_sync_pipe) {
/* do sync here */
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
- /* Send our parent a message saying we've written out "inpkts_to_sync_pipe"
- packets to the capture file. */
+ /* Send our parent a message saying we've written out "inpkts_to_sync_pipe"
+ packets to the capture file. */
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
inpkts_to_sync_pipe = 0;
@@ -1312,14 +1304,14 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &save_file_fd, &ld.err)) {
+ if (ringbuf_switch_file(&ld.pdh, &capture_opts->save_file, &save_file_fd, &ld.err)) {
/* file switch succeeded: reset the conditions */
cnd_reset(cnd_file_duration);
if(cnd_autostop_size)
cnd_reset(cnd_autostop_size);
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
- inpkts_to_sync_pipe = 0;
+ inpkts_to_sync_pipe = 0;
sync_pipe_filename_to_parent(capture_opts->save_file);
} else {
/* File switch failed: stop here */
@@ -1517,8 +1509,6 @@ static void
capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr,
const u_char *pd)
{
- struct wtap_pkthdr whdr;
- union wtap_pseudo_header pseudo_header;
loop_data *ld = (loop_data *) user;
int err;
@@ -1529,22 +1519,11 @@ capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr,
ld->go = FALSE;
}
- /* Convert from libpcap to Wiretap format.
- If that fails, set "ld->go" to FALSE, to stop the capture, and set
- "ld->err" to the error. */
- pd = wtap_process_pcap_packet(ld->wtap_linktype, phdr, pd, &pseudo_header,
- &whdr, &err);
- if (pd == NULL) {
- ld->go = FALSE;
- ld->err = err;
- return;
- }
-
- if (ld->wtap_pdh) {
+ if (ld->pdh) {
/* We're supposed to write the packet to a file; do so.
If this fails, set "ld->go" to FALSE, to stop the capture, and set
"ld->err" to the error. */
- if (!wtap_dump(ld->wtap_pdh, &whdr, &pseudo_header, pd, &err)) {
+ if (!libpcap_write_packet(ld->pdh, phdr, pd, &ld->bytes_written, &err)) {
ld->go = FALSE;
ld->err = err;
}
diff --git a/capture_loop.h b/capture_loop.h
index defb31110b..bfdf734388 100644
--- a/capture_loop.h
+++ b/capture_loop.h
@@ -118,9 +118,11 @@ typedef struct _loop_data {
enum { PIPOK, PIPEOF, PIPERR, PIPNEXIST } cap_pipe_err;
#endif
- /* wiretap (output file) */
- wtap_dumper *wtap_pdh;
+ /* output file */
+ FILE *pdh;
+ int linktype;
gint wtap_linktype;
+ long bytes_written;
} loop_data;
@@ -152,7 +154,7 @@ extern gboolean
capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, char *errmsg, int errmsg_len);
extern gboolean
-capture_loop_init_wiretap_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len);
+capture_loop_init_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len);
extern gboolean
capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close);
diff --git a/pcapio.c b/pcapio.c
new file mode 100644
index 0000000000..ad8f057a33
--- /dev/null
+++ b/pcapio.c
@@ -0,0 +1,186 @@
+/* pcapio.c
+ * Our own private code for writing libpcap files when capturing.
+ *
+ * We have these because we want a way to open a stream for output given
+ * only a file descriptor. libpcap 0.9[.x] has "pcap_dump_fopen()", which
+ * provides that, but
+ *
+ * 1) earlier versions of libpcap doesn't have it
+ *
+ * and
+ *
+ * 2) WinPcap doesn't have it, because a file descriptor opened
+ * by code built for one version of the MSVC++ C library
+ * can't be used by library routines built for another version
+ * (e.g., threaded vs. unthreaded).
+ *
+ * Libpcap's pcap_dump() also doesn't return any error indications.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Derived from code in the Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <pcap.h>
+
+#include <glib.h>
+
+#include "pcapio.h"
+
+/* Magic numbers in "libpcap" files.
+
+ "libpcap" file records are written in the byte order of the host that
+ writes them, and the reader is expected to fix this up.
+
+ PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC
+ is a byte-swapped version of that.
+
+ PCAP_NSEC_MAGIC is for Ulf Lamping's modified "libpcap" format,
+ which uses the same common file format as PCAP_MAGIC, but the
+ timestamps are saved in nanosecond resolution instead of microseconds.
+ PCAP_SWAPPED_NSEC_MAGIC is a byte-swapped version of that. */
+#define PCAP_MAGIC 0xa1b2c3d4
+#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1
+#define PCAP_NSEC_MAGIC 0xa1b23c4d
+#define PCAP_SWAPPED_NSEC_MAGIC 0x4d3cb2a1
+
+/* "libpcap" file header. */
+struct pcap_hdr {
+ guint32 magic; /* magic number */
+ guint16 version_major; /* major version number */
+ guint16 version_minor; /* minor version number */
+ gint32 thiszone; /* GMT to local correction */
+ guint32 sigfigs; /* accuracy of timestamps */
+ guint32 snaplen; /* max length of captured packets, in octets */
+ guint32 network; /* data link type */
+};
+
+/* "libpcap" record header. */
+struct pcaprec_hdr {
+ guint32 ts_sec; /* timestamp seconds */
+ guint32 ts_usec; /* timestamp microseconds (nsecs for PCAP_NSEC_MAGIC) */
+ guint32 incl_len; /* number of octets of packet saved in file */
+ guint32 orig_len; /* actual length of packet */
+};
+
+/* Returns a FILE * to write to on success, NULL on failure; sets "*err" to
+ an error code, or 0 for a short write, on failure */
+FILE *
+libpcap_fdopen(int fd, int linktype, int snaplen, long *bytes_written,
+ int *err)
+{
+ FILE *fp;
+ struct pcap_hdr file_hdr;
+ size_t nwritten;
+
+ fp = fdopen(fd, "wb");
+ if (fp == NULL) {
+ *err = errno;
+ return NULL;
+ }
+
+ file_hdr.magic = PCAP_MAGIC;
+ /* current "libpcap" format is 2.4 */
+ file_hdr.version_major = 2;
+ file_hdr.version_minor = 4;
+ file_hdr.thiszone = 0; /* XXX - current offset? */
+ file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
+ file_hdr.snaplen = snaplen;
+ file_hdr.network = linktype;
+ nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, fp);
+ if (nwritten != sizeof file_hdr) {
+ if (nwritten == 0 && ferror(fp))
+ *err = errno;
+ else
+ *err = 0; /* short write */
+ fclose(fp);
+ return NULL;
+ }
+ *bytes_written = sizeof file_hdr;
+
+ return fp;
+}
+
+/* Write a record for a packet to a dump file.
+ Returns TRUE on success, FALSE on failure. */
+gboolean
+libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
+ long *bytes_written, int *err)
+{
+ struct pcaprec_hdr rec_hdr;
+ size_t nwritten;
+
+ rec_hdr.ts_sec = phdr->ts.tv_sec;
+ rec_hdr.ts_usec = phdr->ts.tv_usec;
+ rec_hdr.incl_len = phdr->caplen;
+ rec_hdr.orig_len = phdr->len;
+ nwritten = fwrite(&rec_hdr, 1, sizeof rec_hdr, fp);
+ if (nwritten != sizeof rec_hdr) {
+ if (nwritten == 0 && ferror(fp))
+ *err = errno;
+ else
+ *err = 0; /* short write */
+ return FALSE;
+ }
+ *bytes_written += sizeof rec_hdr;
+
+ nwritten = fwrite(pd, 1, phdr->caplen, fp);
+ if (nwritten != phdr->caplen) {
+ if (nwritten == 0 && ferror(fp))
+ *err = errno;
+ else
+ *err = 0; /* short write */
+ return FALSE;
+ }
+ *bytes_written += phdr->caplen;
+ return TRUE;
+}
+
+gboolean
+libpcap_dump_flush(FILE *pd, int *err)
+{
+ if (fflush(pd) == EOF) {
+ if (err != NULL)
+ *err = errno;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+libpcap_dump_close(FILE *pd, int *err)
+{
+ if (fclose(pd) == EOF) {
+ if (err != NULL)
+ *err = errno;
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/pcapio.h b/pcapio.h
new file mode 100644
index 0000000000..801a563e49
--- /dev/null
+++ b/pcapio.h
@@ -0,0 +1,44 @@
+/* pcapio.h
+ * Declarations of our own routins for writing libpcap files.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Derived from code in the Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Returns a FILE * to write to on success, NULL on failure; sets "*err" to
+ an error code, or 0 for a short write, on failure */
+extern FILE *
+libpcap_fdopen(int fd, int linktype, int snaplen, long *bytes_written,
+ int *err);
+
+/* Write a record for a packet to a dump file.
+ Returns TRUE on success, FALSE on failure. */
+extern gboolean
+libpcap_write_packet(FILE *fp, const struct pcap_pkthdr *phdr, const u_char *pd,
+ long *bytes_written, int *err);
+
+extern gboolean
+libpcap_dump_flush(FILE *pd, int *err);
+
+extern gboolean
+libpcap_dump_close(FILE *pd, int *err);
diff --git a/ringbuffer.c b/ringbuffer.c
index 0c1e7f4b75..7d1e00af66 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -61,7 +61,11 @@
#include <time.h>
#include <errno.h>
-#include <wiretap/wtap.h>
+#include <pcap.h>
+
+#include <glib.h>
+
+#include "pcapio.h"
#include "ringbuffer.h"
#include "file_util.h"
@@ -79,12 +83,12 @@ typedef struct _ringbuf_data {
gchar *fprefix; /* Filename prefix */
gchar *fsuffix; /* Filename suffix */
gboolean unlimited; /* TRUE if unlimited number of files */
- int filetype;
int linktype;
int snaplen;
int fd; /* Current ringbuffer file descriptor */
- wtap_dumper *pdh;
+ FILE *pdh;
+ long bytes_written; /* Bytes written to the current file */
} ringbuf_data;
static ringbuf_data rb_data;
@@ -224,18 +228,17 @@ const gchar *ringbuf_current_filename(void)
}
/*
- * Calls wtap_dump_fdopen() for the current ringbuffer file
+ * Calls libpcap_fdopen() for the current ringbuffer file
*/
-wtap_dumper*
-ringbuf_init_wtap_dump_fdopen(int filetype, int linktype, int snaplen, int *err)
+FILE *
+ringbuf_init_libpcap_fdopen(int linktype, int snaplen, int *err)
{
- rb_data.filetype = filetype;
rb_data.linktype = linktype;
rb_data.snaplen = snaplen;
- rb_data.pdh = wtap_dump_fdopen(rb_data.fd, filetype, linktype, snaplen, FALSE /* compressed */, err);
-
+ rb_data.pdh = libpcap_fdopen(rb_data.fd, linktype, snaplen,
+ &rb_data.bytes_written, err);
return rb_data.pdh;
}
@@ -243,14 +246,14 @@ ringbuf_init_wtap_dump_fdopen(int filetype, int linktype, int snaplen, int *err)
* Switches to the next ringbuffer file
*/
gboolean
-ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int *err)
+ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err)
{
int next_file_num;
rb_file *next_rfile = NULL;
/* close current file */
- if (!wtap_dump_close(rb_data.pdh, err)) {
+ if (!libpcap_dump_close(rb_data.pdh, err)) {
eth_close(rb_data.fd); /* XXX - the above should have closed this already */
rb_data.pdh = NULL; /* it's still closed, we just got an error while closing */
rb_data.fd = -1;
@@ -270,8 +273,8 @@ ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int
return FALSE;
}
- if (ringbuf_init_wtap_dump_fdopen(rb_data.filetype, rb_data.linktype,
- rb_data.snaplen, err) == NULL) {
+ if (ringbuf_init_libpcap_fdopen(rb_data.linktype, rb_data.snaplen,
+ err) == NULL) {
return FALSE;
}
@@ -284,16 +287,16 @@ ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int
}
/*
- * Calls wtap_dump_close() for the current ringbuffer file
+ * Calls libpcap_dump_close() for the current ringbuffer file
*/
gboolean
-ringbuf_wtap_dump_close(gchar **save_file, int *err)
+ringbuf_libpcap_dump_close(gchar **save_file, int *err)
{
gboolean ret_val = TRUE;
/* close current file, if it's open */
if (rb_data.pdh != NULL) {
- if (!wtap_dump_close(rb_data.pdh, err)) {
+ if (!libpcap_dump_close(rb_data.pdh, err)) {
eth_close(rb_data.fd);
ret_val = FALSE;
}
@@ -345,14 +348,14 @@ ringbuf_error_cleanup(void)
/* try to close via wtap */
if (rb_data.pdh != NULL) {
- if (wtap_dump_close(rb_data.pdh, NULL)) {
+ if (libpcap_dump_close(rb_data.pdh, NULL)) {
rb_data.fd = -1;
}
rb_data.pdh = NULL;
}
/* close directly if still open */
- /* XXX - it shouldn't still be open; "wtap_dump_close()" should leave the
+ /* XXX - it shouldn't still be open; "libpcap_dump_close()" should leave the
file closed even if it fails */
if (rb_data.fd != -1) {
eth_close(rb_data.fd);
diff --git a/ringbuffer.h b/ringbuffer.h
index 396963b7bf..8989f5c4aa 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -40,10 +40,9 @@
int ringbuf_init(const char *capture_name, guint num_files);
const gchar *ringbuf_current_filename(void);
-wtap_dumper* ringbuf_init_wtap_dump_fdopen(int filetype, int linktype,
- int snaplen, int *err);
-gboolean ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int *err);
-gboolean ringbuf_wtap_dump_close(gchar **save_file, int *err);
+FILE *ringbuf_init_libpcap_fdopen(int linktype, int snaplen, int *err);
+gboolean ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err);
+gboolean ringbuf_libpcap_dump_close(gchar **save_file, int *err);
void ringbuf_free(void);
void ringbuf_error_cleanup(void);
diff --git a/tethereal.c b/tethereal.c
index aad2172a22..b0775b0625 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -95,6 +95,7 @@
#include <pcap.h>
#include <setjmp.h>
#include "capture-pcap-util.h"
+#include "pcapio.h"
#include <wiretap/wtap-capture.h>
#ifdef _WIN32
#include "capture-wpcap.h"
@@ -170,9 +171,9 @@ static void report_counts_siginfo(int);
#endif /* HAVE_LIBPCAP */
static int load_cap_file(capture_file *, char *, int);
-static gboolean process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
+static gboolean process_packet(capture_file *cf, long offset,
const struct wtap_pkthdr *whdr, union wtap_pseudo_header *pseudo_header,
- const guchar *pd, int *err);
+ const guchar *pd);
static void show_capture_file_io_error(const char *, int, gboolean);
static void show_print_file_io_error(int err);
static gboolean write_preamble(capture_file *cf);
@@ -1449,10 +1450,16 @@ main(int argc, char *argv[])
exit(status);
}
- if (!quiet) {
+ if (!print_packet_info && !quiet) {
/*
- * The user didn't ask us not to print a count of packets as
- * they arrive, so do so.
+ * We're not printing information for each packet, and the user
+ * didn't ask us not to print a count of packets as they arrive,
+ * so print that count so the user knows that packets are arriving.
+ *
+ * XXX - what if the user wants to do a live capture, doesn't want
+ * to save it to a file, doesn't want information printed for each
+ * packet, does want some "-z" statistic, and wants packet counts
+ * so they know whether they're seeing any packets?
*/
print_packet_counts = TRUE;
}
@@ -1509,7 +1516,7 @@ capture(void)
init_dissection();
ld.wtap_linktype = WTAP_ENCAP_UNKNOWN;
- ld.wtap_pdh = NULL;
+ ld.pdh = NULL;
ld.packet_cb = capture_pcap_cb;
@@ -1545,12 +1552,14 @@ capture(void)
goto error;
}
- /* open the wiretap part of the output file (the output file is already open) */
- if(!capture_loop_init_wiretap_output(&capture_opts, save_file_fd, &ld, errmsg, sizeof errmsg))
+ /* set up to write to the already-opened capture output file/files */
+ if(!capture_loop_init_output(&capture_opts, save_file_fd, &ld, errmsg, sizeof errmsg))
{
goto error;
}
+ ld.wtap_linktype = wtap_pcap_encap_to_wtap_encap(ld.linktype);
+
/* Save the capture file name. */
ld.save_file = capture_opts.save_file;
@@ -1679,13 +1688,12 @@ capture(void)
in effect. */
ld.go = FALSE;
} else if (cnd_autostop_size != NULL &&
- cnd_eval(cnd_autostop_size,
- (guint32)wtap_get_bytes_dumped(ld.wtap_pdh))) {
+ cnd_eval(cnd_autostop_size, (guint32)ld.bytes_written)) {
/* We're saving the capture to a file, and the capture file reached
its maximum size. */
if (capture_opts.multi_files_on) {
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
+ if (ringbuf_switch_file(&ld.pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_autostop_size);
if (cnd_file_duration) {
@@ -1703,7 +1711,7 @@ capture(void)
}
if (capture_opts.output_to_pipe) {
if (ld.packet_count > packet_count_prev) {
- wtap_dump_flush(ld.wtap_pdh);
+ libpcap_dump_flush(ld.pdh, NULL);
packet_count_prev = ld.packet_count;
}
}
@@ -1806,18 +1814,12 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
{
struct wtap_pkthdr whdr;
union wtap_pseudo_header pseudo_header;
+ const guchar *wtap_pd;
loop_data *ld = (loop_data *) user;
int loop_err;
int err;
int save_file_fd;
-
- /* Convert from libpcap to Wiretap format.
- If that fails, ignore the packet (wtap_process_pcap_packet has
- written an error message). */
- pd = wtap_process_pcap_packet(ld->wtap_linktype, phdr, pd, &pseudo_header,
- &whdr, &err);
- if (pd == NULL)
- return;
+ gboolean packet_accepted;
#ifdef SIGINFO
/*
@@ -1835,7 +1837,7 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
*/
if (cnd_file_duration != NULL && cnd_eval(cnd_file_duration)) {
/* time elapsed for this ring file, switch to the next */
- if (ringbuf_switch_file(&ld->wtap_pdh, &ld->save_file, &save_file_fd, &loop_err)) {
+ if (ringbuf_switch_file(&ld->pdh, &ld->save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_file_duration);
} else {
@@ -1845,17 +1847,51 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
}
}
- if (!process_packet(&cfile, ld->wtap_pdh, 0, &whdr, &pseudo_header, pd, &err)) {
- /* Error writing to a capture file */
+ if (do_dissection) {
+ /* We're goint to print packet information, run a read filter, or
+ process taps. Use process_packet() to handle that; in order
+ to do that, we need to convert from libpcap to Wiretap format.
+ If that fails, ignore the packet (wtap_process_pcap_packet has
+ written an error message). */
+ wtap_pd = wtap_process_pcap_packet(ld->wtap_linktype, phdr, pd,
+ &pseudo_header, &whdr, &err);
+ if (wtap_pd == NULL)
+ return;
+
+ packet_accepted = process_packet(&cfile, 0, &whdr, &pseudo_header, wtap_pd);
+ } else {
+ /* We're just writing out packets. */
+ packet_accepted = TRUE;
+ }
+
+ if (packet_accepted) {
+ /* Count this packet. */
+#ifdef HAVE_LIBPCAP
+ ld->packet_count++;
+#endif
+
+ if (ld->pdh != NULL) {
+ if (!libpcap_write_packet(ld->pdh, phdr, pd, &ld->bytes_written, &err)) {
+ /* Error writing to a capture file */
+ if (print_packet_counts) {
+ /* We're printing counts of packets captured; move to the line after
+ the count. */
+ fprintf(stderr, "\n");
+ }
+ show_capture_file_io_error(ld->save_file, err, FALSE);
+ pcap_close(ld->pcap_h);
+ libpcap_dump_close(ld->pdh, &err);
+ exit(2);
+ }
+ }
if (print_packet_counts) {
- /* We're printing counts of packets captured; move to the line after
- the count. */
- fprintf(stderr, "\n");
+ /* We're printing packet counts. */
+ if (ld->packet_count != 0) {
+ fprintf(stderr, "\r%u ", ld->packet_count);
+ /* stderr could be line buffered */
+ fflush(stderr);
+ }
}
- show_capture_file_io_error(ld->save_file, err, FALSE);
- pcap_close(ld->pcap_h);
- wtap_dump_close(ld->wtap_pdh, &err);
- exit(2);
}
#ifdef SIGINFO
@@ -2017,13 +2053,21 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type)
pdh = NULL;
}
while (wtap_read(cf->wth, &err, &err_info, &data_offset)) {
- if (!process_packet(cf, pdh, data_offset, wtap_phdr(cf->wth),
- wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth),
- &err)) {
- /* Error writing to a capture file */
- show_capture_file_io_error(save_file, err, FALSE);
- wtap_dump_close(pdh, &err);
- exit(2);
+ if (process_packet(cf, data_offset, wtap_phdr(cf->wth),
+ wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth))) {
+ /* Either there's no read filtering or this packet passed the
+ filter, so, if we're writing to a capture file, write
+ this packet out. */
+ if (pdh != NULL) {
+ if (!wtap_dump(pdh, wtap_phdr(cf->wth),
+ wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth),
+ &err)) {
+ /* Error writing to a capture file */
+ show_capture_file_io_error(save_file, err, FALSE);
+ wtap_dump_close(pdh, &err);
+ exit(2);
+ }
+ }
}
}
if (err != 0) {
@@ -2148,10 +2192,8 @@ clear_fdata(frame_data *fdata)
}
static gboolean
-process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
- const struct wtap_pkthdr *whdr,
- union wtap_pseudo_header *pseudo_header, const guchar *pd,
- int *err)
+process_packet(capture_file *cf, long offset, const struct wtap_pkthdr *whdr,
+ union wtap_pseudo_header *pseudo_header, const guchar *pd)
{
frame_data fdata;
gboolean create_proto_tree;
@@ -2215,27 +2257,7 @@ process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
}
if (passed) {
- /* Count this packet. */
-#ifdef HAVE_LIBPCAP
- ld.packet_count++;
-#endif
-
/* Process this packet. */
- if (pdh != NULL) {
- /* We're writing to a capture file; write this packet. */
- if (!wtap_dump(pdh, whdr, pseudo_header, pd, err))
- return FALSE;
-#ifdef HAVE_LIBPCAP
- if (print_packet_counts) {
- /* We're printing packet counts. */
- if (ld.packet_count != 0) {
- fprintf(stderr, "\r%u ", ld.packet_count);
- /* stderr could be line buffered */
- fflush(stderr);
- }
- }
-#endif
- }
if (print_packet_info) {
/* We're printing packet information; print the information for
this packet. */
@@ -2275,7 +2297,7 @@ process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
epan_dissect_free(edt);
clear_fdata(&fdata);
}
- return TRUE;
+ return passed;
}
static void