summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--capture.c244
-rw-r--r--capture.h11
-rw-r--r--capture_loop.c10
-rw-r--r--capture_sync.c8
-rw-r--r--cfile.c4
-rw-r--r--cfile.h6
-rw-r--r--file.c17
-rw-r--r--file.h18
-rw-r--r--gtk/capture_dlg.c40
-rw-r--r--gtk/capture_if_dlg.c18
-rw-r--r--gtk/main.c345
-rw-r--r--gtk/summary_dlg.c9
-rw-r--r--summary.c26
-rw-r--r--summary.h13
-rw-r--r--tethereal.c48
15 files changed, 429 insertions, 388 deletions
diff --git a/capture.c b/capture.c
index 229ddf84c0..38242fa2bb 100644
--- a/capture.c
+++ b/capture.c
@@ -83,6 +83,8 @@ 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
@@ -111,23 +113,253 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
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 {
+ 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)
+{
+ int i;
+
+
+ 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
-capture_open_output(capture_options *capture_opts, const char *save_file, gboolean *is_tempfile) {
+capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) {
char tmpname[128+1];
gchar *capfile_name;
- if (save_file != NULL) {
+ if (capture_opts->save_file != NULL) {
/* If the Sync option is set, we return to the caller while the capture
* is in progress. Therefore we need to take a copy of save_file in
* case the caller destroys it after we return.
*/
- capfile_name = g_strdup(save_file);
+ capfile_name = g_strdup(capture_opts->save_file);
if (capture_opts->multi_files_on) {
/* ringbuffer is enabled */
capture_opts->save_file_fd = ringbuf_init(capfile_name,
@@ -176,19 +408,19 @@ capture_open_output(capture_options *capture_opts, const char *save_file, gboole
to the file in question. */
/* Returns TRUE if the capture starts successfully, FALSE otherwise. */
gboolean
-do_capture(capture_options *capture_opts, const char *save_file)
+do_capture(capture_options *capture_opts)
{
gboolean is_tempfile;
gboolean ret;
gchar *title;
/* open the output file (temporary/specified name/ringbuffer) and close the old one */
- if(!capture_open_output(capture_opts, save_file, &is_tempfile)) {
+ if(!capture_open_output(capture_opts, &is_tempfile)) {
return FALSE;
}
title = g_strdup_printf("%s: Capturing - Ethereal",
- get_interface_descriptive_name(cf_get_iface(capture_opts->cf)));
+ get_interface_descriptive_name(capture_opts->iface));
if (capture_opts->sync_mode) {
/* sync mode: do the capture in a child process */
ret = sync_pipe_do_capture(capture_opts, is_tempfile);
diff --git a/capture.h b/capture.h
index fb847104e8..21aa8cedda 100644
--- a/capture.h
+++ b/capture.h
@@ -38,6 +38,9 @@
typedef struct capture_options_tag {
/* general */
void *cf; /**< handle to cfile (note: untyped handle) */
+ gchar *cfilter; /**< Capture filter string */
+ gchar *iface; /**< the network interface to capture from */
+
#ifdef _WIN32
int buffer_size; /**< the capture buffer size (MB) */
#endif
@@ -48,7 +51,7 @@ typedef struct capture_options_tag {
int linktype; /**< Data link type to use, or -1 for
"use default" */
gboolean capture_child; /**< True if this is the child for "-S" */
- gchar *save_file; /**< File the capture was saved in */
+ gchar *save_file; /**< the capture file name */
int save_file_fd; /**< File descriptor for saved file */
/* GUI related */
@@ -89,15 +92,17 @@ typedef struct capture_options_tag {
extern void
capture_opts_init(capture_options *capture_opts, void *cfile);
+extern void
+capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture);
+
/**
* Open a specified file, or create a temporary file, and start a capture
* to the file in question.
*
* @param capture_opts the numerous capture options
- * @param save_file the name of the capture file, or NULL for a temporary file
* @return TRUE if the capture starts successfully, FALSE otherwise.
*/
-extern gboolean do_capture(capture_options *capture_opts, const char *save_file);
+extern gboolean do_capture(capture_options *capture_opts);
/** Do the low-level work of a capture (start the capture child). */
extern int capture_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats);
diff --git a/capture_loop.c b/capture_loop.c
index 7d4d8cd204..cd8776c926 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -558,7 +558,7 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
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->pcap_h = pcap_open_live(cf_get_iface(capture_opts->cf),
+ ld->pcap_h = pcap_open_live(capture_opts->iface,
capture_opts->has_snaplen ? capture_opts->snaplen :
WTAP_MAX_PACKET_SIZE,
capture_opts->promisc_mode, CAP_READ_TIMEOUT,
@@ -582,7 +582,7 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
/* setting the data link type only works on real interfaces */
if (capture_opts->linktype != -1) {
- set_linktype_err_str = set_pcap_linktype(ld->pcap_h, cf_get_iface(capture_opts->cf),
+ set_linktype_err_str = set_pcap_linktype(ld->pcap_h, capture_opts->iface,
capture_opts->linktype);
if (set_linktype_err_str != NULL) {
g_snprintf(errmsg, errmsg_len, "Unable to set data link type (%s).",
@@ -782,7 +782,7 @@ static int capture_loop_open_wiretap_output(capture_options *capture_opts, loop_
} else
#endif
{
- pcap_encap = get_pcap_linktype(ld->pcap_h, cf_get_iface(capture_opts->cf));
+ pcap_encap = get_pcap_linktype(ld->pcap_h, capture_opts->iface);
file_snaplen = pcap_snapshot(ld->pcap_h);
}
@@ -1023,7 +1023,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* init the input filter from the network interface (capture pipe will do nothing) */
- if (!capture_loop_init_filter(&ld, cf_get_iface(capture_opts->cf), cf_get_cfilter(capture_opts->cf), errmsg, sizeof(errmsg))) {
+ if (!capture_loop_init_filter(&ld, capture_opts->iface, capture_opts->cfilter, errmsg, sizeof(errmsg))) {
goto error;
}
@@ -1075,7 +1075,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
if(show_info) {
capture_ui.callback_data = &ld;
capture_ui.counts = &ld.counts;
- capture_info_create(&capture_ui, cf_get_iface(capture_opts->cf));
+ capture_info_create(&capture_ui, capture_opts->iface);
}
/* init the time values */
diff --git a/capture_sync.c b/capture_sync.c
index ae784106a7..d6c5c3e9c1 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -244,7 +244,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
argv = sync_pipe_add_arg(argv, &argc, CHILD_NAME);
argv = sync_pipe_add_arg(argv, &argc, "-i");
- argv = sync_pipe_add_arg(argv, &argc, cf_get_iface(capture_opts->cf));
+ argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
argv = sync_pipe_add_arg(argv, &argc, "-w");
argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
@@ -321,9 +321,9 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
/* Convert filter string to a quote delimited string and pass to child */
filterstring = NULL;
- if (cf_get_cfilter(capture_opts->cf) != NULL && strlen(cf_get_cfilter(capture_opts->cf)) != 0) {
+ if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
argv = sync_pipe_add_arg(argv, &argc, "-f");
- filterstring = sync_pipe_quote_encapsulate(cf_get_cfilter(capture_opts->cf));
+ filterstring = sync_pipe_quote_encapsulate(capture_opts->cfilter);
argv = sync_pipe_add_arg(argv, &argc, filterstring);
}
@@ -485,7 +485,7 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) {
/* The child process started a capture.
Attempt to open the capture file and set up to read it. */
- switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
+ switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, capture_opts->iface, is_tempfile, &err)) {
case CF_OK:
/* We were able to open and set up to read the capture file;
arrange that our callback be called whenever it's possible
diff --git a/cfile.c b/cfile.c
index 225d88b863..6ebf3d6d85 100644
--- a/cfile.c
+++ b/cfile.c
@@ -52,10 +52,6 @@ init_cap_file(capture_file *cf)
cf->rfcode = NULL;
cf->dfilter = NULL;
cf->dfcode = NULL;
-#ifdef HAVE_LIBPCAP
- cf->cfilter = g_strdup("");
-#endif
- cf->iface = NULL;
cf->has_snap = FALSE;
cf->snap = WTAP_MAX_PACKET_SIZE;
cf->count = 0;
diff --git a/cfile.h b/cfile.h
index 0a16fa23d2..3dc11d4da4 100644
--- a/cfile.h
+++ b/cfile.h
@@ -60,14 +60,10 @@ typedef struct _capture_file {
guint32 eusec; /* Elapsed microseconds */
gboolean has_snap; /* TRUE if maximum capture packet length is known */
int snap; /* Maximum captured packet length */
- gchar *iface; /* Interface */
wtap *wth; /* Wiretap session */
- dfilter_t *rfcode; /* Compiled read filter program */
+ dfilter_t *rfcode; /* Compiled read (display) filter program */
gchar *dfilter; /* Display filter string */
dfilter_t *dfcode; /* Compiled display filter program */
-#ifdef HAVE_LIBPCAP
- gchar *cfilter; /* Capture filter string */
-#endif
gchar *sfilter; /* Search filter string */
gboolean sbackward; /* TRUE if search is backward, FALSE if forward */
gboolean hex; /* TRUE is raw data search is being performed */
diff --git a/file.c b/file.c
index 315bf50f0f..cd2212b987 100644
--- a/file.c
+++ b/file.c
@@ -531,7 +531,7 @@ cf_read(capture_file *cf)
#ifdef HAVE_LIBPCAP
cf_status_t
-cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
+cf_start_tail(capture_file *cf, const char *fname, const char *iface, gboolean is_tempfile, int *err)
{
gchar *capture_msg;
cf_status_t cf_status;
@@ -546,7 +546,7 @@ cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *er
packets (yes, I know, we don't have any *yet*). */
set_menus_for_captured_packets(TRUE);
- capture_msg = g_strdup_printf(" %s: <live capture in progress>", get_interface_descriptive_name(cf->iface));
+ capture_msg = g_strdup_printf(" %s: <live capture in progress>", get_interface_descriptive_name(iface));
statusbar_push_file_msg(capture_msg);
@@ -715,14 +715,6 @@ cf_packet_count(capture_file *cf)
}
/* XXX - use a macro instead? */
-/* XXX - move iface this to capture_opts? */
-gchar *
-cf_get_iface(capture_file *cf)
-{
- return cf->iface;
-}
-
-/* XXX - use a macro instead? */
gboolean
cf_is_tempfile(capture_file *cf)
{
@@ -746,11 +738,6 @@ void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
cf->rfcode = rfcode;
}
-gchar *cf_get_cfilter(capture_file *cf)
-{
- return cf->cfilter;
-}
-
typedef struct {
color_filter_t *colorf;
epan_dissect_t *edt;
diff --git a/file.h b/file.h
index 4ab49dcec1..ee47fee173 100644
--- a/file.h
+++ b/file.h
@@ -97,7 +97,7 @@ cf_read_status_t cf_read(capture_file *cf);
* @param err the error code, if an error had occured
* @return one of cf_status_t
*/
-cf_status_t cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err);
+cf_status_t cf_start_tail(capture_file *cf, const char *fname, const char *iface, gboolean is_tempfile, int *err);
/**
* Read packets from the "end" of a capture file.
@@ -154,22 +154,6 @@ int cf_packet_count(capture_file *cf);
gboolean cf_is_tempfile(capture_file *cf);
/**
- * Get the interface name to capture from.
- *
- * @param cf the capture file
- * @return the interface name (don't have to be g_free'd)
- */
-gchar *cf_get_iface(capture_file *cf);
-
-/**
- * Get the capture filter of this capture file.
- *
- * @param cf the capture file
- * @return the capture filter (don't have to be g_free'd)
- */
-gchar *cf_get_cfilter(capture_file *cf);
-
-/**
* Set flag, if the number of packet drops while capturing are known or not.
*
* @param cf the capture file
diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c
index afe10a8e68..f17f34a6d7 100644
--- a/gtk/capture_dlg.c
+++ b/gtk/capture_dlg.c
@@ -607,14 +607,14 @@ capture_prep(void)
combo_list = build_capture_combo_list(if_list, TRUE);
if (combo_list != NULL)
gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
- if (cfile.iface == NULL && prefs.capture_device != NULL) {
+ if (capture_opts->iface == NULL && prefs.capture_device != NULL) {
/* No interface was specified on the command line or in a previous
capture, but there is one specified in the preferences file;
make the one from the preferences file the default */
- cfile.iface = g_strdup(prefs.capture_device);
+ capture_opts->iface = g_strdup(prefs.capture_device);
}
- if (cfile.iface != NULL)
- gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
+ if (capture_opts->iface != NULL)
+ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), capture_opts->iface);
else if (combo_list != NULL) {
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
(char *)combo_list->data);
@@ -744,8 +744,8 @@ capture_prep(void)
if (filter_list != NULL)
gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), filter_list);
- if (cfile.cfilter)
- gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
+ if (capture_opts->cfilter)
+ gtk_entry_set_text(GTK_ENTRY(filter_te), capture_opts->cfilter);
gtk_tooltips_set_tip(tooltips, filter_te,
"Enter a capture filter to reduce the amount of packets to be captured. "
"See \"Capture Filters\" in the online help for further information how to use it.",
@@ -1241,7 +1241,6 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
gchar *if_text;
gchar *if_name;
const gchar *filter_text;
- gchar *save_file;
const gchar *g_save_file;
gchar *cf_name;
gchar *dirname;
@@ -1294,9 +1293,9 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
g_free(entry_text);
return;
}
- if (cfile.iface)
- g_free(cfile.iface);
- cfile.iface = g_strdup(if_name);
+ if (capture_opts->iface)
+ g_free(capture_opts->iface);
+ capture_opts->iface = g_strdup(if_name);
g_free(entry_text);
capture_opts->linktype =
@@ -1330,15 +1329,15 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
no filter is set, which means no packets arrive as input on that
socket, which means Ethereal never sees any packets. */
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
- if (cfile.cfilter)
- g_free(cfile.cfilter);
+ if (capture_opts->cfilter)
+ g_free(capture_opts->cfilter);
g_assert(filter_text != NULL);
- cfile.cfilter = g_strdup(filter_text);
+ capture_opts->cfilter = g_strdup(filter_text);
g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
if (g_save_file && g_save_file[0]) {
/* User specified a file to which the capture should be written. */
- save_file = g_strdup(g_save_file);
+ capture_opts->save_file = g_strdup(g_save_file);
/* Save the directory name for future file dialogs. */
cf_name = g_strdup(g_save_file);
dirname = get_dirname(cf_name); /* Overwrites cf_name */
@@ -1346,7 +1345,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
g_free(cf_name);
} else {
/* User didn't specify a file; save to a temporary file. */
- save_file = NULL;
+ capture_opts->save_file = NULL;
}
capture_opts->has_autostop_packets =
@@ -1421,7 +1420,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
}
/* test if the settings are ok for a ringbuffer */
- if (save_file == NULL) {
+ if (capture_opts->save_file == NULL) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END
"You must specify a filename if you want to use multiple files.");
@@ -1431,7 +1430,8 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END
"You must specify a file size at which is switched to the next capture file\n"
"if you want to use multiple files.");
- g_free(save_file);
+ g_free(capture_opts->save_file);
+ capture_opts->save_file = NULL;
return;
}
} else {
@@ -1468,13 +1468,11 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
window_destroy(GTK_WIDGET(parent_w));
- if (do_capture(capture_opts, save_file)) {
+ if (do_capture(capture_opts)) {
/* The capture succeeded, which means the capture filter syntax is
valid; add this capture filter to the recent capture filter list. */
- cfilter_combo_add_recent(cfile.cfilter);
+ cfilter_combo_add_recent(capture_opts->cfilter);
}
- if (save_file != NULL)
- g_free(save_file);
}
static void
diff --git a/gtk/capture_if_dlg.c b/gtk/capture_if_dlg.c
index 2ea8113cc8..4eb2073a6c 100644
--- a/gtk/capture_if_dlg.c
+++ b/gtk/capture_if_dlg.c
@@ -112,12 +112,16 @@ capture_do_cb(GtkWidget *capture_bt _U_, gpointer if_data)
{
if_dlg_data_t *if_dlg_data = if_data;
- if (cfile.iface)
- g_free(cfile.iface);
+ if (capture_opts->iface)
+ g_free(capture_opts->iface);
- cfile.iface = g_strdup(if_dlg_data->device);
+ capture_opts->iface = g_strdup(if_dlg_data->device);
- do_capture(capture_opts, NULL /* save_file */);
+ if (capture_opts->save_file)
+ g_free(capture_opts->save_file);
+ capture_opts->save_file = NULL;
+
+ do_capture(capture_opts);
}
@@ -127,10 +131,10 @@ capture_prepare_cb(GtkWidget *prepare_bt _U_, gpointer if_data)
{
if_dlg_data_t *if_dlg_data = if_data;
- if (cfile.iface)
- g_free(cfile.iface);
+ if (capture_opts->iface)
+ g_free(capture_opts->iface);
- cfile.iface = g_strdup(if_dlg_data->device);
+ capture_opts->iface = g_strdup(if_dlg_data->device);
capture_prep_cb(NULL, NULL);
}
diff --git a/gtk/main.c b/gtk/main.c
index 93830f8eca..91b3703772 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1158,104 +1158,6 @@ get_positive_int(const char *string, const char *name)
return number;
}
-#ifdef HAVE_LIBPCAP
-/*
- * 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)
-{
- 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 {
- 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)
-{
- 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;
-}
-#endif
-
#if defined(_WIN32) || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
/*
Once every 3 seconds we get a callback here which we use to update
@@ -1368,7 +1270,6 @@ main(int argc, char *argv[])
int err;
#ifdef HAVE_LIBPCAP
gboolean start_capture = FALSE;
- gchar *save_file = NULL;
GList *if_list;
if_info_t *if_info;
GList *lt_list, *lt_entry;
@@ -1572,6 +1473,7 @@ main(int argc, char *argv[])
}
#ifdef _WIN32
+ /* if the user wants a console to be always there, well, we should open one for him */
if (prefs->gui_console_open == console_open_always) {
create_console();
}
@@ -1679,72 +1581,48 @@ main(int argc, char *argv[])
/* Now get our args */
while ((opt = getopt(argc, argv, optstring)) != -1) {
switch (opt) {
+ /*** capture option specific ***/
case 'a': /* autostop criteria */
+ case 'b': /* Ringbuffer option */
+ case 'c': /* Capture xxx packets */
+ case 'f': /* capture filter */
+ case 'k': /* Start capture immediately */
+ case 'H': /* Hide capture info dialog box */
+ case 'i': /* Use interface xxx */
+ case 'p': /* Don't capture in promiscuous mode */
+ case 'Q': /* Quit after capture (just capture to file) */
+ case 's': /* Set the snapshot (capture) length */
+ case 'S': /* "Sync" mode: used for following file ala tail -f */
+ case 'w': /* Write to capture file xxx */
+ case 'y': /* Set the pcap data link type */
+#ifdef _WIN32
+ /* Hidden option supporting Sync mode */
+ case 'Z': /* Write to pipe FD XXX */
+#endif /* _WIN32 */
#ifdef HAVE_LIBPCAP
- if (set_autostop_criterion(optarg) == FALSE) {
- fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
- exit(1);
- }
+ capture_opt_add(capture_opts, opt, optarg, &start_capture);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
- case 'b': /* Ringbuffer option */
#ifdef HAVE_LIBPCAP
- capture_opts->multi_files_on = TRUE;
- capture_opts->has_ring_num_files = TRUE;
- if (get_ring_arguments(optarg) == FALSE) {
- fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
- exit(1);
- }
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
+ /* This is a hidden option supporting Sync mode, so we don't set
+ * the error flags for the user in the non-libpcap case.
+ */
+ case 'W': /* Write to capture file FD xxx */
+ capture_opt_add(capture_opts, opt, optarg, &start_capture);
+ break;
#endif
- break;
+
+ /*** all non capture option specific ***/
case 'B': /* Byte view pane height */
bv_size = get_positive_int(optarg, "byte view pane height");
break;
- case 'c': /* Capture xxx packets */
-#ifdef HAVE_LIBPCAP
- capture_opts->has_autostop_packets = TRUE;
- capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
- case 'f':
-#ifdef HAVE_LIBPCAP
- if (cfile.cfilter)
- g_free(cfile.cfilter);
- cfile.cfilter = g_strdup(optarg);
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'h': /* Print help and exit */
print_usage(TRUE);
exit(0);
break;
- case 'i': /* Use interface xxx */
-#ifdef HAVE_LIBPCAP
- cfile.iface = g_strdup(optarg);
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
- case 'k': /* Start capture immediately */
-#ifdef HAVE_LIBPCAP
- start_capture = TRUE;
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'l': /* Automatic scrolling in live capture mode */
#ifdef HAVE_LIBPCAP
auto_scroll_live = TRUE;
@@ -1753,14 +1631,6 @@ main(int argc, char *argv[])
arg_error = TRUE;
#endif
break;
- case 'H': /* Hide capture info dialog box */
-#ifdef HAVE_LIBPCAP
- capture_opts->show_info = FALSE;
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'L': /* Print list of link-layer types and exit */
#ifdef HAVE_LIBPCAP
list_link_layer_types = TRUE;
@@ -1803,26 +1673,9 @@ 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 'P': /* Packet list pane height */
pl_size = get_positive_int(optarg, "packet list pane height");
break;
- case 'Q': /* Quit after capture (just capture to file) */
-#ifdef HAVE_LIBPCAP
- capture_opts->quit_after_cap = TRUE;
- start_capture = TRUE; /*** -Q implies -k !! ***/
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 'r': /* Read capture file xxx */
/* We may set "last_open_dir" to "cf_name", and if we change
"last_open_dir" later, we free the old value, so we have to
@@ -1832,23 +1685,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->has_snaplen = TRUE;
- capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
- case 'S': /* "Sync" mode: used for following file ala tail -f */
-#ifdef HAVE_LIBPCAP
- capture_opts->sync_mode = TRUE;
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- break;
case 't': /* Time stamp type */
if (strcmp(optarg, "r") == 0)
set_timestamp_setting(TS_RELATIVE);
@@ -1876,40 +1712,6 @@ main(int argc, char *argv[])
#endif
exit(0);
break;
- case 'w': /* Write to capture file xxx */
-#ifdef HAVE_LIBPCAP
- save_file = g_strdup(optarg);
-#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif
- 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, "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 */
-#else /* HAVE_LIBPCAP */
- capture_option_specified = TRUE;
- arg_error = TRUE;
-#endif /* HAVE_LIBPCAP */
- break;
-#ifdef HAVE_LIBPCAP
- /* This is a hidden option supporting Sync mode, so we don't set
- * the error flags for the user in the non-libpcap case.
- */
- case 'W': /* Write to capture file FD xxx */
- capture_opts->save_file_fd = atoi(optarg);
- break;
-#endif
case 'z':
for(tli=tap_list;tli;tli=tli->next){
if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){
@@ -1926,21 +1728,6 @@ main(int argc, char *argv[])
exit(1);
}
break;
-
-#ifdef _WIN32
-#ifdef HAVE_LIBPCAP
- /* 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 /* HAVE_LIBPCAP */
-#endif /* _WIN32 */
-
default:
case '?': /* Bad flag - print usage message */
arg_error = TRUE;
@@ -1973,6 +1760,8 @@ main(int argc, char *argv[])
argv++;
}
+
+
if (argc != 0) {
/*
* Extra command line arguments were specified; complain.
@@ -2029,7 +1818,7 @@ main(int argc, char *argv[])
sync_mode takes precedence;
c) it makes no sense to enable the ring buffer if the maximum
file size is set to "infinite". */
- if (save_file == NULL) {
+ if (capture_opts->save_file == NULL) {
fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
capture_opts->multi_files_on = FALSE;
}
@@ -2046,11 +1835,11 @@ main(int argc, char *argv[])
if (start_capture || list_link_layer_types) {
/* Did the user specify an interface to use? */
- if (cfile.iface == NULL) {
+ if (capture_opts->iface == NULL) {
/* No - is a default specified in the preferences file? */
if (prefs->capture_device != NULL) {
/* Yes - use it. */
- cfile.iface = g_strdup(prefs->capture_device);
+ capture_opts->iface = g_strdup(prefs->capture_device);
} else {
/* No - pick the first one from the list of interfaces. */
if_list = get_interface_list(&err, err_str);
@@ -2070,7 +1859,7 @@ main(int argc, char *argv[])
exit(2);
}
if_info = if_list->data; /* first interface */
- cfile.iface = g_strdup(if_info->name);
+ capture_opts->iface = g_strdup(if_info->name);
free_interface_list(if_list);
}
}
@@ -2087,7 +1876,7 @@ main(int argc, char *argv[])
if (list_link_layer_types) {
/* 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, "ethereal: The list of data link types for the capture device could not be obtained (%s).\n"
@@ -2126,7 +1915,7 @@ main(int argc, char *argv[])
else if (capture_opts->num_files < RINGBUFFER_MIN_NUM_FILES)
capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
#endif
-#endif
+#endif /* HAVE_LIBPCAP */
/* Notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command
@@ -2184,13 +1973,33 @@ main(int argc, char *argv[])
/* close the splash screen, as we are going to open the main window now */
splash_destroy(splash_win);
+
#ifdef HAVE_LIBPCAP
/* Is this a "child" ethereal, which is only supposed to pop up a
capture box to let us stop the capture, and run a capture
to a file that our parent will read? */
- if (!capture_opts->capture_child) {
+ if (capture_opts->capture_child) {
+ /* This is the child process for a sync mode or fork mode capture,
+ so just do the low-level work of a capture - don't create
+ a temporary file and fork off *another* child process (so don't
+ call "do_capture()"). */
+
+ /* Pop up any queued-up alert boxes. */
+ display_queued_messages();
+
+ /* XXX - hand these stats to the parent process */
+ capture_start(capture_opts, &stats_known, &stats);
+
+ /* The capture is done; there's nothing more for us to do. */
+ gtk_exit(0);
+ }
#endif
- /* No. Pop up the main window, and read in a capture file if
+
+ /***********************************************************************/
+ /* Everything is prepared now, preferences and command line was read in,
+ we are NOT a child window for a synced capture. */
+
+ /* Pop up the main window, and read in a capture file if
we were told to. */
create_main_window(pl_size, tv_size, bv_size, prefs);
@@ -2310,8 +2119,15 @@ main(int argc, char *argv[])
}
#ifdef HAVE_LIBPCAP
if (start_capture) {
+ if (capture_opts->save_file != NULL) {
+ /* Save the directory name for future file dialogs. */
+ /* (get_dirname overwrites filename) */
+ s = get_dirname(g_strdup(capture_opts->save_file));
+ set_last_open_dir(s);
+ g_free(s);
+ }
/* "-k" was specified; start a capture. */
- if (do_capture(capture_opts, save_file)) {
+ if (do_capture(capture_opts)) {
/* The capture started. Open tap windows; we do so after creating
the main window, to avoid GTK warnings, and after starting the
capture, so we know we have something to tap. */
@@ -2320,38 +2136,19 @@ main(int argc, char *argv[])
g_free(tap_opt);
}
}
- if (save_file != NULL) {
- /* Save the directory name for future file dialogs. */
- s = get_dirname(save_file); /* Overwrites save_file */
- set_last_open_dir(s);
- g_free(save_file);
- save_file = NULL;
- }
}
else {
set_menus_for_capture_in_progress(FALSE);
}
- } else {
- /* This is the child process for a sync mode or fork mode capture,
- so just do the low-level work of a capture - don't create
- a temporary file and fork off *another* child process (so don't
- call "do_capture()"). */
- /* Pop up any queued-up alert boxes. */
- display_queued_messages();
-
- /* XXX - hand these stats to the parent process */
- capture_start(capture_opts, &stats_known, &stats);
-
- /* The capture is done; there's nothing more for us to do. */
- gtk_exit(0);
- }
- if (!start_capture && (cfile.cfilter == NULL || strlen(cfile.cfilter) == 0)) {
- if (cfile.cfilter) {
- g_free(cfile.cfilter);
+ /* if the user didn't supplied a capture filter, use the one to filter out remote connections like SSH */
+ if (!start_capture && (capture_opts->cfilter == NULL || strlen(capture_opts->cfilter) == 0)) {
+ if (capture_opts->cfilter) {
+ g_free(capture_opts->cfilter);
}
- cfile.cfilter = g_strdup(get_conn_cfilter());
+ capture_opts->cfilter = g_strdup(get_conn_cfilter());
}
+
#else /* HAVE_LIBPCAP */
set_menus_for_capture_in_progress(FALSE);
#endif /* HAVE_LIBPCAP */
diff --git a/gtk/summary_dlg.c b/gtk/summary_dlg.c
index c99e034241..eafb72e7db 100644
--- a/gtk/summary_dlg.c
+++ b/gtk/summary_dlg.c
@@ -35,6 +35,10 @@
#include "globals.h"
#include "file.h"
+#ifdef HAVE_LIBPCAP
+#include "capture.h"
+#include "main.h"
+#endif
#include "summary.h"
#include "summary_dlg.h"
#include "dlg_utils.h"
@@ -111,6 +115,9 @@ summary_open_cb(GtkWidget *w _U_, gpointer d _U_)
/* initial computations */
summary_fill_in(&cfile, &summary);
+#ifdef HAVE_LIBPCAP
+ summary_fill_in_capture(capture_opts, &summary);
+#endif
seconds = summary.stop_time - summary.start_time;
disp_seconds = summary.filtered_stop - summary.filtered_start;
@@ -199,7 +206,7 @@ summary_open_cb(GtkWidget *w _U_, gpointer d _U_)
/* interface */
if (summary.iface) {
- g_snprintf(string_buff, SUM_STR_MAX, "%s", summary.iface);
+ g_snprintf(string_buff, SUM_STR_MAX, "%s", summary.iface_descr);
} else {
g_snprintf(string_buff, SUM_STR_MAX, "unknown");
}
diff --git a/summary.c b/summary.c
index 5d13ef2cd0..e9df777805 100644
--- a/summary.c
+++ b/summary.c
@@ -29,6 +29,9 @@
#include <epan/packet.h>
#include "cfile.h"
#include "summary.h"
+#ifdef HAVE_LIBPCAP
+#include "capture_ui_utils.h"
+#endif
static double
@@ -111,12 +114,25 @@ summary_fill_in(capture_file *cf, summary_tally *st)
st->packet_count = cf->count;
st->drops_known = cf->drops_known;
st->drops = cf->drops;
- st->iface = cf->iface;
st->dfilter = cf->dfilter;
-#ifdef HAVE_LIBPCAP
- st->cfilter = cf->cfilter;
-#else
+ /* capture related */
st->cfilter = NULL;
-#endif
+ st->iface = NULL;
+ st->iface_descr = NULL;
+}
+
+
+#ifdef HAVE_LIBPCAP
+void
+summary_fill_in_capture(capture_options *capture_opts, summary_tally *st)
+{
+ st->cfilter = capture_opts->cfilter;
+ st->iface = capture_opts->iface;
+ if(st->iface) {
+ st->iface_descr = get_interface_descriptive_name(st->iface);
+ } else {
+ st->iface_descr = NULL;
+ }
}
+#endif
diff --git a/summary.h b/summary.h
index 7be3230775..c16780e021 100644
--- a/summary.h
+++ b/summary.h
@@ -25,6 +25,10 @@
#ifndef __SUMMARY_H__
#define __SUMMARY_H__
+#ifdef HAVE_LIBPCAP
+#include "capture.h"
+#endif
+
typedef struct _summary_tally {
guint32 bytes; /* total bytes */
double start_time; /* seconds, with msec resolution */
@@ -48,9 +52,16 @@ typedef struct _summary_tally {
const char *iface; /* interface name */
const char *dfilter; /* display filter */
const char *cfilter; /* capture filter */
+ const char *iface_descr;/* descriptive interface name */
} summary_tally;
-void summary_fill_in(capture_file *cf, summary_tally *st);
+extern void
+summary_fill_in(capture_file *cf, summary_tally *st);
+
+#ifdef HAVE_LIBPCAP
+extern void
+summary_fill_in_capture(capture_options *capture_opts, summary_tally *st);
+#endif
#endif /* summary.h */
diff --git a/tethereal.c b/tethereal.c
index 297409e799..03fb8bed63 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -170,6 +170,8 @@ static loop_data ld;
#ifdef HAVE_LIBPCAP
typedef struct {
gchar *save_file; /* File that user saved capture to */
+ 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 */
@@ -189,6 +191,8 @@ typedef struct {
static capture_options capture_opts = {
"",
+ "",
+ NULL,
WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
infinite, in effect */
TRUE, /* promiscuous mode is the default */
@@ -856,6 +860,10 @@ main(int argc, char *argv[])
char badopt;
ethereal_tap_list *tli;
+
+ /* XXX - better use capture_opts_init instead */
+ capture_opts.cfilter = g_strdup("");
+
set_timestamp_setting(TS_RELATIVE);
/* Register all dissectors; we must do this before checking for the
@@ -1038,9 +1046,9 @@ main(int argc, char *argv[])
case 'f':
#ifdef HAVE_LIBPCAP
capture_filter_specified = TRUE;
- if (cfile.cfilter)
- g_free(cfile.cfilter);
- cfile.cfilter = g_strdup(optarg);
+ if (capture_opts.cfilter)
+ g_free(capture_opts.cfilter);
+ capture_opts.cfilter = g_strdup(optarg);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
@@ -1107,10 +1115,10 @@ main(int argc, char *argv[])
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;
@@ -1311,7 +1319,7 @@ main(int argc, char *argv[])
"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
@@ -1602,15 +1610,15 @@ main(int argc, char *argv[])
#endif
/* Yes; did the user specify an interface to use? */
- if (cfile.iface == NULL) {
+ 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) {
- cfile.iface = g_strdup(prefs->capture_device);
+ capture_opts.iface = g_strdup(prefs->capture_device);
} else {
- cfile.iface = g_strdup(if_text + 1); /* Skip over space */
+ capture_opts.iface = g_strdup(if_text + 1); /* Skip over space */
}
} else {
/* No - pick the first one from the list of interfaces. */
@@ -1632,7 +1640,7 @@ main(int argc, char *argv[])
exit(2);
}
if_info = if_list->data; /* first interface */
- cfile.iface = g_strdup(if_info->name);
+ capture_opts.iface = g_strdup(if_info->name);
free_interface_list(if_list);
}
}
@@ -1640,7 +1648,7 @@ main(int argc, char *argv[])
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"
@@ -1733,13 +1741,13 @@ capture(int out_file_type)
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).",
@@ -1828,9 +1836,9 @@ capture(int out_file_type)
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
@@ -1840,8 +1848,8 @@ capture(int out_file_type)
"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)) {
+ if (pcap_compile(ld.pch, &fcode, capture_opts.cfilter, 1, netmask) < 0) {
+ if (dfilter_compile(capture_opts.cfilter, &rfcode)) {
snprintf(errmsg, sizeof errmsg,
"Unable to parse capture filter string (%s).\n"
" Interestingly enough, this looks like a valid display filter\n"
@@ -1869,7 +1877,7 @@ capture(int out_file_type)
} 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);
@@ -1929,7 +1937,7 @@ capture(int out_file_type)
#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);
@@ -2774,7 +2782,7 @@ print_columns(capture_file *cf)
* 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;
column_len = strlen(cf->cinfo.col_data[i]);
if (column_len < 3)