aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2005-02-23 01:01:19 +0000
committerUlf Lamping <ulf.lamping@web.de>2005-02-23 01:01:19 +0000
commitd643a55488c80c97885abd72070c847dbc93b1ad (patch)
tree403435ea43801f2280a66ae8b9d6da8a4db12d82
parenta25fd8d7cae3a7516da1f67bb77f11fceebb36e8 (diff)
move capture_opts related things (init, command line, ...) from capture.c to a new file capture_opts.c and let both ethereal and tethereal use it.
svn path=/trunk/; revision=13474
-rw-r--r--Makefile.common2
-rw-r--r--capture.c272
-rw-r--r--capture_opts.c318
-rw-r--r--gtk/main.c3
-rw-r--r--tethereal.c274
5 files changed, 361 insertions, 508 deletions
diff --git a/Makefile.common b/Makefile.common
index 287c8e3856..a5b8964909 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -152,6 +152,7 @@ ethereal_SOURCES = \
$(ETHEREAL_COMMON_SRC) \
alert_box.c \
capture.c \
+ capture_opts.c \
capture_sync.c \
capture_loop.c \
color_filters.c \
@@ -186,6 +187,7 @@ ethereal_INCLUDES = \
tethereal_SOURCES = \
$(ETHEREAL_COMMON_SRC) \
$(TETHEREAL_TAP_SRC) \
+ capture_opts.c \
tethereal-tap-register.c \
tethereal.c
diff --git a/capture.c b/capture.c
index f6fff57de3..f728cc2d02 100644
--- a/capture.c
+++ b/capture.c
@@ -76,278 +76,6 @@ static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tem
static void stop_capture_signal_handler(int signo);
-void
-capture_opts_init(capture_options *capture_opts, void *cfile)
-{
- capture_opts->cf = cfile;
- capture_opts->cfilter = g_strdup("");
- capture_opts->iface = NULL;
-#ifdef _WIN32
- capture_opts->buffer_size = 1; /* 1 MB */
-#endif
- capture_opts->has_snaplen = FALSE;
- capture_opts->snaplen = MIN_PACKET_SIZE;
- capture_opts->promisc_mode = TRUE;
- capture_opts->linktype = -1; /* the default linktype */
- capture_opts->capture_child = FALSE;
- capture_opts->save_file = NULL;
- capture_opts->save_file_fd = -1;
- capture_opts->sync_mode = TRUE;
- capture_opts->show_info = TRUE;
- capture_opts->quit_after_cap = FALSE;
-
- capture_opts->multi_files_on = FALSE;
- capture_opts->has_file_duration = FALSE;
- capture_opts->file_duration = 60; /* 1 min */
- capture_opts->has_ring_num_files = TRUE;
- capture_opts->ring_num_files = 2;
-
- capture_opts->has_autostop_files = FALSE;
- capture_opts->autostop_files = 1;
- capture_opts->has_autostop_packets = FALSE;
- capture_opts->autostop_packets = 1;
- capture_opts->has_autostop_filesize = FALSE;
- capture_opts->autostop_filesize = 1024 * 1024; /* 1 MB */
- capture_opts->has_autostop_duration = FALSE;
- capture_opts->autostop_duration = 60; /* 1 min */
-
-}
-
-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, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
- name, string);
- exit(1);
- }
- if (number < 0) {
- fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
- name, string);
- exit(1);
- }
- if (number > INT_MAX) {
- fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
- name, string, 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, "ethereal: 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(capture_options *capture_opts, const char *autostoparg)
-{
- gchar *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((guchar)*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 if (strcmp(autostoparg,"files") == 0) {
- capture_opts->multi_files_on = TRUE;
- capture_opts->has_autostop_files = TRUE;
- capture_opts->autostop_files = get_positive_int(p,"autostop files");
- } 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(capture_options *capture_opts, const char *arg)
-{
- gchar *p = NULL, *colonp;
-
- colonp = strchr(arg, ':');
-
- if (colonp != NULL) {
- p = colonp;
- *p++ = '\0';
- }
-
- capture_opts->ring_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((guchar)*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_file_duration = TRUE;
- capture_opts->file_duration = get_positive_int(p,
- "ring buffer duration");
-
- *colonp = ':'; /* put the colon back */
- return TRUE;
-}
-
-
-void
-capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
-{
-#ifdef _WIN32
- int i;
-#endif
-
- switch(opt) {
- case 'a': /* autostop criteria */
- if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
- fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
- exit(1);
- }
- break;
- case 'b': /* Ringbuffer option */
- capture_opts->multi_files_on = TRUE;
- capture_opts->has_ring_num_files = TRUE;
- if (get_ring_arguments(capture_opts, optarg) == FALSE) {
- fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
- exit(1);
- }
- break;
- case 'c': /* Capture xxx packets */
- capture_opts->has_autostop_packets = TRUE;
- capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
- break;
- case 'f': /* capture filter */
- if (capture_opts->cfilter)
- g_free(capture_opts->cfilter);
- capture_opts->cfilter = g_strdup(optarg);
- break;
- case 'H': /* Hide capture info dialog box */
- capture_opts->show_info = FALSE;
- break;
- case 'i': /* Use interface xxx */
- capture_opts->iface = g_strdup(optarg);
- break;
- case 'k': /* Start capture immediately */
- *start_capture = TRUE;
- break;
- /*case 'l':*/ /* Automatic scrolling in live capture mode */
- case 'p': /* Don't capture in promiscuous mode */
- capture_opts->promisc_mode = FALSE;
- break;
- case 'Q': /* Quit after capture (just capture to file) */
- capture_opts->quit_after_cap = TRUE;
- *start_capture = TRUE; /*** -Q implies -k !! ***/
- break;
- case 's': /* Set the snapshot (capture) length */
- capture_opts->has_snaplen = TRUE;
- capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
- break;
- case 'S': /* "Sync" mode: used for following file ala tail -f */
- capture_opts->sync_mode = TRUE;
- break;
- case 'w': /* Write to capture file xxx */
- capture_opts->save_file = g_strdup(optarg);
- break;
- case 'W': /* Write to capture file FD xxx */
- capture_opts->save_file_fd = atoi(optarg);
- break;
- case 'y': /* Set the pcap data link type */
-#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
- capture_opts->linktype = pcap_datalink_name_to_val(optarg);
- if (capture_opts->linktype == -1) {
- fprintf(stderr, "ethereal: 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 */
- break;
-#ifdef _WIN32
- /* Hidden option supporting Sync mode */
- case 'Z': /* Write to pipe FD XXX */
- /* associate stdout with pipe */
- i = atoi(optarg);
- if (dup2(i, 1) < 0) {
- fprintf(stderr, "Unable to dup pipe handle\n");
- exit(1);
- }
- break;
-#endif /* _WIN32 */
- default:
- /* the caller is responsible to send us only the right opt's */
- g_assert_not_reached();
- }
-}
-
/* open the output file (temporary/specified name/ringbuffer) and close the old one */
/* Returns TRUE if the file opened successfully, FALSE otherwise. */
static gboolean
diff --git a/capture_opts.c b/capture_opts.c
new file mode 100644
index 0000000000..39350851b9
--- /dev/null
+++ b/capture_opts.c
@@ -0,0 +1,318 @@
+/* capture_opts.c
+ * Routines for capture options setting
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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
+
+#ifdef HAVE_LIBPCAP
+
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+
+#include <pcap.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+
+#include "capture.h"
+#include "ringbuffer.h"
+
+
+void
+capture_opts_init(capture_options *capture_opts, void *cfile)
+{
+ capture_opts->cf = cfile;
+ capture_opts->cfilter = g_strdup(""); /* No capture filter string specified */
+ capture_opts->iface = NULL; /* Default is "pick the first interface" */
+#ifdef _WIN32
+ capture_opts->buffer_size = 1; /* 1 MB */
+#endif
+ capture_opts->has_snaplen = FALSE;
+ capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
+ infinite, in effect */
+ capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
+ capture_opts->linktype = -1; /* the default linktype */
+ capture_opts->capture_child = FALSE;
+ capture_opts->save_file = NULL;
+ capture_opts->save_file_fd = -1;
+ capture_opts->sync_mode = TRUE;
+ capture_opts->show_info = TRUE;
+ capture_opts->quit_after_cap = FALSE;
+
+ capture_opts->multi_files_on = FALSE;
+ capture_opts->has_file_duration = FALSE;
+ capture_opts->file_duration = 60; /* 1 min */
+ capture_opts->has_ring_num_files = FALSE;
+ capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
+
+ capture_opts->has_autostop_files = FALSE;
+ capture_opts->autostop_files = 1;
+ capture_opts->has_autostop_packets = FALSE;
+ capture_opts->autostop_packets = 1;
+ capture_opts->has_autostop_filesize = FALSE;
+ capture_opts->autostop_filesize = 1024 * 1024; /* 1 MB */
+ capture_opts->has_autostop_duration = FALSE;
+ capture_opts->autostop_duration = 60; /* 1 min */
+
+}
+
+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, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
+ name, string);
+ exit(1);
+ }
+ if (number < 0) {
+ fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
+ name, string);
+ exit(1);
+ }
+ if (number > INT_MAX) {
+ fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
+ name, string, 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, "ethereal: 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(capture_options *capture_opts, const char *autostoparg)
+{
+ gchar *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((guchar)*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 if (strcmp(autostoparg,"files") == 0) {
+ capture_opts->multi_files_on = TRUE;
+ capture_opts->has_autostop_files = TRUE;
+ capture_opts->autostop_files = get_positive_int(p,"autostop files");
+ } 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(capture_options *capture_opts, const char *arg)
+{
+ gchar *p = NULL, *colonp;
+
+ colonp = strchr(arg, ':');
+
+ if (colonp != NULL) {
+ p = colonp;
+ *p++ = '\0';
+ }
+
+ capture_opts->ring_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((guchar)*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_file_duration = TRUE;
+ capture_opts->file_duration = get_positive_int(p,
+ "ring buffer duration");
+
+ *colonp = ':'; /* put the colon back */
+ return TRUE;
+}
+
+
+void
+capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
+{
+#ifdef _WIN32
+ int i;
+#endif
+
+ switch(opt) {
+ case 'a': /* autostop criteria */
+ if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
+ fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'b': /* Ringbuffer option */
+ capture_opts->multi_files_on = TRUE;
+ capture_opts->has_ring_num_files = TRUE;
+ if (get_ring_arguments(capture_opts, optarg) == FALSE) {
+ fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'c': /* Capture xxx packets */
+ capture_opts->has_autostop_packets = TRUE;
+ capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
+ break;
+ case 'f': /* capture filter */
+ if (capture_opts->cfilter)
+ g_free(capture_opts->cfilter);
+ capture_opts->cfilter = g_strdup(optarg);
+ break;
+ case 'H': /* Hide capture info dialog box */
+ capture_opts->show_info = FALSE;
+ break;
+ case 'i': /* Use interface xxx */
+ capture_opts->iface = g_strdup(optarg);
+ break;
+ case 'k': /* Start capture immediately */
+ *start_capture = TRUE;
+ break;
+ /*case 'l':*/ /* Automatic scrolling in live capture mode */
+ case 'p': /* Don't capture in promiscuous mode */
+ capture_opts->promisc_mode = FALSE;
+ break;
+ case 'Q': /* Quit after capture (just capture to file) */
+ capture_opts->quit_after_cap = TRUE;
+ *start_capture = TRUE; /*** -Q implies -k !! ***/
+ break;
+ case 's': /* Set the snapshot (capture) length */
+ capture_opts->has_snaplen = TRUE;
+ capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
+ break;
+ case 'S': /* "Sync" mode: used for following file ala tail -f */
+ capture_opts->sync_mode = TRUE;
+ break;
+ case 'w': /* Write to capture file xxx */
+ capture_opts->save_file = g_strdup(optarg);
+ break;
+ case 'W': /* Write to capture file FD xxx */
+ capture_opts->save_file_fd = atoi(optarg);
+ break;
+ case 'y': /* Set the pcap data link type */
+#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
+ capture_opts->linktype = pcap_datalink_name_to_val(optarg);
+ if (capture_opts->linktype == -1) {
+ fprintf(stderr, "ethereal: 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 */
+ break;
+#ifdef _WIN32
+ /* Hidden option supporting Sync mode */
+ case 'Z': /* Write to pipe FD XXX */
+ /* associate stdout with pipe */
+ i = atoi(optarg);
+ if (dup2(i, 1) < 0) {
+ fprintf(stderr, "Unable to dup pipe handle\n");
+ exit(1);
+ }
+ break;
+#endif /* _WIN32 */
+ default:
+ /* the caller is responsible to send us only the right opt's */
+ g_assert_not_reached();
+ }
+}
+
+#endif /* HAVE_LIBPCAP */ \ No newline at end of file
diff --git a/gtk/main.c b/gtk/main.c
index 704c8327d2..abb88f89a1 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1620,6 +1620,9 @@ main(int argc, char *argv[])
by preference settings and then again by the command line parameters. */
capture_opts_init(capture_opts, &cfile);
+ capture_opts->snaplen = MIN_PACKET_SIZE;
+ capture_opts->has_ring_num_files = TRUE;
+
command_name = get_basename(ethereal_path);
/* Set "capture_child" to indicate whether this is going to be a child
process for a "-S" capture. */
diff --git a/tethereal.c b/tethereal.c
index 83f0b7046c..bdee92e93c 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -103,11 +103,12 @@
#ifdef HAVE_LIBPCAP
#include <wiretap/wtap-capture.h>
#include <wiretap/libpcap.h>
-#endif
-
#ifdef _WIN32
#include "capture-wpcap.h"
#endif
+#include "capture.h"
+#endif
+
/*
* This is the template for the decode as option; it is shared between the
@@ -168,22 +169,23 @@ typedef struct _loop_data {
static loop_data ld;
#ifdef HAVE_LIBPCAP
+#if 0
typedef struct {
gchar *cfilter; /* Capture filter string */
gchar *iface; /* the network interface to capture from */
int snaplen; /* Maximum captured packet length */
int promisc_mode; /* Capture in promiscuous mode */
- int autostop_count; /* Maximum packet count */
+ int autostop_packets; /* 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 */
+ gboolean multi_files_on; /* TRUE if ring buffer in use */
+ guint32 ring_num_files; /* Number of ring buffer files */
+ gboolean has_file_duration; /* TRUE if ring duration specified */
+ gint32 file_duration; /* Switch file after n seconds */
int linktype; /* Data link type to use, or -1 for
"use default" */
} capture_options;
@@ -208,6 +210,8 @@ static capture_options capture_opts = {
0, /* specified time is off by default */
-1 /* Default to not change link type */
};
+#endif /* 0 */
+static capture_options capture_opts;
static gboolean list_link_layer_types;
@@ -306,145 +310,6 @@ print_usage(gboolean print_ver)
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 {
@@ -847,6 +712,7 @@ main(int argc, char *argv[])
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;
@@ -861,8 +727,7 @@ main(int argc, char *argv[])
gboolean got_tap = FALSE;
#ifdef HAVE_LIBPCAP
- /* XXX - better use capture_opts_init instead */
- capture_opts.cfilter = g_strdup("");
+ capture_opts_init(&capture_opts, NULL /* cfile */);
#endif
set_timestamp_setting(TS_RELATIVE);
@@ -974,32 +839,14 @@ main(int argc, char *argv[])
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_opt_add(&capture_opts, opt, optarg, &start_capture);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
@@ -1044,17 +891,6 @@ main(int argc, char *argv[])
arg_error = TRUE;
#endif
break;
- case 'f':
-#ifdef HAVE_LIBPCAP
- capture_filter_specified = TRUE;
- if (capture_opts.cfilter)
- g_free(capture_opts.cfilter);
- capture_opts.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) {
@@ -1178,14 +1014,6 @@ main(int argc, char *argv[])
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;
@@ -1195,14 +1023,6 @@ main(int argc, char *argv[])
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;
@@ -1260,24 +1080,6 @@ main(int argc, char *argv[])
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))){
@@ -1417,7 +1219,7 @@ main(int argc, char *argv[])
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);
}
@@ -1430,7 +1232,7 @@ main(int argc, char *argv[])
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;
@@ -1520,12 +1322,12 @@ main(int argc, char *argv[])
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
@@ -1694,7 +1496,7 @@ main(int argc, char *argv[])
capture(save_file, out_file_type);
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
ringbuf_free();
}
#else
@@ -1909,9 +1711,9 @@ capture(char *save_file, int out_file_type)
goto error;
}
ld.save_file = save_file;
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
save_file_fd = ringbuf_init(save_file,
- capture_opts.ringbuffer_num_files);
+ 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);
@@ -1972,9 +1774,9 @@ capture(char *save_file, int out_file_type)
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;
@@ -2025,15 +1827,15 @@ capture(char *save_file, int out_file_type)
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
@@ -2055,8 +1857,8 @@ capture(char *save_file, int out_file_type)
/* 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. */
@@ -2066,7 +1868,7 @@ capture(char *save_file, int out_file_type)
(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, &save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */
@@ -2135,7 +1937,7 @@ capture(char *save_file, int out_file_type)
if (save_file != NULL) {
/* We're saving to a file or files; close all files. */
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
} else {
dump_ok = wtap_dump_close(ld.pdh, &err);
@@ -2172,7 +1974,7 @@ capture(char *save_file, int out_file_type)
return TRUE;
error:
- if (capture_opts.ringbuffer_on) {
+ if (capture_opts.multi_files_on) {
ringbuf_error_cleanup();
}
g_free(save_file);