/* main.c
*
- * $Id: main.c,v 1.281 2003/02/17 07:50:49 oabad Exp $
+ * $Id: main.c,v 1.298 2003/06/22 16:07:23 deniel Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include <pcap.h>
#endif
-#ifdef HAVE_LIBZ
-#include <zlib.h> /* to get the libz version number */
-#endif
-
#ifdef NEED_SNPRINTF_H
# include "snprintf.h"
#endif
-#ifdef HAVE_SOME_SNMP
-
-#ifdef HAVE_NET_SNMP
-#include <net-snmp/version.h>
-#endif /* HAVE_NET_SNMP */
-
-#ifdef HAVE_UCD_SNMP
-#include <ucd-snmp/version.h>
-#endif /* HAVE_UCD_SNMP */
-
-#endif /* HAVE_SOME_SNMP */
-
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include "register.h"
#include "ringbuffer.h"
#include "ui_util.h"
-#include "../ui_util.h"
#include "image/clist_ascend.xpm"
#include "image/clist_descend.xpm"
#include "../tap.h"
+#include "../util.h"
#include "compat_macros.h"
#ifdef WIN32
PangoFontDescription *m_r_font, *m_b_font;
#endif
static guint main_ctx, file_ctx, help_ctx;
-static GString *comp_info_str;
+static GString *comp_info_str, *runtime_info_str;
gchar *ethereal_path = NULL;
gchar *last_open_dir = NULL;
gint root_x = G_MAXINT, root_y = G_MAXINT, top_width, top_height;
about_ethereal( GtkWidget *w _U_, gpointer data _U_ ) {
simple_dialog(ESD_TYPE_INFO, NULL,
"Ethereal - Network Protocol Analyzer\n"
- "Version " VERSION " (C) 1998-2002 Gerald Combs <gerald@ethereal.com>\n"
- "Compiled %s\n\n"
+ "Version " VERSION " (C) 1998-2003 Gerald Combs <gerald@ethereal.com>\n"
+ "%s\n%s\n\n"
"Check the man page for complete documentation and\n"
"for the list of contributors.\n"
"\nSee http://www.ethereal.com/ for more information.",
- comp_info_str->str);
+ comp_info_str->str, runtime_info_str->str);
}
#if GTK_MAJOR_VERSION < 2
hfinfo = finfo_selected->hfinfo;
g_assert(hfinfo);
if (hfinfo->type == FT_FRAMENUM) {
- framenum = fvalue_get_integer(finfo_selected->value);
- if (framenum != 0)
- packet_list_set_selected_row(framenum - 1);
+ framenum = fvalue_get_integer(finfo_selected->value);
+ if (framenum != 0)
+ goto_frame(&cfile, framenum);
}
}
}
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_OR_NOT,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_REPLACE,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_AND,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_OR,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_NOT,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_AND_NOT,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
void
if (finfo_selected)
match_selected_cb_do((data ? data : w),
MATCH_SELECTED_OR_NOT,
- proto_alloc_dfilter_string(finfo_selected, cfile.pd));
+ proto_construct_dfilter_string(finfo_selected, cfile.edt));
}
static gchar *
print_usage(gboolean print_ver) {
if (print_ver) {
- fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n",
- comp_info_str->str);
+ fprintf(stderr, "This is GNU " PACKAGE " " VERSION "\n%s\n%s\n",
+ comp_info_str->str, runtime_info_str->str);
}
#ifdef HAVE_LIBPCAP
- fprintf(stderr, "\n%s [ -vh ] [ -klpQS ] [ -a <capture autostop condition> ] ...\n",
+ fprintf(stderr, "\n%s [ -vh ] [ -klnpQS ] [ -a <capture autostop condition> ] ...\n",
PACKAGE);
- fprintf(stderr, "\t[ -b <number of ringbuffer files> ] [ -B <byte view height> ]\n");
- fprintf(stderr, "\t[ -c <count> ] [ -f <capture filter> ] [ -i <interface> ]\n");
- fprintf(stderr, "\t[ -m <medium font> ] [ -n ] [ -N <resolving> ]\n");
+ fprintf(stderr, "\t[ -b <number of ringbuffer files>[:<duration>] ]\n");
+ fprintf(stderr, "\t[ -B <byte view height> ] [ -c <count> ] [ -f <capture filter> ]\n");
+ fprintf(stderr, "\t[ -i <interface> ] [ -m <medium font> ] [ -N <resolving> ]\n");
fprintf(stderr, "\t[ -o <preference setting> ] ... [ -P <packet list height> ]\n");
fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -s <snaplen> ] \n");
fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ]\n");
fprintf(stderr, "\t[ -w <savefile> ] [ <infile> ]\n");
#else
- fprintf(stderr, "\n%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ]\n",
+ fprintf(stderr, "\n%s [ -vh ] [ -n ] [ -B <byte view height> ] [ -m <medium font> ]\n",
PACKAGE);
- fprintf(stderr, "\t[ -n ] [ -N <resolving> ]\n");
- fprintf(stderr, "\t[ -o <preference setting> ... [ -P <packet list height> ]\n");
- fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -t <time stamp format> ]\n");
- fprintf(stderr, "\t[ -T <tree view height> ] [ <infile> ]\n");
+ fprintf(stderr, "\t[ -N <resolving> ] [ -o <preference setting> ...\n");
+ fprintf(stderr, "\t[ -P <packet list height> ] [ -r <infile> ] [ -R <read filter> ]\n");
+ fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ] [ <infile> ]\n");
#endif
}
create_console();
#endif
- printf("%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
+ printf("%s %s\n%s\n%s\n", PACKAGE, VERSION, comp_info_str->str,
+ runtime_info_str->str);
}
static int
-get_positive_int(const char *string, const char *name)
+get_natural_int(const char *string, const char *name)
{
long number;
char *p;
name, string);
exit(1);
}
- if (number == 0) {
- fprintf(stderr, "ethereal: The specified %s \"%s\" is zero\n",
- name, string);
- exit(1);
- }
if (number > INT_MAX) {
fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
name, string, INT_MAX);
return number;
}
+static int
+get_positive_int(const char *string, const char *name)
+{
+ long number;
+
+ number = get_natural_int(string, name);
+
+ if (number == 0) {
+ fprintf(stderr, "ethereal: The specified %s is zero\n",
+ name);
+ exit(1);
+ }
+
+ return number;
+}
+
#ifdef HAVE_LIBPCAP
/*
* Given a string of the form "<autostop criterion>:<value>", as might appear
*colonp = ':'; /* put the colon back */
return TRUE;
}
+
+/*
+ * Given a string of the form "<ring buffer file>:<duration>", as might appear
+ * as an argument to a "-b" option, parse it and set the arguments in
+ * question. Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+static gboolean
+get_ring_arguments(const char *arg)
+{
+ guchar *p = NULL, *colonp;
+
+ colonp = strchr(arg, ':');
+
+ if (colonp != NULL) {
+ p = colonp;
+ *p++ = '\0';
+ }
+
+ capture_opts.ringbuffer_num_files =
+ get_natural_int(arg, "number of ring buffer files");
+
+ if (colonp == NULL)
+ return TRUE;
+
+ /*
+ * Skip over any white space (there probably won't be any, but
+ * as we allow it in the preferences file, we might as well
+ * allow it here).
+ */
+ while (isspace(*p))
+ p++;
+ if (*p == '\0') {
+ /*
+ * Put the colon back, so if our caller uses, in an
+ * error message, the string they passed us, the message
+ * looks correct.
+ */
+ *colonp = ':';
+ return FALSE;
+ }
+
+ capture_opts.has_ring_duration = TRUE;
+ capture_opts.ringbuffer_duration = get_positive_int(p,
+ "ring buffer duration");
+
+ *colonp = ':'; /* put the colon back */
+ return TRUE;
+}
#endif
-#if defined WIN32 || GTK_MAJOR_VERSION < 2
+#if defined WIN32 || GTK_MAJOR_VERSION < 2 || ! defined USE_THREADS
/*
Once every 3 seconds we get a callback here which we use to update
the tap extensions. Since Gtk1 is single threaded we dont have to
void
protect_thread_critical_region(void)
{
-#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2
+#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
g_static_mutex_lock(&update_thread_mutex);
#endif
}
void
unprotect_thread_critical_region(void)
{
-#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2
+#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2 && defined USE_THREADS
g_static_mutex_unlock(&update_thread_mutex);
#endif
}
static ethereal_tap_list *tap_list=NULL;
void
-register_ethereal_tap(char *cmd, void (*func)(char *arg), char *dummy _U_, void (*dummy2)(void) _U_)
+register_ethereal_tap(char *cmd, void (*func)(char *arg))
{
ethereal_tap_list *newtl;
int opt;
extern char *optarg;
gboolean arg_error = FALSE;
-#ifdef HAVE_LIBPCAP
-#ifdef HAVE_PCAP_VERSION
- extern char pcap_version[];
-#endif /* HAVE_PCAP_VERSION */
-#endif /* HAVE_LIBPCAP */
#ifdef WIN32
WSADATA wsaData;
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
+
+ /* Register all tap listeners; we do this before we parse the arguments,
+ as the "-z" argument can specify a registered tap. */
register_all_tap_listeners();
/* Now register the preferences for any non-dissector modules.
else if (strcmp(argv[2], "protocols") == 0)
proto_registrar_dump_protocols();
else {
- fprintf(stderr, "tethereal: Invalid \"%s\" option for -G flag\n",
+ fprintf(stderr, "ethereal: Invalid \"%s\" option for -G flag\n",
argv[2]);
exit(1);
}
}
/* multithread support currently doesn't seem to work in win32 gtk2.0.6 */
-#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2 && defined G_THREADS_ENABLED
+#if ! defined WIN32 && GTK_MAJOR_VERSION >= 2 && defined G_THREADS_ENABLED && defined USE_THREADS
{
GThread *ut;
g_thread_init(NULL);
ut=g_thread_create(update_thread, NULL, FALSE, NULL);
g_thread_set_priority(ut, G_THREAD_PRIORITY_LOW);
}
-#else /* WIN32 || GTK1.2 || !G_THREADS_ENABLED */
+#else /* WIN32 || GTK1.2 || !G_THREADS_ENABLED || !USE_THREADS */
/* this is to keep tap extensions updating once every 3 seconds */
gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
#endif /* !WIN32 && GTK2 && G_THREADS_ENABLED */
+#if HAVE_GNU_ADNS
+ gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL);
+#endif
+
+
/* Set the current locale according to the program environment.
* We haven't localized anything, but some GTK widgets are localized
* (the file selection dialogue, for example).
capture_opts.autostop_filesize = 1;
capture_opts.ringbuffer_on = FALSE;
capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
+ capture_opts.has_ring_duration = FALSE;
+ capture_opts.ringbuffer_duration = 1;
/* If this is a capture child process, it should pay no attention
to the "prefs.capture_prom_mode" setting in the preferences file;
init_cap_file(&cfile);
- /* Assemble the compile-time options */
- comp_info_str = g_string_new("");
-
+ /* Assemble the compile-time version information string */
+ comp_info_str = g_string_new("Compiled ");
g_string_append(comp_info_str, "with ");
g_string_sprintfa(comp_info_str,
#ifdef GTK_MAJOR_VERSION
"GTK+ (version unknown)");
#endif
- g_string_append(comp_info_str, ", with ");
- g_string_sprintfa(comp_info_str,
-#ifdef GLIB_MAJOR_VERSION
- "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
- GLIB_MICRO_VERSION);
-#else
- "GLib (version unknown)");
-#endif
+ g_string_append(comp_info_str, ", ");
+ get_compiled_version_info(comp_info_str);
-#ifdef HAVE_LIBPCAP
- g_string_append(comp_info_str, ", with libpcap ");
-#ifdef HAVE_PCAP_VERSION
- g_string_append(comp_info_str, pcap_version);
-#else /* HAVE_PCAP_VERSION */
- g_string_append(comp_info_str, "(version unknown)");
-#endif /* HAVE_PCAP_VERSION */
-#else /* HAVE_LIBPCAP */
- g_string_append(comp_info_str, ", without libpcap");
-#endif /* HAVE_LIBPCAP */
-
-#ifdef HAVE_LIBZ
- g_string_append(comp_info_str, ", with libz ");
-#ifdef ZLIB_VERSION
- g_string_append(comp_info_str, ZLIB_VERSION);
-#else /* ZLIB_VERSION */
- g_string_append(comp_info_str, "(version unknown)");
-#endif /* ZLIB_VERSION */
-#else /* HAVE_LIBZ */
- g_string_append(comp_info_str, ", without libz");
-#endif /* HAVE_LIBZ */
-
-/* Oh, this is pretty. */
-/* Oh, ha. you think that was pretty. Try this:! --Wes */
-#ifdef HAVE_SOME_SNMP
-
-#ifdef HAVE_UCD_SNMP
- g_string_append(comp_info_str, ", with UCD-SNMP ");
- g_string_append(comp_info_str, VersionInfo);
-#endif /* HAVE_UCD_SNMP */
-
-#ifdef HAVE_NET_SNMP
- g_string_append(comp_info_str, ", with Net-SNMP ");
- g_string_append(comp_info_str, netsnmp_get_version());
-#endif /* HAVE_NET_SNMP */
-
-#else /* no SNMP library */
- g_string_append(comp_info_str, ", without UCD-SNMP or Net-SNMP");
-#endif /* HAVE_SOME_SNMP */
+ /* Assemble the run-time version information string */
+ runtime_info_str = g_string_new("Running ");
+ get_runtime_version_info(runtime_info_str);
/* Now get our args */
while ((opt = getopt(argc, argv, optstring)) != -1) {
case 'b': /* Ringbuffer option */
#ifdef HAVE_LIBPCAP
capture_opts.ringbuffer_on = TRUE;
- capture_opts.ringbuffer_num_files =
- get_positive_int(optarg, "number of ring buffer files");
+ if (get_ring_arguments(optarg) == FALSE) {
+ fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
+ exit(1);
+ }
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
/* Build the column format array */
- col_init(&cfile.cinfo, prefs->num_cols);
+ col_setup(&cfile.cinfo, prefs->num_cols);
for (i = 0; i < cfile.cinfo.num_cols; i++) {
cfile.cinfo.col_fmt[i] = get_column_format(i);
cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
else
cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
+ cfile.cinfo.col_fence[i] = 0;
cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
}
to a file that our parent will read? */
if (!capture_child) {
#endif
- /* No. Pop up the main window, and read in a capture file if
+ /* No. Pop up the main window, register menus for taps (which we
+ must do after creating the main window, so that we can add
+ menu items to the main menu), and read in a capture file if
we were told to. */
-
create_main_window(pl_size, tv_size, bv_size, prefs);
+ register_all_tap_menus();
set_menus_for_capture_file(FALSE);
/* open tap windows after creating the main window to avoid GTK warnings */