1998-09-16 02:39:15 +00:00
|
|
|
/* ethereal.c
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1999-08-10 07:16:47 +00:00
|
|
|
* $Id: ethereal.c,v 1.79 1999/08/10 07:12:51 guy Exp $
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
1999-02-19 05:28:38 +00:00
|
|
|
* Richard Sharpe, 13-Feb-1999, added support for initializing structures
|
|
|
|
* needed by dissect routines
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* To do:
|
|
|
|
* - Live browser/capture display
|
|
|
|
* - Graphs
|
|
|
|
* - Get AIX to work
|
|
|
|
* - Check for end of packet in dissect_* routines.
|
|
|
|
* - Playback window
|
|
|
|
* - Multiple window support
|
|
|
|
* - Add cut/copy/paste
|
|
|
|
* - Create header parsing routines
|
|
|
|
* - Check fopens, freads, fwrites
|
|
|
|
* - Make byte view scrollbars automatic?
|
|
|
|
* - Make byte view selections more fancy?
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
1998-12-17 05:42:33 +00:00
|
|
|
#include <stdlib.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <unistd.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
|
|
|
|
1999-06-12 07:04:35 +00:00
|
|
|
#include <errno.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_DIRECT_H
|
|
|
|
#include <direct.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
1998-09-16 02:39:15 +00:00
|
|
|
#include <netinet/in.h>
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
|
|
|
|
1999-05-11 18:51:10 +00:00
|
|
|
#include <signal.h>
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-01-04 07:39:14 +00:00
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
|
|
# ifdef HAVE_STDARG_H
|
|
|
|
# include <stdarg.h>
|
|
|
|
# else
|
|
|
|
# include <varargs.h>
|
|
|
|
# endif
|
|
|
|
# include "snprintf.h"
|
|
|
|
#endif
|
|
|
|
|
1999-06-14 21:46:36 +00:00
|
|
|
#ifdef NEED_STRERROR_H
|
|
|
|
#include "strerror.h"
|
|
|
|
#endif
|
|
|
|
|
1998-09-27 22:12:47 +00:00
|
|
|
#include "ethereal.h"
|
1999-06-19 01:14:51 +00:00
|
|
|
#include "timestamp.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "packet.h"
|
1999-02-09 00:35:38 +00:00
|
|
|
#include "capture.h"
|
1999-06-22 22:02:39 +00:00
|
|
|
#include "summary.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "file.h"
|
|
|
|
#include "menu.h"
|
|
|
|
#include "etypes.h"
|
1998-10-28 21:38:11 +00:00
|
|
|
#include "prefs.h"
|
1998-11-17 04:29:13 +00:00
|
|
|
#include "column.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
#include "print.h"
|
|
|
|
#include "resolv.h"
|
1998-09-17 03:12:28 +00:00
|
|
|
#include "follow.h"
|
|
|
|
#include "util.h"
|
1999-03-23 03:14:46 +00:00
|
|
|
#include "gtkpacket.h"
|
1999-07-07 22:52:57 +00:00
|
|
|
#include "dfilter.h"
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-04-06 16:24:50 +00:00
|
|
|
static void file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs);
|
|
|
|
static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
|
1999-07-23 08:29:24 +00:00
|
|
|
static void print_cmd_toggle_dest(GtkWidget *widget, gpointer data);
|
|
|
|
static void print_file_cb(GtkWidget *file_bt, gpointer file_te);
|
|
|
|
static void print_fs_ok_cb(GtkWidget *w, gpointer data);
|
|
|
|
static void print_fs_cancel_cb(GtkWidget *w, gpointer data);
|
|
|
|
static void print_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
|
|
|
static void print_close_cb(GtkWidget *close_bt, gpointer parent_w);
|
1999-04-06 16:24:50 +00:00
|
|
|
|
1998-09-17 03:12:28 +00:00
|
|
|
FILE *data_out_file = NULL;
|
|
|
|
packet_info pi;
|
1998-09-16 02:39:15 +00:00
|
|
|
capture_file cf;
|
|
|
|
GtkWidget *file_sel, *packet_list, *tree_view, *byte_view, *prog_bar,
|
1998-10-12 01:40:57 +00:00
|
|
|
*info_bar;
|
1998-09-16 02:39:15 +00:00
|
|
|
GdkFont *m_r_font, *m_b_font;
|
|
|
|
guint main_ctx, file_ctx;
|
|
|
|
gint start_capture = 0;
|
1998-12-27 20:47:53 +00:00
|
|
|
gchar comp_info_str[256];
|
1999-05-11 18:51:10 +00:00
|
|
|
gchar *ethereal_path = NULL;
|
|
|
|
gchar *medium_font = MONO_MEDIUM_FONT;
|
|
|
|
gchar *bold_font = MONO_BOLD_FONT;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-09-27 22:12:47 +00:00
|
|
|
ts_type timestamp_type = RELATIVE;
|
|
|
|
|
1998-12-29 04:05:38 +00:00
|
|
|
GtkStyle *item_style;
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
int sync_mode; /* allow sync */
|
|
|
|
int sync_pipe[2]; /* used to sync father */
|
|
|
|
int fork_mode; /* fork a child to do the capture */
|
|
|
|
int sigusr2_received = 0;
|
|
|
|
int quit_after_cap; /* Makes a "capture only mode". Implies -k */
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1999-05-11 18:51:10 +00:00
|
|
|
|
1999-06-24 16:25:59 +00:00
|
|
|
/* Specifies byte offsets for object selected in tree */
|
|
|
|
static gint tree_selected_start=-1, tree_selected_len=-1;
|
|
|
|
|
1998-10-12 01:40:57 +00:00
|
|
|
#define E_DFILTER_TE_KEY "display_filter_te"
|
1999-08-10 07:16:47 +00:00
|
|
|
#define E_RFILTER_TE_KEY "read_filter_te"
|
1998-10-12 01:40:57 +00:00
|
|
|
|
1998-10-16 01:18:35 +00:00
|
|
|
/* About Ethereal window */
|
|
|
|
void
|
|
|
|
about_ethereal( GtkWidget *w, gpointer data ) {
|
|
|
|
simple_dialog(ESD_TYPE_INFO, NULL,
|
|
|
|
"GNU Ethereal - network protocol analyzer\n"
|
1998-12-27 20:47:53 +00:00
|
|
|
"Version %s (C) 1998 Gerald Combs <gerald@zing.org>\n"
|
|
|
|
"Compiled with %s\n\n"
|
1998-10-16 01:18:35 +00:00
|
|
|
"Contributors:\n"
|
1999-04-06 16:24:50 +00:00
|
|
|
|
|
|
|
"Gilbert Ramirez <gramirez@tivoli.com>\n"
|
1999-04-04 02:49:23 +00:00
|
|
|
"Hannes R. Boehm <hannes@boehm.org>\n"
|
|
|
|
"Mike Hall <mlh@io.com>\n"
|
|
|
|
"Bobo Rajec <bobo@bsp-consulting.sk>\n"
|
|
|
|
"Laurent Deniel <deniel@worldnet.fr>\n"
|
|
|
|
"Don Lafontaine <lafont02@cn.ca>\n"
|
|
|
|
"Guy Harris <guy@netapp.com>\n"
|
|
|
|
"Simon Wilkinson <sxw@dcs.ed.ac.uk>\n"
|
|
|
|
"Joerg Mayer <jmayer@telemation.de>\n"
|
|
|
|
"Martin Maciaszek <fastjack@i-s-o.net>\n"
|
|
|
|
"Didier Jorand <Didier.Jorand@alcatel.fr>\n"
|
1999-04-05 21:54:41 +00:00
|
|
|
"Jun-ichiro itojun Hagino <itojun@iijlab.net>\n"
|
1999-04-06 16:24:50 +00:00
|
|
|
"Richard Sharpe <sharpe@ns.aus.com>\n"
|
1999-05-12 06:04:47 +00:00
|
|
|
"John McDermott <jjm@jkintl.com>\n"
|
1999-06-11 15:30:55 +00:00
|
|
|
"Jeff Jahr <jjahr@shastanets.com>\n"
|
|
|
|
"Brad Robel-Forrest <bradr@watchguard.com>\n"
|
1999-06-11 16:45:02 +00:00
|
|
|
"Ashok Narayanan <ashokn@cisco.com>\n"
|
1999-06-22 22:02:39 +00:00
|
|
|
"Aaron Hillegass <aaron@classmax.com>\n"
|
1999-07-07 00:34:58 +00:00
|
|
|
"Jason Lango <jal@netapp.com>\n"
|
1999-07-08 04:23:28 +00:00
|
|
|
"Johan Feyaerts <Johan.Feyaerts@siemens.atea.be>\n"
|
1999-08-02 05:52:52 +00:00
|
|
|
"Olivier Abad <abad@daba.dhis.org>\n"
|
1999-07-28 23:16:42 +00:00
|
|
|
"Thierry Andry <Thierry.Andry@advalvas.be>\n"
|
1999-04-06 16:24:50 +00:00
|
|
|
|
|
|
|
"\nSee http://ethereal.zing.org for more information",
|
1998-12-27 20:47:53 +00:00
|
|
|
VERSION, comp_info_str);
|
1998-10-16 01:18:35 +00:00
|
|
|
}
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Things to do when the OK button is pressed */
|
|
|
|
void
|
|
|
|
file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
|
1998-10-12 01:40:57 +00:00
|
|
|
gchar *cf_name;
|
1999-08-10 07:16:47 +00:00
|
|
|
GtkWidget *filter_te;
|
|
|
|
gchar *rfilter;
|
1998-10-12 01:40:57 +00:00
|
|
|
int err;
|
1998-12-17 05:42:33 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
|
1999-08-10 07:16:47 +00:00
|
|
|
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
|
|
|
|
rfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_hide(GTK_WIDGET (fs));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET (fs));
|
|
|
|
|
1999-04-06 16:24:50 +00:00
|
|
|
/* this depends upon load_cap_file removing the filename from
|
|
|
|
* cf_name, leaving only the path to the directory. */
|
1999-08-10 07:16:47 +00:00
|
|
|
if ((err = load_cap_file(cf_name, rfilter, &cf)) == 0)
|
1998-09-16 02:39:15 +00:00
|
|
|
chdir(cf_name);
|
|
|
|
g_free(cf_name);
|
1999-08-10 07:16:47 +00:00
|
|
|
if (err == 0) {
|
|
|
|
set_menu_sensitivity("/File/Save", FALSE);
|
|
|
|
set_menu_sensitivity("/File/Save As...", TRUE);
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the progress bar */
|
|
|
|
gint
|
|
|
|
file_progress_cb(gpointer p) {
|
1999-08-05 16:46:04 +00:00
|
|
|
capture_file *cf = (capture_file*) p;
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
|
1999-08-05 16:46:04 +00:00
|
|
|
(gfloat) ftell(cf->fh) / (gfloat) cf->f_len);
|
1998-09-16 02:39:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
1998-09-17 03:12:28 +00:00
|
|
|
/* Follow a TCP stream */
|
|
|
|
void
|
1998-10-12 01:40:57 +00:00
|
|
|
follow_stream_cb( GtkWidget *w, gpointer data ) {
|
1998-09-17 03:12:28 +00:00
|
|
|
char filename1[128];
|
|
|
|
GtkWidget *streamwindow, *box, *text, *vscrollbar, *table;
|
1998-12-22 05:52:51 +00:00
|
|
|
GtkWidget *filter_te = NULL;
|
|
|
|
|
|
|
|
if (w)
|
|
|
|
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
|
|
|
|
|
1998-09-17 03:12:28 +00:00
|
|
|
if( pi.ipproto == 6 ) {
|
|
|
|
/* we got tcp so we can follow */
|
|
|
|
/* check to see if we are using a filter */
|
1998-10-12 01:40:57 +00:00
|
|
|
if( cf.dfilter != NULL ) {
|
1998-09-17 03:12:28 +00:00
|
|
|
/* get rid of this one */
|
1998-10-12 01:40:57 +00:00
|
|
|
g_free( cf.dfilter );
|
|
|
|
cf.dfilter = NULL;
|
1998-09-17 03:12:28 +00:00
|
|
|
}
|
1999-07-31 13:55:16 +00:00
|
|
|
reset_tcp_reassembly();
|
1998-10-12 01:40:57 +00:00
|
|
|
/* create a new one and set the display filter entry accordingly */
|
|
|
|
cf.dfilter = build_follow_filter( &pi );
|
1998-12-22 05:52:51 +00:00
|
|
|
if (filter_te)
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(filter_te), cf.dfilter);
|
1999-07-31 18:26:07 +00:00
|
|
|
/* Run the display filter so it goes in effect. Also we set
|
|
|
|
data_out_file which tells the tcp code to output the data */
|
1998-09-17 03:12:28 +00:00
|
|
|
strcpy( filename1, tmpnam(NULL) );
|
|
|
|
data_out_file = fopen( filename1, "a" );
|
|
|
|
if( data_out_file == NULL ) {
|
|
|
|
fprintf( stderr, "Could not open tmp file %s\n", filename1 );
|
|
|
|
}
|
1999-07-31 18:26:07 +00:00
|
|
|
filter_packets(&cf);
|
1998-09-17 03:12:28 +00:00
|
|
|
/* the data_out_file should now be full of the streams information */
|
|
|
|
fclose( data_out_file );
|
|
|
|
/* the filename1 file now has all the text that was in the session */
|
|
|
|
streamwindow = gtk_window_new( GTK_WINDOW_TOPLEVEL);
|
|
|
|
gtk_widget_set_name( streamwindow, "TCP stream window" );
|
|
|
|
gtk_signal_connect( GTK_OBJECT(streamwindow), "delete_event",
|
|
|
|
NULL, "WM destroy" );
|
|
|
|
gtk_signal_connect( GTK_OBJECT(streamwindow), "destroy",
|
|
|
|
NULL, "WM destroy" );
|
1999-03-23 20:25:50 +00:00
|
|
|
if( incomplete_tcp_stream ) {
|
|
|
|
gtk_window_set_title( GTK_WINDOW(streamwindow),
|
|
|
|
"Contents of TCP stream (incomplete)" );
|
|
|
|
} else {
|
|
|
|
gtk_window_set_title( GTK_WINDOW(streamwindow),
|
|
|
|
"Contents of TCP stream" );
|
|
|
|
}
|
1998-09-17 03:12:28 +00:00
|
|
|
gtk_widget_set_usize( GTK_WIDGET(streamwindow), DEF_WIDTH, DEF_HEIGHT );
|
|
|
|
gtk_container_border_width( GTK_CONTAINER(streamwindow), 2 );
|
|
|
|
/* setup the container */
|
|
|
|
box = gtk_vbox_new( FALSE, 0 );
|
|
|
|
gtk_container_add( GTK_CONTAINER(streamwindow), box );
|
|
|
|
gtk_widget_show( box );
|
|
|
|
/* set up the table we attach to */
|
|
|
|
table = gtk_table_new( 1, 2, FALSE );
|
|
|
|
gtk_table_set_col_spacing( GTK_TABLE(table), 0, 2);
|
|
|
|
gtk_box_pack_start( GTK_BOX(box), table, TRUE, TRUE, 0 );
|
|
|
|
gtk_widget_show( table );
|
|
|
|
/* create a text box */
|
|
|
|
text = gtk_text_new( NULL, NULL );
|
|
|
|
gtk_text_set_editable( GTK_TEXT(text), FALSE);
|
|
|
|
gtk_table_attach( GTK_TABLE(table), text, 0, 1, 0, 1,
|
|
|
|
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
|
|
|
|
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0 );
|
|
|
|
gtk_widget_show(text);
|
|
|
|
/* create the scrollbar */
|
|
|
|
vscrollbar = gtk_vscrollbar_new( GTK_TEXT(text)->vadj );
|
|
|
|
gtk_table_attach( GTK_TABLE(table), vscrollbar, 1, 2, 0, 1,
|
|
|
|
GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0 );
|
|
|
|
gtk_widget_show( vscrollbar );
|
|
|
|
gtk_widget_realize( text );
|
|
|
|
/* stop the updates while we fill the text box */
|
|
|
|
gtk_text_freeze( GTK_TEXT(text) );
|
|
|
|
data_out_file = NULL;
|
|
|
|
data_out_file = fopen( filename1, "r" );
|
|
|
|
if( data_out_file ) {
|
|
|
|
char buffer[1024];
|
|
|
|
int nchars;
|
|
|
|
while( 1 ) {
|
|
|
|
nchars = fread( buffer, 1, 1024, data_out_file );
|
|
|
|
gtk_text_insert( GTK_TEXT(text), m_r_font, NULL, NULL, buffer, nchars );
|
|
|
|
if( nchars < 1024 ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose( data_out_file );
|
|
|
|
unlink( filename1 );
|
|
|
|
}
|
|
|
|
gtk_text_thaw( GTK_TEXT(text) );
|
|
|
|
data_out_file = NULL;
|
|
|
|
gtk_widget_show( streamwindow );
|
1998-10-12 01:40:57 +00:00
|
|
|
if( cf.dfilter != NULL ) {
|
|
|
|
g_free( cf.dfilter );
|
|
|
|
cf.dfilter = NULL;
|
1998-09-17 03:12:28 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Error following stream. Please make\n"
|
|
|
|
"sure you have a TCP packet selected.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-06-24 16:25:59 +00:00
|
|
|
/* Match selected byte pattern */
|
|
|
|
void
|
|
|
|
match_selected_cb(GtkWidget *w, gpointer data)
|
|
|
|
{
|
1999-08-04 03:37:45 +00:00
|
|
|
char *buf = g_malloc(1024);
|
1999-06-24 16:25:59 +00:00
|
|
|
GtkWidget *filter_te = NULL;
|
1999-08-04 03:37:45 +00:00
|
|
|
char *ptr;
|
|
|
|
int i;
|
|
|
|
guint8 *c;
|
1999-06-24 16:25:59 +00:00
|
|
|
|
|
|
|
if (w)
|
1999-08-04 03:37:45 +00:00
|
|
|
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
|
1999-06-24 16:25:59 +00:00
|
|
|
|
|
|
|
if (tree_selected_start<0) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Error determining selected bytes. Please make\n"
|
|
|
|
"sure you have selected a field within the tree\n"
|
|
|
|
"view to be matched.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-08-04 03:37:45 +00:00
|
|
|
/* sprintf(buf, "("); ptr = buf+strlen(buf);
|
1999-06-24 16:25:59 +00:00
|
|
|
for (i=0, c=cf.pd+tree_selected_start; i+4<tree_selected_len; i+=4, c+=4) {
|
1999-08-04 03:37:45 +00:00
|
|
|
sprintf(ptr, "(frame[%d : 4]=0x%02X%02X%02X%02X) and ",
|
1999-06-24 16:25:59 +00:00
|
|
|
tree_selected_start+i,
|
|
|
|
*c,
|
|
|
|
*(c+1),
|
|
|
|
*(c+2),
|
|
|
|
*(c+3));
|
|
|
|
ptr = buf+strlen(buf);
|
1999-08-04 03:37:45 +00:00
|
|
|
}*/
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
c = cf.pd + tree_selected_start;
|
|
|
|
ptr = buf;
|
1999-06-24 16:25:59 +00:00
|
|
|
|
1999-08-04 03:37:45 +00:00
|
|
|
sprintf(ptr, "frame[%d : %d] == ",
|
1999-06-24 16:25:59 +00:00
|
|
|
tree_selected_start+i,
|
|
|
|
tree_selected_len - i);
|
|
|
|
ptr = buf+strlen(buf);
|
1999-08-04 03:37:45 +00:00
|
|
|
/*for (;i<tree_selected_len; i++) {*/
|
|
|
|
if (tree_selected_len == 1) {
|
|
|
|
sprintf(ptr, "0x%02x", *c++);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (i=0;i<tree_selected_len; i++) {
|
|
|
|
if (i == 0 ) {
|
|
|
|
sprintf(ptr, "%02x", *c++);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(ptr, ":%02x", *c++);
|
|
|
|
}
|
|
|
|
ptr = buf+strlen(buf);
|
|
|
|
}
|
1999-06-24 16:25:59 +00:00
|
|
|
}
|
|
|
|
|
1999-08-04 03:37:45 +00:00
|
|
|
/*sprintf(ptr, "))");*/
|
1999-06-24 16:25:59 +00:00
|
|
|
if( cf.dfilter != NULL ) {
|
|
|
|
/* get rid of this one */
|
|
|
|
g_free( cf.dfilter );
|
|
|
|
cf.dfilter = NULL;
|
|
|
|
}
|
|
|
|
/* create a new one and set the display filter entry accordingly */
|
|
|
|
cf.dfilter = buf;
|
|
|
|
if (filter_te)
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(filter_te), cf.dfilter);
|
1999-07-31 18:26:07 +00:00
|
|
|
/* Run the display filter so it goes in effect. */
|
|
|
|
filter_packets(&cf);
|
1999-06-24 16:25:59 +00:00
|
|
|
if( cf.dfilter != NULL ) {
|
|
|
|
g_free( cf.dfilter );
|
|
|
|
cf.dfilter = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Open a file */
|
|
|
|
void
|
1998-10-12 01:40:57 +00:00
|
|
|
file_open_cmd_cb(GtkWidget *w, gpointer data) {
|
1999-08-10 07:16:47 +00:00
|
|
|
GtkWidget *filter_hbox, *filter_bt, *filter_te;
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
file_sel = gtk_file_selection_new ("Ethereal: Open Capture File");
|
|
|
|
|
1998-10-12 01:40:57 +00:00
|
|
|
/* Connect the ok_button to file_ok_sel_cb function and pass along the
|
|
|
|
pointer to the filter entry */
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_sel)->ok_button),
|
|
|
|
"clicked", (GtkSignalFunc) file_sel_ok_cb, file_sel );
|
1998-12-17 05:42:33 +00:00
|
|
|
|
|
|
|
/* Gilbert --- I added this if statement. Is this right? */
|
|
|
|
if (w)
|
1999-08-10 07:16:47 +00:00
|
|
|
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);
|
|
|
|
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
|
1999-08-10 07:16:47 +00:00
|
|
|
E_RFILTER_TE_KEY, filter_te);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* Connect the cancel_button to destroy the widget */
|
|
|
|
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
|
|
|
|
(file_sel)->cancel_button), "clicked", (GtkSignalFunc)
|
|
|
|
gtk_widget_destroy, GTK_OBJECT (file_sel));
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
if( fork_mode && (cf.save_file != NULL) )
|
1999-07-13 02:53:26 +00:00
|
|
|
#else
|
|
|
|
if( cf.save_file != NULL )
|
|
|
|
#endif
|
1999-05-11 18:51:10 +00:00
|
|
|
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), cf.save_file);
|
|
|
|
else
|
|
|
|
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), "");
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
gtk_widget_show(file_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close a file */
|
|
|
|
void
|
|
|
|
file_close_cmd_cb(GtkWidget *widget, gpointer data) {
|
|
|
|
close_cap_file(&cf, info_bar, file_ctx);
|
1998-10-12 01:40:57 +00:00
|
|
|
}
|
|
|
|
|
1999-04-06 16:24:50 +00:00
|
|
|
void
|
|
|
|
file_save_cmd_cb(GtkWidget *w, gpointer data) {
|
|
|
|
file_sel = gtk_file_selection_new ("Ethereal: Save Capture File");
|
|
|
|
|
|
|
|
/* Connect the ok_button to file_ok_sel_cb function and pass along the
|
|
|
|
pointer to the filter entry */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_sel)->ok_button),
|
|
|
|
"clicked", (GtkSignalFunc) file_save_ok_cb, file_sel );
|
|
|
|
|
|
|
|
/* Connect the cancel_button to destroy the widget */
|
|
|
|
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
|
|
|
|
(file_sel)->cancel_button), "clicked", (GtkSignalFunc)
|
|
|
|
gtk_widget_destroy, GTK_OBJECT (file_sel));
|
|
|
|
|
|
|
|
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), "");
|
|
|
|
|
|
|
|
gtk_widget_show(file_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
file_save_as_cmd_cb(GtkWidget *w, gpointer data) {
|
|
|
|
file_sel = gtk_file_selection_new ("Ethereal: Save Capture File as");
|
|
|
|
|
|
|
|
/* Connect the ok_button to file_ok_sel_cb function and pass along the
|
|
|
|
pointer to the filter entry */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_sel)->ok_button),
|
|
|
|
"clicked", (GtkSignalFunc) file_save_as_ok_cb, file_sel );
|
|
|
|
|
|
|
|
/* Connect the cancel_button to destroy the widget */
|
|
|
|
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
|
|
|
|
(file_sel)->cancel_button), "clicked", (GtkSignalFunc)
|
|
|
|
gtk_widget_destroy, GTK_OBJECT (file_sel));
|
|
|
|
|
|
|
|
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel), "");
|
|
|
|
gtk_widget_show(file_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
|
|
|
|
gchar *cf_name;
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
int err;
|
1999-04-06 16:24:50 +00:00
|
|
|
|
|
|
|
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
|
|
|
|
gtk_widget_hide(GTK_WIDGET (fs));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET (fs));
|
|
|
|
|
|
|
|
if (!file_mv(cf.save_file, cf_name))
|
|
|
|
return;
|
|
|
|
g_free(cf.save_file);
|
|
|
|
cf.save_file = g_strdup(cf_name);
|
|
|
|
cf.user_saved = 1;
|
1999-08-10 07:16:47 +00:00
|
|
|
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);
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
}
|
1999-04-06 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
|
|
|
|
gchar *cf_name;
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
int err;
|
1999-04-06 16:24:50 +00:00
|
|
|
|
|
|
|
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
|
|
|
|
gtk_widget_hide(GTK_WIDGET (fs));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET (fs));
|
|
|
|
|
|
|
|
if (!file_cp(cf.save_file, cf_name))
|
|
|
|
return;
|
|
|
|
g_free(cf.save_file);
|
|
|
|
cf.save_file = g_strdup(cf_name);
|
|
|
|
cf.user_saved = 1;
|
1999-08-10 07:16:47 +00:00
|
|
|
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);
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
}
|
1999-04-06 16:24:50 +00:00
|
|
|
}
|
|
|
|
|
1999-08-10 07:16:47 +00:00
|
|
|
/* Reload a file using the current read and display filters */
|
1999-07-27 02:04:38 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
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)));
|
1999-08-10 07:16:47 +00:00
|
|
|
load_cap_file(cf.filename, g_strdup(cf.rfilter), &cf);
|
|
|
|
/* XXX - change the menu if it fails? */
|
1999-07-27 02:04:38 +00:00
|
|
|
}
|
|
|
|
|
1999-07-11 08:40:52 +00:00
|
|
|
/* Run the current display filter on the current packet set, and
|
|
|
|
redisplay. */
|
|
|
|
static void
|
|
|
|
filter_activate_cb(GtkWidget *w, gpointer data) {
|
|
|
|
if (cf.dfilter) g_free(cf.dfilter);
|
|
|
|
cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(w)));
|
|
|
|
filter_packets(&cf);
|
|
|
|
}
|
|
|
|
|
1999-07-23 08:29:24 +00:00
|
|
|
/*
|
|
|
|
* Remember whether we printed to a printer or a file the last time we
|
|
|
|
* printed something.
|
|
|
|
*/
|
|
|
|
static int print_to_file;
|
|
|
|
|
|
|
|
/* Keys for gtk_object_set_data */
|
|
|
|
#define PRINT_CMD_LB_KEY "printer_command_label"
|
|
|
|
#define PRINT_CMD_TE_KEY "printer_command_entry"
|
|
|
|
#define PRINT_FILE_BT_KEY "printer_file_button"
|
|
|
|
#define PRINT_FILE_TE_KEY "printer_file_entry"
|
|
|
|
#define PRINT_DEST_RB_KEY "printer_destination_radio_button"
|
|
|
|
|
|
|
|
/* Print the capture */
|
1998-09-16 02:39:15 +00:00
|
|
|
void
|
1999-07-23 08:29:24 +00:00
|
|
|
file_print_cmd_cb(GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
GtkWidget *print_w;
|
|
|
|
GtkWidget *main_vb, *main_tb, *button;
|
1999-07-23 21:09:25 +00:00
|
|
|
#if 0
|
1999-07-23 08:29:24 +00:00
|
|
|
GtkWidget *format_hb, *format_lb;
|
1999-07-23 21:09:25 +00:00
|
|
|
GSList *format_grp;
|
|
|
|
#endif
|
1999-07-23 08:29:24 +00:00
|
|
|
GtkWidget *dest_rb;
|
|
|
|
GtkWidget *dest_hb, *dest_lb;
|
|
|
|
GtkWidget *cmd_lb, *cmd_te;
|
|
|
|
GtkWidget *file_bt_hb, *file_bt, *file_te;
|
1999-07-23 21:09:25 +00:00
|
|
|
GSList *dest_grp;
|
1999-07-23 08:29:24 +00:00
|
|
|
GtkWidget *bbox, *ok_bt, *cancel_bt;
|
|
|
|
|
|
|
|
/* XXX - don't pop up one if there's already one open; instead,
|
|
|
|
give it the input focus if that's possible. */
|
|
|
|
|
|
|
|
print_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
|
gtk_window_set_title(GTK_WINDOW(print_w), "Ethereal: Print");
|
|
|
|
|
|
|
|
/* Enclosing containers for each row of widgets */
|
|
|
|
main_vb = gtk_vbox_new(FALSE, 5);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(print_w), main_vb);
|
|
|
|
gtk_widget_show(main_vb);
|
|
|
|
|
|
|
|
main_tb = gtk_table_new(4, 2, FALSE);
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
|
|
|
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
|
|
|
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
|
|
|
gtk_widget_show(main_tb);
|
|
|
|
|
1999-07-23 21:09:25 +00:00
|
|
|
/* XXX - printing multiple frames in PostScript looks as if it's
|
|
|
|
tricky - you have to deal with page boundaries, I think -
|
|
|
|
and I'll have to spend some time learning enough about
|
|
|
|
PostScript to figure it out, so, for now, we only print
|
|
|
|
multiple frames as text. */
|
|
|
|
#if 0
|
1999-07-23 08:29:24 +00:00
|
|
|
/* Output format */
|
|
|
|
format_lb = gtk_label_new("Format:");
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(format_lb), 1.0, 0.5);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), format_lb, 0, 1, 0, 1);
|
|
|
|
gtk_widget_show(format_lb);
|
|
|
|
|
|
|
|
format_hb = gtk_hbox_new(FALSE, 0);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), format_hb, 1, 2, 0, 1);
|
|
|
|
gtk_widget_show(format_hb);
|
|
|
|
|
|
|
|
button = gtk_radio_button_new_with_label(NULL, "Plain Text");
|
|
|
|
if (prefs.pr_format == PR_FMT_TEXT)
|
|
|
|
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
|
|
|
|
format_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
|
|
|
|
gtk_box_pack_start(GTK_BOX(format_hb), button, FALSE, FALSE, 10);
|
|
|
|
gtk_widget_show(button);
|
|
|
|
|
|
|
|
button = gtk_radio_button_new_with_label(format_grp, "PostScript");
|
|
|
|
if (prefs.pr_format == PR_FMT_PS)
|
|
|
|
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
|
|
|
|
gtk_box_pack_start(GTK_BOX(format_hb), button, FALSE, FALSE, 10);
|
|
|
|
gtk_widget_show(button);
|
1999-07-23 21:09:25 +00:00
|
|
|
#endif
|
1999-07-23 08:29:24 +00:00
|
|
|
|
|
|
|
/* Output destination */
|
|
|
|
dest_lb = gtk_label_new("Print to:");
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(dest_lb), 1.0, 0.5);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_lb, 0, 1, 1, 2);
|
|
|
|
gtk_widget_show(dest_lb);
|
|
|
|
|
|
|
|
dest_hb = gtk_hbox_new(FALSE, 0);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_hb, 1, 2, 1, 2);
|
|
|
|
gtk_widget_show(dest_hb);
|
|
|
|
|
|
|
|
button = gtk_radio_button_new_with_label(NULL, "Command");
|
|
|
|
if (!print_to_file)
|
|
|
|
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
|
|
|
|
dest_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
|
|
|
|
gtk_box_pack_start(GTK_BOX(dest_hb), button, FALSE, FALSE, 10);
|
|
|
|
gtk_widget_show(button);
|
|
|
|
|
|
|
|
dest_rb = gtk_radio_button_new_with_label(dest_grp, "File");
|
|
|
|
if (print_to_file)
|
|
|
|
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(dest_rb), TRUE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(dest_rb), "toggled",
|
|
|
|
GTK_SIGNAL_FUNC(print_cmd_toggle_dest), NULL);
|
|
|
|
gtk_box_pack_start(GTK_BOX(dest_hb), dest_rb, FALSE, FALSE, 10);
|
|
|
|
gtk_widget_show(dest_rb);
|
|
|
|
|
|
|
|
/* Command text entry */
|
|
|
|
cmd_lb = gtk_label_new("Command:");
|
|
|
|
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_LB_KEY, cmd_lb);
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(cmd_lb), 1.0, 0.5);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_lb, 0, 1, 2, 3);
|
|
|
|
gtk_widget_set_sensitive(cmd_lb, !print_to_file);
|
|
|
|
gtk_widget_show(cmd_lb);
|
|
|
|
|
|
|
|
cmd_te = gtk_entry_new();
|
|
|
|
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_TE_KEY, cmd_te);
|
|
|
|
if (prefs.pr_cmd)
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(cmd_te), prefs.pr_cmd);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_te, 1, 2, 2, 3);
|
|
|
|
gtk_widget_set_sensitive(cmd_te, !print_to_file);
|
|
|
|
gtk_widget_show(cmd_te);
|
|
|
|
|
|
|
|
/* File button and text entry */
|
|
|
|
file_bt_hb = gtk_hbox_new(FALSE, 0);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_bt_hb, 0, 1, 3, 4);
|
|
|
|
gtk_widget_show(file_bt_hb);
|
|
|
|
|
|
|
|
file_bt = gtk_button_new_with_label("File:");
|
|
|
|
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_BT_KEY, file_bt);
|
|
|
|
gtk_box_pack_end(GTK_BOX(file_bt_hb), file_bt, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_set_sensitive(file_bt, print_to_file);
|
|
|
|
gtk_widget_show(file_bt);
|
|
|
|
|
|
|
|
file_te = gtk_entry_new();
|
|
|
|
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_TE_KEY, file_te);
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
|
|
|
|
gtk_widget_set_sensitive(file_te, print_to_file);
|
|
|
|
gtk_widget_show(file_te);
|
|
|
|
|
|
|
|
gtk_signal_connect(GTK_OBJECT(file_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(print_file_cb), GTK_OBJECT(file_te));
|
|
|
|
|
|
|
|
/* Button row: OK and Cancel buttons */
|
|
|
|
bbox = gtk_hbutton_box_new();
|
|
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
|
|
|
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
|
|
|
gtk_widget_show(bbox);
|
|
|
|
|
|
|
|
ok_bt = gtk_button_new_with_label ("OK");
|
|
|
|
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_DEST_RB_KEY, dest_rb);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_CMD_TE_KEY, cmd_te);
|
|
|
|
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_FILE_TE_KEY, file_te);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(print_ok_cb), GTK_OBJECT(print_w));
|
|
|
|
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_grab_default(ok_bt);
|
|
|
|
gtk_widget_show(ok_bt);
|
|
|
|
|
|
|
|
cancel_bt = gtk_button_new_with_label ("Cancel");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
|
|
|
|
GTK_SIGNAL_FUNC(print_close_cb), GTK_OBJECT(print_w));
|
|
|
|
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
|
|
|
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show(cancel_bt);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
display_opt_window_active = TRUE;
|
|
|
|
#endif
|
|
|
|
gtk_widget_show(print_w);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_cmd_toggle_dest(GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
GtkWidget *cmd_lb, *cmd_te, *file_bt, *file_te;
|
|
|
|
int to_file;
|
|
|
|
|
|
|
|
cmd_lb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
|
|
|
PRINT_CMD_LB_KEY));
|
|
|
|
cmd_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
|
|
|
PRINT_CMD_TE_KEY));
|
|
|
|
file_bt = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
|
|
|
PRINT_FILE_BT_KEY));
|
|
|
|
file_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
|
|
|
PRINT_FILE_TE_KEY));
|
|
|
|
if (GTK_TOGGLE_BUTTON (widget)->active) {
|
|
|
|
/* They selected "Print to File" */
|
|
|
|
to_file = TRUE;
|
|
|
|
} else {
|
|
|
|
/* They selected "Print to Command" */
|
|
|
|
to_file = FALSE;
|
|
|
|
}
|
|
|
|
gtk_widget_set_sensitive(cmd_lb, !to_file);
|
|
|
|
gtk_widget_set_sensitive(cmd_te, !to_file);
|
|
|
|
gtk_widget_set_sensitive(file_bt, to_file);
|
|
|
|
gtk_widget_set_sensitive(file_te, to_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_file_cb(GtkWidget *file_bt, gpointer file_te)
|
|
|
|
{
|
|
|
|
GtkWidget *fs;
|
|
|
|
|
|
|
|
fs = gtk_file_selection_new ("Ethereal: Print to File");
|
|
|
|
gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
|
|
|
|
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
|
|
|
|
"clicked", (GtkSignalFunc) print_fs_ok_cb, fs);
|
|
|
|
|
|
|
|
/* Connect the cancel_button to destroy the widget */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
|
|
|
|
"clicked", (GtkSignalFunc) print_fs_cancel_cb, fs);
|
|
|
|
|
|
|
|
gtk_widget_show(fs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_fs_ok_cb(GtkWidget *w, gpointer data)
|
|
|
|
{
|
|
|
|
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
|
|
|
|
PRINT_FILE_TE_KEY)),
|
|
|
|
gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(data));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_fs_cancel_cb(GtkWidget *w, gpointer data)
|
|
|
|
{
|
|
|
|
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(data));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
|
|
|
|
{
|
|
|
|
GtkWidget *button;
|
|
|
|
char *dest;
|
|
|
|
|
|
|
|
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
|
|
|
PRINT_DEST_RB_KEY);
|
|
|
|
if (GTK_TOGGLE_BUTTON (button)->active)
|
|
|
|
print_to_file = TRUE;
|
|
|
|
else
|
|
|
|
print_to_file = FALSE;
|
|
|
|
|
|
|
|
if (print_to_file)
|
|
|
|
dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
|
|
|
|
PRINT_FILE_TE_KEY))));
|
|
|
|
else
|
|
|
|
dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
|
|
|
|
PRINT_CMD_TE_KEY))));
|
|
|
|
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
|
|
|
#if 0
|
|
|
|
display_opt_window_active = FALSE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Now print the packets */
|
|
|
|
if (!print_packets(&cf, print_to_file, dest)) {
|
|
|
|
if (print_to_file)
|
When printing a packet, do it from the protocol tree, not from the GTK+
tree constructed from the protocol tree:
1) The value of "level" field of GTK+ tree items appears to
depend on various random things - see a change I made to
"packet-dns.c" a while ago, to change the order in which
items were put in the tree, so that DNS trees printed with
correct indentation - and, right now, we appear to be doing
*something* wrong, as some packets I printed from one file
here had randomly bogus indentation; I could probably track
the problem down and fix it, but that might just hold us
until we accidentally do something *else* wrong by GTK+'s
lights.
The new code provides its own tree level as it goes.
2) The new code is independent of GTK+, so it could be used with
other toolkits, or with non-GUI variants of Ethereal.
3) This may make it easier to add a "Print..." menu item to let
the user print packets other than the currently selected
packet.
Make the internal routines used to print the packet static.
For the "Print Packet" menu item, put up a message box if they haven't
yet selected a packet.
svn path=/trunk/; revision=362
1999-07-13 04:38:15 +00:00
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
1999-07-23 08:29:24 +00:00
|
|
|
file_write_error_message(errno), dest);
|
|
|
|
else
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
|
|
|
|
prefs.pr_cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_close_cb(GtkWidget *close_bt, gpointer parent_w)
|
|
|
|
{
|
|
|
|
|
|
|
|
gtk_grab_remove(GTK_WIDGET(parent_w));
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
|
|
|
#if 0
|
|
|
|
display_opt_window_active = FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print a packet */
|
|
|
|
void
|
|
|
|
file_print_packet_cmd_cb(GtkWidget *widget, gpointer data) {
|
|
|
|
FILE *fh;
|
|
|
|
|
|
|
|
switch (prefs.pr_dest) {
|
|
|
|
|
|
|
|
case PR_DEST_CMD:
|
|
|
|
fh = popen(prefs.pr_cmd, "w");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PR_DEST_FILE:
|
|
|
|
fh = fopen(prefs.pr_file, "w");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
fh = NULL; /* XXX - "can't happen" */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (fh == NULL) {
|
|
|
|
switch (prefs.pr_dest) {
|
|
|
|
|
|
|
|
case PR_DEST_CMD:
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
|
|
|
|
prefs.pr_cmd);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PR_DEST_FILE:
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL, file_write_error_message(errno),
|
|
|
|
prefs.pr_file);
|
|
|
|
break;
|
When printing a packet, do it from the protocol tree, not from the GTK+
tree constructed from the protocol tree:
1) The value of "level" field of GTK+ tree items appears to
depend on various random things - see a change I made to
"packet-dns.c" a while ago, to change the order in which
items were put in the tree, so that DNS trees printed with
correct indentation - and, right now, we appear to be doing
*something* wrong, as some packets I printed from one file
here had randomly bogus indentation; I could probably track
the problem down and fix it, but that might just hold us
until we accidentally do something *else* wrong by GTK+'s
lights.
The new code provides its own tree level as it goes.
2) The new code is independent of GTK+, so it could be used with
other toolkits, or with non-GUI variants of Ethereal.
3) This may make it easier to add a "Print..." menu item to let
the user print packets other than the currently selected
packet.
Make the internal routines used to print the packet static.
For the "Print Packet" menu item, put up a message box if they haven't
yet selected a packet.
svn path=/trunk/; revision=362
1999-07-13 04:38:15 +00:00
|
|
|
}
|
1999-07-23 08:29:24 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-07-23 21:09:25 +00:00
|
|
|
print_preamble(fh);
|
1999-07-24 03:22:50 +00:00
|
|
|
proto_tree_print(-1, (GNode*) cf.protocol_tree, cf.pd, cf.fd, fh);
|
1999-07-23 21:09:25 +00:00
|
|
|
print_finale(fh);
|
1999-07-23 08:29:24 +00:00
|
|
|
close_print_dest(prefs.pr_dest == PR_DEST_FILE, fh);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* What to do when a list item is selected/unselected */
|
|
|
|
void
|
|
|
|
packet_list_select_cb(GtkWidget *w, gint row, gint col, gpointer evt) {
|
1998-10-16 01:18:35 +00:00
|
|
|
|
1999-07-13 07:14:18 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
if (!sync_mode) {
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1999-07-11 08:40:52 +00:00
|
|
|
if (cf.wth)
|
|
|
|
return;
|
1999-07-13 07:14:18 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
}
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-17 03:12:28 +00:00
|
|
|
blank_packetinfo();
|
1999-07-24 03:22:50 +00:00
|
|
|
select_packet(&cf, row);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_unselect_cb(GtkWidget *w, gint row, gint col, gpointer evt) {
|
Have "close_cap_file()" disable all menu items that make sense only if
you have a capture.
Leave the job of enabling and disabling menu items that make sense only
if you have a capture (except for "File/Save" and "File/Save As...", for
now) up to "load_cap_file()", "close_cap_file()", and the like - don't
scatter that stuff throughout the code.
Disable "File/Print Packet" if no packet is selected; enable it only if
a packet is selected.
If there's a selected packet, and a display filter is run:
if the selected packet passed the filter, re-select it;
if the selected packet didn't pass the filter, un-select it.
If we've opened a live "pcap" capture, but can't do the capture because
we can't get the netmask info, or can't parse the capture filter string,
or can't install the filter, close the live capture and the dump and
delete the dump file.
If we failed to open a live "pcap" capture, don't try to read the
capture file - it doesn't exist.
svn path=/trunk/; revision=384
1999-07-24 02:42:52 +00:00
|
|
|
unselect_packet(&cf);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
tree_view_cb(GtkWidget *w) {
|
1999-06-24 16:25:59 +00:00
|
|
|
|
|
|
|
tree_selected_start = -1;
|
|
|
|
tree_selected_len = -1;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
if (GTK_TREE(w)->selection) {
|
1999-06-24 16:25:59 +00:00
|
|
|
tree_selected_start =
|
|
|
|
(gint) gtk_object_get_data(GTK_OBJECT(GTK_TREE(w)->selection->data),
|
|
|
|
E_TREEINFO_START_KEY);
|
|
|
|
tree_selected_len =
|
|
|
|
(gint) gtk_object_get_data(GTK_OBJECT(GTK_TREE(w)->selection->data),
|
|
|
|
E_TREEINFO_LEN_KEY);
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gtk_text_freeze(GTK_TEXT(byte_view));
|
|
|
|
gtk_text_set_point(GTK_TEXT(byte_view), 0);
|
|
|
|
gtk_text_forward_delete(GTK_TEXT(byte_view),
|
|
|
|
gtk_text_get_length(GTK_TEXT(byte_view)));
|
1999-07-24 03:22:50 +00:00
|
|
|
packet_hex_print(GTK_TEXT(byte_view), cf.pd, cf.fd->cap_len,
|
1999-06-24 16:25:59 +00:00
|
|
|
tree_selected_start,
|
|
|
|
tree_selected_len);
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_text_thaw(GTK_TEXT(byte_view));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
file_quit_cmd_cb (GtkWidget *widget, gpointer data) {
|
1999-04-06 16:35:47 +00:00
|
|
|
if (cf.save_file && !cf.user_saved) {
|
|
|
|
unlink(cf.save_file);
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_exit(0);
|
|
|
|
}
|
|
|
|
|
1998-09-17 03:12:28 +00:00
|
|
|
void blank_packetinfo() {
|
1999-07-31 11:21:06 +00:00
|
|
|
pi.ip_src = 0;
|
|
|
|
pi.ip_dst = 0;
|
1998-09-17 03:12:28 +00:00
|
|
|
pi.ipproto = 0;
|
|
|
|
pi.srcport = 0;
|
|
|
|
pi.destport = 0;
|
|
|
|
}
|
|
|
|
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
/* Things to do when the main window is realized */
|
1998-09-16 02:39:15 +00:00
|
|
|
void
|
|
|
|
main_realize_cb(GtkWidget *w, gpointer data) {
|
1999-07-09 04:18:36 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1998-09-16 02:39:15 +00:00
|
|
|
if (start_capture) {
|
1999-05-11 18:51:10 +00:00
|
|
|
capture();
|
1998-09-16 02:39:15 +00:00
|
|
|
start_capture = 0;
|
|
|
|
}
|
1999-07-09 04:18:36 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
static void
|
|
|
|
sigusr2_handler(int sig) {
|
|
|
|
sigusr2_received = 1;
|
|
|
|
signal(SIGUSR2, sigusr2_handler);
|
|
|
|
}
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1999-05-11 18:51:10 +00:00
|
|
|
|
1999-07-07 22:52:57 +00:00
|
|
|
/* call initialization routines at program startup time */
|
1999-02-19 05:28:38 +00:00
|
|
|
static void
|
|
|
|
ethereal_proto_init(void) {
|
1999-07-07 22:52:57 +00:00
|
|
|
proto_init();
|
1999-02-19 05:28:38 +00:00
|
|
|
init_dissect_udp();
|
1999-07-07 22:52:57 +00:00
|
|
|
dfilter_init();
|
1999-02-19 05:28:38 +00:00
|
|
|
}
|
|
|
|
|
Improve the alert boxes put up for file open/read/write errors. (Some
influence came from
http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html
which has a section on dialog box and alert box messages. However,
we're largely dealing with technoids, not with The Rest Of Us, so I
didn't go as far as one perhaps should.)
Unfortunately, it looks like it's a bit more work to arrange that, if
you give a bad file name to the "-r" flag, the dialog box pop up only
*after* the main window pops up - it has the annoying habit of popping
up *before* the main window pops up, and sometimes getting *obscured* by
it, when I do that. The removal of the dialog box stuff from
"load_cap_file()" was intended to facilitate that work. (It might also
be nice if, when an open from the "File/Open" menu item fails, we keep
the file selection box open, and give the user a chance to correct
typos, choose another file name, etc.)
svn path=/trunk/; revision=310
1999-06-12 09:10:20 +00:00
|
|
|
static void
|
1998-09-16 02:39:15 +00:00
|
|
|
print_usage(void) {
|
|
|
|
|
1998-12-27 20:47:53 +00:00
|
|
|
fprintf(stderr, "This is GNU %s %s, compiled with %s\n", PACKAGE,
|
1999-05-11 18:51:10 +00:00
|
|
|
VERSION, comp_info_str);
|
|
|
|
fprintf(stderr, "%s [-vh] [-FkQS] [-b bold font] [-B byte view height] [-c count]\n",
|
1998-09-16 02:39:15 +00:00
|
|
|
PACKAGE);
|
1999-05-11 18:51:10 +00:00
|
|
|
fprintf(stderr, " [-f \"filter expression\"] [-i interface] [-m medium font] [-n]\n");
|
|
|
|
fprintf(stderr, " [-P packet list height] [-r infile] [-s snaplen]\n");
|
|
|
|
fprintf(stderr, " [-t <time stamp format>] [-T tree view height] [-w savefile] \n");
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
1998-11-17 04:29:13 +00:00
|
|
|
/* And now our feature presentation... [ fade to music ] */
|
1998-09-16 02:39:15 +00:00
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
Have Ethereal, when invoked as "ethereal-dump-fields", dump out a
glossary of display filter symbols, just as it does with "-G", except
that, as it can discover that it was so invoked before even looking at
the command-line arguments, it needn't even bother calling "gtk_init()"
to process those command-line arguments GTK+ cares about, and thus
needn't do any X stuff at all when so invoked.
That allows Ethereal to be built in an environment where you don't have
an X server, and, if your connection to your X server is slow, allows
you to built it faster.
Get rid of the "-G" flag, as it had only a somewhat specialized use.
svn path=/trunk/; revision=444
1999-08-05 06:34:43 +00:00
|
|
|
char *command_name;
|
1999-07-13 02:53:26 +00:00
|
|
|
int i;
|
|
|
|
#ifndef WIN32
|
|
|
|
int opt;
|
1998-09-16 02:39:15 +00:00
|
|
|
extern char *optarg;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1999-06-12 07:04:35 +00:00
|
|
|
char *pf_path;
|
|
|
|
int pf_open_errno = 0;
|
1999-06-15 03:46:46 +00:00
|
|
|
int err;
|
1998-09-16 02:39:15 +00:00
|
|
|
GtkWidget *window, *main_vbox, *menubar, *u_pane, *l_pane,
|
|
|
|
*bv_table, *bv_hscroll, *bv_vscroll, *stat_hbox,
|
1998-10-12 01:40:57 +00:00
|
|
|
*tv_scrollw, *filter_bt, *filter_te;
|
1999-07-22 21:14:13 +00:00
|
|
|
GtkStyle *pl_style;
|
1999-08-10 07:16:47 +00:00
|
|
|
GtkAccelGroup *accel;
|
|
|
|
GtkWidget *packet_sw;
|
1998-11-18 03:01:44 +00:00
|
|
|
gint pl_size = 280, tv_size = 95, bv_size = 75;
|
1999-08-10 07:16:47 +00:00
|
|
|
gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
|
1998-11-17 04:29:13 +00:00
|
|
|
e_prefs *prefs;
|
1999-07-22 21:14:13 +00:00
|
|
|
gchar **col_title;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1999-05-11 18:51:10 +00:00
|
|
|
ethereal_path = argv[0];
|
|
|
|
|
Have Ethereal, when invoked as "ethereal-dump-fields", dump out a
glossary of display filter symbols, just as it does with "-G", except
that, as it can discover that it was so invoked before even looking at
the command-line arguments, it needn't even bother calling "gtk_init()"
to process those command-line arguments GTK+ cares about, and thus
needn't do any X stuff at all when so invoked.
That allows Ethereal to be built in an environment where you don't have
an X server, and, if your connection to your X server is slow, allows
you to built it faster.
Get rid of the "-G" flag, as it had only a somewhat specialized use.
svn path=/trunk/; revision=444
1999-08-05 06:34:43 +00:00
|
|
|
/* If invoked as "ethereal-dump-fields", we dump out a glossary of
|
|
|
|
display filter symbols; we specify that by checking the name,
|
|
|
|
so that we can do so before looking at the argument list -
|
|
|
|
we don't want to look at the argument list, because we don't
|
|
|
|
want to call "gtk_init()", because we don't want to have to
|
|
|
|
do any X stuff just to do a build. */
|
1999-08-05 18:20:41 +00:00
|
|
|
command_name = strrchr(ethereal_path, '/');
|
Have Ethereal, when invoked as "ethereal-dump-fields", dump out a
glossary of display filter symbols, just as it does with "-G", except
that, as it can discover that it was so invoked before even looking at
the command-line arguments, it needn't even bother calling "gtk_init()"
to process those command-line arguments GTK+ cares about, and thus
needn't do any X stuff at all when so invoked.
That allows Ethereal to be built in an environment where you don't have
an X server, and, if your connection to your X server is slow, allows
you to built it faster.
Get rid of the "-G" flag, as it had only a somewhat specialized use.
svn path=/trunk/; revision=444
1999-08-05 06:34:43 +00:00
|
|
|
if (command_name == NULL)
|
|
|
|
command_name = ethereal_path;
|
|
|
|
else
|
|
|
|
command_name++;
|
|
|
|
if (strcmp(command_name, "ethereal-dump-fields") == 0) {
|
|
|
|
ethereal_proto_init();
|
|
|
|
proto_registrar_dump();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
1998-11-17 04:29:13 +00:00
|
|
|
/* Let GTK get its args */
|
|
|
|
gtk_init (&argc, &argv);
|
1999-05-11 18:51:10 +00:00
|
|
|
|
1999-06-12 07:04:35 +00:00
|
|
|
prefs = read_prefs(&pf_path);
|
|
|
|
if (pf_path != NULL) {
|
|
|
|
/* The preferences file exists, but couldn't be opened; "pf_path" is
|
|
|
|
its pathname. Remember "errno", as that says why the attempt
|
|
|
|
failed. */
|
|
|
|
pf_open_errno = errno;
|
|
|
|
}
|
1998-11-17 04:29:13 +00:00
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Initialize the capture file struct */
|
1999-04-06 16:24:50 +00:00
|
|
|
cf.plist = NULL;
|
1999-08-10 04:13:37 +00:00
|
|
|
cf.plist_end = NULL;
|
1999-04-06 16:24:50 +00:00
|
|
|
cf.wth = NULL;
|
|
|
|
cf.fh = NULL;
|
|
|
|
cf.dfilter = NULL;
|
1999-07-07 22:52:57 +00:00
|
|
|
cf.dfcode = NULL;
|
1999-07-09 04:18:36 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
cf.cfilter = NULL;
|
|
|
|
#endif
|
1999-04-06 16:24:50 +00:00
|
|
|
cf.iface = NULL;
|
|
|
|
cf.save_file = NULL;
|
|
|
|
cf.user_saved = 0;
|
1999-05-06 05:45:58 +00:00
|
|
|
cf.snap = MAX_PACKET_SIZE;
|
1999-04-06 16:24:50 +00:00
|
|
|
cf.count = 0;
|
|
|
|
cf.cinfo.num_cols = prefs->num_cols;
|
1999-07-28 03:29:02 +00:00
|
|
|
cf.cinfo.col_fmt = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
|
1999-04-06 16:24:50 +00:00
|
|
|
cf.cinfo.fmt_matx = (gboolean **) g_malloc(sizeof(gboolean *) * cf.cinfo.num_cols);
|
|
|
|
cf.cinfo.col_data = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
|
1999-07-28 03:29:02 +00:00
|
|
|
cf.cinfo.col_width = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
|
1998-11-17 04:29:13 +00:00
|
|
|
|
1998-12-27 20:47:53 +00:00
|
|
|
/* Assemble the compile-time options */
|
|
|
|
snprintf(comp_info_str, 256,
|
|
|
|
#ifdef GTK_MAJOR_VERSION
|
1999-07-09 04:18:36 +00:00
|
|
|
"GTK+ %d.%d.%d, %s libpcap", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
|
|
|
|
GTK_MICRO_VERSION,
|
1998-12-27 20:47:53 +00:00
|
|
|
#else
|
1999-07-09 04:18:36 +00:00
|
|
|
"GTK+ (version unknown), %s libpcap",
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
"with"
|
|
|
|
#else
|
|
|
|
"without"
|
1998-12-27 20:47:53 +00:00
|
|
|
#endif
|
1999-07-07 22:52:57 +00:00
|
|
|
);
|
1998-12-27 20:47:53 +00:00
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifndef WIN32
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Now get our args */
|
1999-08-08 01:29:24 +00:00
|
|
|
while ((opt = getopt(argc, argv, "b:B:c:f:Fhi:km:nP:Qr:R:Ss:t:T:w:v")) != EOF) {
|
1998-09-16 02:39:15 +00:00
|
|
|
switch (opt) {
|
|
|
|
case 'b': /* Bold font */
|
|
|
|
bold_font = g_strdup(optarg);
|
|
|
|
break;
|
|
|
|
case 'B': /* Byte view pane height */
|
|
|
|
bv_size = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'c': /* Capture xxx packets */
|
|
|
|
cf.count = atoi(optarg);
|
|
|
|
break;
|
1999-07-09 04:18:36 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-07-13 02:53:26 +00:00
|
|
|
case 'f':
|
1999-05-11 18:51:10 +00:00
|
|
|
cf.cfilter = g_strdup(optarg);
|
|
|
|
break;
|
|
|
|
case 'F': /* Fork to capture */
|
|
|
|
fork_mode = 1;
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'h': /* Print help and exit */
|
|
|
|
print_usage();
|
|
|
|
exit(0);
|
|
|
|
break;
|
|
|
|
case 'i': /* Use interface xxx */
|
|
|
|
cf.iface = g_strdup(optarg);
|
|
|
|
break;
|
|
|
|
case 'm': /* Medium font */
|
|
|
|
medium_font = g_strdup(optarg);
|
|
|
|
break;
|
|
|
|
case 'n': /* No name resolution */
|
|
|
|
g_resolving_actif = 0;
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'k': /* Start capture immediately */
|
|
|
|
start_capture = 1;
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'P': /* Packet list pane height */
|
|
|
|
pl_size = atoi(optarg);
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
case 'Q': /* Quit after capture (just capture to file) */
|
|
|
|
quit_after_cap = 1;
|
|
|
|
start_capture = 1; /*** -Q implies -k !! ***/
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'r': /* Read capture file xxx */
|
|
|
|
cf_name = g_strdup(optarg);
|
|
|
|
break;
|
1999-08-08 01:29:24 +00:00
|
|
|
case 'R': /* Read file filter */
|
|
|
|
rfilter = g_strdup(optarg);
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1998-09-16 02:39:15 +00:00
|
|
|
case 's': /* Set the snapshot (capture) length */
|
|
|
|
cf.snap = atoi(optarg);
|
|
|
|
break;
|
1999-05-11 18:51:10 +00:00
|
|
|
case 'S': /* "Sync" mode: used for following file ala tail -f */
|
|
|
|
sync_mode = 1;
|
|
|
|
fork_mode = 1; /* -S implies -F */
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-27 22:12:47 +00:00
|
|
|
case 't': /* Time stamp type */
|
|
|
|
if (strcmp(optarg, "r") == 0)
|
|
|
|
timestamp_type = RELATIVE;
|
|
|
|
else if (strcmp(optarg, "a") == 0)
|
|
|
|
timestamp_type = ABSOLUTE;
|
|
|
|
else if (strcmp(optarg, "d") == 0)
|
|
|
|
timestamp_type = DELTA;
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "ethereal: Invalid time stamp type \"%s\"\n",
|
|
|
|
optarg);
|
|
|
|
fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
|
|
|
|
fprintf(stderr, "or \"d\" for delta.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'T': /* Tree view pane height */
|
|
|
|
tv_size = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'v': /* Show version and exit */
|
1998-12-27 20:47:53 +00:00
|
|
|
printf("%s %s, with %s\n", PACKAGE, VERSION, comp_info_str);
|
1998-09-16 02:39:15 +00:00
|
|
|
exit(0);
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1998-09-16 02:39:15 +00:00
|
|
|
case 'w': /* Write capture file xxx */
|
|
|
|
cf.save_file = g_strdup(optarg);
|
|
|
|
break;
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1998-12-29 04:05:38 +00:00
|
|
|
|
1999-06-15 03:46:46 +00:00
|
|
|
if (start_capture) {
|
|
|
|
if (cf.iface == NULL) {
|
|
|
|
fprintf(stderr, "ethereal: \"-k\" flag was specified without \"-i\" flag\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (cf.save_file == NULL) {
|
|
|
|
fprintf(stderr, "ethereal: \"-k\" flag was specified without \"-w\" flag\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-07-13 02:53:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
1999-05-11 18:51:10 +00:00
|
|
|
if (sync_mode)
|
|
|
|
signal(SIGUSR2, sigusr2_handler);
|
1999-07-13 02:53:26 +00:00
|
|
|
#endif
|
1999-05-11 18:51:10 +00:00
|
|
|
|
1998-12-29 04:05:38 +00:00
|
|
|
/* Build the column format array */
|
1999-07-22 21:14:13 +00:00
|
|
|
col_title = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
1998-12-29 04:05:38 +00:00
|
|
|
for (i = 0; i < cf.cinfo.num_cols; i++) {
|
1999-07-28 03:29:02 +00:00
|
|
|
cf.cinfo.col_fmt[i] = get_column_format(i);
|
1999-07-22 21:14:13 +00:00
|
|
|
col_title[i] = g_strdup(get_column_title(i));
|
1998-12-29 04:05:38 +00:00
|
|
|
cf.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
|
|
|
|
NUM_COL_FMTS);
|
1999-07-28 03:29:02 +00:00
|
|
|
get_column_format_matches(cf.cinfo.fmt_matx[i], cf.cinfo.col_fmt[i]);
|
1998-12-29 04:05:38 +00:00
|
|
|
cf.cinfo.col_data[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
|
|
|
|
}
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
if (cf.snap < 1)
|
1999-02-11 06:17:30 +00:00
|
|
|
cf.snap = MAX_PACKET_SIZE;
|
|
|
|
else if (cf.snap < MIN_PACKET_SIZE)
|
|
|
|
cf.snap = MIN_PACKET_SIZE;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
rc_file = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(RC_FILE) + 4);
|
|
|
|
sprintf(rc_file, "%s/%s", getenv("HOME"), RC_FILE);
|
|
|
|
gtk_rc_parse(rc_file);
|
|
|
|
|
|
|
|
if ((m_r_font = gdk_font_load(medium_font)) == NULL) {
|
1999-06-15 03:46:46 +00:00
|
|
|
fprintf(stderr, "ethereal: Error font %s not found (use -m option)\n", medium_font);
|
1998-09-16 02:39:15 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((m_b_font = gdk_font_load(bold_font)) == NULL) {
|
1999-06-15 03:46:46 +00:00
|
|
|
fprintf(stderr, "ethereal: Error font %s not found (use -b option)\n", bold_font);
|
1998-09-16 02:39:15 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Main window */
|
|
|
|
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
|
|
gtk_widget_set_name(window, "main window");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(window), "delete_event",
|
|
|
|
GTK_SIGNAL_FUNC(file_quit_cmd_cb), "WM destroy");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(window), "destroy",
|
|
|
|
GTK_SIGNAL_FUNC(file_quit_cmd_cb), "WM destroy");
|
|
|
|
gtk_signal_connect(GTK_OBJECT (window), "realize",
|
1999-06-15 03:46:46 +00:00
|
|
|
GTK_SIGNAL_FUNC(main_realize_cb), NULL);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_window_set_title(GTK_WINDOW(window), "The Ethereal Network Analyzer");
|
|
|
|
gtk_widget_set_usize(GTK_WIDGET(window), DEF_WIDTH, -1);
|
1998-12-27 20:47:53 +00:00
|
|
|
gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
/* Container for menu bar, paned windows and progress/info box */
|
|
|
|
main_vbox = gtk_vbox_new(FALSE, 1);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
|
|
|
|
gtk_container_add(GTK_CONTAINER(window), main_vbox);
|
|
|
|
gtk_widget_show(main_vbox);
|
|
|
|
|
|
|
|
/* Menu bar */
|
|
|
|
get_main_menu(&menubar, &accel);
|
1998-12-17 05:42:33 +00:00
|
|
|
gtk_window_add_accel_group(GTK_WINDOW(window), accel);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show(menubar);
|
|
|
|
|
|
|
|
/* Panes for the packet list, tree, and byte view */
|
|
|
|
u_pane = gtk_vpaned_new();
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_paned_gutter_size(GTK_PANED(u_pane), (GTK_PANED(u_pane))->handle_size);
|
1998-09-16 02:39:15 +00:00
|
|
|
l_pane = gtk_vpaned_new();
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(main_vbox), u_pane);
|
|
|
|
gtk_widget_show(u_pane);
|
|
|
|
gtk_paned_add2 (GTK_PANED(u_pane), l_pane);
|
|
|
|
gtk_widget_show(l_pane);
|
|
|
|
|
|
|
|
/* Packet list */
|
1999-07-22 21:14:13 +00:00
|
|
|
packet_list = gtk_clist_new_with_titles(cf.cinfo.num_cols, col_title);
|
1998-11-17 04:29:13 +00:00
|
|
|
gtk_clist_column_titles_passive(GTK_CLIST(packet_list));
|
1998-12-17 05:42:33 +00:00
|
|
|
packet_sw = gtk_scrolled_window_new(NULL, NULL);
|
|
|
|
gtk_widget_show(packet_sw);
|
|
|
|
gtk_container_add(GTK_CONTAINER(packet_sw), packet_list);
|
1998-09-16 02:39:15 +00:00
|
|
|
pl_style = gtk_style_new();
|
|
|
|
gdk_font_unref(pl_style->font);
|
|
|
|
pl_style->font = m_r_font;
|
|
|
|
gtk_widget_set_style(packet_list, pl_style);
|
|
|
|
gtk_widget_set_name(packet_list, "packet list");
|
|
|
|
gtk_signal_connect(GTK_OBJECT(packet_list), "select_row",
|
|
|
|
GTK_SIGNAL_FUNC(packet_list_select_cb), NULL);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(packet_list), "unselect_row",
|
|
|
|
GTK_SIGNAL_FUNC(packet_list_unselect_cb), NULL);
|
1998-11-17 04:29:13 +00:00
|
|
|
for (i = 0; i < cf.cinfo.num_cols; i++) {
|
1999-07-28 03:29:02 +00:00
|
|
|
if (get_column_resize_type(cf.cinfo.col_fmt[i]) != RESIZE_MANUAL)
|
|
|
|
gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, TRUE);
|
|
|
|
|
|
|
|
/* Right-justify the packet number column. */
|
|
|
|
if (cf.cinfo.col_fmt[i] == COL_NUMBER)
|
1998-11-17 04:29:13 +00:00
|
|
|
gtk_clist_set_column_justification(GTK_CLIST(packet_list), i,
|
|
|
|
GTK_JUSTIFY_RIGHT);
|
1999-07-28 03:29:02 +00:00
|
|
|
|
|
|
|
/* Save static column sizes to use during a "-S" capture, so that
|
|
|
|
the columns don't resize during a live capture. */
|
|
|
|
cf.cinfo.col_width[i] = get_column_width(get_column_format(i),
|
|
|
|
pl_style->font);
|
1998-11-17 04:29:13 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_set_usize(packet_list, -1, pl_size);
|
1998-12-17 05:42:33 +00:00
|
|
|
gtk_paned_add1(GTK_PANED(u_pane), packet_sw);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_show(packet_list);
|
|
|
|
|
|
|
|
/* Tree view */
|
|
|
|
tv_scrollw = gtk_scrolled_window_new(NULL, NULL);
|
|
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tv_scrollw),
|
|
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_paned_add1(GTK_PANED(l_pane), tv_scrollw);
|
|
|
|
gtk_widget_set_usize(tv_scrollw, -1, tv_size);
|
|
|
|
gtk_widget_show(tv_scrollw);
|
|
|
|
|
|
|
|
tree_view = gtk_tree_new();
|
1998-12-17 05:42:33 +00:00
|
|
|
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(tv_scrollw),
|
|
|
|
tree_view);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_tree_set_selection_mode(GTK_TREE(tree_view), GTK_SELECTION_SINGLE);
|
|
|
|
gtk_tree_set_view_lines(GTK_TREE(tree_view), FALSE);
|
|
|
|
gtk_tree_set_view_mode(GTK_TREE(tree_view), TRUE);
|
|
|
|
gtk_signal_connect(GTK_OBJECT(tree_view), "selection_changed",
|
|
|
|
GTK_SIGNAL_FUNC(tree_view_cb), NULL);
|
|
|
|
gtk_widget_show(tree_view);
|
|
|
|
|
1998-12-29 04:05:38 +00:00
|
|
|
item_style = gtk_style_new();
|
|
|
|
gdk_font_unref(item_style->font);
|
|
|
|
item_style->font = m_r_font;
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
/* Byte view */
|
|
|
|
bv_table = gtk_table_new (2, 2, FALSE);
|
|
|
|
gtk_paned_add2(GTK_PANED(l_pane), bv_table);
|
|
|
|
gtk_widget_set_usize(bv_table, -1, bv_size);
|
|
|
|
gtk_widget_show(bv_table);
|
|
|
|
|
|
|
|
byte_view = gtk_text_new(NULL, NULL);
|
|
|
|
gtk_text_set_editable(GTK_TEXT(byte_view), FALSE);
|
|
|
|
gtk_text_set_word_wrap(GTK_TEXT(byte_view), FALSE);
|
|
|
|
gtk_table_attach (GTK_TABLE (bv_table), byte_view, 0, 1, 0, 1,
|
|
|
|
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
|
|
|
|
gtk_widget_show(byte_view);
|
|
|
|
|
|
|
|
bv_hscroll = gtk_hscrollbar_new(GTK_TEXT(byte_view)->hadj);
|
|
|
|
gtk_table_attach(GTK_TABLE(bv_table), bv_hscroll, 0, 1, 1, 2,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (bv_hscroll);
|
|
|
|
|
|
|
|
bv_vscroll = gtk_vscrollbar_new(GTK_TEXT(byte_view)->vadj);
|
|
|
|
gtk_table_attach(GTK_TABLE(bv_table), bv_vscroll, 1, 2, 0, 1,
|
|
|
|
GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
|
|
|
|
gtk_widget_show(bv_vscroll);
|
|
|
|
|
1998-10-12 01:40:57 +00:00
|
|
|
/* Progress/filter/info box */
|
1998-09-16 02:39:15 +00:00
|
|
|
stat_hbox = gtk_hbox_new(FALSE, 1);
|
|
|
|
gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
|
|
|
|
gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show(stat_hbox);
|
|
|
|
|
|
|
|
prog_bar = gtk_progress_bar_new();
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_box_pack_start(GTK_BOX(stat_hbox), prog_bar, FALSE, TRUE, 3);
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_show(prog_bar);
|
|
|
|
|
1998-10-12 01:40:57 +00:00
|
|
|
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(stat_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(stat_hbox), filter_te, TRUE, TRUE, 3);
|
1999-07-11 08:40:52 +00:00
|
|
|
gtk_signal_connect(GTK_OBJECT(filter_te), "activate",
|
|
|
|
GTK_SIGNAL_FUNC(filter_activate_cb), (gpointer) NULL);
|
1998-10-12 01:40:57 +00:00
|
|
|
gtk_widget_show(filter_te);
|
1998-11-18 03:17:18 +00:00
|
|
|
|
1999-06-15 04:48:57 +00:00
|
|
|
set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
|
1999-07-27 02:04:38 +00:00
|
|
|
set_menu_object_data("/File/Reload", E_DFILTER_TE_KEY, filter_te);
|
1999-03-01 18:57:07 +00:00
|
|
|
set_menu_object_data("/Tools/Follow TCP Stream", E_DFILTER_TE_KEY,
|
|
|
|
filter_te);
|
1998-09-16 02:39:15 +00:00
|
|
|
info_bar = gtk_statusbar_new();
|
|
|
|
main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
|
|
|
|
file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
|
|
|
|
gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
|
|
|
|
gtk_box_pack_start(GTK_BOX(stat_hbox), info_bar, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show(info_bar);
|
|
|
|
|
1999-02-19 05:28:38 +00:00
|
|
|
/*
|
|
|
|
Hmmm should we do it here
|
|
|
|
*/
|
|
|
|
|
|
|
|
ethereal_proto_init(); /* Init anything that needs initializing */
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_widget_show(window);
|
1999-04-06 16:24:50 +00:00
|
|
|
|
1999-06-15 03:46:46 +00:00
|
|
|
/* If we were given the name of a capture file, read it in now;
|
|
|
|
we defer it until now, so that, if we can't open it, and pop
|
|
|
|
up an alert box, the alert box is more likely to cmoe up on
|
|
|
|
top of the main window - but before the preference-file-error
|
|
|
|
alert box, so, if we get one of those, it's more likely to come
|
|
|
|
up on top of us. */
|
|
|
|
if (cf_name) {
|
1999-08-10 07:16:47 +00:00
|
|
|
err = load_cap_file(cf_name, rfilter, &cf);
|
1999-06-15 03:46:46 +00:00
|
|
|
cf_name[0] = '\0';
|
1999-08-10 07:16:47 +00:00
|
|
|
if (err == 0)
|
|
|
|
set_menu_sensitivity("/File/Save As...", TRUE);
|
1999-06-15 03:46:46 +00:00
|
|
|
}
|
|
|
|
|
1999-06-12 07:04:35 +00:00
|
|
|
/* If we failed to open the preferences file, pop up an alert box;
|
|
|
|
we defer it until now, so that the alert box is more likely to
|
|
|
|
come up on top of the main window. */
|
|
|
|
if (pf_path != NULL) {
|
|
|
|
simple_dialog(ESD_TYPE_WARN, NULL,
|
|
|
|
"Can't open preferences file\n\"%s\": %s.", pf_path,
|
|
|
|
strerror(pf_open_errno));
|
|
|
|
}
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
gtk_main();
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|