aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2005-02-06 21:20:35 +0000
committerUlf Lamping <ulf.lamping@web.de>2005-02-06 21:20:35 +0000
commit3a63719e389bd9fd1f27a1a467501c8d7fe3eb69 (patch)
tree0ed850112dc342fd11812f8dba14fa2cb1a08b33
parenta6694a746ff0ff2402e3989dfb3cf135122cf821 (diff)
another two steps towards privilege seperation:
move another two capture related fields (iface and cfilter) from cfile to capture_opts also move the handling of capture related command line options from main.c to capture.c, that way a future privilege seperated capture program can use the same code to parse it's command line than Ethereal. It might be even possible to share this parser code even with Tethereal, didn't took a closer look at this. svn path=/trunk/; revision=13320
-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)