From Cal Turney:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 31 Jan 2011 12:19:15 +0000 (12:19 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 31 Jan 2011 12:19:15 +0000 (12:19 +0000)
Bug 5621 - With String in Packet details searches, highlight row in tree
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5621

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@35718 f5534014-38df-0310-8fa8-9805f1628bb7

cfile.h
file.c
file.h
gtk/find_dlg.c
gtk/main.c
gtk/main_proto_draw.c
gtk/menus.h

diff --git a/cfile.h b/cfile.h
index fe912bb261cd8cd7229a86ea867bcb8f921e5436..a54fddc0a0da2f4645b1bfa22bd2a2a5011d1b53 100644 (file)
--- a/cfile.h
+++ b/cfile.h
@@ -70,15 +70,16 @@ typedef struct _capture_file {
   gchar       *dfilter;         /* Display filter string */
   gboolean     redissecting;    /* TRUE if currently redissecting (cf_redissect_packets) */
   /* search */
-  gchar       *sfilter;         /* Search filter string */
-  search_direction dir;         /* Direction in which to do searches */
-  gboolean     hex;             /* TRUE is raw data search is being performed */
-  gboolean     string;          /* TRUE is text search is being performed */
-  guint32      search_pos;      /* Position of last character found in search */
-  search_charset_t scs_type;    /* Character set for text search */
+  gchar       *sfilter;         /* Filter, hex value, or string being searched */
+  gboolean     hex;             /* TRUE if "Hex value" search was last selected */
+  gboolean     string;          /* TRUE if "String" search was last selected */
+  gboolean     summary_data;    /* TRUE if "String" search in "Packet list" (Info column) was last selected */
+  gboolean     decode_data;     /* TRUE if "String" search in "Packet details" was last selected */
+  gboolean     packet_data;     /* TRUE if "String" search in "Packet data" was last selected */
+  guint32      search_pos;      /* Byte position of last byte found in a hex search */
   gboolean     case_type;       /* TRUE if case-insensitive text search */
-  gboolean     decode_data;     /* TRUE if searching protocol tree text */
-  gboolean     summary_data;    /* TRUE if searching Info column text */
+  search_charset_t scs_type;    /* Character set for text search */
+  search_direction dir;         /* Direction in which to do searches */
   gboolean     search_in_progress; /* TRUE if user just clicked OK in the Find dialog or hit <control>N/B */
   /* packet data */
   union wtap_pseudo_header pseudo_header; /* Packet pseudo_header */
diff --git a/file.c b/file.c
index 65b35b554b383f5f87bbdee3da23f3182fe9d2a0..34526aed71ed84b366e4ae8c2e7e94b68d92689a 100644 (file)
--- a/file.c
+++ b/file.c
@@ -3408,14 +3408,6 @@ cf_change_time_formats(capture_file *cf)
 }
 #endif /* NEW_PACKET_LIST */
 
-
-typedef struct {
-    const char  *string;
-    size_t      string_len;
-    capture_file    *cf;
-    gboolean    frame_matched;
-} match_data;
-
 gboolean
 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
                              search_direction dir)
@@ -3427,6 +3419,18 @@ cf_find_packet_protocol_tree(capture_file *cf, const char *string,
   return find_packet(cf, match_protocol_tree, &mdata, dir);
 }
 
+gboolean
+cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
+{
+  mdata->frame_matched = FALSE;
+  mdata->string = convert_string_case(cf->sfilter, cf->case_type);
+  mdata->string_len = strlen(mdata->string);
+  mdata->cf = cf;
+  /* Iterate through all the nodes looking for matching text */
+  proto_tree_children_foreach(tree, match_subtree_text, mdata);
+  return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED; 
+}
+
 static match_result
 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
 {
@@ -3498,6 +3502,7 @@ match_subtree_text(proto_node *node, gpointer data)
       if (c_match == string_len) {
         /* No need to look further; we have a match */
         mdata->frame_matched = TRUE;
+        mdata->finfo = fi;
         return;
       }
     } else
diff --git a/file.h b/file.h
index c2d319e465c0bb71a0ddeecf1eab14ccf0c96d5d..e30a064d03361ec43b185ff742400cfa947d8a76 100644 (file)
--- a/file.h
+++ b/file.h
@@ -71,6 +71,14 @@ typedef enum {
 
 typedef void (*cf_callback_t) (gint event, gpointer data, gpointer user_data);
 
+typedef struct {
+    const char    *string;
+    size_t         string_len;
+    capture_file  *cf;
+    gboolean       frame_matched;
+    field_info    *finfo;
+} match_data;
+
 extern void
 cf_callback_add(cf_callback_t func, gpointer user_data);
 
@@ -404,6 +412,17 @@ cf_print_status_t cf_write_carrays_packets(capture_file *cf, print_args_t *print
 gboolean cf_find_packet_protocol_tree(capture_file *cf, const char *string,
                                       search_direction dir);
 
+/**
+ * Find field with a label that contains text string cfile->sfilter.
+ *
+ * @param cf the capture file
+ * @param tree the protocol tree
+ * @param mdata the first field (mdata->finfo) that matched the string
+ * @return TRUE if a packet was found, FALSE otherwise
+ */
+extern gboolean cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,
+                                             match_data *mdata);
+
 /**
  * Find packet whose summary line contains a specified text string.
  *
index 713186f4c84b4d25feb0d96d820ed8414cdce010..3145b7bd413bb6b01aefcc84c302f6e8c6787071 100644 (file)
@@ -60,7 +60,7 @@
 #define E_FIND_STRINGTYPE_KEY "find_string_type"
 #define E_FIND_STRINGTYPE_LABEL_KEY "find_string_type_label"
 #define E_CASE_SEARCH_KEY     "case_insensitive_search"
-#define E_SOURCE_HEX_KEY      "hex_data_source"
+#define E_SOURCE_DATA_KEY     "packet_data_source"
 #define E_SOURCE_DECODE_KEY   "decode_data_source"
 #define E_SOURCE_SUMMARY_KEY  "summary_data_source"
 #define E_FILT_TE_BUTTON_KEY  "find_filter_button"
@@ -68,6 +68,7 @@
 static gboolean case_type = TRUE;
 static gboolean summary_data = FALSE;
 static gboolean decode_data = FALSE;
+static gboolean packet_data = FALSE;
 
 static void
 find_filter_te_syntax_check_cb(GtkWidget *w, gpointer parent_w);
@@ -119,7 +120,7 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
                 *up_rb, *down_rb,
 
                 *data_frame, *data_vb,
-                *hex_data_rb, *decode_data_rb, *summary_data_rb,
+                *packet_data_rb, *decode_data_rb, *summary_data_rb,
 
                 *string_opt_frame, *string_opt_vb,
                 *case_cb, *combo_lb, *combo_cb,
@@ -245,22 +246,22 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
   summary_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "Packet list");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(summary_data_rb), summary_data);
   gtk_box_pack_start(GTK_BOX(data_vb), summary_data_rb, TRUE, TRUE, 0);
-  gtk_tooltips_set_tip (tooltips, summary_data_rb, ("Search for string in the Info column of the packet summary (top pane)"), NULL);
+  gtk_tooltips_set_tip (tooltips, summary_data_rb, ("Search for string in the Info column of the packet summary (summary pane)"), NULL);
   gtk_widget_show(summary_data_rb);
 
   /* Packet details */
   decode_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(summary_data_rb), "Packet details");
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(decode_data_rb), decode_data);
   gtk_box_pack_start(GTK_BOX(data_vb), decode_data_rb, TRUE, TRUE, 0);
-  gtk_tooltips_set_tip (tooltips, decode_data_rb, ("Search for string in the decoded packet display (middle pane)"), NULL);
+  gtk_tooltips_set_tip (tooltips, decode_data_rb, ("Search for string among the decoded packet display labels (tree view pane)"), NULL);
   gtk_widget_show(decode_data_rb);
 
   /* Packet bytes */
-  hex_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(summary_data_rb), "Packet bytes");
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_data_rb), !decode_data && !summary_data);
-  gtk_box_pack_start(GTK_BOX(data_vb), hex_data_rb, TRUE, TRUE, 0);
-  gtk_tooltips_set_tip (tooltips, hex_data_rb, ("Search for string in the packet data"), NULL);
-  gtk_widget_show(hex_data_rb);
+  packet_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(summary_data_rb), "Packet bytes");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(packet_data_rb), packet_data);
+  gtk_box_pack_start(GTK_BOX(data_vb), packet_data_rb, TRUE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, packet_data_rb, ("Search for string in the ASCII-converted packet data (hex view pane)"), NULL);
+  gtk_widget_show(packet_data_rb);
 
   /* string options frame */
   string_opt_frame = gtk_frame_new("String Options");
@@ -344,7 +345,7 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
   g_object_set_data(G_OBJECT(find_frame_w), E_FIND_STRINGTYPE_LABEL_KEY, combo_lb);
   g_object_set_data(G_OBJECT(find_frame_w), E_FIND_STRINGTYPE_KEY, combo_cb);
   g_object_set_data(G_OBJECT(find_frame_w), E_CASE_SEARCH_KEY, case_cb);
-  g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_HEX_KEY, hex_data_rb);
+  g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_DATA_KEY, packet_data_rb);
   g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_DECODE_KEY, decode_data_rb);
   g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_SUMMARY_KEY, summary_data_rb);
   g_object_set_data(G_OBJECT(find_frame_w), E_FILT_TE_BUTTON_KEY, filter_bt);
@@ -472,11 +473,11 @@ hex_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
 static void
 string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
 {
-    GtkWidget   *string_rb, *hex_data_rb, *decode_data_rb, *summary_data_rb,
+    GtkWidget   *string_rb, *packet_data_rb, *decode_data_rb, *summary_data_rb,
                 *data_combo_lb, *data_combo_cb, *data_case_cb, *filter_tb;
 
     string_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGDATA_KEY);
-    hex_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_HEX_KEY);
+    packet_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DATA_KEY);
     decode_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DECODE_KEY);
     summary_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_SUMMARY_KEY);
 
@@ -486,7 +487,7 @@ string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
     filter_tb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_FILT_TE_PTR_KEY);
 
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(string_rb))) {
-        gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), TRUE);
+        gtk_widget_set_sensitive(GTK_WIDGET(packet_data_rb), TRUE);
         gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), TRUE);
         gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), TRUE);
         gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), TRUE);
@@ -500,7 +501,7 @@ string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
        }
 
     } else {
-        gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), FALSE);
+        gtk_widget_set_sensitive(GTK_WIDGET(packet_data_rb), FALSE);
         gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), FALSE);
         gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), FALSE);
         gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), FALSE);
@@ -545,7 +546,7 @@ static void
 find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
 {
   GtkWidget       *filter_te, *up_rb, *hex_rb, *string_rb, *combo_cb,
-                  *case_cb, *decode_data_rb, *summary_data_rb;
+                  *case_cb, *packet_data_rb, *decode_data_rb, *summary_data_rb;
   const gchar     *filter_text;
   search_charset_t scs_type = SCS_ASCII_AND_UNICODE;
   guint8          *bytes = NULL;
@@ -561,6 +562,7 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
   string_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGDATA_KEY);
   combo_cb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGTYPE_KEY);
   case_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CASE_SEARCH_KEY);
+  packet_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DATA_KEY);
   decode_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DECODE_KEY);
   summary_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_SUMMARY_KEY);
 
@@ -578,6 +580,7 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
   string_type = gtk_combo_box_get_active (GTK_COMBO_BOX(combo_cb));
 
   case_type = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_cb));
+  packet_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(packet_data_rb));
   decode_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(decode_data_rb));
   summary_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(summary_data_rb));
 
@@ -646,10 +649,12 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
   cfile.string = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb));
   cfile.scs_type = scs_type;
   cfile.case_type = case_type;
+  cfile.packet_data = packet_data;
   cfile.decode_data = decode_data;
   cfile.summary_data = summary_data;
 
   if (cfile.hex) {
+    /* Hex value in packet data */ 
     found_packet = cf_find_packet_data(&cfile, bytes, nbytes, cfile.dir);
     g_free(bytes);
     if (!found_packet) {
@@ -658,50 +663,36 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
       return;
     }
   } else if (cfile.string) {
-    /* OK, what are we searching? */
-    if (cfile.decode_data) {
-      /* The text in the protocol tree */
-      if(string){
-        found_packet = cf_find_packet_protocol_tree(&cfile, string, cfile.dir);
-        g_free(string);
-      }
+    if (cfile.summary_data) {
+      /* String in the Info column of the summary line */
+      found_packet = cf_find_packet_summary_line(&cfile, string, cfile.dir);
+      g_free(string);
       if (!found_packet) {
-        /* We didn't find the packet. */
-        statusbar_push_temporary_msg("No packet contained that string in its dissected display.");
+        statusbar_push_temporary_msg("No packet contained that string in its Info column.");
         return;
       }
-    } else if (cfile.summary_data) {
-      /* The text in the summary line */
-      if(string){
-        found_packet = cf_find_packet_summary_line(&cfile, string, cfile.dir);
-        g_free(string);
-      }
+    } else if (cfile.decode_data) {
+      /* String in the protocol tree headings */
+      found_packet = cf_find_packet_protocol_tree(&cfile, string, cfile.dir);
+      g_free(string);
       if (!found_packet) {
-        /* We didn't find the packet. */
-        simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
-            "%sNo match found!%s\n\n"
-            "No packet contained that string in its Info column.",
-            simple_dialog_primary_start(), simple_dialog_primary_end());
+        statusbar_push_temporary_msg("No packet contained that string in its dissected display.");
         return;
       }
-    } else {
-      /* The raw packet data */
-      if(string){
-       found_packet = cf_find_packet_data(&cfile, string, strlen(string),
-                                          cfile.dir);
-        g_free(string);
-      }
+    } else if (cfile.packet_data) {
+      /* String in the ASCII-converted packet data */
+      found_packet = cf_find_packet_data(&cfile, string, strlen(string), cfile.dir);
+      g_free(string);
       if (!found_packet) {
-        /* We didn't find the packet. */
-        statusbar_push_temporary_msg("No packet contained that string in its data.");
+        statusbar_push_temporary_msg("No packet contained that string in its ASCII-converted data.");
         return;
       }
     }
   } else {
+    /* Search via display filter */
     found_packet = cf_find_packet_dfilter(&cfile, sfcode, cfile.dir);
     dfilter_free(sfcode);
     if (!found_packet) {
-      /* We didn't find a packet */
       statusbar_push_temporary_msg("No packet matched that filter.");
       g_free(bytes);
       return;
index 8d370d6fc38463f877888f69be839f14f60df9c4..7053316790dbed626cb9f7e0460c7e104b12b2fb 100644 (file)
@@ -1683,7 +1683,8 @@ main_cf_cb_packet_selected(gpointer data)
 
     /* Note: Both string and hex value searches in the packet data produce a non-zero 
        search_pos if successful */
-    if(cf->search_in_progress && cf->search_pos != 0) {
+    if(cf->search_in_progress && 
+      (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
         highlight_field(cf->edt->tvb, cf->search_pos,
                         (GtkTreeView *)tree_view_gbl, cf->edt->tree);
     } 
index b698a82259ba46aa4623e79b2e6debd2a1014524..f834acb50cc024759745accda04151dd2242fe8b 100644 (file)
@@ -541,14 +541,23 @@ gboolean
 highlight_field(tvbuff_t *tvb, gint byte, GtkTreeView *tree_view,
                 proto_tree *tree)
 {
-    GtkTreeModel *model;
-    GtkTreePath  *first_path, *path;
+    GtkTreeModel *model = NULL;
+    GtkTreePath  *first_path = NULL, *path = NULL;
     GtkTreeIter   parent;
+    field_info   *finfo = NULL;
+    match_data    mdata;
     struct field_lookup_info fli;
-    field_info   *finfo;
 
-    /* Find the finfo that corresponds to our byte. */
-    finfo = proto_find_field_from_offset(tree, byte, tvb);
+    if (cfile.search_in_progress && cfile.string && cfile.decode_data) {
+        /* The tree where the target string matched one of the labels was discarded in
+           match_protocol_tree() so we have to search again in the latest tree. (Uugh) */
+        if (cf_find_string_protocol_tree(&cfile, tree, &mdata)) {
+            finfo = mdata.finfo;
+        }
+    } else {
+        /* Find the finfo that corresponds to our byte. */
+        finfo = proto_find_field_from_offset(tree, byte, tvb);
+    }
 
     if (!finfo) {
         return FALSE;
@@ -583,8 +592,8 @@ highlight_field(tvbuff_t *tvb, gint byte, GtkTreeView *tree_view,
        not be highlighted. If the user just clicked on one of the bytes comprising that field, the
        above call didn't trigger a 'gtk_tree_view_get_selection' event. Call redraw_packet_bytes()
        to make the highlighting of the entire field visible. */   
-    if (!cfile.search_in_progress) {        
-        if (cfile.hex || (cfile.string && !(cfile.summary_data || cfile.decode_data))) {
+    if (!cfile.search_in_progress) {
+        if (cfile.hex || (cfile.string && cfile.packet_data)) {
             redraw_packet_bytes(byte_nb_ptr_gbl, cfile.current_frame, cfile.finfo_selected);
         }
     }
@@ -1577,17 +1586,16 @@ packet_hex_print(GtkWidget *bv, const guint8 *pd, frame_data *fd,
 
     if (finfo != NULL) {
 
-        if (cfile.search_in_progress) { 
-            if (cfile.hex || (cfile.string && !(cfile.summary_data || cfile.decode_data))) {        
-                /* In the hex view, only highlight the target bytes or string. The entire
-                   field can then be displayed by clicking on any of the bytes in the field. */
-                if (cfile.hex) {
-                    blen = (int)strlen(cfile.sfilter)/2;
-                } else {
-                    blen = (int)strlen(cfile.sfilter);
-                }
-                bstart = cfile.search_pos - (blen-1);
+        if (cfile.search_in_progress && (cfile.hex || (cfile.string && cfile.packet_data))) {
+            /* In the hex view, only highlight the target bytes or string. The entire
+               field can then be displayed by clicking on any of the bytes in the field. */
+            if (cfile.hex) {
+                blen = (int)strlen(cfile.sfilter)/2;
+            } else {
+                blen = (int)strlen(cfile.sfilter);
             }
+            bstart = cfile.search_pos - (blen-1);
+
         } else {       
             blen = finfo->length;
             bstart = finfo->start;
index 306b3262cdedca4d0e811a34344282b1184cdbc9..8d89a4bf58e4006073906a7a7639d66171289707 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 #endif /* __cplusplus */
 
 /*#define MAIN_MENU_USE_UIMANAGER 1 */
+#define MAIN_MENU_USE_UIMANAGER 1
 
        /* Add a new recent capture filename to the "Recent Files" submenu
    (duplicates will be ignored) */