Applied the "Updated find capabilities...." from Greg Morris.
authorsharpe <sharpe@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 11 Aug 2003 22:41:10 +0000 (22:41 +0000)
committersharpe <sharpe@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 11 Aug 2003 22:41:10 +0000 (22:41 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@8158 f5534014-38df-0310-8fa8-9805f1628bb7

file.c
file.h
gtk/find_dlg.c

diff --git a/file.c b/file.c
index b4e921a9ff23036e362228f94ae034714edaad49..e802dd6620e3211ae2b9737e2c952fc78c63a249 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.301 2003/08/05 00:01:26 guy Exp $
+ * $Id: file.c,v 1.302 2003/08/11 22:41:09 sharpe Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -29,6 +29,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#include <gtk/gtk.h>
+#include <gtk/keys.h>
+#include <gtk/compat_macros.h>
 
 #include <time.h>
 
@@ -78,6 +81,7 @@
 #include "globals.h"
 #include <epan/epan_dissect.h>
 #include "tap.h"
+#include "packet-data.h"
 
 #ifdef HAVE_LIBPCAP
 gboolean auto_scroll_live;
@@ -93,10 +97,12 @@ static void rescan_packets(capture_file *cf, const char *action, const char *act
 
 static void freeze_plist(capture_file *cf);
 static void thaw_plist(capture_file *cf);
+static void proto_tree_get_node(GNode *node, gpointer data);
 
 static char *file_rename_error_message(int err);
 static char *file_close_error_message(int err);
 static gboolean copy_binary_file(char *from_filename, char *to_filename);
+static char decode_data[16536];
 
 /* Update the progress bar this many times when reading a file. */
 #define N_PROGBAR_UPDATES      100
@@ -105,6 +111,18 @@ static gboolean copy_binary_file(char *from_filename, char *to_filename);
    XXX - is this the right number? */
 #define        FRAME_DATA_CHUNK_SIZE   1024
 
+
+typedef struct {
+       int             level;
+       FILE            *fh;
+       GSList          *src_list;
+       gboolean        print_all_levels;
+       gboolean        print_hex_for_data;
+       char_enc        encoding;
+       gint            format;         /* text or PostScript */
+} print_data;
+
+
 int
 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
 {
@@ -1455,6 +1473,276 @@ get_int_value(char char_val)
     }
 }
 
+static char*
+get_info_string(epan_dissect_t* edt)
+{
+    int i;
+
+    for (i=0;i<edt->pi.cinfo->num_cols;i++) {
+        if (strcmp(edt->pi.cinfo->col_title[i], "Info")==0) {
+            return edt->pi.cinfo->col_data[i];
+        }
+    }
+    return NULL;
+}
+
+/*
+ * Find the data source for a specified field, and return a pointer
+ * to the data in it.
+ */
+static const guint8 *
+get_field_data(GSList *src_list, field_info *fi)
+{
+       GSList *src_le;
+       data_source *src;
+       tvbuff_t *src_tvb;
+
+       for (src_le = src_list; src_le != NULL; src_le = src_le->next) {
+               src = src_le->data;
+               src_tvb = src->tvb;
+               if (fi->ds_tvb == src_tvb) {
+                       /*
+                        * Found it.
+                        */
+            if(tvb_length_remaining(src_tvb, 0) < fi->length+fi->start){
+                return NULL;
+            }
+                       return tvb_get_ptr(src_tvb, fi->start, fi->length);
+               }
+       }
+       return NULL;    /* not found */
+}
+
+/* Print a tree's data, and any child nodes to the buffer. */
+static
+void proto_tree_get_node(GNode *node, gpointer data)
+{
+       field_info      *fi = PITEM_FINFO(node);
+       print_data      *pdata = (print_data*) data;
+       const guint8    *pd;
+       gchar           label_str[ITEM_LABEL_LENGTH];
+       gchar           *label_ptr, *string_ptr;
+
+    string_ptr = decode_data;
+
+       /* Don't print invisible entries. */
+       if (!fi->visible)
+               return;
+
+       /* was a free format label produced? */
+       if (fi->representation) {
+               label_ptr = fi->representation;
+       }
+       else { /* no, make a generic label */
+               label_ptr = label_str;
+               proto_item_fill_label(fi, label_str);
+       }
+    
+    strcat(string_ptr, label_ptr);
+
+    /*
+        * Find the data for this field.
+        */
+       pd = get_field_data(pdata->src_list, fi);
+    if (pd!=NULL) {
+        if (strlen(pd) > 0) {
+            strcat(string_ptr, pd);
+        }
+    }
+
+       /* If we're printing all levels, or if this node is one with a
+          subtree and its subtree is expanded, recurse into the subtree,
+          if it exists. */
+       g_assert(fi->tree_type >= -1 && fi->tree_type < num_tree_types);
+       if (pdata->print_all_levels ||
+           (fi->tree_type >= 0 && tree_is_expanded[fi->tree_type])) {
+               if (g_node_n_children(node) > 0) {
+                       pdata->level++;
+                       g_node_children_foreach(node, G_TRAVERSE_ALL,
+                               proto_tree_get_node, pdata);
+                       pdata->level--;
+               }
+       }
+}
+
+gboolean
+find_in_gtk_data(capture_file *cf, gpointer *data, char *ascii_text, gboolean case_type, gboolean summary_search)
+{
+    frame_data *start_fd;
+    frame_data *fdata;
+    frame_data *new_fd = NULL;
+    progdlg_t  *progbar = NULL;
+    gboolean    stop_flag;
+    int         count;
+    int         err;
+    guint32     i;
+    guint16     c_match=0;
+    gboolean    frame_matched;
+    int         row;
+    float       prog_val;
+    GTimeVal    start_time;
+    gchar       status_str[100];
+    guint8      c_char=0;
+    guint32     buf_len=0;
+    guint8      hex_val=0;
+    char        char_val;
+    guint8      num1, num2;
+    gchar       *uppercase;
+    epan_dissect_t*   new_edt;
+    char        *info_string;
+       print_data  ndata;
+
+    start_fd = cf->current_frame;
+    if (start_fd != NULL)  {
+      /* Iterate through the list of packets, starting at the packet we've
+         picked, calling a routine to run the filter on the packet, see if
+         it matches, and stop if so.  */
+      count = 0;
+      fdata = start_fd;
+
+      if (case_type) {
+          g_strup(ascii_text);
+      }
+
+      cf->progbar_nextstep = 0;
+      /* When we reach the value that triggers a progress bar update,
+         bump that value by this amount. */
+      cf->progbar_quantum = cf->count/N_PROGBAR_UPDATES;
+
+      stop_flag = FALSE;
+      g_get_current_time(&start_time);
+
+      fdata = start_fd;
+      for (;;) {
+        /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+           when we update it, we have to run the GTK+ main loop to get it
+           to repaint what's pending, and doing so may involve an "ioctl()"
+           to see if there's any pending input from an X server, and doing
+           that for every packet can be costly, especially on a big file. */
+        if (count >= cf->progbar_nextstep) {
+          /* let's not divide by zero. I should never be started
+           * with count == 0, so let's assert that
+           */
+          g_assert(cf->count > 0);
+
+          prog_val = (gfloat) count / cf->count;
+
+          /* Create the progress bar if necessary */
+          if (progbar == NULL)
+             progbar = delayed_create_progress_dlg("Searching", cf->sfilter, "Cancel",
+               &stop_flag, &start_time, prog_val);
+
+          if (progbar != NULL) {
+            g_snprintf(status_str, sizeof(status_str),
+                       "%4u of %u frames", count, cf->count);
+            update_progress_dlg(progbar, prog_val, status_str);
+          }
+
+          cf->progbar_nextstep += cf->progbar_quantum;
+        }
+
+        if (stop_flag) {
+          /* Well, the user decided to abort the search.  Go back to the
+             frame where we started. */
+          new_fd = start_fd;
+          break;
+        }
+
+        /* Go past the current frame. */
+        if (cf->sbackward) {
+          /* Go on to the previous frame. */
+          fdata = fdata->prev;
+          if (fdata == NULL)
+            fdata = cf->plist_end;     /* wrap around */
+        } else {
+          /* Go on to the next frame. */
+          fdata = fdata->next;
+          if (fdata == NULL)
+            fdata = cf->plist; /* wrap around */
+        }
+
+        count++;
+
+        /* Is this packet in the display? */
+        if (fdata->flags.passed_dfilter) {
+          /* Yes.  Does it match the search filter? */
+          /* XXX - do something with "err" */
+          wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
+                  cf->pd, fdata->cap_len, &err);
+          new_edt = epan_dissect_new(TRUE, TRUE);
+          epan_dissect_run(new_edt, &cfile.pseudo_header, cfile.pd, fdata, &cfile.cinfo);
+          if (summary_search) {
+              info_string = get_info_string(new_edt);
+              if (info_string == NULL) {
+                  simple_dialog(ESD_TYPE_CRIT, NULL, "Can't find info column. Terminating.");
+                  return FALSE;
+              }
+          }
+          else
+          {
+              strcpy(decode_data,"\0");
+              info_string = decode_data;
+              ndata.level = 0;
+              ndata.fh = NULL;
+              ndata.src_list = new_edt->pi.data_src;
+              ndata.encoding = new_edt->pi.fd->flags.encoding;
+              ndata.print_all_levels = TRUE;
+              ndata.print_hex_for_data = FALSE;
+              ndata.format = 0;
+              g_node_children_foreach((GNode*) new_edt->tree, G_TRAVERSE_ALL,
+                  proto_tree_get_node, &ndata);
+          }
+          if (case_type) {
+              g_strup(info_string);
+          }
+          frame_matched = FALSE;
+          buf_len = strlen(info_string);
+          for (i=0;i<buf_len;i++) {
+              c_char = info_string[i];
+              if (c_char == ascii_text[c_match]) {
+                 c_match++;
+                 if (c_match == strlen(ascii_text)) {
+                    frame_matched = TRUE;
+                    break;
+                 }
+              }
+              else
+              {
+                 c_match = 0;
+              }
+          }
+          if (frame_matched) {
+            new_fd = fdata;
+            break;     /* found it! */
+          }
+          epan_dissect_free(new_edt);
+        }
+
+        if (fdata == start_fd) {
+          /* We're back to the frame we were on originally, and that frame
+             doesn't match the search filter.  The search failed. */
+          break;
+        }
+      }
+
+      /* We're done scanning the packets; destroy the progress bar if it
+         was created. */
+      if (progbar != NULL)
+        destroy_progress_dlg(progbar);
+    }
+
+    if (new_fd != NULL) {
+      /* We found a frame.  Find what row it's in. */
+      row = packet_list_find_row_from_data(new_fd);
+      g_assert(row != -1);
+
+      /* Select that row, make it the focus row, and make it visible. */
+      packet_list_set_selected_row(row);
+      return TRUE;     /* success */
+    } else
+      return FALSE;    /* failure */
+}
+
 gboolean
 find_ascii(capture_file *cf, char *ascii_text, gboolean ascii_search, char *ftype, gboolean case_type)
 {
diff --git a/file.h b/file.h
index 4b65464a6257e03cd7e3c9f2ad26b97d8acf0095..94ce1895cc294a8997e48cc15cd919abadaf43e7 100644 (file)
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
 /* file.h
  * Definitions for file structures and routines
  *
- * $Id: file.h,v 1.102 2003/08/05 00:01:27 guy Exp $
+ * $Id: file.h,v 1.103 2003/08/11 22:41:09 sharpe Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -58,7 +58,7 @@ void change_time_formats(capture_file *);
 gboolean find_packet(capture_file *cf, dfilter_t *sfcode);
 guint8 get_int_value(char char_val);
 gboolean find_ascii(capture_file *cf, char *ascii_text, gboolean ascii_search, char *ftype, gboolean case_type);
-
+gboolean find_in_gtk_data(capture_file *cf, gpointer *data, char *ascii_text, gboolean case_type, gboolean search_type);
 gboolean goto_frame(capture_file *cf, guint fnumber);
 
 void select_packet(capture_file *, int);
index 6423f3b78888de3fa643ffee9249a75c88c3bd0d..07290f59fecb89a9128f15698403e3d35bf6955c 100644 (file)
@@ -1,7 +1,7 @@
 /* find_dlg.c
  * Routines for "find frame" window
  *
- * $Id: find_dlg.c,v 1.30 2003/08/05 00:01:27 guy Exp $
+ * $Id: find_dlg.c,v 1.31 2003/08/11 22:41:10 sharpe Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -41,6 +41,7 @@
 #include "compat_macros.h"
 #include "prefs.h"
 #include "prefs_dlg.h"
+#include "keys.h"
 
 /* Capture callback data keys */
 #define E_FIND_FILT_KEY     "find_filter_te"
 #define E_FIND_FILTERDATA_KEY "find_filter"
 #define E_FIND_STRINGTYPE_KEY "find_string_type"
 #define E_CASE_SEARCH_KEY "case_insensitive_search"
+#define E_SOURCE_HEX_KEY "hex_data_source"
+#define E_SOURCE_DECODE_KEY "decode_data_source"
+#define E_SOURCE_SUMMARY_KEY "summary_data_source"
 
 static gboolean case_type = TRUE;
+static gboolean summary_data = FALSE;
+static gboolean decode_data = FALSE;
 
 static void
 find_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
@@ -62,6 +68,9 @@ find_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
 static void
 find_frame_destroy_cb(GtkWidget *win, gpointer user_data);
 
+static void
+ascii_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
+
 /*
  * Keep a static pointer to the current "Find Frame" window, if any, so
  * that if somebody tries to do "Find Frame" while there's already a
@@ -76,6 +85,7 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
   GtkWidget     *main_vb, *filter_hb, *filter_bt, *filter_te,
                 *direction_hb, *forward_rb, *backward_rb, 
                 *hex_hb, *hex_rb, *ascii_rb, *filter_rb,
+                *data_hb, *hex_data_rb, *decode_data_rb, *summary_data_rb,
                 *combo_hb, *combo_cb, *combo_lb,
                 *bbox, *ok_bt, *cancel_bt, *case_cb;
 #if GTK_MAJOR_VERSION < 2
@@ -199,9 +209,54 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
 #endif
   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ascii_rb), cfile.ascii);
   gtk_box_pack_start(GTK_BOX(hex_hb), ascii_rb, TRUE, TRUE, 0);
+  SIGNAL_CONNECT(ascii_rb, "clicked", ascii_selected_cb, find_frame_w);
   gtk_widget_show(ascii_rb);
 
-  /* String Type Selection Dropdown Box */
+  /* Hex, Decode, or Summary Data Search */
+  /* Source Hex Data Search Window*/
+  data_hb = gtk_hbox_new(FALSE, 3);
+  gtk_container_add(GTK_CONTAINER(main_vb), data_hb);
+  gtk_widget_show(data_hb);
+
+#if GTK_MAJOR_VERSION < 2
+  hex_data_rb = dlg_radio_button_new_with_label_with_mnemonic(NULL, "Hex",
+                                                             accel_group);
+#else
+  hex_data_rb = gtk_radio_button_new_with_mnemonic(NULL, "Hex");
+#endif
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hex_data_rb), !decode_data && !summary_data);
+  gtk_box_pack_start(GTK_BOX(data_hb), hex_data_rb, TRUE, TRUE, 0);
+  gtk_widget_show(hex_data_rb);
+
+  /* Search Decode Window */
+#if GTK_MAJOR_VERSION < 2
+  decode_data_rb = dlg_radio_button_new_with_label_with_mnemonic(
+               gtk_radio_button_group(GTK_RADIO_BUTTON(hex_data_rb)),
+               "Decode", accel_group);
+#else
+  decode_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(
+               GTK_RADIO_BUTTON(hex_data_rb), "Decode");
+#endif
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(decode_data_rb), decode_data);
+  gtk_box_pack_start(GTK_BOX(data_hb), decode_data_rb, TRUE, TRUE, 0);
+  gtk_widget_show(decode_data_rb);
+
+  /* Search Summary Window */
+
+#if GTK_MAJOR_VERSION < 2
+  summary_data_rb = dlg_radio_button_new_with_label_with_mnemonic(
+               gtk_radio_button_group(GTK_RADIO_BUTTON(hex_data_rb)),
+               "Summary", accel_group);
+#else
+  summary_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(
+               GTK_RADIO_BUTTON(hex_data_rb), "Summary");
+#endif
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(summary_data_rb), summary_data);
+  gtk_box_pack_start(GTK_BOX(data_hb), summary_data_rb, TRUE, TRUE, 0);
+  gtk_widget_show(summary_data_rb);
+
+  /* String Type Selection Dropdown Box 
+     These only apply to the Hex Window search option */
   combo_hb = gtk_hbox_new(FALSE, 3);
   gtk_container_add(GTK_CONTAINER(main_vb), combo_hb);
   gtk_widget_show(combo_hb);
@@ -269,8 +324,12 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
   OBJECT_SET_DATA(find_frame_w, E_FIND_ASCIIDATA_KEY, ascii_rb);
   OBJECT_SET_DATA(find_frame_w, E_FIND_STRINGTYPE_KEY, combo_cb);
   OBJECT_SET_DATA(find_frame_w, E_CASE_SEARCH_KEY, case_cb);
+  OBJECT_SET_DATA(find_frame_w, E_SOURCE_HEX_KEY, hex_data_rb);
+  OBJECT_SET_DATA(find_frame_w, E_SOURCE_DECODE_KEY, decode_data_rb);
+  OBJECT_SET_DATA(find_frame_w, E_SOURCE_SUMMARY_KEY, summary_data_rb);
   
 
+  ascii_selected_cb(NULL, find_frame_w);
   /* Catch the "activate" signal on the filter text entry, so that
      if the user types Return there, we act as if the "OK" button
      had been selected, as happens if Return is typed if some widget
@@ -288,10 +347,46 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
   gtk_widget_show(find_frame_w);
 }
 
+/* 
+ *  This function will disable the string options until
+ *  the string search is selected.
+ */  
+static void
+ascii_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
+{
+    GtkWidget   *ascii_rb, *hex_data_rb, *decode_data_rb, *summary_data_rb,
+                *data_combo_cb, *data_case_cb;
+
+    ascii_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_ASCIIDATA_KEY);
+    hex_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_HEX_KEY);
+    decode_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_DECODE_KEY);
+    summary_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_SUMMARY_KEY);
+    data_combo_cb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_KEY);
+    data_case_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CASE_SEARCH_KEY);
+
+    
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ascii_rb))) {
+      gtk_widget_set_sensitive(GTK_WIDGET(hex_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_cb), TRUE);
+      gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), TRUE);
+    } else {
+        gtk_widget_set_sensitive(GTK_WIDGET(hex_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_cb), FALSE);
+        gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), FALSE);
+    }
+    return;
+}
+
+
 static void
 find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
 {
-  GtkWidget *filter_te, *backward_rb, *hex_rb, *ascii_rb, *combo_cb, *case_cb;
+  GtkWidget *filter_te, *backward_rb, *hex_rb, *ascii_rb, *combo_cb, *case_cb,
+            *decode_data_rb, *summary_data_rb;
   gchar     *filter_text, *string_type;
   dfilter_t *sfcode;
 
@@ -301,11 +396,15 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
   ascii_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_ASCIIDATA_KEY);
   combo_cb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_KEY);
   case_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CASE_SEARCH_KEY);
+  decode_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_DECODE_KEY);
+  summary_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_SUMMARY_KEY);
 
   filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
   string_type = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo_cb)->entry));
 
   case_type = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_cb));
+  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));
 
   /*
    * Try to compile the filter.
@@ -345,10 +444,23 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
   }
   else
   {
-      if (!find_ascii(&cfile, filter_text, cfile.ascii, string_type, case_type)) {
-          /* We didn't find the packet. */
-          simple_dialog(ESD_TYPE_CRIT, NULL, "No packet matched search criteria.");
-          return;
+      if (!decode_data && !summary_data) {
+          if (!find_ascii(&cfile, filter_text, cfile.ascii, string_type, case_type)) {
+              /* We didn't find the packet. */
+              simple_dialog(ESD_TYPE_CRIT, NULL, "No packet matched search criteria.");
+              return;
+          }
+      }
+      else
+      {
+          /* Use the cfile.hex to indicate if summary or decode search */
+          /* This way the Next and Previous find options will work */
+          cfile.hex = summary_data; 
+          if (!find_in_gtk_data(&cfile, parent_w, filter_text, case_type, summary_data)) {
+              /* We didn't find the packet. */
+              simple_dialog(ESD_TYPE_CRIT, NULL, "No packet matched search criteria.");
+              return;
+          }
       }
   }
   gtk_widget_destroy(GTK_WIDGET(parent_w));
@@ -382,7 +494,12 @@ find_previous_next(GtkWidget *w, gpointer d, gboolean sens)
      cfile.sbackward = sens;
      if (cfile.hex || cfile.ascii) 
      {
-         find_ascii(&cfile, cfile.sfilter, cfile.ascii, cfile.ftype, case_type);
+         if (!decode_data && !summary_data) {
+            find_ascii(&cfile, cfile.sfilter, cfile.ascii, cfile.ftype, case_type);
+         }
+         else {
+            find_in_gtk_data(&cfile, d, cfile.sfilter, case_type, cfile.hex);
+         }
      }
      else 
      {