summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/libwireshark0.symbols1
-rw-r--r--echld/dispatcher.c3
-rw-r--r--epan/disabled_protos.c388
-rw-r--r--epan/disabled_protos.h41
-rw-r--r--epan/packet.c7
-rw-r--r--epan/packet.h7
-rw-r--r--rawshark.c3
-rw-r--r--tfshark.c3
-rw-r--r--tshark.c3
-rw-r--r--ui/gtk/main.c4
-rw-r--r--ui/gtk/proto_dlg.c900
-rw-r--r--ui/help_url.c3
-rw-r--r--ui/help_url.h1
-rw-r--r--ui/qt/wireshark_application.cpp3
-rw-r--r--wireshark-qt.cpp1
15 files changed, 932 insertions, 436 deletions
diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols
index 38a6456f40..f67bb255a0 100644
--- a/debian/libwireshark0.symbols
+++ b/debian/libwireshark0.symbols
@@ -527,6 +527,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
find_dissector@Base 1.9.1
find_dissector_table@Base 1.9.1
find_heur_dissector_by_short_name@Base 1.99.8
+ find_heur_dissector_by_unique_short_name@Base 1.99.8
find_heur_dissector_list@Base 1.99.2
find_or_create_conversation@Base 1.9.1
find_protocol_by_id@Base 1.9.1
diff --git a/echld/dispatcher.c b/echld/dispatcher.c
index 21f0957312..9de70ae75b 100644
--- a/echld/dispatcher.c
+++ b/echld/dispatcher.c
@@ -508,12 +508,13 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) {
/* disabled protocols as per configuration file */
set_disabled_protos_list();
-
+ set_disabled_heur_dissector_list();
setlocale(LC_ALL, "");
DISP_DBG((1,"---5"));
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno);
DISP_DBG((1,"---6"));
diff --git a/epan/disabled_protos.c b/epan/disabled_protos.c
index 1afe9c96db..4d30e13510 100644
--- a/epan/disabled_protos.c
+++ b/epan/disabled_protos.c
@@ -34,18 +34,39 @@
#include <wsutil/filesystem.h>
#include <epan/proto.h>
+#include <epan/packet.h>
#include "disabled_protos.h"
#include <wsutil/file_util.h>
-#define GLOBAL_PROTOCOLS_FILE_NAME "disabled_protos"
#define PROTOCOLS_FILE_NAME "disabled_protos"
+#define HEURISTICS_FILE_NAME "heuristic_protos"
+
+/*
+ * Item in a list of disabled protocols.
+ */
+typedef struct {
+ char *name; /* protocol name */
+} protocol_def;
+
+/*
+ * Item in a list of heuristic dissectors and their enabled state.
+ */
+typedef struct {
+ char *name; /* heuristic short name */
+ gboolean enabled; /* heuristc enabled */
+} heur_protocol_def;
/*
* List of disabled protocols
*/
static GList *global_disabled_protos = NULL;
static GList *disabled_protos = NULL;
+/*
+ * List of disabled heuristics
+ */
+static GList *global_disabled_heuristics = NULL;
+static GList *disabled_heuristics = NULL;
#define INIT_BUF_SIZE 128
@@ -68,6 +89,25 @@ discard_existing_list (GList **flp)
}
}
+static void
+heur_discard_existing_list (GList **flp)
+{
+ GList *fl_ent;
+ heur_protocol_def *prot;
+
+ if (*flp != NULL) {
+ fl_ent = g_list_first(*flp);
+ while (fl_ent != NULL) {
+ prot = (heur_protocol_def *) fl_ent->data;
+ g_free(prot->name);
+ g_free(prot);
+ fl_ent = fl_ent->next;
+ }
+ g_list_free(*flp);
+ *flp = NULL;
+ }
+}
+
/*
* Read in a list of disabled protocols.
*
@@ -92,7 +132,7 @@ read_disabled_protos_list(char **gpath_return, int *gopen_errno_return,
FILE *ff;
/* Construct the pathname of the global disabled protocols file. */
- gff_path = get_datafile_path(GLOBAL_PROTOCOLS_FILE_NAME);
+ gff_path = get_datafile_path(PROTOCOLS_FILE_NAME);
/* If we already have a list of protocols, discard it. */
discard_existing_list (&global_disabled_protos);
@@ -258,6 +298,7 @@ read_disabled_protos_list_file(const char *ff_path, FILE *ff,
return 0;
error:
+ g_free(prot_name);
return errno;
}
@@ -408,6 +449,349 @@ save_disabled_protos_list(char **pref_path_return, int *errno_return)
g_free(ff_path);
}
+void
+set_disabled_heur_dissector_list(void)
+{
+ GList *fl_ent;
+ heur_protocol_def *heur;
+ heur_dtbl_entry_t* h;
+
+ /*
+ * assume all heuristics are enabled by default
+ */
+ if (disabled_heuristics == NULL)
+ goto skip;
+
+ fl_ent = g_list_first(disabled_heuristics);
+
+ while (fl_ent != NULL) {
+ heur = (heur_protocol_def *) fl_ent->data;
+ h = find_heur_dissector_by_unique_short_name(heur->name);
+ if (h != NULL) {
+ h->enabled = heur->enabled;
+ }
+
+ fl_ent = fl_ent->next;
+ }
+
+skip:
+ if (global_disabled_heuristics == NULL)
+ return;
+
+ fl_ent = g_list_first(global_disabled_heuristics);
+
+ while (fl_ent != NULL) {
+ heur = (heur_protocol_def *) fl_ent->data;
+
+ h = find_heur_dissector_by_unique_short_name(heur->name);
+ if (h != NULL) {
+ h->enabled = heur->enabled;
+ }
+
+ fl_ent = fl_ent->next;
+ }
+}
+
+static int
+read_disabled_heur_dissector_list_file(const char *ff_path, FILE *ff,
+ GList **flp)
+{
+ heur_protocol_def *heur;
+ int c;
+ char *heuristic_name;
+ int heuristic_name_len;
+ int name_index;
+ gboolean parse_enabled;
+ gboolean enabled;
+ int line = 1;
+
+
+ /* Allocate the protocol name buffer. */
+ heuristic_name_len = INIT_BUF_SIZE;
+ heuristic_name = (char *)g_malloc(heuristic_name_len + 1);
+
+ for (line = 1; ; line++) {
+ /* Lines in a disabled protocol file contain the "filter name" of
+ a protocol to be disabled. */
+
+ /* Skip over leading white space, if any. */
+ while ((c = getc(ff)) != EOF && g_ascii_isspace(c)) {
+ if (c == '\n') {
+ /* Blank line. */
+ continue;
+ }
+ }
+
+ if (c == EOF) {
+ if (ferror(ff))
+ goto error; /* I/O error */
+ else
+ break; /* Nothing more to read */
+ }
+ ungetc(c, ff); /* Unread the non-white-space character. */
+
+ /* Get the name of the protocol. */
+ name_index = 0;
+ enabled = FALSE;
+ parse_enabled = FALSE;
+ for (;;) {
+ c = getc(ff);
+ if (c == EOF)
+ break; /* End of file, or I/O error */
+ if (g_ascii_isspace(c))
+ break; /* Trailing white space, or end of line. */
+ if (c == ',') {/* Separator for enable/disable */
+ parse_enabled = TRUE;
+ continue;
+ }
+ if (c == '#')
+ break; /* Start of comment, running to end of line. */
+ if (parse_enabled) {
+ enabled = ((c == '1') ? TRUE : FALSE);
+ break;
+ }
+ /* Add this character to the protocol name string. */
+ if (name_index >= heuristic_name_len) {
+ /* protocol name buffer isn't long enough; double its length. */
+ heuristic_name_len *= 2;
+ heuristic_name = (char *)g_realloc(heuristic_name, heuristic_name_len + 1);
+ }
+ heuristic_name[name_index] = c;
+ name_index++;
+ }
+
+ if (g_ascii_isspace(c) && c != '\n') {
+ /* Skip over trailing white space. */
+ while ((c = getc(ff)) != EOF && c != '\n' && g_ascii_isspace(c))
+ ;
+ if (c != EOF && c != '\n' && c != '#') {
+ /* Non-white-space after the protocol name; warn about it,
+ in case we come up with a reason to use it. */
+ g_warning("'%s' line %d has extra stuff after the protocol name.",
+ ff_path, line);
+ }
+ }
+ if (c != EOF && c != '\n') {
+ /* Skip to end of line. */
+ while ((c = getc(ff)) != EOF && c != '\n')
+ ;
+ }
+
+ if (c == EOF) {
+ if (ferror(ff))
+ goto error; /* I/O error */
+ else {
+ /* EOF, not error; no newline seen before EOF */
+ g_warning("'%s' line %d doesn't have a newline.", ff_path,
+ line);
+ }
+ break; /* nothing more to read */
+ }
+
+ /* Null-terminate the protocol name. */
+ if (name_index >= heuristic_name_len) {
+ /* protocol name buffer isn't long enough; double its length. */
+ heuristic_name_len *= 2;
+ heuristic_name = (char *)g_realloc(heuristic_name, heuristic_name_len + 1);
+ }
+ heuristic_name[name_index] = '\0';
+
+ /* Add the new protocol to the list of disabled protocols */
+ heur = (heur_protocol_def *) g_malloc(sizeof(heur_protocol_def));
+ heur->name = g_strdup(heuristic_name);
+ heur->enabled = enabled;
+ *flp = g_list_append(*flp, heur);
+ }
+ g_free(heuristic_name);
+ return 0;
+
+error:
+ g_free(heuristic_name);
+ return errno;
+}
+
+void
+read_disabled_heur_dissector_list(char **gpath_return, int *gopen_errno_return,
+ int *gread_errno_return,
+ char **path_return, int *open_errno_return,
+ int *read_errno_return)
+{
+ int err;
+ char *gff_path, *ff_path;
+ FILE *ff;
+
+ /* Construct the pathname of the global disabled heuristic dissectors file. */
+ gff_path = get_datafile_path(HEURISTICS_FILE_NAME);
+
+ /* If we already have a list of protocols, discard it. */
+ heur_discard_existing_list(&global_disabled_heuristics);
+
+ /* Read the global disabled protocols file, if it exists. */
+ *gpath_return = NULL;
+ if ((ff = ws_fopen(gff_path, "r")) != NULL) {
+ /* We succeeded in opening it; read it. */
+ err = read_disabled_heur_dissector_list_file(gff_path, ff,
+ &global_disabled_heuristics);
+ if (err != 0) {
+ /* We had an error reading the file; return the errno and the
+ pathname, so our caller can report the error. */
+ *gopen_errno_return = 0;
+ *gread_errno_return = err;
+ *gpath_return = gff_path;
+ } else
+ g_free(gff_path);
+ fclose(ff);
+ } else {
+ /* We failed to open it. If we failed for some reason other than
+ "it doesn't exist", return the errno and the pathname, so our
+ caller can report the error. */
+ if (errno != ENOENT) {
+ *gopen_errno_return = errno;
+ *gread_errno_return = 0;
+ *gpath_return = gff_path;
+ } else
+ g_free(gff_path);
+ }
+
+ /* Construct the pathname of the user's disabled protocols file. */
+ ff_path = get_persconffile_path(HEURISTICS_FILE_NAME, TRUE);
+
+ /* If we already have a list of protocols, discard it. */
+ heur_discard_existing_list (&disabled_heuristics);
+
+ /* Read the user's disabled protocols file, if it exists. */
+ *path_return = NULL;
+ if ((ff = ws_fopen(ff_path, "r")) != NULL) {
+ /* We succeeded in opening it; read it. */
+ err = read_disabled_heur_dissector_list_file(ff_path, ff, &disabled_heuristics);
+ if (err != 0) {
+ /* We had an error reading the file; return the errno and the
+ pathname, so our caller can report the error. */
+ *open_errno_return = 0;
+ *read_errno_return = err;
+ *path_return = ff_path;
+ } else
+ g_free(ff_path);
+ fclose(ff);
+ } else {
+ /* We failed to open it. If we failed for some reason other than
+ "it doesn't exist", return the errno and the pathname, so our
+ caller can report the error. */
+ if (errno != ENOENT) {
+ *open_errno_return = errno;
+ *read_errno_return = 0;
+ *path_return = ff_path;
+ } else
+ g_free(ff_path);
+ }
+}
+
+static gint
+heur_compare(gconstpointer a, gconstpointer b)
+{
+ return strcmp(((heur_dtbl_entry_t*)a)->short_name,
+ ((heur_dtbl_entry_t*)b)->short_name);
+}
+
+static void
+write_heur_dissector(gpointer data, gpointer user_data)
+{
+ heur_dtbl_entry_t* dtbl_entry = (heur_dtbl_entry_t*)data;
+ FILE *ff = (FILE*)user_data;
+
+ /* Write out the heuristic short name and its enabled state */
+ fprintf(ff, "%s,%d\n", dtbl_entry->short_name, dtbl_entry->enabled ? 1 : 0);
+}
+
+static void
+sort_dissector_table_entries(const char *table_name _U_,
+ heur_dtbl_entry_t *dtbl_entry, gpointer user_data)
+{
+ GSList **list = (GSList**)user_data;
+ *list = g_slist_insert_sorted(*list, dtbl_entry, heur_compare);
+}
+
+static void
+sort_heur_dissector_tables(const char *table_name, heur_dissector_list_t *list, gpointer w)
+{
+ if (list) {
+ heur_dissector_table_foreach(table_name, sort_dissector_table_entries, w);
+ }
+}
+
+WS_DLL_PUBLIC void
+save_disabled_heur_dissector_list(char **pref_path_return, int *errno_return)
+{
+ gchar *ff_path, *ff_path_new;
+ GSList *sorted_heur_list = NULL;
+ FILE *ff;
+
+ *pref_path_return = NULL; /* assume no error */
+
+ ff_path = get_persconffile_path(HEURISTICS_FILE_NAME, TRUE);
+
+ /* Write to "XXX.new", and rename if that succeeds.
+ That means we don't trash the file if we fail to write it out
+ completely. */
+ ff_path_new = g_strdup_printf("%s.new", ff_path);
+
+ if ((ff = ws_fopen(ff_path_new, "w")) == NULL) {
+ *pref_path_return = ff_path;
+ *errno_return = errno;
+ g_free(ff_path_new);
+ return;
+ }
+
+ /* Iterate over all the heuristic dissectors to sort them in alphabetical order by short name */
+ dissector_all_heur_tables_foreach_table(sort_heur_dissector_tables, &sorted_heur_list, NULL);
+
+ /* Write the list */
+ g_slist_foreach(sorted_heur_list, write_heur_dissector, ff);
+ g_slist_free(sorted_heur_list);
+
+ if (fclose(ff) == EOF) {
+ *pref_path_return = ff_path;
+ *errno_return = errno;
+ ws_unlink(ff_path_new);
+ g_free(ff_path_new);
+ return;
+ }
+
+#ifdef _WIN32
+ /* ANSI C doesn't say whether "rename()" removes the target if it
+ exists; the Win32 call to rename files doesn't do so, which I
+ infer is the reason why the MSVC++ "rename()" doesn't do so.
+ We must therefore remove the target file first, on Windows.
+
+ XXX - ws_rename() should be ws_stdio_rename() on Windows,
+ and ws_stdio_rename() uses MoveFileEx() with MOVEFILE_REPLACE_EXISTING,
+ so it should remove the target if it exists, so this stuff
+ shouldn't be necessary. Perhaps it dates back to when we were
+ calling rename(), with that being a wrapper around Microsoft's
+ _rename(), which didn't remove the target. */
+ if (ws_remove(ff_path) < 0 && errno != ENOENT) {
+ /* It failed for some reason other than "it's not there"; if
+ it's not there, we don't need to remove it, so we just
+ drive on. */
+ *pref_path_return = ff_path;
+ *errno_return = errno;
+ ws_unlink(ff_path_new);
+ g_free(ff_path_new);
+ return;
+ }
+#endif
+
+ if (ws_rename(ff_path_new, ff_path) < 0) {
+ *pref_path_return = ff_path;
+ *errno_return = errno;
+ ws_unlink(ff_path_new);
+ g_free(ff_path_new);
+ return;
+ }
+ g_free(ff_path_new);
+ g_free(ff_path);
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/disabled_protos.h b/epan/disabled_protos.h
index ac9b746e4a..2f06c22fc5 100644
--- a/epan/disabled_protos.h
+++ b/epan/disabled_protos.h
@@ -29,13 +29,6 @@ extern "C" {
#endif /* __cplusplus */
/*
- * Item in a list of disabled protocols.
- */
-typedef struct {
- char *name; /* protocol name */
-} protocol_def;
-
-/*
* Read in a list of disabled protocols.
*
* On success, "*pref_path_return" is set to NULL.
@@ -68,6 +61,40 @@ set_disabled_protos_list(void);
WS_DLL_PUBLIC void
save_disabled_protos_list(char **pref_path_return, int *errno_return);
+/*
+ * Read in a list of disabled protocols.
+ *
+ * On success, "*pref_path_return" is set to NULL.
+ * On error, "*pref_path_return" is set to point to the pathname of
+ * the file we tried to read - it should be freed by our caller -
+ * and "*open_errno_return" is set to the error if we couldn't open the file
+ * or "*read_errno_return" is set to the error if we got an error reading
+ * the file.
+ */
+WS_DLL_PUBLIC void
+read_disabled_heur_dissector_list(char **gpath_return, int *gopen_errno_return,
+ int *gread_errno_return,
+ char **path_return, int *open_errno_return,
+ int *read_errno_return);
+
+/*
+ * Disable protocols as per the stored configuration
+ */
+WS_DLL_PUBLIC void
+set_disabled_heur_dissector_list(void);
+
+/*
+ * Write out a list of disabled heuristic dissectors.
+ *
+ * On success, "*pref_path_return" is set to NULL.
+ * On error, "*pref_path_return" is set to point to the pathname of
+ * the file we tried to read - it should be freed by our caller -
+ * and "*errno_return" is set to the error.
+ */
+WS_DLL_PUBLIC void
+save_disabled_heur_dissector_list(char **pref_path_return, int *errno_return);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/epan/packet.c b/epan/packet.c
index 725b23e4ce..2a8cb0ede2 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1981,6 +1981,11 @@ find_heur_dissector_by_short_name(heur_dissector_list_t heur_list, const char *s
return found_entry ? (heur_dtbl_entry_t *)(found_entry->data) : NULL;
}
+heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name)
+{
+ return (heur_dtbl_entry_t*)g_hash_table_lookup(heuristic_short_names, (gpointer)short_name);
+}
+
void
heur_dissector_add(const char *name, heur_dissector_t dissector, const char *display_name, const char *short_name, const int proto)
{
@@ -2041,7 +2046,7 @@ heur_dissector_add(const char *name, heur_dissector_t dissector, const char *dis
hdtbl_entry->enabled = TRUE;
/* do the table insertion */
- g_hash_table_insert(heuristic_short_names, (gpointer)short_name, hdtbl_entry); /* Just a copy */
+ g_hash_table_insert(heuristic_short_names, (gpointer)short_name, hdtbl_entry);
sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
(gpointer)hdtbl_entry);
diff --git a/epan/packet.h b/epan/packet.h
index aac75334e5..bf2598402d 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -448,6 +448,13 @@ WS_DLL_PUBLIC heur_dissector_list_t find_heur_dissector_list(const char *name);
WS_DLL_PUBLIC heur_dtbl_entry_t* find_heur_dissector_by_short_name(heur_dissector_list_t heur_list,
const char *short_name);
+/** Find a heuristic dissector by the unique short protocol name provided during registration.
+ *
+ * @param short_name short name of the protocol to look at
+ * @return pointer to the heuristic dissector entry, NULL if not such dissector exists
+ */
+WS_DLL_PUBLIC heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name);
+
/** Add a sub-dissector to a heuristic dissector list.
* Call this in the proto_handoff function of the sub-dissector.
*
diff --git a/rawshark.c b/rawshark.c
index e34e1a7a08..6981f6d3a5 100644
--- a/rawshark.c
+++ b/rawshark.c
@@ -559,6 +559,8 @@ DIAG_ON(cast-qual)
/* Read the disabled protocols file. */
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
&dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+ &dp_path, &dp_open_errno, &dp_read_errno);
if (gdp_path != NULL) {
if (gdp_open_errno != 0) {
cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
@@ -797,6 +799,7 @@ DIAG_ON(cast-qual)
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
/* Build the column format array */
diff --git a/tfshark.c b/tfshark.c
index 05f1603e2a..47053cac99 100644
--- a/tfshark.c
+++ b/tfshark.c
@@ -1070,6 +1070,8 @@ DIAG_ON(cast-qual)
/* Read the disabled protocols file. */
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
&dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+ &dp_path, &dp_open_errno, &dp_read_errno);
if (gdp_path != NULL) {
if (gdp_open_errno != 0) {
cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
@@ -1428,6 +1430,7 @@ DIAG_ON(cast-qual)
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
/* Build the column format array */
diff --git a/tshark.c b/tshark.c
index a7adc0ae5f..06771c2171 100644
--- a/tshark.c
+++ b/tshark.c
@@ -1308,6 +1308,8 @@ DIAG_ON(cast-qual)
/* Read the disabled protocols file. */
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
&dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+ &dp_path, &dp_open_errno, &dp_read_errno);
if (gdp_path != NULL) {
if (gdp_open_errno != 0) {
cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
@@ -2027,6 +2029,7 @@ DIAG_ON(cast-qual)
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
/* Build the column format array */
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
index 3a5efb4f92..643d9c7f3a 100644
--- a/ui/gtk/main.c
+++ b/ui/gtk/main.c
@@ -2054,6 +2054,8 @@ read_configuration_files(char **gdp_path, char **dp_path)
/* Read the disabled protocols file. */
read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
+ dp_path, &dp_open_errno, &dp_read_errno);
if (*gdp_path != NULL) {
if (gdp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
@@ -3002,6 +3004,7 @@ DIAG_ON(cast-qual)
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
@@ -3844,6 +3847,7 @@ void change_configuration_profile (const gchar *profile_name)
proto_enable_all();
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
/* Reload color filters */
diff --git a/ui/gtk/proto_dlg.c b/ui/gtk/proto_dlg.c
index 7badba7956..d47a77a094 100644
--- a/ui/gtk/proto_dlg.c
+++ b/ui/gtk/proto_dlg.c
@@ -42,39 +42,16 @@
#include "ui/gtk/help_dlg.h"
#include "simple_dialog.h"
-static gboolean proto_delete_event_cb(GtkWidget *, GdkEvent *, gpointer);
-static void proto_ok_cb(GtkWidget *, gpointer);
-static void proto_apply_cb(GtkWidget *, gpointer);
-static void proto_save_cb(GtkWidget *, gpointer);
-static void proto_cancel_cb(GtkWidget *, gpointer);
-static void proto_destroy_cb(GtkWidget *, gpointer);
-#if defined(HEUR_DISSECTOR_LIST)
-static void heur_proto_destroy_cb(GtkWidget *, gpointer);
-#endif
-
-static void show_proto_selection(GtkListStore *proto_store);
-#if defined(HEUR_DISSECTOR_LIST)
-static void show_heur_selection(GtkListStore *proto_store);
-#endif
static gboolean set_proto_selection(GtkWidget *);
static gboolean revert_proto_selection(void);
-static void proto_col_clicked_cb(GtkWidget *col _U_, GtkWidget *proto_list);
-
-static void toggle_all_cb(GtkWidget *button, gpointer parent_w);
-static void enable_all_cb(GtkWidget *button, gpointer parent_w);
-static void disable_all_cb(GtkWidget *button, gpointer parent_w);
-static void status_toggled(GtkCellRendererToggle *, gchar *, gpointer);
-
static GtkWidget *proto_w = NULL;
/* list of protocols */
static GSList *protocol_list = NULL;
-#if defined(HEUR_DISSECTOR_LIST)
/* list of heuristic protocols */
static GSList *heur_protocol_list = NULL;
-#endif
typedef struct protocol_data {
const char *name;
@@ -85,312 +62,23 @@ typedef struct protocol_data {
GtkTreeIter iter;
} protocol_data_t;
+typedef struct heur_protocol_data {
+ const char *name;
+ const char *abbrev;
+ gchar *list_name;
+ gboolean enabled;
+ gboolean was_enabled;
+ GtkTreeIter iter;
+} heur_protocol_data_t;
+
#define DISABLED "Disabled"
#define STATUS_TXT(x) ((x) ? "" : DISABLED)
-
-#if defined(HEUR_DISSECTOR_LIST)
-static GtkWidget *
-build_heur_dissectors_treeview(void)
-{
- GtkWidget *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
- *ok_bt, *save_bt, *cancel_bt;
-
- static const gchar *titles[] = { "Status", "Heuristic Protocol", "Description" };
- GtkListStore *proto_store;
- GtkCellRenderer *proto_rend;
- GtkTreeViewColumn *proto_col;
-
- /* Protocol list */
- proto_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_widget_show(proto_vb);
-
- proto_sw = scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(proto_sw),
- GTK_SHADOW_IN);
- gtk_box_pack_start(GTK_BOX(proto_vb), proto_sw, TRUE, TRUE, 0);
- gtk_widget_show(proto_sw);
-
- proto_store = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_POINTER);
- show_heur_selection(proto_store);
- /* default sort on "abbrev" column */
- gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(proto_store), 1,
- GTK_SORT_ASCENDING);
-
- proto_list = tree_view_new(GTK_TREE_MODEL(proto_store));
- gtk_container_add(GTK_CONTAINER(proto_sw), proto_list);
-
- proto_rend = gtk_cell_renderer_toggle_new();
- g_signal_connect(proto_rend, "toggled", G_CALLBACK(status_toggled), proto_store);
- proto_col = gtk_tree_view_column_new_with_attributes(titles[0], proto_rend, "active", 0, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 0);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- proto_rend = gtk_cell_renderer_text_new();
- proto_col = gtk_tree_view_column_new_with_attributes(titles[1], proto_rend, "text", 1, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 1);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- proto_rend = gtk_cell_renderer_text_new();
- proto_col = gtk_tree_view_column_new_with_attributes(titles[2], proto_rend, "text", 2, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 2);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- gtk_tree_view_set_search_column(GTK_TREE_VIEW(proto_list), 1); /* col 1 in the *model* */
- g_object_unref(G_OBJECT(proto_store));
- gtk_widget_show(proto_list);
-
- label = gtk_label_new("Disabling a heuristic dissector prevents higher layer protocols from being displayed");
- gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(proto_vb), label, FALSE, FALSE, 5);
-
- bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
- gtk_box_set_spacing(GTK_BOX(bbox), 5);
- gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
-
- /* Enable All */
- button = gtk_button_new_with_label("Enable All");
- g_signal_connect(button, "clicked", G_CALLBACK(enable_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- /* Disable All */
- button = gtk_button_new_with_label("Disable All");
- g_signal_connect(button, "clicked", G_CALLBACK(disable_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- /* Invert */
- button = gtk_button_new_with_label("Invert");
- g_signal_connect(button, "clicked", G_CALLBACK(toggle_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-
- /* Button row */
- bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
- gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
-
- ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
- /*g_signal_connect(ok_bt, "clicked", G_CALLBACK(proto_ok_cb), proto_w);*/
- gtk_widget_grab_default(ok_bt);
-
- /*apply_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY);*/
- /* g_signal_connect(apply_bt, "clicked", G_CALLBACK(proto_apply_cb), proto_w);*/
-
- save_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
- /* g_signal_connect(save_bt, "clicked", G_CALLBACK(proto_save_cb), proto_w);*/
-
- cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
- window_set_cancel_button(proto_w, cancel_bt, proto_cancel_cb);
-
- /*help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);*/
- /*g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_ENABLED_PROTOCOLS_DIALOG);*/
-
- /*g_signal_connect(proto_w, "delete_event", G_CALLBACK(proto_delete_event_cb), NULL);*/
- g_signal_connect(proto_w, "destroy", G_CALLBACK(heur_proto_destroy_cb), NULL);
-
- gtk_widget_show(proto_w);
-
- gtk_widget_grab_focus(proto_list); /* XXX: force focus to the tree_view. This hack req'd so "type-ahead find"
- * will be effective after the window is displayed. The issue is
- * that any call to gtk_tree_view_column_set_sort_column_id above
- * apparently sets the focus to the column header button and thus
- * type-ahead find is, in effect, disabled on the column.
- * Also required: a grab_focus whenever the column header is
- * clicked to change the column sort order since the click
- * also changes the focus to the column header button.
- * Is there a better way to do this ?
- */
-
- /* hide the Save button if the user uses implicit save */
- if(!prefs.gui_use_pref_save) {
- gtk_widget_hide(save_bt);
- }
-
- return proto_vb;
-
-}
-#endif
-
-static GtkWidget *
-build_protocols_treeview(void)
-{
- GtkWidget *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
- *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
-
- static const gchar *titles[] = { "Status", "Protocol", "Description" };
- GtkListStore *proto_store;
- GtkCellRenderer *proto_rend;
- GtkTreeViewColumn *proto_col;
-
- /* Protocol list */
- proto_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
- gtk_widget_show(proto_vb);
-
- proto_sw = scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(proto_sw),
- GTK_SHADOW_IN);
- gtk_box_pack_start(GTK_BOX(proto_vb), proto_sw, TRUE, TRUE, 0);
- gtk_widget_show(proto_sw);
-
- proto_store = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_POINTER);
- show_proto_selection(proto_store);
- /* default sort on "abbrev" column */
- gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(proto_store), 1,
- GTK_SORT_ASCENDING);
-
- proto_list = tree_view_new(GTK_TREE_MODEL(proto_store));
- gtk_container_add(GTK_CONTAINER(proto_sw), proto_list);
-
- proto_rend = gtk_cell_renderer_toggle_new();
- g_signal_connect(proto_rend, "toggled", G_CALLBACK(status_toggled), proto_store);
- proto_col = gtk_tree_view_column_new_with_attributes(titles[0], proto_rend, "active", 0, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 0);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- proto_rend = gtk_cell_renderer_text_new();
- proto_col = gtk_tree_view_column_new_with_attributes(titles[1], proto_rend, "text", 1, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 1);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- proto_rend = gtk_cell_renderer_text_new();
- proto_col = gtk_tree_view_column_new_with_attributes(titles[2], proto_rend, "text", 2, NULL);
- gtk_tree_view_column_set_sort_column_id(proto_col, 2);
- g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
- gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
-
- gtk_tree_view_set_search_column(GTK_TREE_VIEW(proto_list), 1); /* col 1 in the *model* */
- g_object_unref(G_OBJECT(proto_store));
- gtk_widget_show(proto_list);
-
- label = gtk_label_new("Disabling a protocol prevents higher layer protocols from being displayed");
- gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
- gtk_widget_show(label);
- gtk_box_pack_start(GTK_BOX(proto_vb), label, FALSE, FALSE, 5);
-
- bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
- gtk_box_set_spacing(GTK_BOX(bbox), 5);
- gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
-
- /* Enable All */
- button = gtk_button_new_with_label("Enable All");
- g_signal_connect(button, "clicked", G_CALLBACK(enable_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- /* Disable All */
- button = gtk_button_new_with_label("Disable All");
- g_signal_connect(button, "clicked", G_CALLBACK(disable_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- /* Invert */
- button = gtk_button_new_with_label("Invert");
- g_signal_connect(button, "clicked", G_CALLBACK(toggle_all_cb), proto_list);
- gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-
- /* Button row */
- bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
- gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
- gtk_widget_show(bbox);
-
- ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
- g_signal_connect(ok_bt, "clicked", G_CALLBACK(proto_ok_cb), proto_w);
- gtk_widget_grab_default(ok_bt);
-
- apply_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY);
- g_signal_connect(apply_bt, "clicked", G_CALLBACK(proto_apply_cb), proto_w);
-
- save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
- g_signal_connect(save_bt, "clicked", G_CALLBACK(proto_save_cb), proto_w);
-
- cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
- window_set_cancel_button(proto_w, cancel_bt, proto_cancel_cb);
-
- help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
- g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_ENABLED_PROTOCOLS_DIALOG);
-
- g_signal_connect(proto_w, "delete_event", G_CALLBACK(proto_delete_event_cb), NULL);
- g_signal_connect(proto_w, "destroy", G_CALLBACK(proto_destroy_cb), NULL);
-
- gtk_widget_show(proto_w);
-
- gtk_widget_grab_focus(proto_list); /* XXX: force focus to the tree_view. This hack req'd so "type-ahead find"
- * will be effective after the window is displayed. The issue is
- * that any call to gtk_tree_view_column_set_sort_column_id above
- * apparently sets the focus to the column header button and thus
- * type-ahead find is, in effect, disabled on the column.
- * Also required: a grab_focus whenever the column header is
- * clicked to change the column sort order since the click
- * also changes the focus to the column header button.
- * Is there a better way to do this ?
- */
-
- /* hide the Save button if the user uses implicit save */
- if(!prefs.gui_use_pref_save) {
- gtk_widget_hide(save_bt);
- }
-
- return proto_vb;
-
-}
-
-void
-proto_cb(GtkWidget *w _U_, gpointer data _U_)
-{
-
- GtkWidget *main_vb, *main_nb, *page_lb, *protocols_page;
-#if defined(HEUR_DISSECTOR_LIST)
- GtkWidget *heur_dissectors_page;
-#endif
- if (proto_w != NULL) {
- reactivate_window(proto_w);
- return;
- }
-
- proto_w = dlg_conf_window_new("Wireshark: Enabled Protocols");
- gtk_window_set_default_size(GTK_WINDOW(proto_w), DEF_WIDTH , DEF_HEIGHT);
-
- /* Container for each row of widgets */
-
- main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
- gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
- gtk_container_add(GTK_CONTAINER(proto_w), main_vb);
- gtk_widget_show(main_vb);
-
- main_nb = gtk_notebook_new();
- gtk_box_pack_start(GTK_BOX(main_vb), main_nb, TRUE, TRUE, 0);
-
-
- /* Protocol selection tab ("enable/disable" protocols) */
- page_lb = gtk_label_new("Enabled Protocols");
- protocols_page = build_protocols_treeview();
- gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), protocols_page, page_lb);
-
-#if defined(HEUR_DISSECTOR_LIST)
- page_lb = gtk_label_new("Enabled Heuristic dissectors");
- heur_dissectors_page = build_heur_dissectors_treeview();
- gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), heur_dissectors_page, page_lb);
-#endif
- gtk_widget_show_all(proto_w);
- window_present(proto_w);
-} /* proto_cb */
+#define ENABLE_COLUMN 0
+#define PROTOCOL_COLUMN 1
+#define DESCRIPTION_COLUMN 2
+#define HEUR_SHORT_NAME_COLUMN 2
+#define PROTO_DATA_COLUMN 3
/* protocol list column header clicked (to change sort) */
/* grab_focus(treeview) req'd so that type-ahead find works. */
@@ -410,18 +98,39 @@ status_toggled(GtkCellRendererToggle *cell _U_, gchar *path_str, gpointer data)
protocol_data_t *p;
gtk_tree_model_get_iter(model, &iter, path);
- gtk_tree_model_get(model, &iter, 3, &p, -1);
+ gtk_tree_model_get(model, &iter, PROTO_DATA_COLUMN, &p, -1);
if (p->enabled)
p->enabled = FALSE;
else
p->enabled = TRUE;
- gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, p->enabled, -1);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, ENABLE_COLUMN, p->enabled, -1);
gtk_tree_path_free(path);
} /* status toggled */
+static void
+heur_status_toggled(GtkCellRendererToggle *cell _U_, gchar *path_str, gpointer data)
+{
+ GtkTreeModel *model = (GtkTreeModel *)data;
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+ heur_protocol_data_t *p;
+
+ gtk_tree_model_get_iter(model, &iter, path);
+ gtk_tree_model_get(model, &iter, PROTO_DATA_COLUMN, &p, -1);
+
+ if (p->enabled)
+ p->enabled = FALSE;
+ else
+ p->enabled = TRUE;
+
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, ENABLE_COLUMN, p->enabled, -1);
+
+ gtk_tree_path_free(path);
+} /* heur_status toggled */
+
/* XXX - We need callbacks for Gtk2 */
/* Toggle All */
@@ -439,7 +148,7 @@ toggle_all_cb(GtkWidget *button _U_, gpointer pl)
else
p->enabled = TRUE;
- gtk_list_store_set(s, &p->iter, 0, p->enabled, -1);
+ gtk_list_store_set(s, &p->iter, ENABLE_COLUMN, p->enabled, -1);
}
}
@@ -454,7 +163,7 @@ set_active_all(GtkWidget *w, gboolean new_state)
protocol_data_t *p = (protocol_data_t *)entry->data;
p->enabled = new_state;
- gtk_list_store_set(s, &p->iter, 0, new_state, -1);
+ gtk_list_store_set(s, &p->iter, ENABLE_COLUMN, new_state, -1);
}
}
@@ -472,6 +181,47 @@ disable_all_cb(GtkWidget *button _U_, gpointer pl)
set_active_all((GtkWidget *)pl, FALSE);
}
+void heur_toggle_all_cb(GtkWidget *button _U_, gpointer pl)
+{
+ GSList *entry;
+ GtkListStore *s = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pl)));
+
+ for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+ heur_protocol_data_t *p = (heur_protocol_data_t *)entry->data;
+
+ if (p->enabled)
+ p->enabled = FALSE;
+ else
+ p->enabled = TRUE;
+
+ gtk_list_store_set(s, &p->iter, ENABLE_COLUMN, p->enabled, -1);
+ }
+}
+
+static void
+heur_set_active_all(GtkWidget *w, gboolean new_state)
+{
+ GtkListStore *s = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
+ GSList *entry;
+
+ for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+ heur_protocol_data_t *p = (heur_protocol_data_t *)entry->data;
+
+ p->enabled = new_state;
+ gtk_list_store_set(s, &p->iter, ENABLE_COLUMN, new_state, -1);
+ }
+}
+
+void heur_enable_all_cb(GtkWidget *button _U_, gpointer pl)
+{
+ heur_set_active_all((GtkWidget *)pl, TRUE);
+}
+
+void heur_disable_all_cb(GtkWidget *button _U_, gpointer pl)
+{
+ heur_set_active_all((GtkWidget *)pl, FALSE);
+}
+
static void
proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
{
@@ -488,7 +238,6 @@ proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
}
}
-#if defined(HEUR_DISSECTOR_LIST)
static void
heur_proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
{
@@ -504,21 +253,8 @@ heur_proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
heur_protocol_list = NULL;
}
}
-#endif
-
-/* Treat this as a cancel, by calling "proto_cancel_cb()".
- XXX - that'll destroy the Protocols dialog; will that upset
- a higher-level handler that says "OK, we've been asked to delete
- this, so destroy it"? */
-static gboolean
-proto_delete_event_cb(GtkWidget *proto_w_lcl, GdkEvent *event _U_,
- gpointer dummy _U_)
-{
- proto_cancel_cb(NULL, proto_w_lcl);
- return FALSE;
-}
-/* Update protocol_list 'was_enabled' to current value of 'enabled' */
+/* Update protocol_list and heur_protocol_list 'was_enabled' to current value of 'enabled' */
static void
update_was_enabled(void)
{
@@ -528,6 +264,11 @@ update_was_enabled(void)
protocol_data_t *p = (protocol_data_t *)entry->data;
p->was_enabled = p->enabled;
}
+
+ for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+ heur_protocol_data_t *p = (heur_protocol_data_t *)entry->data;
+ p->was_enabled = p->enabled;
+ }
}
static void
@@ -552,6 +293,14 @@ proto_write(gpointer parent_w _U_)
pf_path, g_strerror(pf_save_errno));
g_free(pf_path);
}
+
+ save_disabled_heur_dissector_list(&pf_path, &pf_save_errno);
+ if (pf_path != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "Could not save to your disabled heuristic protocol file\n\"%s\": %s.",
+ pf_path, g_strerror(pf_save_errno));
+ g_free(pf_path);
+ }
}
}
@@ -614,10 +363,23 @@ proto_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
redissect_packets();
}
+/* Treat this as a cancel, by calling "proto_cancel_cb()".
+ XXX - that'll destroy the Protocols dialog; will that upset
+ a higher-level handler that says "OK, we've been asked to delete
+ this, so destroy it"? */
+static gboolean
+proto_delete_event_cb(GtkWidget *proto_w_lcl, GdkEvent *event _U_,
+ gpointer dummy _U_)
+{
+ proto_cancel_cb(NULL, proto_w_lcl);
+ return FALSE;
+}
+
static gboolean
set_proto_selection(GtkWidget *parent_w _U_)
{
GSList *entry;
+ heur_dtbl_entry_t* h;
gboolean need_redissect = FALSE;
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
@@ -631,6 +393,16 @@ set_proto_selection(GtkWidget *parent_w _U_)
}
}
+ for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+ heur_protocol_data_t *p = (heur_protocol_data_t*)entry->data;
+
+ h = find_heur_dissector_by_unique_short_name(p->abbrev);
+ if ((h != NULL) && (h->enabled != p->enabled)) {
+ h->enabled = p->enabled;
+ need_redissect = TRUE;
+ }
+ }
+
return need_redissect;
} /* set_proto_selection */
@@ -655,6 +427,19 @@ revert_proto_selection(void)
}
}
+ /*
+ * Undo all the changes we've made to heuristic enable flags.
+ */
+ for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+ heur_protocol_data_t *p = (heur_protocol_data_t*)entry->data;
+
+ heur_dtbl_entry_t* h = find_heur_dissector_by_unique_short_name(p->abbrev);
+ if ((h != NULL) && (h->enabled != p->was_enabled)) {
+ h->enabled = p->was_enabled;
+ need_redissect = TRUE;
+ }
+ }
+
return need_redissect;
} /* revert_proto_selection */
@@ -668,74 +453,18 @@ protocol_data_compare(gconstpointer a, gconstpointer b)
return strcmp(ap->abbrev, bp->abbrev);
}
-static void
-create_protocol_list(void)
-{
- gint i;
- void *cookie;
- protocol_t *protocol;
- protocol_data_t *p;
-
- /* Iterate over all the protocols */
-
- for (i = proto_get_first_protocol(&cookie); i != -1;
- i = proto_get_next_protocol(&cookie)) {
- if (proto_can_toggle_protocol(i)) {
- p = (protocol_data_t *)g_malloc(sizeof(protocol_data_t));
- protocol = find_protocol_by_id(i);
- p->name = proto_get_protocol_name(i);
- p->abbrev = proto_get_protocol_short_name(protocol);
- p->hfinfo_index = i;
- p->enabled = proto_is_protocol_enabled(protocol);
- p->was_enabled = p->enabled;
- protocol_list = g_slist_insert_sorted(protocol_list, p, protocol_data_compare);
- }
- }
-}
-#if defined(HEUR_DISSECTOR_LIST)
-static void
-get_heur_dissector(gpointer data, gpointer user_data)
-{
- protocol_data_t *p;
- const char *table_name = user_data;
- heur_dtbl_entry_t *dtbl_entry = data;
- int proto_id;
-
- if(dtbl_entry){
- p = g_malloc(sizeof(protocol_data_t));
- proto_id = proto_get_id(dtbl_entry->protocol);
-
- p->name = proto_get_protocol_name(proto_id);
- p->abbrev = g_strdup_printf("%s(%s)",proto_get_protocol_short_name(dtbl_entry->protocol),table_name);
- p->hfinfo_index = proto_id;
- if(!proto_is_protocol_enabled(dtbl_entry->protocol)){
- p->enabled = FALSE;
- }else {
- p->enabled = dtbl_entry->enabled;
- }
- p->was_enabled = p->enabled;
- heur_protocol_list = g_slist_insert_sorted(heur_protocol_list, p, protocol_data_compare);
- }
-}
-
-static void
-get_heur_dissector_tables(const char *table_name, gpointer table, gpointer w _U_)
+static gint
+heur_protocol_data_compare(gconstpointer a, gconstpointer b)
{
- heur_dissector_list_t *list = table;
-
- if(list){
- g_slist_foreach (*list, get_heur_dissector, (gpointer)table_name);
- }
+ const heur_protocol_data_t *ap = (const heur_protocol_data_t *)a;
+ const heur_protocol_data_t *bp = (const heur_protocol_data_t *)b;
+ return strcmp(ap->abbrev, bp->abbrev);
}
-#endif
-#if defined(HEUR_DISSECTOR_LIST)
static void
-create_heur_protocol_list(void)
+create_protocol_list(void)
{
- dissector_all_heur_tables_foreach_table(get_heur_dissector_tables, NULL);
-
gint i;
void *cookie;
protocol_t *protocol;
@@ -746,7 +475,7 @@ create_heur_protocol_list(void)
for (i = proto_get_first_protocol(&cookie); i != -1;
i = proto_get_next_protocol(&cookie)) {
if (proto_can_toggle_protocol(i)) {
- p = g_malloc(sizeof(protocol_data_t));
+ p = (protocol_data_t *)g_malloc(sizeof(protocol_data_t));
protocol = find_protocol_by_id(i);
p->name = proto_get_protocol_name(i);
p->abbrev = proto_get_protocol_short_name(protocol);
@@ -757,7 +486,6 @@ create_heur_protocol_list(void)
}
}
}
-#endif
static void
show_proto_selection(GtkListStore *proto_store)
@@ -773,39 +501,63 @@ show_proto_selection(GtkListStore *proto_store)
gtk_list_store_append(proto_store, &p->iter);
gtk_list_store_set(proto_store, &p->iter,
- 0, p->enabled,
- 1, p->abbrev,
- 2, p->name,
- 3, p,
+ ENABLE_COLUMN, p->enabled,
+ PROTOCOL_COLUMN, p->abbrev,
+ DESCRIPTION_COLUMN, p->name,
+ PROTO_DATA_COLUMN, p,
-1);
}
-
} /* show_proto_selection */
-#if defined(HEUR_DISSECTOR_LIST)
+static void
+populate_heur_dissector_table_entries(const char *table_name _U_,
+ heur_dtbl_entry_t *dtbl_entry, gpointer user_data _U_)
+{
+ heur_protocol_data_t *p;
+
+ if (dtbl_entry->protocol) {
+
+ p = g_new(heur_protocol_data_t, 1);
+ p->name = dtbl_entry->display_name;
+ p->abbrev = dtbl_entry->short_name;
+ p->enabled = dtbl_entry->enabled;
+ p->list_name = dtbl_entry->list_name;
+ p->was_enabled = p->enabled;
+ heur_protocol_list = g_slist_insert_sorted(heur_protocol_list, p, heur_protocol_data_compare);
+
+ }else{
+ g_warning("no protocol info");
+ }
+}
+
+static void
+populate_heur_dissector_tables(const char *table_name, heur_dissector_list_t *list, gpointer w)
+{
+ if (list) {
+ heur_dissector_table_foreach(table_name, populate_heur_dissector_table_entries, w);
+ }
+}
+
static void
show_heur_selection(GtkListStore *proto_store)
{
GSList *entry;
- protocol_data_t *p;
if (heur_protocol_list == NULL)
- create_heur_protocol_list();
+ dissector_all_heur_tables_foreach_table(populate_heur_dissector_tables, NULL, NULL);
for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
- p = entry->data;
+ heur_protocol_data_t *p = (heur_protocol_data_t *)entry->data;
gtk_list_store_append(proto_store, &p->iter);
gtk_list_store_set(proto_store, &p->iter,
- 0, p->enabled,
- 1, p->abbrev,
- 2, p->name,
- 3, p,
+ ENABLE_COLUMN, p->enabled,
+ PROTOCOL_COLUMN, p->name,
+ HEUR_SHORT_NAME_COLUMN, p->abbrev,
+ PROTO_DATA_COLUMN, p,
-1);
}
-
-} /* show_proto_selection */
-#endif
+}
static void
proto_disable_dialog_cb(gpointer dialog _U_, gint btn, gpointer data)
@@ -854,6 +606,304 @@ proto_disable_cb(GtkWidget *w _U_, gpointer data _U_)
simple_dialog_set_cb(dialog, proto_disable_dialog_cb, GINT_TO_POINTER(id));
}
+static GtkWidget *
+build_heur_dissectors_treeview(void)
+{
+ GtkWidget *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
+ *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
+
+ static const gchar *titles[] = { "Status", "Heuristic Protocol", "Short name"};
+ GtkListStore *proto_store;
+ GtkCellRenderer *proto_rend;
+ GtkTreeViewColumn *proto_col;
+
+ /* Protocol list */
+ proto_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_widget_show(proto_vb);
+
+ proto_sw = scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(proto_sw),
+ GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(proto_vb), proto_sw, TRUE, TRUE, 0);
+ gtk_widget_show(proto_sw);
+
+ proto_store = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+ show_heur_selection(proto_store);
+ /* default sort on "abbrev" column */
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(proto_store), PROTOCOL_COLUMN,
+ GTK_SORT_ASCENDING);
+
+ proto_list = tree_view_new(GTK_TREE_MODEL(proto_store));
+ gtk_container_add(GTK_CONTAINER(proto_sw), proto_list);
+
+ proto_rend = gtk_cell_renderer_toggle_new();
+ g_signal_connect(proto_rend, "toggled", G_CALLBACK(heur_status_toggled), proto_store);
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[ENABLE_COLUMN], proto_rend, "active", ENABLE_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, ENABLE_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+ proto_rend = gtk_cell_renderer_text_new();
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[PROTOCOL_COLUMN], proto_rend, "text", PROTOCOL_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, PROTOCOL_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+ proto_rend = gtk_cell_renderer_text_new();
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[HEUR_SHORT_NAME_COLUMN], proto_rend, "text", HEUR_SHORT_NAME_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, HEUR_SHORT_NAME_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+
+ gtk_tree_view_set_search_column(GTK_TREE_VIEW(proto_list), PROTOCOL_COLUMN); /* col 1 in the *model* */
+ g_object_unref(G_OBJECT(proto_store));
+ gtk_widget_show(proto_list);
+
+ label = gtk_label_new("Disabling a heuristic protocol prevents higher layer protocols from being displayed");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(proto_vb), label, FALSE, FALSE, 5);
+
+ bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ /* Enable All */
+ button = gtk_button_new_with_label("Enable All");
+ g_signal_connect(button, "clicked", G_CALLBACK(heur_enable_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ /* Disable All */
+ button = gtk_button_new_with_label("Disable All");
+ g_signal_connect(button, "clicked", G_CALLBACK(heur_disable_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ /* Invert */
+ button = gtk_button_new_with_label("Invert");
+ g_signal_connect(button, "clicked", G_CALLBACK(heur_toggle_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+
+ /* Button row */
+ bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
+ gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+ g_signal_connect(ok_bt, "clicked", G_CALLBACK(proto_ok_cb), proto_w);
+ gtk_widget_grab_default(ok_bt);
+
+ apply_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY);
+ g_signal_connect(apply_bt, "clicked", G_CALLBACK(proto_apply_cb), proto_w);
+
+ save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
+ g_signal_connect(save_bt, "clicked", G_CALLBACK(proto_save_cb), proto_w);
+
+ cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
+ window_set_cancel_button(proto_w, cancel_bt, proto_cancel_cb);
+
+ help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
+ g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_ENABLED_HEURISTICS_DIALOG);
+
+ g_signal_connect(proto_w, "delete_event", G_CALLBACK(proto_delete_event_cb), NULL);
+ g_signal_connect(proto_w, "destroy", G_CALLBACK(heur_proto_destroy_cb), NULL);
+
+ gtk_widget_show(proto_w);
+
+ gtk_widget_grab_focus(proto_list); /* XXX: force focus to the tree_view. This hack req'd so "type-ahead find"
+ * will be effective after the window is displayed. The issue is
+ * that any call to gtk_tree_view_column_set_sort_column_id above
+ * apparently sets the focus to the column header button and thus
+ * type-ahead find is, in effect, disabled on the column.
+ * Also required: a grab_focus whenever the column header is
+ * clicked to change the column sort order since the click
+ * also changes the focus to the column header button.
+ * Is there a better way to do this ?
+ */
+
+ /* hide the Save button if the user uses implicit save */
+ if(!prefs.gui_use_pref_save) {
+ gtk_widget_hide(save_bt);
+ }
+
+ return proto_vb;
+
+}
+
+static GtkWidget *
+build_protocols_treeview(void)
+{
+ GtkWidget *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
+ *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
+
+ static const gchar *titles[] = { "Status", "Protocol", "Description" };
+ GtkListStore *proto_store;
+ GtkCellRenderer *proto_rend;
+ GtkTreeViewColumn *proto_col;
+
+ /* Protocol list */
+ proto_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE);
+ gtk_widget_show(proto_vb);
+
+ proto_sw = scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(proto_sw),
+ GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(proto_vb), proto_sw, TRUE, TRUE, 0);
+ gtk_widget_show(proto_sw);
+
+ proto_store = gtk_list_store_new(4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
+
+ show_proto_selection(proto_store);
+ /* default sort on "abbrev" column */
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(proto_store), PROTOCOL_COLUMN,
+ GTK_SORT_ASCENDING);
+
+ proto_list = tree_view_new(GTK_TREE_MODEL(proto_store));
+ gtk_container_add(GTK_CONTAINER(proto_sw), proto_list);
+
+ proto_rend = gtk_cell_renderer_toggle_new();
+ g_signal_connect(proto_rend, "toggled", G_CALLBACK(status_toggled), proto_store);
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[ENABLE_COLUMN], proto_rend, "active", ENABLE_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, ENABLE_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+ proto_rend = gtk_cell_renderer_text_new();
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[PROTOCOL_COLUMN], proto_rend, "text", PROTOCOL_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, PROTOCOL_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+ proto_rend = gtk_cell_renderer_text_new();
+ proto_col = gtk_tree_view_column_new_with_attributes(titles[DESCRIPTION_COLUMN], proto_rend, "text", DESCRIPTION_COLUMN, NULL);
+ gtk_tree_view_column_set_sort_column_id(proto_col, DESCRIPTION_COLUMN);
+ g_signal_connect(proto_col, "clicked", G_CALLBACK(proto_col_clicked_cb), proto_list);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(proto_list), proto_col);
+
+ gtk_tree_view_set_search_column(GTK_TREE_VIEW(proto_list), PROTOCOL_COLUMN); /* col 1 in the *model* */
+ g_object_unref(G_OBJECT(proto_store));
+ gtk_widget_show(proto_list);
+
+ label = gtk_label_new("Disabling a protocol prevents higher layer protocols from being displayed");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(proto_vb), label, FALSE, FALSE, 5);
+
+ bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ /* Enable All */
+ button = gtk_button_new_with_label("Enable All");
+ g_signal_connect(button, "clicked", G_CALLBACK(enable_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ /* Disable All */
+ button = gtk_button_new_with_label("Disable All");
+ g_signal_connect(button, "clicked", G_CALLBACK(disable_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ /* Invert */
+ button = gtk_button_new_with_label("Invert");
+ g_signal_connect(button, "clicked", G_CALLBACK(toggle_all_cb), proto_list);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+
+ /* Button row */
+ bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_APPLY, GTK_STOCK_SAVE, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
+ gtk_box_pack_start(GTK_BOX(proto_vb), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+ g_signal_connect(ok_bt, "clicked", G_CALLBACK(proto_ok_cb), proto_w);
+ gtk_widget_grab_default(ok_bt);
+
+ apply_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_APPLY);
+ g_signal_connect(apply_bt, "clicked", G_CALLBACK(proto_apply_cb), proto_w);
+
+ save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE);
+ g_signal_connect(save_bt, "clicked", G_CALLBACK(proto_save_cb), proto_w);
+
+ cancel_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
+ window_set_cancel_button(proto_w, cancel_bt, proto_cancel_cb);
+
+ help_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
+ g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_ENABLED_PROTOCOLS_DIALOG);
+
+ g_signal_connect(proto_w, "delete_event", G_CALLBACK(proto_delete_event_cb), NULL);
+ g_signal_connect(proto_w, "destroy", G_CALLBACK(proto_destroy_cb), NULL);
+
+ gtk_widget_show(proto_w);
+
+ gtk_widget_grab_focus(proto_list); /* XXX: force focus to the tree_view. This hack req'd so "type-ahead find"
+ * will be effective after the window is displayed. The issue is
+ * that any call to gtk_tree_view_column_set_sort_column_id above
+ * apparently sets the focus to the column header button and thus
+ * type-ahead find is, in effect, disabled on the column.
+ * Also required: a grab_focus whenever the column header is
+ * clicked to change the column sort order since the click
+ * also changes the focus to the column header button.
+ * Is there a better way to do this ?
+ */
+
+ /* hide the Save button if the user uses implicit save */
+ if(!prefs.gui_use_pref_save) {
+ gtk_widget_hide(save_bt);
+ }
+
+ return proto_vb;
+
+}
+
+void
+proto_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+
+ GtkWidget *main_vb, *main_nb, *page_lb, *protocols_page;
+ GtkWidget *heur_dissectors_page;
+ if (proto_w != NULL) {
+ reactivate_window(proto_w);
+ return;
+ }
+
+ proto_w = dlg_conf_window_new("Wireshark: Enabled Protocols");
+ gtk_window_set_default_size(GTK_WINDOW(proto_w), DEF_WIDTH , DEF_HEIGHT);
+
+ /* Container for each row of widgets */
+
+ main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
+ gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
+ gtk_container_add(GTK_CONTAINER(proto_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ main_nb = gtk_notebook_new();
+ gtk_box_pack_start(GTK_BOX(main_vb), main_nb, TRUE, TRUE, 0);
+
+
+ /* Protocol selection tab ("enable/disable" protocols) */
+ page_lb = gtk_label_new("Enabled Protocols");
+ protocols_page = build_protocols_treeview();
+ gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), protocols_page, page_lb);
+
+ page_lb = gtk_label_new("Enabled Heuristic dissectors");
+ heur_dissectors_page = build_heur_dissectors_treeview();
+ gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), heur_dissectors_page, page_lb);
+
+ gtk_widget_show_all(proto_w);
+ window_present(proto_w);
+} /* proto_cb */
+
/*
* Editor modelines
*
diff --git a/ui/help_url.c b/ui/help_url.c
index f45315002e..0e2fe5dce6 100644
--- a/ui/help_url.c
+++ b/ui/help_url.c
@@ -250,6 +250,9 @@ topic_action_url(topic_action_e action)
case(HELP_ENABLED_PROTOCOLS_DIALOG):
url = user_guide_url("ChCustProtocolDissectionSection.html");
break;
+ case(HELP_ENABLED_HEURISTICS_DIALOG):
+ url = user_guide_url("ChCustProtocolDissectionSection.html");
+ break;
case(HELP_DECODE_AS_DIALOG):
url = user_guide_url("ChCustProtocolDissectionSection.html");
break;
diff --git a/ui/help_url.h b/ui/help_url.h
index bbf82821da..ae1002f319 100644
--- a/ui/help_url.h
+++ b/ui/help_url.h
@@ -80,6 +80,7 @@ typedef enum {
HELP_CAPTURE_INTERFACES_DIALOG,
HELP_CAPTURE_MANAGE_INTERFACES_DIALOG,
HELP_ENABLED_PROTOCOLS_DIALOG,
+ HELP_ENABLED_HEURISTICS_DIALOG,
HELP_DECODE_AS_DIALOG,
HELP_DECODE_AS_SHOW_DIALOG,
HELP_FOLLOW_STREAM_DIALOG,
diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp
index fb37ccf2e8..92c347bc65 100644
--- a/ui/qt/wireshark_application.cpp
+++ b/ui/qt/wireshark_application.cpp
@@ -372,6 +372,7 @@ void WiresharkApplication::setConfigurationProfile(const gchar *profile_name)
proto_enable_all();
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
/* Reload color filters */
@@ -768,6 +769,8 @@ _e_prefs *WiresharkApplication::readConfigurationFiles(char **gdp_path, char **d
/* Read the disabled protocols file. */
read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
dp_path, &dp_open_errno, &dp_read_errno);
+ read_disabled_heur_dissector_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
+ dp_path, &dp_open_errno, &dp_read_errno);
if (*gdp_path != NULL) {
if (gdp_open_errno != 0) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp
index 57bafc10c5..dd98a08699 100644
--- a/wireshark-qt.cpp
+++ b/wireshark-qt.cpp
@@ -1291,6 +1291,7 @@ DIAG_ON(cast-qual)
/* disabled protocols as per configuration file */
if (gdp_path == NULL && dp_path == NULL) {
set_disabled_protos_list();
+ set_disabled_heur_dissector_list();
}
build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);