Add the ability to specify a filter to be used when reading the file to

the "Open File" dialog box (the "Open File" dialog box equivalent of the
"-R" flag).  Have "load_cap_file()" take the filter expression as an
argument, and make the global "rfilter" into a member of a
"capture_file" structure.

When reading a temporary capture file after a live capture, don't apply
any filter.

Move the code that pops up error boxes on file opens when reading a
capture file back to "load_cap_file()"; it also pops up error boxes if
the filter expression can't be parsed.

Don't enable "File/Save" or "File/Save As..." if an attempt to read a
capture file fails - if there was already an open capture file, it was
closed by "load_cap_file()", so we no longer have an open file to save.

svn path=/trunk/; revision=460
This commit is contained in:
Guy Harris 1999-08-10 07:16:47 +00:00
parent 7ec128ccb2
commit 8eb998e360
5 changed files with 146 additions and 120 deletions

View File

@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
* $Id: capture.c,v 1.41 1999/08/05 11:12:14 deniel Exp $
* $Id: capture.c,v 1.42 1999/08/10 07:12:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -598,11 +598,8 @@ capture(void) {
if (pch) {
/* "pch" is non-NULL only if we successfully started a capture.
If we haven't, there's no capture file to load. */
err = load_cap_file(cf.save_file, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf.save_file);
} else {
err = load_cap_file(cf.save_file, NULL, &cf);
if (err == 0) {
set_menu_sensitivity("/File/Save", TRUE);
set_menu_sensitivity("/File/Save As...", FALSE);
}

View File

@ -121,7 +121,7 @@ Reads packet data from I<file>.
=item -R
Causes the specified filter (which uses the syntax of display filters,
rather than that of capture filters) to be applied, when a packet file
rather than that of capture filters) to be applied, when a capture file
is read, to all packets read from the capture file; packets not matching
the filter are discarded.
@ -169,7 +169,10 @@ Sets the default capture file name.
=item File:Open, File:Close, File:Reload
Open, close, or reload a capture file.
Open, close, or reload a capture file. The I<File:Open> dialog box
allows a filter to be specified; when the capture file is read, the
filter is applied to all packets read from the file, and packets not
matching the filter are discarded.
=item File:Print

View File

@ -1,6 +1,6 @@
/* ethereal.c
*
* $Id: ethereal.c,v 1.78 1999/08/10 04:13:37 guy Exp $
* $Id: ethereal.c,v 1.79 1999/08/10 07:12:51 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -119,7 +119,6 @@ gchar comp_info_str[256];
gchar *ethereal_path = NULL;
gchar *medium_font = MONO_MEDIUM_FONT;
gchar *bold_font = MONO_BOLD_FONT;
gchar *rfilter = NULL;
ts_type timestamp_type = RELATIVE;
@ -137,6 +136,7 @@ int quit_after_cap; /* Makes a "capture only mode". Implies -k */
static gint tree_selected_start=-1, tree_selected_len=-1;
#define E_DFILTER_TE_KEY "display_filter_te"
#define E_RFILTER_TE_KEY "read_filter_te"
/* About Ethereal window */
void
@ -178,23 +178,25 @@ about_ethereal( GtkWidget *w, gpointer data ) {
void
file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
gchar *cf_name;
GtkWidget *filter_te;
gchar *rfilter;
int err;
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
rfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
gtk_widget_hide(GTK_WIDGET (fs));
gtk_widget_destroy(GTK_WIDGET (fs));
/* this depends upon load_cap_file removing the filename from
* cf_name, leaving only the path to the directory. */
if ((err = load_cap_file(cf_name, &cf)) == 0)
if ((err = load_cap_file(cf_name, rfilter, &cf)) == 0)
chdir(cf_name);
else {
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf_name);
}
g_free(cf_name);
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
if (err == 0) {
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
}
}
/* Update the progress bar */
@ -385,6 +387,8 @@ match_selected_cb(GtkWidget *w, gpointer data)
/* Open a file */
void
file_open_cmd_cb(GtkWidget *w, gpointer data) {
GtkWidget *filter_hbox, *filter_bt, *filter_te;
file_sel = gtk_file_selection_new ("Ethereal: Open Capture File");
/* Connect the ok_button to file_ok_sel_cb function and pass along the
@ -394,8 +398,30 @@ file_open_cmd_cb(GtkWidget *w, gpointer data) {
/* Gilbert --- I added this if statement. Is this right? */
if (w)
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
filter_hbox = gtk_hbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(filter_hbox), 0);
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_sel)->action_area),
filter_hbox, FALSE, FALSE, 0);
gtk_widget_show(filter_hbox);
filter_bt = gtk_button_new_with_label("Filter:");
gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked",
GTK_SIGNAL_FUNC(prefs_cb), (gpointer) E_PR_PG_FILTER);
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_bt, FALSE, TRUE, 0);
gtk_widget_show(filter_bt);
filter_te = gtk_entry_new();
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_te, TRUE, TRUE, 3);
if (cf.rfilter != NULL)
gtk_entry_set_text(GTK_ENTRY(filter_te), cf.rfilter);
gtk_widget_show(filter_te);
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
E_RFILTER_TE_KEY, filter_te);
/* Connect the cancel_button to destroy the widget */
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
@ -471,14 +497,11 @@ file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
g_free(cf.save_file);
cf.save_file = g_strdup(cf_name);
cf.user_saved = 1;
err = load_cap_file(cf_name, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf_name);
err = load_cap_file(cf_name, g_strdup(cf.rfilter), &cf);
if (err == 0) {
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
}
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
}
static void
@ -495,32 +518,25 @@ file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
g_free(cf.save_file);
cf.save_file = g_strdup(cf_name);
cf.user_saved = 1;
err = load_cap_file(cf_name, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf_name);
err = load_cap_file(cf_name, g_strdup(cf.rfilter), &cf);
if (err == 0) {
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
}
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
}
/* Reload a file using the current display filter */
/* Reload a file using the current read and display filters */
void
file_reload_cmd_cb(GtkWidget *w, gpointer data) {
/*GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);*/
GtkWidget *filter_te;
int err;
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
if (cf.dfilter) g_free(cf.dfilter);
cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
err = load_cap_file(cf.filename, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf.filename);
}
load_cap_file(cf.filename, g_strdup(cf.rfilter), &cf);
/* XXX - change the menu if it fails? */
}
/* Run the current display filter on the current packet set, and
@ -973,10 +989,10 @@ main(int argc, char *argv[])
*bv_table, *bv_hscroll, *bv_vscroll, *stat_hbox,
*tv_scrollw, *filter_bt, *filter_te;
GtkStyle *pl_style;
GtkAccelGroup *accel;
GtkWidget *packet_sw;
GtkAccelGroup *accel;
GtkWidget *packet_sw;
gint pl_size = 280, tv_size = 95, bv_size = 75;
gchar *rc_file, *cf_name = NULL;
gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
e_prefs *prefs;
gchar **col_title;
@ -1350,13 +1366,10 @@ main(int argc, char *argv[])
alert box, so, if we get one of those, it's more likely to come
up on top of us. */
if (cf_name) {
err = load_cap_file(cf_name, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf_name);
}
err = load_cap_file(cf_name, rfilter, &cf);
cf_name[0] = '\0';
set_menu_sensitivity("/File/Save As...", TRUE);
if (err == 0)
set_menu_sensitivity("/File/Save As...", TRUE);
}
/* If we failed to open the preferences file, pop up an alert box;

98
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.60 1999/08/10 06:54:12 guy Exp $
* $Id: file.c,v 1.61 1999/08/10 07:12:52 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -82,7 +82,6 @@ extern GtkWidget *packet_list, *prog_bar, *info_bar, *byte_view, *tree_view;
extern guint file_ctx;
extern int sync_mode;
extern int sync_pipe[];
extern gchar *rfilter;
guint cap_input_id;
@ -187,7 +186,7 @@ close_cap_file(capture_file *cf, void *w, guint context) {
}
int
load_cap_file(char *fname, capture_file *cf) {
load_cap_file(char *fname, char *rfilter, capture_file *cf) {
gchar *name_ptr, *load_msg, *load_fmt = " Loading: %s...";
gchar *done_fmt = " File: %s Drops: %d";
gchar *err_fmt = " Error: Could not load '%s'";
@ -204,62 +203,75 @@ load_cap_file(char *fname, capture_file *cf) {
name_ptr = fname;
else
name_ptr++;
rfcode = NULL;
if (rfilter)
if (dfilter_compile(rfilter, &rfcode) != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
"Unable to parse filter string \"%s\".", rfilter);
goto fail;
}
err = open_cap_file(fname, cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), fname);
goto fail;
}
load_msg = g_malloc(strlen(name_ptr) + strlen(load_fmt) + 2);
sprintf(load_msg, load_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
timeout = gtk_timeout_add(250, file_progress_cb, (gpointer) cf);
rfcode = NULL;
if (rfilter)
if (dfilter_compile(rfilter, &rfcode) != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
"Unable to parse filter string \"%s\".", rfilter);
}
err = open_cap_file(fname, cf);
if ((err == 0) && (cf->cd_t != WTAP_FILE_UNKNOWN)) {
freeze_clist(cf);
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
wtap_close(cf->wth);
cf->wth = NULL;
cf->fh = fopen(fname, "r");
thaw_clist(cf);
}
freeze_clist(cf);
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
wtap_close(cf->wth);
cf->wth = NULL;
cf->fh = fopen(fname, "r");
thaw_clist(cf);
gtk_timeout_remove(timeout);
gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
if (err == 0) {
msg_len = strlen(name_ptr) + strlen(done_fmt) + 64;
load_msg = g_realloc(load_msg, msg_len);
msg_len = strlen(name_ptr) + strlen(done_fmt) + 64;
load_msg = g_realloc(load_msg, msg_len);
if (cf->user_saved || !cf->save_file)
snprintf(load_msg, msg_len, done_fmt, name_ptr, cf->drops);
else
snprintf(load_msg, msg_len, done_fmt, "<none>", cf->drops);
if (cf->user_saved || !cf->save_file)
snprintf(load_msg, msg_len, done_fmt, name_ptr, cf->drops);
else
snprintf(load_msg, msg_len, done_fmt, "<none>", cf->drops);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
g_free(load_msg);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
g_free(load_msg);
/* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */
/* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */
/* Enable menu items that make sense if you have a capture. */
set_menu_sensitivity("/File/Close", TRUE);
set_menu_sensitivity("/File/Reload", TRUE);
set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Display/Options...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
} else {
msg_len = strlen(name_ptr) + strlen(err_fmt) + 2;
load_msg = g_realloc(load_msg, msg_len);
snprintf(load_msg, msg_len, err_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
g_free(load_msg);
}
return err;
/* Remember the new read filter string. */
if (cf->rfilter != NULL)
g_free(cf->rfilter);
cf->rfilter = rfilter;
/* Enable menu items that make sense if you have a capture. */
set_menu_sensitivity("/File/Close", TRUE);
set_menu_sensitivity("/File/Reload", TRUE);
set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Display/Options...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
return 0;
fail:
msg_len = strlen(name_ptr) + strlen(err_fmt) + 2;
load_msg = g_malloc(msg_len);
snprintf(load_msg, msg_len, err_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
g_free(load_msg);
if (rfilter != NULL)
g_free(rfilter); /* assumed to be "g_strdup()"ed, if not null */
return -1;
}
#ifdef HAVE_LIBPCAP

59
file.h
View File

@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
* $Id: file.h,v 1.27 1999/08/10 04:13:37 guy Exp $
* $Id: file.h,v 1.28 1999/08/10 07:12:52 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -47,27 +47,28 @@
typedef struct bpf_program bpf_prog;
typedef struct _capture_file {
FILE *fh; /* Capture file */
gchar *filename; /* filename */
long f_len; /* File length */
guint16 cd_t; /* Capture data type */
FILE *fh; /* Capture file */
gchar *filename; /* filename */
long f_len; /* File length */
guint16 cd_t; /* Capture data type */
const gchar *cd_t_desc;/* Description of that data type */
guint32 vers; /* Version. For tcpdump minor is appended to major */
guint32 count; /* Packet count */
gfloat unfiltered_count; /* used for dfilter progress bar */
guint32 drops; /* Dropped packets */
guint32 esec; /* Elapsed seconds */
guint32 eusec; /* Elapsed microseconds */
guint32 snap; /* Captured packet length */
gchar *iface; /* Interface */
gchar *save_file; /* File that user saved capture to */
gint user_saved;/* Was capture file saved by user yet? */
wtap *wth; /* Wiretap session */
gchar *dfilter; /* Display filter string */
GNode *dfcode; /* Compiled display filter program */
guint32 vers; /* Version. For tcpdump minor is appended to major */
guint32 count; /* Packet count */
gfloat unfiltered_count; /* used for dfilter progress bar */
guint32 drops; /* Dropped packets */
guint32 esec; /* Elapsed seconds */
guint32 eusec; /* Elapsed microseconds */
guint32 snap; /* Captured packet length */
gchar *iface; /* Interface */
gchar *save_file; /* File that user saved capture to */
gint user_saved;/* Was capture file saved by user yet? */
wtap *wth; /* Wiretap session */
gchar *rfilter; /* Read filter string */
gchar *dfilter; /* Display filter string */
GNode *dfcode; /* Compiled display filter program */
#ifdef HAVE_LIBPCAP
gchar *cfilter; /* Capture filter string */
bpf_prog fcode; /* Compiled capture filter program */
gchar *cfilter; /* Capture filter string */
bpf_prog fcode; /* Compiled capture filter program */
#endif
/* XXX - I'm cheating for now. I'll hardcode 65536 here until I re-arrange
* more header files so that ethereal.h is split up into two files, a
@ -75,15 +76,15 @@ typedef struct _capture_file {
* moved to different header files) --gilbert
*/
/*guint8 pd[MAX_PACKET_SIZE];*/ /* Packet data */
guint8 pd[65536]; /* Packet data */
frame_data *plist; /* Packet list */
frame_data *plist_end; /* Last packet in list */
guint8 pd[65536]; /* Packet data */
frame_data *plist; /* Packet list */
frame_data *plist_end; /* Last packet in list */
column_info cinfo; /* Column formatting information */
int selected_packet; /* Index in packet list of currently selected packet, if any */
int selected_row; /* Row in packet display of currently selected packet, if any */
frame_data *fd; /* Frame data for currently selected packet */
proto_tree *protocol_tree; /* Protocol tree for currently selected packet */
FILE *print_fh; /* File we're printing to */
int selected_packet; /* Index in packet list of currently selected packet, if any */
int selected_row; /* Row in packet display of currently selected packet, if any */
frame_data *fd; /* Frame data for currently selected packet */
proto_tree *protocol_tree; /* Protocol tree for currently selected packet */
FILE *print_fh; /* File we're printing to */
} capture_file;
@ -101,7 +102,7 @@ typedef struct _capture_file {
int open_cap_file(char *, capture_file *);
void close_cap_file(capture_file *, void *, guint);
int load_cap_file(char *, capture_file *);
int load_cap_file(char *, char *, capture_file *);
int tail_cap_file(char *, capture_file *);
/* size_t read_frame_header(capture_file *); */