2 * Routines for "find frame" window
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/proto.h>
35 #include <epan/dfilter/dfilter.h>
36 #include <epan/strutil.h>
41 #include "filter_dlg.h"
42 #include "alert_box.h"
43 #include "simple_dialog.h"
44 #include "dlg_utils.h"
45 #include "compat_macros.h"
46 #include <epan/prefs.h>
47 #include "prefs_dlg.h"
50 /* Capture callback data keys */
51 #define E_FIND_FILT_KEY "find_filter_te"
52 #define E_FIND_BACKWARD_KEY "find_backward"
53 #define E_FIND_HEXDATA_KEY "find_hex"
54 #define E_FIND_STRINGDATA_KEY "find_string"
55 #define E_FIND_FILTERDATA_KEY "find_filter"
56 #define E_FIND_STRINGTYPE_KEY "find_string_type"
57 #define E_FIND_STRINGTYPE_LABEL_KEY "find_string_type_label"
58 #define E_CASE_SEARCH_KEY "case_insensitive_search"
59 #define E_SOURCE_HEX_KEY "hex_data_source"
60 #define E_SOURCE_DECODE_KEY "decode_data_source"
61 #define E_SOURCE_SUMMARY_KEY "summary_data_source"
62 #define E_FILT_TE_BUTTON_KEY "find_filter_button"
64 static gboolean case_type = TRUE;
65 static gboolean summary_data = FALSE;
66 static gboolean decode_data = FALSE;
69 find_filter_te_syntax_check_cb(GtkWidget *w, gpointer parent_w);
72 find_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
75 find_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
78 find_frame_destroy_cb(GtkWidget *win, gpointer user_data);
81 hex_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
84 string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
87 filter_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
90 * Keep a static pointer to the current "Find Packet" window, if any, so
91 * that if somebody tries to do "Find Packet" while there's already a
92 * "Find Packet" window up, we just pop up the existing one, rather than
95 static GtkWidget *find_frame_w;
96 static GtkWidget *filter_text_box;
99 find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
101 GtkWidget *main_vb, *main_find_hb, *main_options_hb,
103 *find_type_frame, *find_type_vb,
104 *find_type_hb, *find_type_lb, *hex_rb, *string_rb, *filter_rb,
105 *filter_hb, *filter_bt,
107 *direction_frame, *direction_vb,
110 *data_frame, *data_vb,
111 *hex_data_rb, *decode_data_rb, *summary_data_rb,
113 *string_opt_frame, *string_opt_vb,
114 *case_cb, *combo_lb, *combo_cb,
116 *bbox, *ok_bt, *cancel_bt;
117 GtkTooltips *tooltips;
118 #if GTK_MAJOR_VERSION < 2
119 GtkAccelGroup *accel_group;
122 /* No Apply button, but "OK" not only sets our text widget, it
123 activates it (i.e., it causes us to do the search). */
124 static construct_args_t args = {
125 "Ethereal: Search Filter",
130 if (find_frame_w != NULL) {
131 /* There's already a "Find Packet" dialog box; reactivate it. */
132 reactivate_window(find_frame_w);
136 find_frame_w = dlg_window_new("Ethereal: Find Packet");
138 tooltips = gtk_tooltips_new ();
140 #if GTK_MAJOR_VERSION < 2
141 /* Accelerator group for the accelerators (or, as they're called in
142 Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
143 Ctrl+<key> is an accelerator). */
144 accel_group = gtk_accel_group_new();
145 gtk_window_add_accel_group(GTK_WINDOW(find_frame_w), accel_group);
148 /* Container for each row of widgets */
149 main_vb = gtk_vbox_new(FALSE, 3);
150 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
151 gtk_container_add(GTK_CONTAINER(find_frame_w), main_vb);
152 gtk_widget_show(main_vb);
156 main_find_hb = gtk_hbox_new(FALSE, 3);
157 gtk_container_add(GTK_CONTAINER(main_vb), main_find_hb);
158 gtk_widget_show(main_find_hb);
162 find_type_frame = gtk_frame_new("Find");
163 gtk_box_pack_start(GTK_BOX(main_find_hb), find_type_frame, TRUE, TRUE, 0);
164 gtk_widget_show(find_type_frame);
166 find_type_vb = gtk_vbox_new(FALSE, 3);
167 gtk_container_border_width(GTK_CONTAINER(find_type_vb), 3);
168 gtk_container_add(GTK_CONTAINER(find_type_frame), find_type_vb);
169 gtk_widget_show(find_type_vb);
172 find_type_hb = gtk_hbox_new(FALSE, 3);
173 gtk_container_add(GTK_CONTAINER(find_type_vb), find_type_hb);
174 gtk_widget_show(find_type_hb);
176 find_type_lb = gtk_label_new("By:");
177 gtk_box_pack_start(GTK_BOX(find_type_hb), find_type_lb, FALSE, FALSE, 0);
178 gtk_widget_show(find_type_lb);
181 filter_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL,
182 "_Display filter", accel_group);
183 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filter_rb), !cfile.hex && !cfile.string);
184 gtk_box_pack_start(GTK_BOX(find_type_hb), filter_rb, FALSE, FALSE, 0);
185 gtk_tooltips_set_tip (tooltips, filter_rb, ("Search for data by display filter syntax.\ne.g. ip.addr==10.1.1.1"), NULL);
186 gtk_widget_show(filter_rb);
189 hex_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(filter_rb,
190 "_Hex value", accel_group);
191 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_rb), cfile.hex);
192 gtk_box_pack_start(GTK_BOX(find_type_hb), hex_rb, FALSE, FALSE, 0);
193 gtk_tooltips_set_tip (tooltips, hex_rb, ("Search for data by hex string.\ne.g. fffffda5"), NULL);
194 gtk_widget_show(hex_rb);
197 string_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(filter_rb,
198 "_String", accel_group);
199 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(string_rb), cfile.string);
200 gtk_box_pack_start(GTK_BOX(find_type_hb), string_rb, FALSE, FALSE, 0);
201 gtk_tooltips_set_tip (tooltips, string_rb, ("Search for data by string value.\ne.g. My String"), NULL);
202 gtk_widget_show(string_rb);
205 filter_hb = gtk_hbox_new(FALSE, 3);
206 gtk_box_pack_start(GTK_BOX(find_type_vb), filter_hb, FALSE, FALSE, 0);
207 gtk_widget_show(filter_hb);
209 filter_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
210 SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &args);
211 SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
212 OBJECT_SET_DATA(filter_bt, E_FILT_TE_BUTTON_KEY, filter_bt);
213 gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, TRUE, 0);
214 gtk_tooltips_set_tip (tooltips, filter_bt, ("Click on the filter button to select a display filter,\nor enter your search criteria into the text box"), NULL);
215 gtk_widget_show(filter_bt);
217 filter_text_box = gtk_entry_new();
218 if (cfile.sfilter) gtk_entry_set_text(GTK_ENTRY(filter_text_box), cfile.sfilter);
219 OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_text_box);
220 OBJECT_SET_DATA(find_frame_w, E_FILT_TE_PTR_KEY, filter_text_box);
221 gtk_box_pack_start(GTK_BOX(filter_hb), filter_text_box, TRUE, TRUE, 0);
222 SIGNAL_CONNECT(filter_text_box, "changed", find_filter_te_syntax_check_cb, find_frame_w);
223 gtk_widget_show(filter_text_box);
227 main_options_hb = gtk_hbox_new(FALSE, 3);
228 gtk_container_add(GTK_CONTAINER(main_vb), main_options_hb);
229 gtk_widget_show(main_options_hb);
232 /* search in frame */
233 data_frame = gtk_frame_new("Search In");
234 gtk_box_pack_start(GTK_BOX(main_options_hb), data_frame, TRUE, TRUE, 0);
235 gtk_widget_show(data_frame);
238 data_vb = gtk_vbox_new(TRUE, 0);
239 gtk_container_border_width(GTK_CONTAINER(data_vb), 3);
240 gtk_container_add(GTK_CONTAINER(data_frame), data_vb);
241 gtk_widget_show(data_vb);
244 summary_data_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL,
245 "Packet list", accel_group);
246 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(summary_data_rb), summary_data);
247 gtk_box_pack_start(GTK_BOX(data_vb), summary_data_rb, TRUE, TRUE, 0);
248 gtk_tooltips_set_tip (tooltips, summary_data_rb, ("Search for string in the Info column of the packet summary (top pane)"), NULL);
249 gtk_widget_show(summary_data_rb);
252 decode_data_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(summary_data_rb,
253 "Packet details", accel_group);
254 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(decode_data_rb), decode_data);
255 gtk_box_pack_start(GTK_BOX(data_vb), decode_data_rb, TRUE, TRUE, 0);
256 gtk_tooltips_set_tip (tooltips, decode_data_rb, ("Search for string in the decoded packet display (middle pane)"), NULL);
257 gtk_widget_show(decode_data_rb);
260 hex_data_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(summary_data_rb,
261 "Packet bytes", accel_group);
262 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_data_rb), !decode_data && !summary_data);
263 gtk_box_pack_start(GTK_BOX(data_vb), hex_data_rb, TRUE, TRUE, 0);
264 gtk_tooltips_set_tip (tooltips, hex_data_rb, ("Search for string in the packet data"), NULL);
265 gtk_widget_show(hex_data_rb);
267 /* string options frame */
268 string_opt_frame = gtk_frame_new("String Options");
269 gtk_box_pack_start(GTK_BOX(main_options_hb), string_opt_frame, TRUE, TRUE, 0);
270 gtk_widget_show(string_opt_frame);
272 string_opt_vb = gtk_vbox_new(FALSE, 0);
273 gtk_container_add(GTK_CONTAINER(string_opt_frame), string_opt_vb);
274 gtk_container_border_width(GTK_CONTAINER(string_opt_vb), 3);
275 gtk_widget_show(string_opt_vb);
277 case_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
278 "Case sensitive", accel_group);
279 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_cb), !case_type);
280 gtk_container_add(GTK_CONTAINER(string_opt_vb), case_cb);
281 gtk_tooltips_set_tip (tooltips, case_cb, ("Search by mixed upper/lower case?"), NULL);
282 gtk_widget_show(case_cb);
284 combo_lb = gtk_label_new("Character set:");
285 gtk_container_add(GTK_CONTAINER(string_opt_vb), combo_lb);
286 gtk_misc_set_alignment(GTK_MISC(combo_lb), 0.0, 0.5);
287 gtk_widget_show(combo_lb);
289 /* String Type Selection Dropdown Box
290 These only apply to the Hex Window search option */
291 /* Create Combo Box */
292 combo_cb = gtk_combo_new();
294 glist = g_list_append(glist, "ASCII Unicode & Non-Unicode");
295 glist = g_list_append(glist, "ASCII Non-Unicode");
296 glist = g_list_append(glist, "ASCII Unicode");
298 gtk_combo_set_popdown_strings(GTK_COMBO(combo_cb), glist);
299 /* You only get to choose from the options we offer */
300 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(combo_cb)->entry), FALSE);
301 gtk_container_add(GTK_CONTAINER(string_opt_vb), combo_cb);
302 gtk_widget_show(combo_cb);
305 /* direction frame */
306 direction_frame = gtk_frame_new("Direction");
307 gtk_box_pack_start(GTK_BOX(main_options_hb), direction_frame, FALSE, FALSE, 0);
308 gtk_widget_show(direction_frame);
310 /* Direction row: Forward and reverse radio buttons */
311 direction_vb = gtk_vbox_new(FALSE, 0);
312 gtk_container_border_width(GTK_CONTAINER(direction_vb), 3);
313 gtk_container_add(GTK_CONTAINER(direction_frame), direction_vb);
314 gtk_widget_show(direction_vb);
316 up_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "_Up", accel_group);
317 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(up_rb), cfile.sbackward);
318 gtk_box_pack_start(GTK_BOX(direction_vb), up_rb, FALSE, FALSE, 0);
319 gtk_widget_show(up_rb);
321 down_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(up_rb, "_Down", accel_group);
322 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(down_rb), !cfile.sbackward);
323 gtk_box_pack_start(GTK_BOX(direction_vb), down_rb, FALSE, FALSE, 0);
324 gtk_widget_show(down_rb);
328 bbox = dlg_button_row_new(GTK_STOCK_FIND, GTK_STOCK_CANCEL, NULL);
329 gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
330 gtk_widget_show(bbox);
332 ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_FIND);
333 SIGNAL_CONNECT(ok_bt, "clicked", find_frame_ok_cb, find_frame_w);
335 cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
336 SIGNAL_CONNECT(cancel_bt, "clicked", find_frame_close_cb, find_frame_w);
338 /* Attach pointers to needed widgets to the capture prefs window/object */
339 OBJECT_SET_DATA(find_frame_w, E_FIND_FILT_KEY, filter_text_box);
340 OBJECT_SET_DATA(find_frame_w, E_FIND_BACKWARD_KEY, up_rb);
341 OBJECT_SET_DATA(find_frame_w, E_FIND_FILTERDATA_KEY, filter_rb);
342 OBJECT_SET_DATA(find_frame_w, E_FIND_HEXDATA_KEY, hex_rb);
343 OBJECT_SET_DATA(find_frame_w, E_FIND_STRINGDATA_KEY, string_rb);
344 OBJECT_SET_DATA(find_frame_w, E_FIND_STRINGTYPE_LABEL_KEY, combo_lb);
345 OBJECT_SET_DATA(find_frame_w, E_FIND_STRINGTYPE_KEY, combo_cb);
346 OBJECT_SET_DATA(find_frame_w, E_CASE_SEARCH_KEY, case_cb);
347 OBJECT_SET_DATA(find_frame_w, E_SOURCE_HEX_KEY, hex_data_rb);
348 OBJECT_SET_DATA(find_frame_w, E_SOURCE_DECODE_KEY, decode_data_rb);
349 OBJECT_SET_DATA(find_frame_w, E_SOURCE_SUMMARY_KEY, summary_data_rb);
350 OBJECT_SET_DATA(find_frame_w, E_FILT_TE_BUTTON_KEY, filter_bt);
353 * Now that we've attached the pointers, connect the signals - if
354 * we do so before we've attached the pointers, the signals may
355 * be delivered before the pointers are attached; the signal
356 * handlers expect the pointers to be attached, and won't be happy.
358 SIGNAL_CONNECT(hex_rb, "clicked", hex_selected_cb, find_frame_w);
359 SIGNAL_CONNECT(string_rb, "clicked", string_selected_cb, find_frame_w);
360 SIGNAL_CONNECT(filter_rb, "clicked", filter_selected_cb, find_frame_w);
362 string_selected_cb(NULL, find_frame_w);
363 filter_selected_cb(NULL, find_frame_w);
365 window_set_cancel_button(find_frame_w, cancel_bt, window_cancel_button_cb);
367 gtk_widget_grab_default(ok_bt);
369 /* Catch the "activate" signal on the filter text entry, so that
370 if the user types Return there, we act as if the "OK" button
371 had been selected, as happens if Return is typed if some widget
372 that *doesn't* handle the Return key has the input focus. */
373 dlg_set_activate(filter_text_box, ok_bt);
375 /* Give the initial focus to the "Filter" entry box. */
376 gtk_widget_grab_focus(filter_text_box);
378 SIGNAL_CONNECT(find_frame_w, "delete_event", window_delete_event_cb, NULL);
379 SIGNAL_CONNECT(find_frame_w, "destroy", find_frame_destroy_cb, NULL);
381 gtk_widget_show(find_frame_w);
382 window_present(find_frame_w);
385 /* this function opens the find frame dialogue and sets the filter string */
387 find_frame_with_filter(char *filter)
389 find_frame_cb(NULL, NULL);
390 gtk_entry_set_text(GTK_ENTRY(filter_text_box), filter);
394 * Check the filter syntax based on the type of search we're doing.
397 find_filter_te_syntax_check_cb(GtkWidget *w, gpointer parent_w)
400 GtkWidget *hex_rb, *string_rb;
401 guint8 *bytes = NULL;
404 hex_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_HEXDATA_KEY);
405 string_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGDATA_KEY);
407 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb))) {
409 * Hex search - scan the search string to make sure it's valid hex.
411 strval = gtk_entry_get_text(GTK_ENTRY(w));
412 if (strval == NULL) {
413 /* XXX - can this happen? */
414 colorize_filter_te_as_invalid(w);
416 bytes = convert_string_to_hex(strval, &nbytes);
418 colorize_filter_te_as_invalid(w);
421 colorize_filter_te_as_valid(w);
424 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb))) {
426 * String search. Make sure the string isn't empty.
428 strval = gtk_entry_get_text(GTK_ENTRY(w));
429 if (strval == NULL) {
430 /* XXX - can this happen? */
431 colorize_filter_te_as_invalid(w);
433 if (strcmp(strval, "") == 0)
434 colorize_filter_te_as_invalid(w);
436 colorize_filter_te_as_valid(w);
440 * Display filter search; check it with "filter_te_syntax_check_cb()".
442 filter_te_syntax_check_cb(w);
447 * This function will re-check the search text syntax.
450 hex_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
452 GtkWidget *filter_text_box;
454 filter_text_box = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_FILT_TE_PTR_KEY);
456 /* Re-check the display filter. */
457 find_filter_te_syntax_check_cb(filter_text_box, parent_w);
462 * This function will disable the string options until
463 * the string search is selected.
466 string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
468 GtkWidget *string_rb, *hex_data_rb, *decode_data_rb, *summary_data_rb,
469 *data_combo_lb, *data_combo_cb, *data_case_cb, *filter_text_box;
471 string_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGDATA_KEY);
472 hex_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_HEX_KEY);
473 decode_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_DECODE_KEY);
474 summary_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_SUMMARY_KEY);
476 data_combo_lb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_LABEL_KEY);
477 data_combo_cb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_KEY);
478 data_case_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CASE_SEARCH_KEY);
479 filter_text_box = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_FILT_TE_PTR_KEY);
481 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(string_rb))) {
482 gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), TRUE);
483 gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), TRUE);
484 gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), TRUE);
485 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), TRUE);
486 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_cb), TRUE);
487 gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), TRUE);
489 gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), FALSE);
490 gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), FALSE);
491 gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), FALSE);
492 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), FALSE);
493 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_cb), FALSE);
494 gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), FALSE);
496 /* Re-check the display filter. */
497 find_filter_te_syntax_check_cb(filter_text_box, parent_w);
502 * This function will disable the filter button until
503 * the filter search is selected.
506 filter_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
508 GtkWidget *filter_bt, *filter_rb;
510 filter_bt = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FILT_TE_BUTTON_KEY);
511 filter_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_FILTERDATA_KEY);
513 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filter_rb)))
515 gtk_widget_set_sensitive(GTK_WIDGET(filter_bt), TRUE);
519 gtk_widget_set_sensitive(GTK_WIDGET(filter_bt), FALSE);
525 find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
527 GtkWidget *filter_te, *up_rb, *hex_rb, *string_rb, *combo_cb,
528 *case_cb, *decode_data_rb, *summary_data_rb;
529 const gchar *filter_text, *string_type;
530 search_charset_t scs_type = SCS_ASCII_AND_UNICODE;
531 guint8 *bytes = NULL;
535 gboolean found_packet;
537 filter_te = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_FILT_KEY);
538 up_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_BACKWARD_KEY);
539 hex_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_HEXDATA_KEY);
540 string_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGDATA_KEY);
541 combo_cb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_KEY);
542 case_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CASE_SEARCH_KEY);
543 decode_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_DECODE_KEY);
544 summary_data_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_SOURCE_SUMMARY_KEY);
546 filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
547 string_type = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo_cb)->entry));
549 case_type = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_cb));
550 decode_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(decode_data_rb));
551 summary_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(summary_data_rb));
554 * Process the search criterion.
556 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb))) {
558 * Hex search - scan the search string to make sure it's valid hex
559 * and to find out how many bytes there are.
561 bytes = convert_string_to_hex(filter_text, &nbytes);
563 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
564 "You didn't specify a valid hex string.");
567 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb))) {
570 * Make sure we're searching for something, first.
572 if (strcmp(filter_text, "") == 0) {
573 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
574 "You didn't specify any text for which to search.");
579 * We are - get the character set type.
581 if (strcmp(string_type, "ASCII Unicode & Non-Unicode") == 0)
582 scs_type = SCS_ASCII_AND_UNICODE;
583 else if (strcmp(string_type, "ASCII Non-Unicode") == 0)
584 scs_type = SCS_ASCII;
585 else if (strcmp(string_type, "ASCII Unicode") == 0)
586 scs_type = SCS_UNICODE;
588 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "You didn't choose a valid character set.");
591 string = convert_string_case(filter_text, case_type);
594 * Display filter search - try to compile the filter.
596 if (!dfilter_compile(filter_text, &sfcode)) {
597 /* The attempt failed; report an error. */
598 bad_dfilter_alert_box(filter_text);
603 if (sfcode == NULL) {
604 /* Yes - complain. */
605 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
606 "You specified a filter that doesn't test anything.");
612 * Remember the search parameters.
615 g_free(cfile.sfilter);
616 cfile.sfilter = g_strdup(filter_text);
617 cfile.sbackward = GTK_TOGGLE_BUTTON (up_rb)->active;
618 cfile.hex = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb));
619 cfile.string = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb));
620 cfile.scs_type = scs_type;
621 cfile.case_type = case_type;
622 cfile.decode_data = decode_data;
623 cfile.summary_data = summary_data;
626 found_packet = find_packet_data(&cfile, bytes, nbytes);
629 /* We didn't find a packet */
630 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
631 "%sFound no match!%s\n\n"
632 "No packet contained those bytes.",
633 simple_dialog_primary_start(), simple_dialog_primary_end());
637 } else if (cfile.string) {
638 /* OK, what are we searching? */
639 if (cfile.decode_data) {
640 /* The text in the protocol tree */
641 found_packet = find_packet_protocol_tree(&cfile, string);
644 /* We didn't find the packet. */
645 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
646 "%sFound no match!%s\n\n"
647 "No packet contained that string in its dissected display.",
648 simple_dialog_primary_start(), simple_dialog_primary_end());
651 } else if (cfile.summary_data) {
652 /* The text in the summary line */
653 found_packet = find_packet_summary_line(&cfile, string);
656 /* We didn't find the packet. */
657 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
658 "%sFound no match!%s\n\n"
659 "No packet contained that string in its Info column.",
660 simple_dialog_primary_start(), simple_dialog_primary_end());
664 /* The raw packet data */
665 found_packet = find_packet_data(&cfile, string, strlen(string));
668 /* We didn't find the packet. */
669 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
670 "%sFound no match!%s\n\n"
671 "No packet contained that string in its data.",
672 simple_dialog_primary_start(), simple_dialog_primary_end());
677 found_packet = find_packet_dfilter(&cfile, sfcode);
678 dfilter_free(sfcode);
680 /* We didn't find a packet */
681 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
682 "%sFound no match!%s\n\n"
683 "No packet matched that filter.",
684 simple_dialog_primary_start(), simple_dialog_primary_end());
689 window_destroy(GTK_WIDGET(parent_w));
693 find_frame_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
695 gtk_grab_remove(GTK_WIDGET(parent_w));
696 window_destroy(GTK_WIDGET(parent_w));
700 find_frame_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
702 /* Note that we no longer have a "Find Packet" dialog box. */
707 find_previous_next(GtkWidget *w, gpointer d, gboolean sens)
715 cfile.sbackward = sens;
717 bytes = convert_string_to_hex(cfile.sfilter, &nbytes);
720 * XXX - this shouldn't happen, as we've already successfully
721 * translated the string once.
725 find_packet_data(&cfile, bytes, nbytes);
727 } else if (cfile.string) {
728 string = convert_string_case(cfile.sfilter, cfile.case_type);
729 /* OK, what are we searching? */
730 if (cfile.decode_data) {
731 /* The text in the protocol tree */
732 find_packet_protocol_tree(&cfile, string);
733 } else if (cfile.summary_data) {
734 /* The text in the summary line */
735 find_packet_summary_line(&cfile, string);
737 /* The raw packet data */
738 find_packet_data(&cfile, string, strlen(string));
742 if (!dfilter_compile(cfile.sfilter, &sfcode)) {
744 * XXX - this shouldn't happen, as we've already successfully
745 * translated the string once.
749 if (sfcode == NULL) {
751 * XXX - this shouldn't happen, as we've already found that the
752 * string wasn't null.
756 find_packet_dfilter(&cfile, sfcode);
757 dfilter_free(sfcode);
764 find_next_cb(GtkWidget *w , gpointer d)
766 find_previous_next(w, d, FALSE);
770 find_previous_cb(GtkWidget *w , gpointer d)
772 find_previous_next(w, d, TRUE);
775 /* this function jumps to the next packet matching the filter */
777 find_previous_next_frame_with_filter(char *filter, gboolean backwards)
780 gboolean sbackwards_saved;
782 /* temporarily set the direction we want to search */
783 sbackwards_saved=cfile.sbackward;
784 cfile.sbackward = backwards;
786 if (!dfilter_compile(filter, &sfcode)) {
788 * XXX - this shouldn't happen, as the filter string is machine
793 if (sfcode == NULL) {
795 * XXX - this shouldn't happen, as the filter string is machine
800 find_packet_dfilter(&cfile, sfcode);
801 dfilter_free(sfcode);
802 cfile.sbackward=sbackwards_saved;