Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: [Wireshark-dev] Enable/disable Heuristic dissectors from enabled protocols dialo

From: Anders Broman <a.broman@xxxxxxxxxxxx>
Date: Sun, 22 Jan 2012 20:10:53 +0100
Anders Broman skrev 2012-01-20 10:37:


-----Original Message-----
From: wireshark-dev-bounces@xxxxxxxxxxxxx [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] On Behalf Of Guy Harris
Sent: den 20 januari 2012 05:53
To: wireshark-dev@xxxxxxxxxxxxx
Subject: Re: [Wireshark-dev] [Wireshark-commits] rev 40601: /trunk/epan/ /trunk/epan/: packet.c packet.h


On Jan 19, 2012, at 6:43 PM, wmeier@xxxxxxxxxxxxx wrote:

http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=40601

User: wmeier
Date: 2012/01/19 06:43 PM

Log:
Add 'heur_dissector_set_enabled()' to allow a dissector to
enable/disable heuristic dissection; Rename some vars; Do some minor
re-indentation and whitespace changes.
Hmm.

Should this be done from the enable/disable dissectors dialog?  E.g., if a protocol has both key-based (uint or string or whatever we add in the future) and
heuristic dissectors, should there be checkboxes to control the key-based and heuristic dissectors, and if it has only a heuristic dissector, should there be an
entry for it?
I have half finished code to add enable dissable heuristics dissectors from the enable/disable dissectors dialog sitting on my home computer. I can
Submitt that code on Sunday at the earliest.
Regards
Anders
Here is the code. Only the GUI part is complete.
Regards
Anders
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list<wireshark-dev@xxxxxxxxxxxxx>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
              mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe
___________________________________________________________________________
Sent via:    Wireshark-dev mailing list<wireshark-dev@xxxxxxxxxxxxx>
Archives:    http://www.wireshark.org/lists/wireshark-dev
Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
              mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe


Index: ui/gtk/proto_dlg.c
===================================================================
--- ui/gtk/proto_dlg.c	(revision 40653)
+++ ui/gtk/proto_dlg.c	(working copy)
@@ -38,14 +38,14 @@
 #include <epan/filesystem.h>
 
 #include "../util.h"
-#include "ui/simple_dialog.h"
+#include "../simple_dialog.h"
 #include "../disabled_protos.h"
 
-#include "ui/gtk/main.h"
-#include "ui/gtk/gui_utils.h"
-#include "ui/gtk/dlg_utils.h"
-#include "ui/gtk/proto_dlg.h"
-#include "ui/gtk/help_dlg.h"
+#include "gtk/main.h"
+#include "gtk/gui_utils.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/proto_dlg.h"
+#include "gtk/help_dlg.h"
 
 
 static gboolean proto_delete_event_cb(GtkWidget *, GdkEvent *, gpointer);
@@ -54,8 +54,10 @@
 static void proto_save_cb(GtkWidget *, gpointer);
 static void proto_cancel_cb(GtkWidget *, gpointer);
 static void proto_destroy_cb(GtkWidget *, gpointer);
+static void heur_proto_destroy_cb(GtkWidget *, gpointer);
 
 static void show_proto_selection(GtkListStore *proto_store);
+static void show_heur_selection(GtkListStore *proto_store);
 static gboolean set_proto_selection(GtkWidget *);
 static gboolean revert_proto_selection(void);
 
@@ -71,6 +73,9 @@
 /* list of protocols */
 static GSList *protocol_list = NULL;
 
+/* list of heuristic protocols */
+static GSList *heur_protocol_list = NULL;
+
 typedef struct protocol_data {
   const char  *name;
   const char  *abbrev;
@@ -83,44 +88,151 @@
 #define DISABLED "Disabled"
 #define STATUS_TXT(x) ((x) ? "" : DISABLED)
 
-void
-proto_cb(GtkWidget *w _U_, gpointer data _U_)
+
+static GtkWidget *
+build_heur_dissectors_treeview()
 {
+  GtkWidget  *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
+             *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
 
-  GtkWidget *main_vb, *bbox, *proto_list, *label, *proto_sw, *proto_frame,
-            *proto_vb, *button, *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
-  const gchar *titles[] = { "Status", "Protocol", "Description" };
+  const gchar *titles[] = { "Status", "Heuristic Protocol", "Description" };
   GtkListStore *proto_store;
   GtkCellRenderer *proto_rend;
   GtkTreeViewColumn *proto_col;
 
+  /* Protocol list */
+  proto_vb = gtk_vbox_new(FALSE, 0);
+  gtk_widget_show(proto_vb);
 
-  if (proto_w != NULL) {
-    reactivate_window(proto_w);
-    return;
+  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_hbutton_box_new();
+  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);
   }
 
-  proto_w = dlg_conf_window_new("Wireshark: Enabled Protocols");
-  gtk_window_set_default_size(GTK_WINDOW(proto_w), DEF_WIDTH , DEF_HEIGHT);
+  return proto_vb;
 
-  /* Container for each row of widgets */
+}
 
-  main_vb = gtk_vbox_new(FALSE, 6);
-  gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
-  gtk_container_add(GTK_CONTAINER(proto_w), main_vb);
-  gtk_widget_show(main_vb);
+static GtkWidget *
+build_protocols_treeview()
+{
+  GtkWidget  *bbox, *proto_list, *label, *proto_sw, *proto_vb, *button,
+             *ok_bt, *apply_bt, *save_bt, *cancel_bt, *help_bt;
 
-  /* Protocol selection list ("enable/disable" protocols) */
+  const gchar *titles[] = { "Status", "Protocol", "Description" };
+  GtkListStore *proto_store;
+  GtkCellRenderer *proto_rend;
+  GtkTreeViewColumn *proto_col;
 
-  proto_frame = gtk_frame_new("Enabled Protocols");
-  gtk_box_pack_start(GTK_BOX(main_vb), proto_frame, TRUE, TRUE, 0);
-  gtk_widget_show(proto_frame);
-
   /* Protocol list */
-
   proto_vb = gtk_vbox_new(FALSE, 0);
-  gtk_container_add(GTK_CONTAINER(proto_frame), proto_vb);
-  gtk_container_set_border_width(GTK_CONTAINER(proto_vb), 5);
   gtk_widget_show(proto_vb);
 
   proto_sw = scrolled_window_new(NULL, NULL);
@@ -195,7 +307,7 @@
 
   /* 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(main_vb), bbox, FALSE, FALSE, 0);
+  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);
@@ -235,6 +347,45 @@
     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, *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 = gtk_vbox_new(FALSE, 6);
+  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 */
 
@@ -334,6 +485,22 @@
   }
 }
 
+static void
+heur_proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+  GSList *entry;
+
+  proto_w = NULL;
+  /* remove protocol list */
+  if (heur_protocol_list) {
+    for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+      g_free(entry->data);
+    }
+    g_slist_free(heur_protocol_list);
+    heur_protocol_list = NULL;
+  }
+}
+
 /* 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
@@ -521,8 +688,75 @@
       }
   }
 }
+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_)
+{
+	heur_dissector_list_t *list = table;
+
+	if(list){
+		g_slist_foreach (*list, get_heur_dissector, (gpointer)table_name);
+	}
+
+}
+
+static void
+create_heur_protocol_list(void)
+{
+	dissector_all_heur_tables_foreach_table(get_heur_dissector_tables, NULL);
+
+#if 0
+  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 = 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);
+      }
+  }
+#endif
+}
+
+static void
 show_proto_selection(GtkListStore *proto_store)
 {
   GSList *entry;
@@ -546,6 +780,29 @@
 } /* show_proto_selection */
 
 static void
+show_heur_selection(GtkListStore *proto_store)
+{
+  GSList *entry;
+  protocol_data_t *p;
+
+  if (heur_protocol_list == NULL)
+    create_heur_protocol_list();
+
+  for (entry = heur_protocol_list; entry != NULL; entry = g_slist_next(entry)) {
+    p = 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,
+                      -1);
+  }
+
+} /* show_proto_selection */
+
+static void
 proto_disable_dialog_cb(gpointer dialog _U_, gint btn, gpointer data)
 {
   protocol_t *protocol;