From Greg Morris: code to support searches for text or raw binary data
in a frame in Find Frame. svn path=/trunk/; revision=8067
This commit is contained in:
parent
d6ed142549
commit
487d0def6b
1
AUTHORS
1
AUTHORS
|
@ -1307,6 +1307,7 @@ Andrew Esh <Andrew.Esh[AT]tricord.com> {
|
|||
Greg Morris <GMORRIS[AT]novell.com> {
|
||||
NCP - NetWare Core Protocol
|
||||
NDPS - Novell Distributed Print System
|
||||
"Find Frame" code to search for text or binary data
|
||||
}
|
||||
|
||||
Dirk Steinberg <dws[AT]dirksteinberg.de> {
|
||||
|
|
5
cfile.h
5
cfile.h
|
@ -1,7 +1,7 @@
|
|||
/* cfile.h
|
||||
* capture_file definition & GUI-independent manipulation
|
||||
*
|
||||
* $Id: cfile.h,v 1.1 2002/09/06 23:14:04 sahlberg Exp $
|
||||
* $Id: cfile.h,v 1.2 2003/07/22 23:08:47 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -65,6 +65,9 @@ typedef struct _capture_file {
|
|||
#endif
|
||||
gchar *sfilter; /* Search filter string */
|
||||
gboolean sbackward; /* TRUE if search is backward, FALSE if forward */
|
||||
gboolean hex; /* TRUE is Hex search is being performed */
|
||||
gboolean ascii; /* TRUE is ASCII search is being performed */
|
||||
char *ftype; /* Find Frame String Type */
|
||||
union wtap_pseudo_header pseudo_header; /* Packet pseudo_header */
|
||||
guint8 pd[WTAP_MAX_PACKET_SIZE]; /* Packet data */
|
||||
GMemChunk *plist_chunk; /* Memory chunk for frame_data structures */
|
||||
|
|
242
file.c
242
file.c
|
@ -1,7 +1,7 @@
|
|||
/* file.c
|
||||
* File I/O routines
|
||||
*
|
||||
* $Id: file.c,v 1.299 2003/06/24 06:14:46 guy Exp $
|
||||
* $Id: file.c,v 1.300 2003/07/22 23:08:47 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -1428,6 +1428,246 @@ change_time_formats(capture_file *cf)
|
|||
thaw_plist(cf);
|
||||
}
|
||||
|
||||
guint8
|
||||
get_int_value(char char_val)
|
||||
{
|
||||
switch (char_val) {
|
||||
case 'a':
|
||||
case 'A':
|
||||
return(10);
|
||||
case 'b':
|
||||
case 'B':
|
||||
return(11);
|
||||
case 'c':
|
||||
case 'C':
|
||||
return(12);
|
||||
case 'd':
|
||||
case 'D':
|
||||
return(13);
|
||||
case 'e':
|
||||
case 'E':
|
||||
return(14);
|
||||
case 'f':
|
||||
case 'F':
|
||||
return(15);
|
||||
default:
|
||||
return(atoi(&char_val));
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
find_ascii(capture_file *cf, char *ascii_text, gboolean ascii_search, char *ftype)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
frame_matched = FALSE;
|
||||
buf_len = fdata->pkt_len;
|
||||
for (i=0;i<buf_len;i++) {
|
||||
c_char = cf->pd[i];
|
||||
/* Check to see if this is an String or Hex search */
|
||||
if (ascii_search) {
|
||||
/* Now check the String Type */
|
||||
if(strcmp(ftype,"ASCII Unicode & Non-Unicode")==0)
|
||||
{
|
||||
if (c_char != 0) {
|
||||
if (c_char == ascii_text[c_match]) {
|
||||
c_match++;
|
||||
if (c_match == strlen(ascii_text)) {
|
||||
frame_matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c_match = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strcmp(ftype,"ASCII Non-Unicode")==0)
|
||||
{
|
||||
if (c_char == ascii_text[c_match]) {
|
||||
c_match++;
|
||||
if (c_match == strlen(ascii_text)) {
|
||||
frame_matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c_match = 0;
|
||||
}
|
||||
}
|
||||
else if(strcmp(ftype, "ASCII Unicode")==0)
|
||||
{
|
||||
if (c_char == ascii_text[c_match]) {
|
||||
c_match++;
|
||||
i++;
|
||||
if (c_match == strlen(ascii_text)) {
|
||||
frame_matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c_match = 0;
|
||||
}
|
||||
}
|
||||
else if(strcmp(ftype,"EBCDIC")==0)
|
||||
{
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"EBCDIC Find Not supported yet.");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Invalid String type specified.");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else /* Hex Search */
|
||||
{
|
||||
char_val = ascii_text[c_match];
|
||||
num1 = get_int_value(char_val);
|
||||
char_val = ascii_text[++c_match];
|
||||
num2 = get_int_value(char_val);
|
||||
hex_val = (num1*0x10)+num2;
|
||||
if ( c_char == hex_val) {
|
||||
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! */
|
||||
}
|
||||
}
|
||||
|
||||
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_packet(capture_file *cf, dfilter_t *sfcode)
|
||||
{
|
||||
|
|
4
file.h
4
file.h
|
@ -1,7 +1,7 @@
|
|||
/* file.h
|
||||
* Definitions for file structures and routines
|
||||
*
|
||||
* $Id: file.h,v 1.99 2003/03/02 22:07:21 guy Exp $
|
||||
* $Id: file.h,v 1.100 2003/07/22 23:08:47 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -56,6 +56,8 @@ void redissect_packets(capture_file *cf);
|
|||
int print_packets(capture_file *cf, print_args_t *print_args);
|
||||
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 goto_frame(capture_file *cf, guint fnumber);
|
||||
|
||||
|
|
121
gtk/find_dlg.c
121
gtk/find_dlg.c
|
@ -1,7 +1,7 @@
|
|||
/* find_dlg.c
|
||||
* Routines for "find frame" window
|
||||
*
|
||||
* $Id: find_dlg.c,v 1.28 2003/04/24 23:18:07 guy Exp $
|
||||
* $Id: find_dlg.c,v 1.29 2003/07/22 23:08:48 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -39,10 +39,16 @@
|
|||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "compat_macros.h"
|
||||
#include "prefs.h"
|
||||
#include "prefs_dlg.h"
|
||||
|
||||
/* Capture callback data keys */
|
||||
#define E_FIND_FILT_KEY "find_filter_te"
|
||||
#define E_FIND_BACKWARD_KEY "find_backward"
|
||||
#define E_FIND_HEXDATA_KEY "find_hex"
|
||||
#define E_FIND_ASCIIDATA_KEY "find_ascii"
|
||||
#define E_FIND_FILTERDATA_KEY "find_filter"
|
||||
#define E_FIND_STRINGTYPE_KEY "find_string_type"
|
||||
|
||||
static void
|
||||
find_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
||||
|
@ -66,10 +72,13 @@ 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,
|
||||
*combo_hb, *combo_cb, *combo_lb,
|
||||
*bbox, *ok_bt, *cancel_bt;
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
GtkAccelGroup *accel_group;
|
||||
#endif
|
||||
GList *glist = NULL;
|
||||
/* No Apply button, but "OK" not only sets our text widget, it
|
||||
activates it (i.e., it causes us to do the search). */
|
||||
static construct_args_t args = {
|
||||
|
@ -145,6 +154,71 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
|
|||
gtk_box_pack_start(GTK_BOX(direction_hb), backward_rb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(backward_rb);
|
||||
|
||||
|
||||
/* Filter/Hex/Ascii Search */
|
||||
/* Filter */
|
||||
hex_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), hex_hb);
|
||||
gtk_widget_show(hex_hb);
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
filter_rb = dlg_radio_button_new_with_label_with_mnemonic(NULL, "_Display Filter",
|
||||
accel_group);
|
||||
#else
|
||||
filter_rb = gtk_radio_button_new_with_mnemonic(NULL, "_Display Filter");
|
||||
#endif
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filter_rb), !cfile.hex && !cfile.ascii);
|
||||
gtk_box_pack_start(GTK_BOX(hex_hb), filter_rb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(filter_rb);
|
||||
|
||||
/* Hex */
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
hex_rb = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(filter_rb)),
|
||||
"_Hex", accel_group);
|
||||
#else
|
||||
hex_rb = gtk_radio_button_new_with_mnemonic_from_widget(
|
||||
GTK_RADIO_BUTTON(filter_rb), "_Hex");
|
||||
#endif
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hex_rb), cfile.hex);
|
||||
gtk_box_pack_start(GTK_BOX(hex_hb), hex_rb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(hex_rb);
|
||||
|
||||
/* ASCII Search */
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
ascii_rb = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(filter_rb)),
|
||||
"_String", accel_group);
|
||||
#else
|
||||
ascii_rb = gtk_radio_button_new_with_mnemonic_from_widget(
|
||||
GTK_RADIO_BUTTON(filter_rb), "_String");
|
||||
#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);
|
||||
gtk_widget_show(ascii_rb);
|
||||
|
||||
/* String Type Selection Dropdown Box */
|
||||
combo_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), combo_hb);
|
||||
gtk_widget_show(combo_hb);
|
||||
/* Create Label */
|
||||
combo_lb = gtk_label_new("Find String Type:");
|
||||
gtk_box_pack_start(GTK_BOX(combo_hb), combo_lb, FALSE, FALSE, 6);
|
||||
gtk_widget_show(combo_lb);
|
||||
/* Create Combo Box */
|
||||
combo_cb = gtk_combo_new();
|
||||
/*gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), "Find String Type:");*/
|
||||
|
||||
glist = g_list_append(glist, "ASCII Unicode & Non-Unicode");
|
||||
glist = g_list_append(glist, "ASCII Non-Unicode");
|
||||
glist = g_list_append(glist, "ASCII Unicode");
|
||||
glist = g_list_append(glist, "EBCDIC");
|
||||
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(combo_cb), glist);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), combo_cb);
|
||||
gtk_widget_show(combo_cb);
|
||||
|
||||
/* Button row: OK and cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
|
@ -176,6 +250,11 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
|
|||
/* Attach pointers to needed widgets to the capture prefs window/object */
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_FILT_KEY, filter_te);
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_BACKWARD_KEY, backward_rb);
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_FILTERDATA_KEY, filter_rb);
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_HEXDATA_KEY, hex_rb);
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_ASCIIDATA_KEY, ascii_rb);
|
||||
OBJECT_SET_DATA(find_frame_w, E_FIND_STRINGTYPE_KEY, combo_cb);
|
||||
|
||||
|
||||
/* Catch the "activate" signal on the filter text entry, so that
|
||||
if the user types Return there, we act as if the "OK" button
|
||||
|
@ -197,29 +276,33 @@ find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
|
|||
static void
|
||||
find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
||||
{
|
||||
GtkWidget *filter_te, *backward_rb;
|
||||
gchar *filter_text;
|
||||
GtkWidget *filter_te, *backward_rb, *hex_rb, *ascii_rb, *combo_cb;
|
||||
gchar *filter_text, *string_type;
|
||||
dfilter_t *sfcode;
|
||||
|
||||
filter_te = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_FILT_KEY);
|
||||
backward_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_BACKWARD_KEY);
|
||||
hex_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_HEXDATA_KEY);
|
||||
ascii_rb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_ASCIIDATA_KEY);
|
||||
combo_cb = (GtkWidget *)OBJECT_GET_DATA(parent_w, E_FIND_STRINGTYPE_KEY);
|
||||
|
||||
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
||||
string_type = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo_cb)->entry));
|
||||
|
||||
/*
|
||||
* Try to compile the filter.
|
||||
*/
|
||||
if (!dfilter_compile(filter_text, &sfcode)) {
|
||||
if (!dfilter_compile(filter_text, &sfcode) && !GTK_TOGGLE_BUTTON (hex_rb)->active && !GTK_TOGGLE_BUTTON (ascii_rb)->active) {
|
||||
/* The attempt failed; report an error. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Was it empty? */
|
||||
if (sfcode == NULL) {
|
||||
if (sfcode == NULL && !GTK_TOGGLE_BUTTON (hex_rb)->active && !GTK_TOGGLE_BUTTON (ascii_rb)->active) {
|
||||
/* Yes - complain. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"You didn't specify a filter to use when searching for a frame.");
|
||||
"You didn't specify valid search criteria.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,13 +314,25 @@ find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
|||
cfile.sfilter = g_strdup(filter_text);
|
||||
|
||||
cfile.sbackward = GTK_TOGGLE_BUTTON (backward_rb)->active;
|
||||
cfile.hex = GTK_TOGGLE_BUTTON (hex_rb)->active;
|
||||
cfile.ascii = GTK_TOGGLE_BUTTON (ascii_rb)->active;
|
||||
cfile.ftype = g_strdup(string_type);
|
||||
|
||||
if (!GTK_TOGGLE_BUTTON (hex_rb)->active && !GTK_TOGGLE_BUTTON (ascii_rb)->active ) {
|
||||
if (!find_packet(&cfile, sfcode)) {
|
||||
/* We didn't find the packet. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, "No packet matched that filter.");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!find_ascii(&cfile, filter_text, cfile.ascii, string_type)) {
|
||||
/* 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));
|
||||
}
|
||||
|
||||
|
@ -260,13 +355,21 @@ find_previous_next(GtkWidget *w, gpointer d, gboolean sens)
|
|||
{
|
||||
dfilter_t *sfcode;
|
||||
|
||||
|
||||
if (cfile.sfilter) {
|
||||
if (!dfilter_compile(cfile.sfilter, &sfcode))
|
||||
if (!dfilter_compile(cfile.sfilter, &sfcode) && !cfile.hex && !cfile.ascii)
|
||||
return;
|
||||
if (sfcode == NULL)
|
||||
if (sfcode == NULL && !cfile.hex && !cfile.ascii)
|
||||
return;
|
||||
cfile.sbackward = sens;
|
||||
if (cfile.hex || cfile.ascii)
|
||||
{
|
||||
find_ascii(&cfile, cfile.sfilter, cfile.ascii, cfile.ftype);
|
||||
}
|
||||
else
|
||||
{
|
||||
find_packet(&cfile, sfcode);
|
||||
}
|
||||
} else
|
||||
find_frame_cb(w, d);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue