* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-/* With MSVC and a libethereal.dll this file needs to import some variables
- in a special way. Therefore _NEED_VAR_IMPORT_ is defined. */
-#define _NEED_VAR_IMPORT_
-
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <signal.h>
-#ifdef HAVE_LIBPCAP
-#include <pcap.h>
-#include <setjmp.h>
-#endif
-
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include "getopt.h"
#endif
-#include "svnversion.h"
-
#include <glib.h>
#include <epan/epan.h>
#include <epan/filesystem.h>
#include "util.h"
#include "clopts_common.h"
#include "version_info.h"
-#ifdef HAVE_LIBPCAP
-#include "pcap-util.h"
-#endif
#include <epan/conversation.h>
#include <epan/plugins.h>
#include "register.h"
#include "capture_ui_utils.h"
#include <epan/epan_dissect.h>
#include <epan/tap.h>
+#include <epan/stat_cmd_args.h>
#include <epan/timestamp.h>
#ifdef HAVE_LIBPCAP
+#include <pcap.h>
+#include <setjmp.h>
+#include "pcap-util.h"
#include <wiretap/wtap-capture.h>
#include <wiretap/libpcap.h>
-#endif
-
#ifdef _WIN32
#include "capture-wpcap.h"
-#endif
+#endif /* _WIN32 */
+#include "capture.h"
+#endif /* HAVE_LIBPCAP */
+#include "epan/emem.h"
/*
* This is the template for the decode as option; it is shared between the
*/
static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
-static guint32 firstsec, firstusec;
-static guint32 prevsec, prevusec;
+static nstime_t first_ts;
+static nstime_t prev_ts;
static GString *comp_info_str, *runtime_info_str;
-static gboolean quiet;
static gboolean print_packet_info; /* TRUE if we're to print packet information */
/*
static print_stream_t *print_stream;
#ifdef HAVE_LIBPCAP
+/*
+ * TRUE if we're to print packet counts to keep track of captured packets.
+ */
+static gboolean print_packet_counts;
+
typedef struct _loop_data {
gboolean go; /* TRUE as long as we're supposed to keep capturing */
gint linktype;
gboolean from_pipe; /* TRUE if we are capturing data from a pipe */
pcap_t *pch;
+ char *save_file; /* Name of file to which we're writing */
wtap_dumper *pdh;
jmp_buf stopenv;
gboolean output_to_pipe;
STATE_EXPECT_REC_HDR, STATE_READ_REC_HDR,
STATE_EXPECT_DATA, STATE_READ_DATA
} pipe_state;
-
enum { PIPOK, PIPEOF, PIPERR, PIPNEXIST } pipe_err;
#endif
} loop_data;
static loop_data ld;
#ifdef HAVE_LIBPCAP
-typedef struct {
- gchar *save_file; /* File that user saved capture to */
- int snaplen; /* Maximum captured packet length */
- int promisc_mode; /* Capture in promiscuous mode */
- int autostop_count; /* Maximum packet count */
- gboolean has_autostop_duration; /* TRUE if maximum capture duration
- is specified */
- gint32 autostop_duration; /* Maximum capture duration */
- gboolean has_autostop_filesize; /* TRUE if maximum capture file size
- is specified */
- gint32 autostop_filesize; /* Maximum capture file size */
- gboolean ringbuffer_on; /* TRUE if ring buffer in use */
- guint32 ringbuffer_num_files; /* Number of ring buffer files */
- gboolean has_ring_duration; /* TRUE if ring duration specified */
- gint32 ringbuffer_duration; /* Switch file after n seconds */
- int linktype; /* Data link type to use, or -1 for
- "use default" */
-} capture_options;
-
-static capture_options capture_opts = {
- "",
- WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
- infinite, in effect */
- TRUE, /* promiscuous mode is the default */
- 0, /* max packet count - default is 0,
- meaning infinite */
- FALSE, /* maximum capture duration not
- specified by default */
- 0, /* maximum capture duration */
- FALSE, /* maximum capture file size not
- specified by default */
- 0, /* maximum capture file size */
- FALSE, /* ring buffer off by default */
- RINGBUFFER_MIN_NUM_FILES, /* default number of ring buffer
- files */
- FALSE, /* Switch ring file after some */
- 0, /* specified time is off by default */
- -1 /* Default to not change link type */
-};
+static capture_options capture_opts;
-static gboolean list_link_layer_types;
#ifdef SIGINFO
static gboolean infodelay; /* if TRUE, don't print capture info in SIGINFO handler */
#endif /* HAVE_LIBPCAP */
-static int capture(int);
-static void capture_pcap_cb(guchar *, const struct pcap_pkthdr *,
- const guchar *);
+static int capture(char *, int);
+static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
static void report_counts(void);
#ifdef _WIN32
static BOOL WINAPI capture_cleanup(DWORD);
#endif /* _WIN32 */
#endif /* HAVE_LIBPCAP */
-static int load_cap_file(capture_file *, capture_options *capture_opts, int);
+static int load_cap_file(capture_file *, char *, int);
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);
static gboolean write_preamble(capture_file *cf);
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
static gboolean write_finale(void);
-static char *cf_open_error_message(int err, gchar *err_info,
+static const char *cf_open_error_message(int err, gchar *err_info,
gboolean for_writing, int file_type);
#ifdef HAVE_LIBPCAP
#ifndef _WIN32
if (print_ver) {
output = stdout;
- fprintf(output, "This is GNU t" PACKAGE " " VERSION
-#ifdef SVNVERSION
- " (" SVNVERSION ")"
-#endif
- "\n (C) 1998-2004 Gerald Combs <gerald@ethereal.com>"
+ fprintf(output, "This is t" PACKAGE " " VERSION "%s"
+ "\n (C) 1998-2005 Gerald Combs <gerald@ethereal.com>"
"\n%s\n%s\n",
- comp_info_str->str, runtime_info_str->str);
+ svnversion, comp_info_str->str, runtime_info_str->str);
} else {
output = stderr;
}
#ifdef HAVE_LIBPCAP
fprintf(output, "\nt%s [ -vh ] [ -DlLnpqSVx ] [ -a <capture autostop condition> ] ...\n",
PACKAGE);
- fprintf(output, "\t[ -b <number of ring buffer files>[:<duration>] ] [ -c <count> ]\n");
+ fprintf(output, "\t[ -b <capture ring buffer option> ] ... [ -c <capture packet count> ]\n");
fprintf(output, "\t[ -d %s ] ...\n", decode_as_arg_template);
- fprintf(output, "\t[ -f <capture filter> ] [ -F <output file type> ] [ -i <interface> ]\n");
- fprintf(output, "\t[ -N <resolving> ] [ -o <preference setting> ] ... [ -r <infile> ]\n");
- fprintf(output, "\t[ -R <read filter> ] [ -s <snaplen> ] [ -t <time stamp format> ]\n");
- fprintf(output, "\t[ -T pdml|ps|psml|text ] [ -w <savefile> ] [ -y <link type> ]\n");
- fprintf(output, "\t[ -z <statistics string> ]\n");
+ fprintf(output, "\t[ -f <capture filter> ] [ -F <output file type> ]\n");
+ fprintf(output, "\t[ -i <capture interface> ] [ -N <name resolving flags> ]\n");
+ fprintf(output, "\t[ -o <preference setting> ] ... [ -r <infile> ]\n");
+ fprintf(output, "\t[ -R <read (display) filter> ] [ -s <capture snaplen> ]\n");
+ fprintf(output, "\t[ -t <time stamp format> ] [ -T pdml|ps|psml|text ]\n");
+ fprintf(output, "\t[ -w <savefile> ] [ -y <capture link type> ] [ -z <statistics> ]\n");
#else
fprintf(output, "\nt%s [ -vh ] [ -lnVx ]\n", PACKAGE);
fprintf(output, "\t[ -d %s ] ...\n", decode_as_arg_template);
- fprintf(output, "\t[ -F <output file type> ] [ -N <resolving> ]\n");
- fprintf(output, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
- fprintf(output, "\t[ -t <time stamp format> ] [ -T pdml|ps|psml|text ] [ -w <savefile> ]\n");
- fprintf(output, "\t[ -z <statistics string> ]\n");
+ fprintf(output, "\t[ -F <output file type> ] [ -N <name resolving flags> ]\n");
+ fprintf(output, "\t[ -o <preference setting> ] ... [ -r <infile> ]\n");
+ fprintf(output, "\t[ -R <read (display) filter> ] \t[ -t <time stamp format> ]\n");
+ fprintf(output, "\t[ -T pdml|ps|psml|text ] [ -w <savefile> ] [ -z <statistics ]\n");
#endif
fprintf(output, "Valid file type arguments to the \"-F\" flag:\n");
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
fprintf(output, "\tdefault is libpcap\n");
}
-#ifdef HAVE_LIBPCAP
-static int
-get_natural_int(const char *string, const char *name)
-{
- long number;
- char *p;
-
- number = strtol(string, &p, 10);
- if (p == string || *p != '\0') {
- fprintf(stderr, "tethereal: The specified %s \"%s\" isn't a decimal number\n",
- name, string);
- exit(1);
- }
- if (number < 0) {
- fprintf(stderr, "tethereal: The specified %s is a negative number\n",
- name);
- exit(1);
- }
- if (number > INT_MAX) {
- fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
- name, INT_MAX);
- exit(1);
- }
- return number;
-}
-
-static int
-get_positive_int(const char *string, const char *name)
-{
- long number;
-
- number = get_natural_int(string, name);
-
- if (number == 0) {
- fprintf(stderr, "tethereal: The specified %s is zero\n",
- name);
- exit(1);
- }
-
- return number;
-}
-
-/*
- * Given a string of the form "<autostop criterion>:<value>", as might appear
- * as an argument to a "-a" option, parse it and set the criterion in
- * question. Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-set_autostop_criterion(const char *autostoparg)
-{
- guchar *p, *colonp;
-
- colonp = strchr(autostoparg, ':');
- if (colonp == NULL)
- return FALSE;
-
- p = colonp;
- *p++ = '\0';
-
- /*
- * Skip over any white space (there probably won't be any, but
- * as we allow it in the preferences file, we might as well
- * allow it here).
- */
- while (isspace(*p))
- p++;
- if (*p == '\0') {
- /*
- * Put the colon back, so if our caller uses, in an
- * error message, the string they passed us, the message
- * looks correct.
- */
- *colonp = ':';
- return FALSE;
- }
- if (strcmp(autostoparg,"duration") == 0) {
- capture_opts.has_autostop_duration = TRUE;
- capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
- } else if (strcmp(autostoparg,"filesize") == 0) {
- capture_opts.has_autostop_filesize = TRUE;
- capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
- } else {
- return FALSE;
- }
- *colonp = ':'; /* put the colon back */
- return TRUE;
-}
-
-/*
- * Given a string of the form "<ring buffer file>:<duration>", as might appear
- * as an argument to a "-b" option, parse it and set the arguments in
- * question. Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_ring_arguments(const char *arg)
-{
- guchar *p = NULL, *colonp;
-
- colonp = strchr(arg, ':');
-
- if (colonp != NULL) {
- p = colonp;
- *p++ = '\0';
- }
-
- capture_opts.ringbuffer_num_files =
- get_natural_int(arg, "number of ring buffer files");
-
- if (colonp == NULL)
- return TRUE;
-
- /*
- * Skip over any white space (there probably won't be any, but
- * as we allow it in the preferences file, we might as well
- * allow it here).
- */
- while (isspace(*p))
- p++;
- if (*p == '\0') {
- /*
- * Put the colon back, so if our caller uses, in an
- * error message, the string they passed us, the message
- * looks correct.
- */
- *colonp = ':';
- return FALSE;
- }
-
- capture_opts.has_ring_duration = TRUE;
- capture_opts.ringbuffer_duration = get_positive_int(p,
- "ring buffer duration");
-
- *colonp = ':'; /* put the colon back */
- return TRUE;
-}
-#endif
-
-/* structure to keep track of what tap listeners have been registered.
- */
-typedef struct _ethereal_tap_list {
- struct _ethereal_tap_list *next;
- char *cmd;
- void (*func)(char *arg);
-} ethereal_tap_list;
-static ethereal_tap_list *tap_list=NULL;
-
-void
-register_ethereal_tap(char *cmd, void (*func)(char *arg))
-{
- ethereal_tap_list *newtl;
-
- newtl=malloc(sizeof(ethereal_tap_list));
- newtl->next=tap_list;
- tap_list=newtl;
- newtl->cmd=cmd;
- newtl->func=func;
-
-}
-
/*
* For a dissector table, print on the stream described by output,
* its short name (which is what's used in the "-d" option) and its
* descriptive name.
*/
static void
-display_dissector_table_names(char *table_name, char *ui_name, gpointer output)
+display_dissector_table_names(char *table_name, const char *ui_name,
+ gpointer output)
{
fprintf((FILE *)output, "\t%s (%s)\n", table_name, ui_name);
}
* name for the protocol that corresponds to this handle.
*/
static void
-display_dissector_names(gchar *table _U_, gpointer handle, gpointer output)
+display_dissector_names(const gchar *table _U_, gpointer handle, gpointer output)
{
int proto_id;
const gchar* proto_filter_name;
* whole list of dissectors.
*/
static void
-find_protocol_name_func(gchar *table _U_, gpointer handle, gpointer user_data)
+find_protocol_name_func(const gchar *table _U_, gpointer handle, gpointer user_data)
{
int proto_id;
char *p;
gchar err_str[PCAP_ERRBUF_SIZE];
gchar *cant_get_if_list_errstr;
+ gboolean list_link_layer_types = FALSE;
#else
gboolean capture_option_specified = FALSE;
#endif
+ gboolean quiet = FALSE;
+ gchar *save_file = NULL;
int out_file_type = WTAP_FILE_PCAP;
gchar *cf_name = NULL, *rfilter = NULL;
#ifdef HAVE_LIBPCAP
+ gboolean start_capture = FALSE;
gchar *if_text;
GList *lt_list, *lt_entry;
data_link_info_t *data_link_info;
dfilter_t *rfcode = NULL;
e_prefs *prefs;
char badopt;
- ethereal_tap_list *tli;
- set_timestamp_setting(TS_RELATIVE);
+ /* initialize memory allocation subsystem */
+ ep_init_chunk();
+ se_init_chunk();
+
+#ifdef HAVE_LIBPCAP
+ capture_opts_init(&capture_opts, NULL /* cfile */);
+#endif
+
+ timestamp_set_type(TS_RELATIVE);
+ timestamp_set_precision(TS_PREC_AUTO);
/* Register all dissectors; we must do this before checking for the
"-G" flag, as the "-G" flag dumps information registered by the
/* Register all tap listeners; we do this before we parse the arguments,
as the "-z" argument can specify a registered tap. */
+
+ /* we register the plugin taps before the other taps because
+ stats_tree taps plugins will be registered as tap listeners
+ by stats_tree_stat.c and need to registered before that */
+#ifdef HAVE_PLUGINS
+ register_all_plugin_tap_listeners();
+#endif
register_all_tap_listeners();
/* Now register the preferences for any non-dissector modules.
while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) {
switch (opt) {
case 'a': /* autostop criteria */
-#ifdef HAVE_LIBPCAP
- if (set_autostop_criterion(optarg) == FALSE) {
- fprintf(stderr, "tethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
- exit(1);
- }
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'b': /* Ringbuffer option */
-#ifdef HAVE_LIBPCAP
- capture_opts.ringbuffer_on = TRUE;
- if (get_ring_arguments(optarg) == FALSE) {
- fprintf(stderr, "tethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
- exit(1);
- }
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'c': /* Capture xxx packets */
+ case 'f': /* capture filter */
+ case 'p': /* Don't capture in promiscuous mode */
+ case 's': /* Set the snapshot (capture) length */
+ case 'y': /* Set the pcap data link type */
#ifdef HAVE_LIBPCAP
- capture_opts.autostop_count =
- get_positive_int(optarg, "packet count");
+ capture_opts_add_opt(&capture_opts, "tethereal", opt, optarg, &start_capture);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
arg_error = TRUE;
#endif
break;
- case 'f':
-#ifdef HAVE_LIBPCAP
- capture_filter_specified = TRUE;
- if (cfile.cfilter)
- g_free(cfile.cfilter);
- cfile.cfilter = g_strdup(optarg);
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'F':
out_file_type = wtap_short_string_to_file_type(optarg);
if (out_file_type < 0) {
fprintf(stderr, "tethereal: there is no interface with that adapter index\n");
exit(1);
}
- cfile.iface = g_strdup(if_info->name);
+ capture_opts.iface = g_strdup(if_info->name);
free_interface_list(if_list);
} else
- cfile.iface = g_strdup(optarg);
+ capture_opts.iface = g_strdup(optarg);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
break;
}
break;
- case 'p': /* Don't capture in promiscuous mode */
-#ifdef HAVE_LIBPCAP
- capture_opts.promisc_mode = FALSE;
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'q': /* Quiet */
quiet = TRUE;
break;
case 'R': /* Read file filter */
rfilter = optarg;
break;
- case 's': /* Set the snapshot (capture) length */
-#ifdef HAVE_LIBPCAP
- capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'S': /* show packets in real time */
print_packet_info = TRUE;
break;
case 't': /* Time stamp type */
if (strcmp(optarg, "r") == 0)
- set_timestamp_setting(TS_RELATIVE);
+ timestamp_set_type(TS_RELATIVE);
else if (strcmp(optarg, "a") == 0)
- set_timestamp_setting(TS_ABSOLUTE);
+ timestamp_set_type(TS_ABSOLUTE);
else if (strcmp(optarg, "ad") == 0)
- set_timestamp_setting(TS_ABSOLUTE_WITH_DATE);
+ timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
else if (strcmp(optarg, "d") == 0)
- set_timestamp_setting(TS_DELTA);
+ timestamp_set_type(TS_DELTA);
else {
fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
optarg);
}
break;
case 'v': /* Show version and exit */
- printf("t" PACKAGE " " VERSION
-#ifdef SVNVERSION
- " (" SVNVERSION ")"
-#endif
- "\n%s\n%s\n",
- comp_info_str->str, runtime_info_str->str);
+ printf("t" PACKAGE " " VERSION "%s\n%s\n%s\n",
+ svnversion, comp_info_str->str, runtime_info_str->str);
exit(0);
break;
case 'w': /* Write to capture file xxx */
- capture_opts.save_file = g_strdup(optarg);
+ save_file = g_strdup(optarg);
break;
case 'V': /* Verbose */
verbose = TRUE;
case 'x': /* Print packet data in hex (and ASCII) */
print_hex = TRUE;
break;
- case 'y': /* Set the pcap data link type */
-#ifdef HAVE_LIBPCAP
-#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
- capture_opts.linktype = pcap_datalink_name_to_val(optarg);
- if (capture_opts.linktype == -1) {
- fprintf(stderr, "tethereal: The specified data link type \"%s\" isn't valid\n",
- optarg);
- exit(1);
- }
-#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
- /* XXX - just treat it as a number */
- capture_opts.linktype = get_natural_int(optarg, "data link type");
-#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'z':
- for(tli=tap_list;tli;tli=tli->next){
- if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){
- (*tli->func)(optarg);
- break;
- }
- }
- if(!tli){
- fprintf(stderr,"tethereal: invalid -z argument.\n");
- fprintf(stderr," -z argument must be one of :\n");
- for(tli=tap_list;tli;tli=tli->next){
- fprintf(stderr," %s\n",tli->cmd);
- }
- exit(1);
- }
+ /* We won't call the init function for the stat this soon
+ as it would disallow MATE's fields (which are registered
+ by the preferences set callback) from being used as
+ part of a tap filter. Instead, we just add the argument
+ to a list of stat arguments. */
+ if (!process_stat_cmd_arg(optarg)) {
+ fprintf(stderr,"tethereal: invalid -z argument.\n");
+ fprintf(stderr," -z argument must be one of :\n");
+ list_stat_cmd_args();
+ exit(1);
+ }
break;
default:
case '?': /* Bad flag - print usage message */
"tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
exit(2);
}
- cfile.cfilter = get_args_as_string(argc, argv, optind);
+ capture_opts.cfilter = get_args_as_string(argc, argv, optind);
#else
capture_option_specified = TRUE;
#endif
#ifdef HAVE_LIBPCAP
ld.output_to_pipe = FALSE;
#endif
- if (capture_opts.save_file != NULL) {
+ if (save_file != NULL) {
/* We're writing to a capture file. */
- if (strcmp(capture_opts.save_file, "-") == 0) {
+ if (strcmp(save_file, "-") == 0) {
/* Write to the standard output. */
- g_free(capture_opts.save_file);
- capture_opts.save_file = g_strdup("");
+ g_free(save_file);
+ save_file = g_strdup("");
#ifdef HAVE_LIBPCAP
/* XXX - should we check whether it's a pipe? It's arguably
silly to do "-w - >output_file" rather than "-w output_file",
}
#ifdef HAVE_LIBPCAP
else {
- err = test_for_fifo(capture_opts.save_file);
+ err = test_for_fifo(save_file);
switch (err) {
case ENOENT: /* it doesn't exist, so we'll be creating it,
exit(1);
}
/* No - did they specify a ring buffer option? */
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
fprintf(stderr, "tethereal: Ring buffer requested, but a capture isn't being done.\n");
exit(1);
}
} else {
/* If they didn't specify a "-w" flag, but specified a maximum capture
file size, tell them that this doesn't work, and exit. */
- if (capture_opts.has_autostop_filesize && capture_opts.save_file == NULL) {
+ if (capture_opts.has_autostop_filesize && save_file == NULL) {
fprintf(stderr, "tethereal: Maximum capture file size specified, but "
"capture isn't being saved to a file.\n");
exit(1);
}
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
/* Ring buffer works only under certain conditions:
a) ring buffer does not work if you're not saving the capture to
a file;
c) it makes no sense to enable the ring buffer if the maximum
file size is set to "infinite";
d) file must not be a pipe. */
- if (capture_opts.save_file == NULL) {
+ if (save_file == NULL) {
fprintf(stderr, "tethereal: Ring buffer requested, but "
"capture isn't being saved to a file.\n");
exit(1);
line that their preferences have changed. */
prefs_apply_all();
+ /* At this point MATE will have registered its field array so we can
+ have a tap filter with one of MATE's late-registered fields as part
+ of the filter. We can now process all the "-z" arguments. */
+ start_requested_stats();
+
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
else if (capture_opts.snaplen < MIN_PACKET_SIZE)
capture_opts.snaplen = MIN_PACKET_SIZE;
- /* Check the value range of the ringbuffer_num_files parameter */
- if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
- capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
+ /* Check the value range of the ring_num_files parameter */
+ if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
+ capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
#if RINGBUFFER_MIN_NUM_FILES > 0
- else if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
- capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
+ else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
+ capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
#endif
#endif
epan_cleanup();
exit(2);
}
- err = load_cap_file(&cfile, &capture_opts, out_file_type);
+
+ /* Set timestamp precision; there should arguably be a command-line
+ option to let the user set this. */
+ switch(wtap_file_tsprecision(cfile.wth)) {
+ case(WTAP_FILE_TSPREC_SEC):
+ timestamp_set_precision(TS_PREC_AUTO_SEC);
+ break;
+ case(WTAP_FILE_TSPREC_DSEC):
+ timestamp_set_precision(TS_PREC_AUTO_DSEC);
+ break;
+ case(WTAP_FILE_TSPREC_CSEC):
+ timestamp_set_precision(TS_PREC_AUTO_CSEC);
+ break;
+ case(WTAP_FILE_TSPREC_MSEC):
+ timestamp_set_precision(TS_PREC_AUTO_MSEC);
+ break;
+ case(WTAP_FILE_TSPREC_USEC):
+ timestamp_set_precision(TS_PREC_AUTO_USEC);
+ break;
+ case(WTAP_FILE_TSPREC_NSEC):
+ timestamp_set_precision(TS_PREC_AUTO_NSEC);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ /* Process the packets in the file */
+ err = load_cap_file(&cfile, save_file, out_file_type);
if (err != 0) {
epan_cleanup();
exit(2);
#ifdef _WIN32
if (!has_wpcap) {
- fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
- exit(2);
+ fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
+ exit(2);
}
#endif
/* Yes; did the user specify an interface to use? */
- if (cfile.iface == NULL) {
- /* No - is a default specified in the preferences file? */
- if (prefs->capture_device != NULL) {
- /* Yes - use it. */
- if_text = strrchr(prefs->capture_device, ' ');
- if (if_text == NULL) {
- cfile.iface = g_strdup(prefs->capture_device);
- } else {
- cfile.iface = g_strdup(if_text + 1); /* Skip over space */
- }
- } else {
- /* No - pick the first one from the list of interfaces. */
- if_list = get_interface_list(&err, err_str);
- if (if_list == NULL) {
- switch (err) {
-
- case CANT_GET_INTERFACE_LIST:
- cant_get_if_list_errstr =
- cant_get_if_list_error_message(err_str);
- fprintf(stderr, "tethereal: %s\n", cant_get_if_list_errstr);
- g_free(cant_get_if_list_errstr);
- break;
-
- case NO_INTERFACES_FOUND:
- fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
- break;
- }
- exit(2);
- }
- if_info = if_list->data; /* first interface */
- cfile.iface = g_strdup(if_info->name);
- free_interface_list(if_list);
- }
+ if (capture_opts.iface == NULL) {
+ /* No - is a default specified in the preferences file? */
+ if (prefs->capture_device != NULL) {
+ /* Yes - use it. */
+ if_text = strrchr(prefs->capture_device, ' ');
+ if (if_text == NULL) {
+ capture_opts.iface = g_strdup(prefs->capture_device);
+ } else {
+ capture_opts.iface = g_strdup(if_text + 1); /* Skip over space */
+ }
+ } else {
+ /* No - pick the first one from the list of interfaces. */
+ if_list = get_interface_list(&err, err_str);
+ if (if_list == NULL) {
+ switch (err) {
+
+ case CANT_GET_INTERFACE_LIST:
+ cant_get_if_list_errstr = cant_get_if_list_error_message(err_str);
+ fprintf(stderr, "tethereal: %s\n", cant_get_if_list_errstr);
+ g_free(cant_get_if_list_errstr);
+ break;
+
+ case NO_INTERFACES_FOUND:
+ fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
+ break;
+ }
+ exit(2);
+ }
+ if_info = if_list->data; /* first interface */
+ capture_opts.iface = g_strdup(if_info->name);
+ free_interface_list(if_list);
+ }
}
if (list_link_layer_types) {
/* We were asked to list the link-layer types for an interface.
Get the list of link-layer types for the capture device. */
- lt_list = get_pcap_linktype_list(cfile.iface, err_str);
+ lt_list = get_pcap_linktype_list(capture_opts.iface, err_str);
if (lt_list == NULL) {
if (err_str[0] != '\0') {
fprintf(stderr, "tethereal: The list of data link types for the capture device could not be obtained (%s).\n"
exit(0);
}
- capture(out_file_type);
+ if (!quiet) {
+ /*
+ * The user didn't ask us not to print a count of packets as
+ * they arrive, so do so.
+ */
+ print_packet_counts = TRUE;
+ }
- if (capture_opts.ringbuffer_on) {
+ /* For now, assume libpcap gives microsecond precision. */
+ timestamp_set_precision(TS_PREC_AUTO_USEC);
+
+ capture(save_file, out_file_type);
+
+ if (capture_opts.multi_files_on) {
ringbuf_free();
}
#else
static condition *volatile cnd_ring_timeout = NULL; /* this must be visible in process_packet */
static int
-capture(int out_file_type)
+capture(char *save_file, int out_file_type)
{
int pcap_encap;
int file_snaplen;
#ifndef _WIN32
void (*oldhandler)(int);
static const char ppamsg[] = "can't find PPA for ";
- char *libpcap_warn;
+ const char *libpcap_warn;
volatile int pipe_fd = -1;
struct pcap_hdr hdr;
struct pcaprec_modified_hdr rechdr;
if they succeed; to tell if that's happened, we have to clear
the error buffer, and check if it's still a null string. */
open_err_str[0] = '\0';
- ld.pch = pcap_open_live(cfile.iface, capture_opts.snaplen,
+ ld.pch = pcap_open_live(capture_opts.iface, capture_opts.snaplen,
capture_opts.promisc_mode, 1000, open_err_str);
if (ld.pch != NULL) {
/* setting the data link type only works on real interfaces */
if (capture_opts.linktype != -1) {
- set_linktype_err_str = set_pcap_linktype(ld.pch, cfile.iface,
+ set_linktype_err_str = set_pcap_linktype(ld.pch, capture_opts.iface,
capture_opts.linktype);
if (set_linktype_err_str != NULL) {
- snprintf(errmsg, sizeof errmsg, "Unable to set data link type (%s).",
+ g_snprintf(errmsg, sizeof errmsg, "Unable to set data link type (%s).",
set_linktype_err_str);
goto error;
}
users; don't warn about permissions problems.
Do, however, warn that WAN devices aren't supported. */
- snprintf(errmsg, sizeof errmsg,
- "The capture session could not be initiated (%s).\n"
- "Please check that you have the proper interface specified.\n"
- "\n"
- "Note that the WinPcap 2.x version of the driver Ethereal uses for packet\n"
- "capture on Windows doesn't support capturing on PPP/WAN interfaces in\n"
- "Windows NT/2000/XP/2003 Server, and that the WinPcap 3.0 and later versions\n"
- "don't support capturing on PPP/WAN interfaces at all.\n",
+ g_snprintf(errmsg, sizeof errmsg,
+"The capture session could not be initiated (%s).\n"
+"Please check that you have the proper interface specified.\n"
+"\n"
+"Note that version 3.0 of WinPcap, and earlier versions of WinPcap, don't\n"
+"support capturing on PPP/WAN interfaces on Windows NT 4.0 / 2000 / XP /\n"
+"Server 2003.\n"
+"WinPcap 3.1 has support for it on Windows 2000 / XP / Server 2003, but has no\n"
+"support for it on Windows NT 4.0 or Windows Vista (Beta 1).\n",
open_err_str);
goto error;
#else
/* try to open cfile.iface as a pipe */
- pipe_fd = pipe_open_live(cfile.iface, &hdr, &ld, errmsg, sizeof errmsg);
+ pipe_fd = pipe_open_live(capture_opts.iface, &hdr, &ld, errmsg,
+ sizeof errmsg);
if (pipe_fd == -1) {
"at the URL lists a number of mirror sites.";
else
libpcap_warn = "";
- snprintf(errmsg, sizeof errmsg,
+ g_snprintf(errmsg, sizeof errmsg,
"The capture session could not be initiated (%s).\n"
"Please check to make sure you have sufficient permissions, and that\n"
"you have the proper interface or pipe specified.%s", open_err_str,
setgid(getgid());
#endif
- if (cfile.cfilter && !ld.from_pipe) {
+ if (capture_opts.cfilter && !ld.from_pipe) {
/* A capture filter was specified; set it up. */
- if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
+ if (pcap_lookupnet(capture_opts.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
/*
* Well, we can't get the netmask for this interface; it's used
* only for filters that check for broadcast IP addresses, so
"Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
netmask = 0;
}
- if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
- if (dfilter_compile(cfile.cfilter, &rfcode)) {
- snprintf(errmsg, sizeof errmsg,
+ if (pcap_compile(ld.pch, &fcode, capture_opts.cfilter, 1, netmask) < 0) {
+ if (dfilter_compile(capture_opts.cfilter, &rfcode)) {
+ g_snprintf(errmsg, sizeof errmsg,
"Unable to parse capture filter string (%s).\n"
" Interestingly enough, this looks like a valid display filter\n"
" Are you sure you didn't mix them up?",
pcap_geterr(ld.pch));
} else {
- snprintf(errmsg, sizeof errmsg,
+ g_snprintf(errmsg, sizeof errmsg,
"Unable to parse capture filter string (%s).",
pcap_geterr(ld.pch));
}
goto error;
}
if (pcap_setfilter(ld.pch, &fcode) < 0) {
- snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
+ g_snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
pcap_geterr(ld.pch));
+#ifdef HAVE_PCAP_FREECODE
+ pcap_freecode(&fcode);
+#endif
goto error;
}
+#ifdef HAVE_PCAP_FREECODE
+ pcap_freecode(&fcode);
+#endif
}
/* Set up to write to the capture file. */
} else
#endif
{
- pcap_encap = get_pcap_linktype(ld.pch, cfile.iface);
+ pcap_encap = get_pcap_linktype(ld.pch, capture_opts.iface);
file_snaplen = pcap_snapshot(ld.pch);
}
ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
- if (capture_opts.save_file != NULL) {
+ if (save_file != NULL) {
/* Set up to write to the capture file. */
if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
strcpy(errmsg, "The network you're capturing from is of a type"
" that Tethereal doesn't support.");
goto error;
}
- if (capture_opts.ringbuffer_on) {
- save_file_fd = ringbuf_init(capture_opts.save_file,
- capture_opts.ringbuffer_num_files);
+ ld.save_file = save_file;
+ if (capture_opts.multi_files_on) {
+ save_file_fd = ringbuf_init(save_file,
+ capture_opts.ring_num_files);
if (save_file_fd != -1) {
ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
file_snaplen, &err);
ld.pdh = NULL;
}
} else {
- ld.pdh = wtap_dump_open(capture_opts.save_file, out_file_type,
- ld.linktype, file_snaplen, &err);
+ ld.pdh = wtap_dump_open(save_file, out_file_type,
+ ld.linktype, file_snaplen, FALSE /* compress */, &err);
}
if (ld.pdh == NULL) {
- snprintf(errmsg, sizeof errmsg,
+ g_snprintf(errmsg, sizeof errmsg,
cf_open_error_message(err, NULL, TRUE, out_file_type),
- *capture_opts.save_file == '\0' ? "stdout" : capture_opts.save_file);
+ *save_file == '\0' ? "stdout" : save_file);
goto error;
}
}
#endif /* _WIN32 */
/* Let the user know what interface was chosen. */
- descr = get_interface_descriptive_name(cfile.iface);
+ descr = get_interface_descriptive_name(capture_opts.iface);
fprintf(stderr, "Capturing on %s\n", descr);
g_free(descr);
cnd_stop_timeout = cnd_new((const char*)CND_CLASS_TIMEOUT,
(gint32)capture_opts.autostop_duration);
- if (capture_opts.ringbuffer_on && capture_opts.has_ring_duration)
+ if (capture_opts.multi_files_on && capture_opts.has_file_duration)
cnd_ring_timeout = cnd_new(CND_CLASS_TIMEOUT,
- capture_opts.ringbuffer_duration);
+ capture_opts.file_duration);
if (!setjmp(ld.stopenv)) {
ld.go = TRUE;
reading the FIFO sees the packets immediately and doesn't get
any partial packet, forcing it to block in the middle of reading
that packet. */
- if (capture_opts.autostop_count == 0)
+ if (capture_opts.autostop_packets == 0)
pcap_cnt = -1;
else {
- if (ld.packet_count >= capture_opts.autostop_count) {
+ if (ld.packet_count >= capture_opts.autostop_packets) {
/* XXX do we need this test here? */
/* It appears there's nothing more to capture. */
break;
}
- pcap_cnt = capture_opts.autostop_count - ld.packet_count;
+ pcap_cnt = capture_opts.autostop_packets - ld.packet_count;
}
} else {
/* We need to check the capture file size or the timeout after
errmsg, sizeof errmsg);
} else
#endif
- inpkts = pcap_dispatch(ld.pch, pcap_cnt, capture_pcap_cb, (guchar *) &ld);
+ inpkts = pcap_dispatch(ld.pch, pcap_cnt, capture_pcap_cb, (u_char *) &ld);
if (inpkts < 0) {
/* Error from "pcap_dispatch()", or error or "no more packets" from
"pipe_dispatch(). */
/* The specified capture time has elapsed; stop the capture. */
ld.go = FALSE;
} else if (inpkts > 0) {
- if (capture_opts.autostop_count != 0 &&
- ld.packet_count >= capture_opts.autostop_count) {
+ if (capture_opts.autostop_packets != 0 &&
+ ld.packet_count >= capture_opts.autostop_packets) {
/* The specified number of packets have been captured and have
passed both any capture filter in effect and any read filter
in effect. */
(guint32)wtap_get_bytes_dumped(ld.pdh))) {
/* We're saving the capture to a file, and the capture file reached
its maximum size. */
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&ld.pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
+ if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_stop_capturesize);
if (cnd_ring_timeout) {
}
if (ld.output_to_pipe) {
if (ld.packet_count > packet_count_prev) {
- if (fflush(wtap_dump_file(ld.pdh))) {
- volatile_err = errno;
- ld.go = FALSE;
- }
+ wtap_dump_flush(ld.pdh);
packet_count_prev = ld.packet_count;
}
}
if (cnd_ring_timeout != NULL)
cnd_delete(cnd_ring_timeout);
- if ((capture_opts.save_file != NULL) && !quiet) {
- /* We're saving to a file, which means we're printing packet counts
- to stderr if we are not running silent and deep.
+ if (print_packet_counts) {
+ /* We're printing packet counts to stderr.
Send a newline so that we move to the line after the packet count. */
fprintf(stderr, "\n");
}
if (volatile_err == 0)
write_err = FALSE;
else {
- show_capture_file_io_error(capture_opts.save_file, volatile_err, FALSE);
+ show_capture_file_io_error(save_file, volatile_err, FALSE);
write_err = TRUE;
}
- if (capture_opts.save_file != NULL) {
+ if (save_file != NULL) {
/* We're saving to a file or files; close all files. */
- if (capture_opts.ringbuffer_on) {
- dump_ok = ringbuf_wtap_dump_close(&capture_opts.save_file, &err);
+ if (capture_opts.multi_files_on) {
+ dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
} else {
dump_ok = wtap_dump_close(ld.pdh, &err);
}
/* If we've displayed a message about a write error, there's no point
in displaying another message about an error on close. */
if (!dump_ok && !write_err)
- show_capture_file_io_error(capture_opts.save_file, err, TRUE);
+ show_capture_file_io_error(save_file, err, TRUE);
}
#ifndef _WIN32
return TRUE;
error:
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
ringbuf_error_cleanup();
}
- g_free(capture_opts.save_file);
- capture_opts.save_file = NULL;
+ g_free(save_file);
+ save_file = NULL;
fprintf(stderr, "tethereal: %s\n", errmsg);
#ifndef _WIN32
if (ld.from_pipe) {
}
static void
-capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
- const guchar *pd)
+capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
+ const u_char *pd)
{
struct wtap_pkthdr whdr;
union wtap_pseudo_header pseudo_header;
*/
if (cnd_ring_timeout != NULL && cnd_eval(cnd_ring_timeout)) {
/* time elapsed for this ring file, switch to the next */
- if (ringbuf_switch_file(&ldat->pdh, &capture_opts.save_file, &save_file_fd, &loop_err)) {
+ if (ringbuf_switch_file(&ldat->pdh, &ldat->save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
cnd_reset(cnd_ring_timeout);
} else {
if (!process_packet(&cfile, ldat->pdh, 0, &whdr, &pseudo_header, pd, &err)) {
/* Error writing to a capture file */
- if (!quiet) {
- /* We're capturing packets, so (if -q not specified) we're printing
- a count of packets captured; move to the line after the count. */
+ 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(capture_opts.save_file, err, FALSE);
+ show_capture_file_io_error(ldat->save_file, err, FALSE);
pcap_close(ldat->pch);
wtap_dump_close(ldat->pdh, &err);
exit(2);
signal(SIGINFO, report_counts_siginfo);
#endif /* SIGINFO */
- if (quiet || print_packet_info) {
+ if (!print_packet_counts) {
/* Report the count only if we aren't printing a packet count
as packets arrive. */
fprintf(stderr, "%u packets captured\n", ld.packet_count);
#endif /* HAVE_LIBPCAP */
static int
-load_cap_file(capture_file *cf, capture_options *capture_opts, int out_file_type)
+load_cap_file(capture_file *cf, char *save_file, int out_file_type)
{
gint linktype;
int snapshot_length;
long data_offset;
linktype = wtap_file_encap(cf->wth);
- if (capture_opts->save_file != NULL) {
+ if (save_file != NULL) {
/* Set up to write to the capture file. */
snapshot_length = wtap_snapshot_length(cf->wth);
if (snapshot_length == 0) {
/* Snapshot length of input file not known. */
snapshot_length = WTAP_MAX_PACKET_SIZE;
}
- pdh = wtap_dump_open(capture_opts->save_file, out_file_type,
- linktype, snapshot_length, &err);
+ pdh = wtap_dump_open(save_file, out_file_type,
+ linktype, snapshot_length, FALSE /* compressed */, &err);
if (pdh == NULL) {
/* We couldn't set up to write to the capture file. */
fprintf(stderr,
"tethereal: The file \"%s\" couldn't be created for some "
"unknown reason.\n",
- *capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
+ *save_file == '\0' ? "stdout" : save_file);
break;
case WTAP_ERR_SHORT_WRITE:
fprintf(stderr,
"tethereal: A full header couldn't be written to the file \"%s\".\n",
- *capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file);
+ *save_file == '\0' ? "stdout" : save_file);
break;
default:
fprintf(stderr,
"tethereal: The file \"%s\" could not be created: %s\n.",
- *capture_opts->save_file == '\0' ? "stdout" : capture_opts->save_file,
+ *save_file == '\0' ? "stdout" : save_file,
wtap_strerror(err));
break;
}
wtap_pseudoheader(cf->wth), wtap_buf_ptr(cf->wth),
&err)) {
/* Error writing to a capture file */
- show_capture_file_io_error(capture_opts->save_file, err, FALSE);
+ show_capture_file_io_error(save_file, err, FALSE);
wtap_dump_close(pdh, &err);
exit(2);
}
cf->filename, wtap_strerror(err));
break;
}
- if (capture_opts->save_file != NULL) {
+ if (save_file != NULL) {
/* Now close the capture file. */
if (!wtap_dump_close(pdh, &err))
- show_capture_file_io_error(capture_opts->save_file, err, TRUE);
+ show_capture_file_io_error(save_file, err, TRUE);
}
} else {
- if (capture_opts->save_file != NULL) {
+ if (save_file != NULL) {
/* Now close the capture file. */
if (!wtap_dump_close(pdh, &err))
- show_capture_file_io_error(capture_opts->save_file, err, TRUE);
+ show_capture_file_io_error(save_file, err, TRUE);
} else {
if (print_packet_info) {
if (!write_finale()) {
fdata->cap_len = phdr->caplen;
fdata->file_off = offset;
fdata->lnk_t = phdr->pkt_encap;
- fdata->abs_secs = phdr->ts.tv_sec;
- fdata->abs_usecs = phdr->ts.tv_usec;
+ fdata->abs_ts = *((nstime_t *) &phdr->ts);
fdata->flags.passed_dfilter = 0;
fdata->flags.encoding = CHAR_ASCII;
fdata->flags.visited = 0;
/* If we don't have the time stamp of the first packet in the
capture, it's because this is the first packet. Save the time
stamp of this packet as the time stamp of the first packet. */
- if (!firstsec && !firstusec) {
- firstsec = fdata->abs_secs;
- firstusec = fdata->abs_usecs;
+ if (nstime_is_zero(&first_ts)) {
+ first_ts = fdata->abs_ts;
}
/* If we don't have the time stamp of the previous displayed packet,
it's because this is the first displayed packet. Save the time
stamp of this packet as the time stamp of the previous displayed
packet. */
- if (!prevsec && !prevusec) {
- prevsec = fdata->abs_secs;
- prevusec = fdata->abs_usecs;
+ if (nstime_is_zero(&prev_ts)) {
+ prev_ts = fdata->abs_ts;
}
/* Get the time elapsed between the first packet and this packet. */
- compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
- fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
+ nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
/* If it's greater than the current elapsed time, set the elapsed time
to it (we check for "greater than" so as not to be confused by
time moving backwards). */
- if ((gint32)cf->esec < fdata->rel_secs
- || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
- cf->esec = fdata->rel_secs;
- cf->eusec = fdata->rel_usecs;
+ if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
+ || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
+ cf->elapsed_time = fdata->rel_ts;
}
/* Get the time elapsed between the previous displayed packet and
this packet. */
- compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
- fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
- prevsec = fdata->abs_secs;
- prevusec = fdata->abs_usecs;
+ nstime_delta(&fdata->del_ts, &fdata->abs_ts, &prev_ts);
+ prev_ts = fdata->abs_ts;
}
/* Free up all data attached to a "frame_data" structure. */
if (!wtap_dump(pdh, whdr, pseudo_header, pd, err))
return FALSE;
#ifdef HAVE_LIBPCAP
- /* Report packet capture count if not quiet */
- if (!quiet && !print_packet_info) {
- /* Don't print a packet count if we were asked not to with "-q"
- or if we're also printing packet info. */
+ 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 */
for (i = 0; i < cf->cinfo.num_cols; i++) {
switch (cf->cinfo.col_fmt[i]) {
case COL_NUMBER:
+#ifdef HAVE_LIBPCAP
/*
* Don't print this if we're doing a live capture from a network
* interface - if we're doing a live capture, you won't be
* the same time, sort of like an "Update list of packets
* in real time" capture in Ethereal.)
*/
- if (cf->iface != NULL)
+ if (capture_opts.iface != NULL)
continue;
+#endif
column_len = strlen(cf->cinfo.col_data[i]);
if (column_len < 3)
column_len = 3;
}
}
-static char *
+static const char *
cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
int file_type)
{
- char *errmsg;
+ const char *errmsg;
static char errmsg_errno[1024+1];
if (err < 0) {
case WTAP_ERR_UNSUPPORTED:
/* Seen only when opening a capture file for reading. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" isn't a capture file in a format Tethereal understands.\n"
"(%s)", err_info);
g_free(err_info);
case WTAP_ERR_CANT_WRITE_TO_PIPE:
/* Seen only when opening a capture file for writing. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" is a pipe, and %s capture files can't be "
"written to a pipe.", wtap_file_type_string(file_type));
errmsg = errmsg_errno;
if (for_writing)
errmsg = "Tethereal can't save this capture in that format.";
else {
- snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" is a capture for a network type that Tethereal doesn't support.\n"
"(%s)", err_info);
g_free(err_info);
case WTAP_ERR_BAD_RECORD:
/* Seen only when opening a capture file for reading. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" appears to be damaged or corrupt.\n"
"(%s)", err_info);
g_free(err_info);
break;
default:
- snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" could not be %s: %s.",
for_writing ? "created" : "opened",
wtap_strerror(err));
fprintf(stderr, "\n");
}
-gboolean
-cf_open(capture_file *cf, char *fname, gboolean is_tempfile, int *err)
+cf_status_t
+cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
{
wtap *wth;
gchar *err_info;
init_dissection();
cf->wth = wth;
- cf->filed = -1; /* not used, but set it anyway */
- cf->f_len = 0; /* not used, but set it anyway */
+ cf->f_datalen = 0; /* not used, but set it anyway */
/* Set the file name because we need it to set the follow stream filter.
XXX - is that still true? We need it for other reasons, though,
cf->count = 0;
cf->drops_known = FALSE;
cf->drops = 0;
- cf->esec = 0;
- cf->eusec = 0;
cf->snap = wtap_snapshot_length(cf->wth);
if (cf->snap == 0) {
/* Snapshot length not known. */
cf->snap = WTAP_MAX_PACKET_SIZE;
} else
cf->has_snap = TRUE;
- firstsec = 0, firstusec = 0;
- prevsec = 0, prevusec = 0;
+ nstime_set_zero(&cf->elapsed_time);
+ nstime_set_zero(&first_ts);
+ nstime_set_zero(&prev_ts);
- return TRUE;
+ return CF_OK;
fail:
- snprintf(err_msg, sizeof err_msg,
+ g_snprintf(err_msg, sizeof err_msg,
cf_open_error_message(*err, err_info, FALSE, 0), fname);
fprintf(stderr, "tethereal: %s\n", err_msg);
- return FALSE;
+ return CF_ERROR;
}
#ifdef HAVE_LIBPCAP
if (errno == ENOENT || errno == ENOTDIR)
ldat->pipe_err = PIPNEXIST;
else {
- snprintf(errmsg, errmsgl,
+ g_snprintf(errmsg, errmsgl,
"The capture session could not be initiated "
"due to error on pipe: %s", strerror(errno));
ldat->pipe_err = PIPERR;
*/
ldat->pipe_err = PIPNEXIST;
} else {
- snprintf(errmsg, errmsgl,
+ g_snprintf(errmsg, errmsgl,
"The capture session could not be initiated because\n"
"\"%s\" is neither an interface nor a pipe", pipename);
ldat->pipe_err = PIPERR;
}
fd = open(pipename, O_RDONLY);
if (fd == -1) {
- snprintf(errmsg, errmsgl,
+ g_snprintf(errmsg, errmsgl,
"The capture session could not be initiated "
"due to error on pipe open: %s", strerror(errno));
ldat->pipe_err = PIPERR;
b = read(fd, ((char *)&magic)+bytes_read, sizeof magic-bytes_read);
if (b <= 0) {
if (b == 0)
- snprintf(errmsg, errmsgl, "End of file on pipe during open");
+ g_snprintf(errmsg, errmsgl, "End of file on pipe during open");
else
- snprintf(errmsg, errmsgl, "Error on pipe during open: %s",
+ g_snprintf(errmsg, errmsgl, "Error on pipe during open: %s",
strerror(errno));
goto error;
}
break;
default:
/* Not a "libpcap" type we know about. */
- snprintf(errmsg, errmsgl, "Unrecognized libpcap format");
+ g_snprintf(errmsg, errmsgl, "Unrecognized libpcap format");
goto error;
}
sizeof(struct pcap_hdr) - bytes_read);
if (b <= 0) {
if (b == 0)
- snprintf(errmsg, errmsgl, "End of file on pipe during open");
+ g_snprintf(errmsg, errmsgl, "End of file on pipe during open");
else
- snprintf(errmsg, errmsgl, "Error on pipe during open: %s",
+ g_snprintf(errmsg, errmsgl, "Error on pipe during open: %s",
strerror(errno));
goto error;
}
}
if (hdr->version_major < 2) {
- snprintf(errmsg, errmsgl, "Unable to read old libpcap format");
+ g_snprintf(errmsg, errmsgl, "Unable to read old libpcap format");
goto error;
}
break;
default:
- snprintf(errmsg, errmsgl, "pipe_dispatch: invalid state");
+ g_snprintf(errmsg, errmsgl, "pipe_dispatch: invalid state");
result = PD_ERR;
} /* switch (ldat->pipe_state) */
/* We've read the header. Take care of byte order. */
adjust_header(ldat, hdr, &rechdr->hdr);
if (rechdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
- snprintf(errmsg, errmsgl, "Frame %u too long (%d bytes)",
+ g_snprintf(errmsg, errmsgl, "Frame %u too long (%d bytes)",
ldat->packet_count+1, rechdr->hdr.incl_len);
break;
}
phdr.caplen = rechdr->hdr.incl_len;
phdr.len = rechdr->hdr.orig_len;
- capture_pcap_cb((guchar *)ldat, &phdr, data);
+ capture_pcap_cb((u_char *)ldat, &phdr, data);
ldat->pipe_state = STATE_EXPECT_REC_HDR;
return 1;
return -1;
case PD_PIPE_ERR:
- snprintf(errmsg, errmsgl, "Error reading from pipe: %s",
+ g_snprintf(errmsg, errmsgl, "Error reading from pipe: %s",
strerror(errno));
/* Fall through */
case PD_ERR: