aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--file.c109
-rw-r--r--file.h3
-rw-r--r--gtk/display_opts.c18
-rw-r--r--gtk/main.c7
-rw-r--r--gtk/prefs_dlg.c54
-rw-r--r--prefs-int.h3
-rw-r--r--prefs.c44
-rw-r--r--prefs.h7
-rw-r--r--tethereal.c7
9 files changed, 189 insertions, 63 deletions
diff --git a/file.c b/file.c
index f1595d0737..f9c895e0e7 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.196 2000/07/07 23:09:03 guy Exp $
+ * $Id: file.c,v 1.197 2000/07/09 03:29:26 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -95,6 +95,9 @@ static guint32 prevsec, prevusec;
static void read_packet(capture_file *cf, int offset);
+static void rescan_packets(capture_file *cf, const char *action,
+ gboolean refilter);
+
static void set_selected_row(int row);
static void freeze_clist(capture_file *cf);
@@ -589,7 +592,8 @@ apply_color_filter(gpointer filter_arg, gpointer argp)
static int
add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
- union wtap_pseudo_header *pseudo_header, const u_char *buf)
+ union wtap_pseudo_header *pseudo_header, const u_char *buf,
+ gboolean refilter)
{
apply_color_filter_args args;
gint i, row;
@@ -620,37 +624,57 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
fdata->cinfo->col_data[i][0] = '\0';
}
- /* Apply the filters */
- if (cf->dfcode != NULL || filter_list != NULL) {
+ /* If either
+
+ we have a display filter and are re-applying it;
+
+ we have a list of color filters;
+
+ we have plugins to apply;
+
+ allocate a protocol tree root node, so that we'll construct
+ a protocol tree against which a filter expression can be
+ evaluated. */
+ if ((cf->dfcode != NULL && refilter) || filter_list != NULL
+#ifdef HAVE_PLUGINS
+ || enabled_plugins_number > 0
+#endif
+ )
protocol_tree = proto_tree_create_root();
- dissect_packet(pseudo_header, buf, fdata, protocol_tree);
- if (cf->dfcode != NULL)
- fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
- else
- fdata->flags.passed_dfilter = 1;
- /* Apply color filters, if we have any. */
+ /* Dissect the frame. */
+ dissect_packet(pseudo_header, buf, fdata, protocol_tree);
+
+ /* If we have a display filter, apply it if we're refiltering, otherwise
+ leave the "passed_dfilter" flag alone.
+
+ If we don't have a display filter, set "passed_dfilter" to 1. */
+ if (cf->dfcode != NULL) {
+ if (refilter) {
+ if (cf->dfcode != NULL)
+ fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
+ else
+ fdata->flags.passed_dfilter = 1;
+ }
+ } else
+ fdata->flags.passed_dfilter = 1;
+
+ /* If we have color filters, and the frame is to be displayed, apply
+ the color filters. */
+ if (fdata->flags.passed_dfilter) {
if (filter_list != NULL) {
args.protocol_tree = protocol_tree;
args.pd = buf;
args.fdata = fdata;
g_slist_foreach(filter_list, apply_color_filter, &args);
}
- proto_tree_free(protocol_tree);
- }
- else {
-#ifdef HAVE_PLUGINS
- if (enabled_plugins_number > 0)
- protocol_tree = proto_tree_create_root();
-#endif
- dissect_packet(pseudo_header, buf, fdata, protocol_tree);
- fdata->flags.passed_dfilter = 1;
-#ifdef HAVE_PLUGINS
- if (protocol_tree)
- proto_tree_free(protocol_tree);
-#endif
}
+ /* There are no more filters to apply, so we don't need any protocol
+ tree; free it if we created it. */
+ if (protocol_tree != NULL)
+ proto_tree_free(protocol_tree);
+
if (fdata->flags.passed_dfilter) {
/* This frame passed the display filter, so add it to the clist. */
@@ -766,7 +790,7 @@ read_packet(capture_file *cf, int offset)
cf->count++;
fdata->num = cf->count;
- add_packet_to_packet_list(fdata, cf, pseudo_header, buf);
+ add_packet_to_packet_list(fdata, cf, pseudo_header, buf, TRUE);
} else {
/* XXX - if we didn't have read filters, or if we could avoid
allocating the "frame_data" structure until we knew whether
@@ -814,18 +838,32 @@ filter_packets(capture_file *cf, gchar *dftext)
dfilter_destroy(cf->dfcode);
cf->dfcode = dfcode;
- /* Now go through the list of packets we've read from the capture file,
- applying the current display filter, and, if the packet passes the
- display filter, add it to the summary display, appropriately
- colored. (That's how we colorize the display - it's like filtering
- the display, only we don't install a new filter.) */
- colorize_packets(cf);
+ /* Now rescan the packet list, applying the new filter. */
+ rescan_packets(cf, "Filtering", TRUE);
return 1;
}
void
colorize_packets(capture_file *cf)
{
+ rescan_packets(cf, "Colorizing", FALSE);
+}
+
+void
+redissect_packets(capture_file *cf)
+{
+ rescan_packets(cf, "Reprocessing", TRUE);
+}
+
+/* Rescan the list of packets, reconstructing the CList.
+
+ "action" describes why we're doing this; it's used in the progress
+ dialog box.
+
+ "refilter" is TRUE if we need to re-evaluate the filter expression. */
+static void
+rescan_packets(capture_file *cf, const char *action, gboolean refilter)
+{
frame_data *fdata;
progdlg_t *progbar;
gboolean stop_flag;
@@ -866,9 +904,9 @@ colorize_packets(capture_file *cf)
cf->first_displayed = NULL;
cf->last_displayed = NULL;
- /* Iterate through the list of packets, calling a routine
- to run the filter on the packet, see if it matches, and
- put it in the display list if so. */
+ /* Iterate through the list of frames. Call a routine for each frame
+ to check whether it should be displayed and, if so, add it to
+ the display list. */
firstsec = 0;
firstusec = 0;
prevsec = 0;
@@ -883,7 +921,7 @@ colorize_packets(capture_file *cf)
count = 0;
stop_flag = FALSE;
- progbar = create_progress_dlg("Filtering", "Stop", &stop_flag);
+ progbar = create_progress_dlg(action, "Stop", &stop_flag);
for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
@@ -923,7 +961,8 @@ colorize_packets(capture_file *cf)
wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
cf->pd, fdata->cap_len);
- row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd);
+ row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd,
+ refilter);
if (fdata == selected_frame)
selected_row = row;
}
diff --git a/file.h b/file.h
index b91cfbba68..72b6c87bd2 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.70 2000/07/03 08:35:41 guy Exp $
+ * $Id: file.h,v 1.71 2000/07/09 03:29:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -140,6 +140,7 @@ int save_cap_file(char *, capture_file *, gboolean, guint);
int filter_packets(capture_file *cf, gchar *dfilter);
void colorize_packets(capture_file *);
+void redissect_packets(capture_file *cf);
int print_packets(capture_file *cf, print_args_t *print_args);
void change_time_formats(capture_file *);
gboolean find_packet(capture_file *cf, dfilter *sfcode);
diff --git a/gtk/display_opts.c b/gtk/display_opts.c
index 8ae7224da3..6f8f398ad8 100644
--- a/gtk/display_opts.c
+++ b/gtk/display_opts.c
@@ -1,7 +1,7 @@
/* display_opts.c
* Routines for packet display windows
*
- * $Id: display_opts.c,v 1.10 2000/07/05 02:45:39 guy Exp $
+ * $Id: display_opts.c,v 1.11 2000/07/09 03:29:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -241,6 +241,7 @@ static void
get_display_options(GtkWidget *parent_w)
{
GtkWidget *button;
+ gboolean bval;
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
E_DISPLAY_TIME_ABS_KEY);
@@ -267,7 +268,20 @@ get_display_options(GtkWidget *parent_w)
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
E_DISPLAY_IP_DSCP_KEY);
- g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active);
+ bval = (GTK_TOGGLE_BUTTON (button)->active);
+ if (g_ip_dscp_actif != bval) {
+ g_ip_dscp_actif = bval;
+
+ /* XXX - we "know" here that the IP dissector doesn't need to be
+ notified if this preference changed.
+
+ Ultimately, we should probably remove this item from the
+ "Display options" dialog box, as it can be changed from the
+ "IP" tab in the "Preferences" dialog box. */
+
+ /* Redissect all the packets, and re-evaluate the display filter. */
+ redissect_packets(&cfile);
+ }
}
static void
diff --git a/gtk/main.c b/gtk/main.c
index f76a91ecd4..5f4fca2b5d 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1,6 +1,6 @@
/* main.c
*
- * $Id: main.c,v 1.128 2000/07/05 09:41:04 guy Exp $
+ * $Id: main.c,v 1.129 2000/07/09 03:29:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -1485,6 +1485,11 @@ main(int argc, char *argv[])
}
}
+ /* Notify all registered modules that have had any of their preferences
+ changed either from one of the preferences file or from the command
+ line that its preferences have changed. */
+ prefs_apply_all();
+
#ifndef HAVE_LIBPCAP
if (capture_option_specified)
fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n");
diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c
index a107816ac5..7af69af96b 100644
--- a/gtk/prefs_dlg.c
+++ b/gtk/prefs_dlg.c
@@ -1,7 +1,7 @@
/* prefs_dlg.c
* Routines for handling preferences
*
- * $Id: prefs_dlg.c,v 1.14 2000/07/05 09:41:07 guy Exp $
+ * $Id: prefs_dlg.c,v 1.15 2000/07/09 03:29:42 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -334,8 +334,11 @@ pref_fetch(pref_t *pref, gpointer user_data)
char *str_val;
char *p;
guint uval;
+ gboolean bval;
GSList *rb_entry;
GtkWidget *button;
+ gint enumval;
+ gboolean *pref_changed_p = user_data;
/* Fetch the value of the preference, and set the appropriate variable
to it. */
@@ -348,11 +351,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
#endif
- *pref->varp.uint = uval;
+ if (*pref->varp.uint != uval) {
+ *pref_changed_p = TRUE;
+ *pref->varp.uint = uval;
+ }
break;
case PREF_BOOL:
- *pref->varp.bool = GTK_TOGGLE_BUTTON(pref->control)->active;
+ bval = GTK_TOGGLE_BUTTON(pref->control)->active;
+ if (*pref->varp.bool != bval) {
+ *pref_changed_p = TRUE;
+ *pref->varp.bool = bval;
+ }
break;
case PREF_ENUM:
@@ -377,15 +387,22 @@ pref_fetch(pref_t *pref, gpointer user_data)
/* Get the label, and translate it to a value. */
gtk_label_get(GTK_LABEL(label), &label_string);
- *pref->varp.enump = find_val_for_string(label_string,
+ enumval = find_val_for_string(label_string,
pref->info.enum_info.enumvals, 1);
+ if (*pref->varp.enump != enumval) {
+ *pref_changed_p = TRUE;
+ *pref->varp.enump = enumval;
+ }
break;
case PREF_STRING:
str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
- if (*pref->varp.string != NULL)
- g_free(*pref->varp.string);
- *pref->varp.string = g_strdup(str_val);
+ if (*pref->varp.string == NULL || strcmp(*pref->varp.string, str_val) != 0) {
+ *pref_changed_p = TRUE;
+ if (*pref->varp.string != NULL)
+ g_free(*pref->varp.string);
+ *pref->varp.string = g_strdup(str_val);
+ }
break;
}
}
@@ -393,9 +410,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
static void
module_prefs_fetch(module_t *module, gpointer user_data)
{
+ gboolean *must_redissect_p = user_data;
+
/* For all preferences in this module, fetch its value from this
- module's notebook page. */
- prefs_pref_foreach(module, pref_fetch, NULL);
+ module's notebook page. Find out whether any of them changed. */
+ module->prefs_changed = FALSE; /* assume none of them changed */
+ prefs_pref_foreach(module, pref_fetch, &module->prefs_changed);
+
+ /* If any of them changed, indicate that we must redissect and refilter
+ the current capture (if we have one), as the preference change
+ could cause packets to be dissected differently. */
+ if (module->prefs_changed)
+ *must_redissect_p = TRUE;
}
static void
@@ -432,13 +458,21 @@ module_prefs_clean(module_t *module, gpointer user_data)
static void
prefs_main_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
{
+ gboolean must_redissect = FALSE;
+
printer_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
column_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
stream_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
gui_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
- prefs_module_foreach(module_prefs_fetch, NULL);
+ prefs_module_foreach(module_prefs_fetch, &must_redissect);
+ prefs_apply_all();
prefs_module_foreach(module_prefs_clean, NULL);
gtk_widget_destroy(GTK_WIDGET(parent_w));
+
+ if (must_redissect) {
+ /* Redissect all the packets, and re-evaluate the display filter. */
+ redissect_packets(&cfile);
+ }
}
static void
diff --git a/prefs-int.h b/prefs-int.h
index 0e96f5ff39..3df04f88b6 100644
--- a/prefs-int.h
+++ b/prefs-int.h
@@ -2,7 +2,7 @@
* Definitions for implementation of preference handling routines;
* used by "friends" of the preferences type.
*
- * $Id: prefs-int.h,v 1.1 2000/07/05 09:40:40 guy Exp $
+ * $Id: prefs-int.h,v 1.2 2000/07/09 03:29:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -33,6 +33,7 @@ struct pref_module {
void (*apply_cb)(void); /* routine to call when preferences applied */
GList *prefs; /* list of its preferences */
int numprefs; /* number of preferences */
+ gboolean prefs_changed; /* if TRUE, a preference has changed since we last checked */
};
typedef enum {
diff --git a/prefs.c b/prefs.c
index e4b2e18829..77f99d0494 100644
--- a/prefs.c
+++ b/prefs.c
@@ -1,7 +1,7 @@
/* prefs.c
* Routines for handling preferences
*
- * $Id: prefs.c,v 1.31 2000/07/05 09:40:41 guy Exp $
+ * $Id: prefs.c,v 1.32 2000/07/09 03:29:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -100,6 +100,7 @@ prefs_register_module(const char *name, const char *title,
module->apply_cb = apply_cb;
module->prefs = NULL; /* no preferences, to start */
module->numprefs = 0;
+ module->prefs_changed = FALSE;
modules = g_list_append(modules, module);
@@ -161,11 +162,18 @@ call_apply_cb(gpointer data, gpointer user_data)
{
module_t *module = data;
- (*module->apply_cb)();
+ if (module->prefs_changed) {
+ if (module->apply_cb != NULL)
+ (*module->apply_cb)();
+ module->prefs_changed = FALSE;
+ }
}
/*
- * Call the "apply" callback function for each module.
+ * Call the "apply" callback function for each module if any of its
+ * preferences have changed, and then clear the flag saying its
+ * preferences have changed, as the module has been notified of that
+ * fact.
*/
void
prefs_apply_all(void)
@@ -714,6 +722,8 @@ set_pref(gchar *pref_name, gchar *value)
fmt_data *cfmt;
unsigned long int cval;
guint uval;
+ gboolean bval;
+ gint enum_val;
char *p;
gchar *dotp;
module_t *module;
@@ -836,27 +846,41 @@ set_pref(gchar *pref_name, gchar *value)
uval = strtoul(value, &p, pref->info.base);
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
- *pref->varp.uint = uval;
+ if (*pref->varp.uint != uval) {
+ module->prefs_changed = TRUE;
+ *pref->varp.uint = uval;
+ }
break;
case PREF_BOOL:
/* XXX - give an error if it's neither "true" nor "false"? */
if (strcasecmp(value, "true") == 0)
- *pref->varp.bool = TRUE;
+ bval = TRUE;
else
- *pref->varp.bool = FALSE;
+ bval = FALSE;
+ if (*pref->varp.bool != bval) {
+ module->prefs_changed = TRUE;
+ *pref->varp.bool = bval;
+ }
break;
case PREF_ENUM:
/* XXX - give an error if it doesn't match? */
- *pref->varp.enump = find_val_for_string(value,
+ enum_val = find_val_for_string(value,
pref->info.enum_info.enumvals, 1);
+ if (*pref->varp.enump != enum_val) {
+ module->prefs_changed = TRUE;
+ *pref->varp.enump = enum_val;
+ }
break;
case PREF_STRING:
- if (*pref->varp.string != NULL)
- g_free(*pref->varp.string);
- *pref->varp.string = g_strdup(value);
+ if (*pref->varp.string == NULL || strcmp(*pref->varp.string, value) != 0) {
+ module->prefs_changed = TRUE;
+ if (*pref->varp.string != NULL)
+ g_free(*pref->varp.string);
+ *pref->varp.string = g_strdup(value);
+ }
break;
}
}
diff --git a/prefs.h b/prefs.h
index ab628c0eb5..c53410ab82 100644
--- a/prefs.h
+++ b/prefs.h
@@ -1,7 +1,7 @@
/* prefs.h
* Definitions for preference handling routines
*
- * $Id: prefs.h,v 1.16 2000/07/05 09:40:42 guy Exp $
+ * $Id: prefs.h,v 1.17 2000/07/09 03:29:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -76,7 +76,10 @@ typedef void (*module_cb)(module_t *module, gpointer user_data);
void prefs_module_foreach(module_cb callback, gpointer user_data);
/*
- * Call the "apply" callback function for each module.
+ * Call the "apply" callback function for each module if any of its
+ * preferences have changed, and then clear the flag saying its
+ * preferences have changed, as the module has been notified of that
+ * fact.
*/
void prefs_apply_all(void);
diff --git a/tethereal.c b/tethereal.c
index bc98efed2b..47fa116c2d 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -1,6 +1,6 @@
/* tethereal.c
*
- * $Id: tethereal.c,v 1.34 2000/07/05 09:40:43 guy Exp $
+ * $Id: tethereal.c,v 1.35 2000/07/09 03:29:29 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -411,6 +411,11 @@ main(int argc, char *argv[])
}
}
+ /* Notify all registered modules that have had any of their preferences
+ changed either from one of the preferences file or from the command
+ line that its preferences have changed. */
+ prefs_apply_all();
+
#ifndef HAVE_LIBPCAP
if (capture_option_specified)
fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");