diff options
-rw-r--r-- | AUTHORS | 7 | ||||
-rw-r--r-- | doc/ethereal.pod.template | 2 | ||||
-rw-r--r-- | gtk/capture_dlg.c | 165 | ||||
-rw-r--r-- | gtk/capture_prefs.c | 884 | ||||
-rw-r--r-- | pcap-util.c | 3 | ||||
-rw-r--r-- | pcap-util.h | 3 | ||||
-rw-r--r-- | prefs.c | 125 | ||||
-rw-r--r-- | prefs.h | 7 |
8 files changed, 1138 insertions, 58 deletions
@@ -1828,6 +1828,12 @@ Brian K. Teravskis <Brian_Teravskis [AT] Cargill.com> { Support for saving RTP analysis data in CSV form } +Nathan Jennings <njen [AT] bellsouth.net> { + Support for user-supplied interface descriptions + Support for hiding interfaces in drop-down list in capture + dialog +} + And assorted fixes and enhancements by the people listed above and by: Pavel Roskin <proski [AT] gnu.org> @@ -1838,7 +1844,6 @@ And assorted fixes and enhancements by the people listed above and by: Marcio Franco <franco.marcio [AT] rd.francetelecom.fr> Kaloian Stoilov <kalkata [AT] yahoo.com> Steven Lass <stevenlass [AT] mail.com> - Nathan Jennings <njen [AT] bellsouth.net> Gregory Stark <gsstark [AT] mit.edu> Darren Steele <steeley [AT] steeley.co.uk> <smhuang [AT] pcs.csie.nctu.edu.tw> diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index ac70f18ad7..8e3362c888 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -2073,6 +2073,7 @@ B<http://www.ethereal.com>. Jean-Michel Fayard <jean-michel.fayard [AT] moufrei.de> Josef Korelus <jkor [AT] quick.cz> Brian K. Teravskis <Brian_Teravskis [AT] Cargill.com> + Nathan Jennings <njen [AT] bellsouth.net> Pavel Roskin <proski [AT] gnu.org> Georgi Guninski <guninski [AT] guninski.com> Jason Copenhaver <jcopenha [AT] typedef.org> @@ -2081,7 +2082,6 @@ B<http://www.ethereal.com>. Marcio Franco <franco.marcio [AT] rd.francetelecom.fr> Kaloian Stoilov <kalkata [AT] yahoo.com> Steven Lass <stevenlass [AT] mail.com> - Nathan Jennings <njen [AT] bellsouth.net> Gregory Stark <gsstark [AT] mit.edu> Darren Steele <steeley [AT] steeley.co.uk> <smhuang [AT] pcs.csie.nctu.edu.tw> diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c index a6fa99f727..1331b69b14 100644 --- a/gtk/capture_dlg.c +++ b/gtk/capture_dlg.c @@ -1,7 +1,7 @@ /* capture_dlg.c * Routines for packet capture windows * - * $Id: capture_dlg.c,v 1.79 2003/07/25 04:11:50 gram Exp $ + * $Id: capture_dlg.c,v 1.80 2003/09/08 21:44:42 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -104,6 +104,15 @@ capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w); static void capture_prep_destroy_cb(GtkWidget *win, gpointer user_data); +static GList * +capture_dev_descr_add(GList *if_list); + +static char * +capture_dev_descr_find(gchar *devs_descr, gchar *if_name); + +static GList * +capture_dev_hide(GList *if_list); + void capture_stop_cb(GtkWidget *w _U_, gpointer d _U_) { @@ -221,8 +230,15 @@ capture_prep_cb(GtkWidget *w _U_, gpointer d _U_) gtk_widget_show(if_lb); if_cb = gtk_combo_new(); - if (if_list != NULL) + if (if_list != NULL) { + /* remove interface(s) from list if "hidden" */ + if (prefs.capture_devices_hide != NULL) + if_list = capture_dev_hide(if_list); + /* prepend interface descriptions to device name */ + if (prefs.capture_devices_descr != NULL) + if_list = capture_dev_descr_add(if_list); gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list); + } if (cfile.iface == NULL && prefs.capture_device != NULL) { /* No interface was specified on the command line or in a previous capture, but there is one specified in the preferences file; @@ -789,7 +805,9 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) { if_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry))); - /* Windows combo entries have a description followed by the interface name */ + /* Remove interface description. Also, Windows combo entries have a + description followed by the interface name. These two cases are + OK as long as they're in front (see capture_dev_descr_add()). */ if_name = strrchr(if_text, ' '); if (if_name == NULL) { if_name = if_text; @@ -1057,4 +1075,145 @@ capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w) } +/* + * Prepend capture devices description to interface list. Remove OS (pcap) + * supplied description if present. + */ +static GList * +capture_dev_descr_add(GList *if_list) +{ + + GList *if_new_list = NULL; + char *osd; + char *tmp_descr; + gchar *tmp_devs_descr; + gchar *tmp_dev_name; + guint i; + guint nitems; + + /* Seems we need to be at list head for g_list_length()? */ + if_list = g_list_first(if_list); + nitems = g_list_length(if_list); + + /* Create new interface list with "(descr) if_name". */ + for (i=0; i < nitems; i++) { + tmp_dev_name = g_list_nth_data(if_list, i); + /* should never happen, but just in case */ + if (tmp_dev_name == NULL) { + if (if_new_list != NULL) + free_interface_list(if_new_list); + return if_list; + } + /* create copy since capture_dev_descr_find() inserts terminator */ + tmp_devs_descr = g_strdup(prefs.capture_devices_descr); + /* find matching description */ + tmp_descr = capture_dev_descr_find(tmp_devs_descr, tmp_dev_name); + /* prepend description */ + if (tmp_descr != NULL) { + /* remove OS (pcap) description */ + if ((osd = strrchr(tmp_dev_name, ' ')) != NULL) { + osd++; + if (osd != NULL) + tmp_dev_name = osd; + } + if_new_list = g_list_append(if_new_list, + g_strdup_printf("%s %s", tmp_descr, tmp_dev_name)); + } + /* no description for this interface, just copy name */ + else { + if_new_list = g_list_append(if_new_list, g_strdup(tmp_dev_name)); + } + g_free(tmp_devs_descr); + } + + free_interface_list(if_list); + /* return pointer to new interface list with descriptions */ + return if_new_list; +} + +/* + * Find capture device description that matches interface name. + */ +static char * +capture_dev_descr_find(gchar *devs_descr, gchar *if_name) +{ + char *p; + char *p2 = NULL; + char *descr = NULL; + int lp = 0; + int ct = 0; + + if (if_name == NULL) + return NULL; + + if ((p = strstr(devs_descr, if_name)) == NULL) + return NULL; + + while (p != NULL) { + /* error: ran into next interface description */ + if (*p == ',') + return NULL; + /* found left parenthesis, start of description */ + else if (*p == '(') { + lp++; + /* save pointer to beginning of description */ + p2 = p; + p++; + continue; + } + else if (*p == ')') { + /* end of description */ + break; + } + else { + p++; + ct++; + } + } + + if ((lp == 1) && (ct > 0) && (p2 != NULL)) { + /* set returned pointer to beginning of description */ + descr = p2; + /* insert terminator */ + *(p+1) = '\0'; + return descr; + } + else + return NULL; +} + +/* + * Remove "hidden" interface(s) from list. + */ +static GList * +capture_dev_hide(GList *if_list) +{ + GList *if_new_list = NULL; + gchar *tmp_dev_name; + guint i; + guint nitems; + + /* Seems we need to be at list head for g_list_length()? */ + if_list = g_list_first(if_list); + nitems = g_list_length(if_list); + + /* Create new list without "hidden" interfaces. */ + for (i=0; i < nitems; i++) { + tmp_dev_name = g_list_nth_data(if_list, i); + /* should never happen, but just in case */ + if (tmp_dev_name == NULL) { + if (if_new_list != NULL) + free_interface_list(if_new_list); + return if_list; + } + /* check if interface name is in "hidden" preferences string */ + if (strstr(prefs.capture_devices_hide, tmp_dev_name) == NULL) + if_new_list = g_list_append(if_new_list, g_strdup(tmp_dev_name)); + } + + free_interface_list(if_list); + /* return pointer to new interface list */ + return if_new_list; +} + #endif /* HAVE_LIBPCAP */ diff --git a/gtk/capture_prefs.c b/gtk/capture_prefs.c index 1af5e6d19b..3c4f091071 100644 --- a/gtk/capture_prefs.c +++ b/gtk/capture_prefs.c @@ -1,7 +1,7 @@ /* capture_prefs.c * Dialog box for capture preferences * - * $Id: capture_prefs.c,v 1.17 2002/11/11 18:57:00 oabad Exp $ + * $Id: capture_prefs.c,v 1.18 2003/09/08 21:44:42 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -28,6 +28,7 @@ #ifdef HAVE_LIBPCAP +#include <string.h> #include <gtk/gtk.h> #include <pcap.h> @@ -38,21 +39,50 @@ #include "prefs.h" #include "prefs_dlg.h" #include "ui_util.h" +#include "simple_dialog.h" #include "pcap-util.h" #include "main.h" #include "compat_macros.h" -#define DEVICE_KEY "device" -#define PROM_MODE_KEY "prom_mode" +#define DEVICE_KEY "device" +#define PROM_MODE_KEY "prom_mode" #define CAPTURE_REAL_TIME_KEY "capture_real_time" -#define AUTO_SCROLL_KEY "auto_scroll" +#define AUTO_SCROLL_KEY "auto_scroll" + +#define DEVOPTS_CALLER_PTR_KEY "devopts_caller_ptr" +#define DEVOPTS_DIALOG_PTR_KEY "devopts_dialog_ptr" + +#define CAPTURE_TABLE_ROWS 5 +#define DEVICES_OPTS_ROWS 2 +#define IF_OPTS_CLIST_COLS 3 +#define IF_OPTS_MAX_DESCR_LEN 128 + +/* interface options dialog */ +static GtkWidget *new_clist, *if_descr_te, *if_hide_cb; +static gint ifrow; /* last interface row selected */ + +static void ifopts_edit_cb(GtkWidget *w, gpointer data); +static void ifopts_edit_ok_cb(GtkWidget *w, gpointer parent_w); +static void ifopts_edit_close_cb(GtkWidget *close_bt, gpointer parent_w); +static void ifopts_edit_destroy_cb(GtkWidget *win, gpointer data); +static void ifopts_edit_ifsel_cb(GtkWidget *clist, gint row, gint column, + GdkEventButton *event, gpointer data); +static void ifopts_edit_ifunsel_cb(GtkWidget *clist, gint row, gint column, + GdkEventButton *event, gpointer data); +static void ifopts_old_options_add(GtkCList *clist); +static gboolean ifopts_old_options_chk(GtkCList *clist, gchar *ifname); +static void ifopts_new_options_add(GtkCList *clist, gchar *ifname); +static void ifopts_options_free(gchar *text[]); +static void ifopts_if_clist_add(GtkCList *clist); +static void ifopts_write_new_descr(void); +static void ifopts_write_new_hide(void); -#define CAPTURE_TABLE_ROWS 4 GtkWidget* capture_prefs_show(void) { GtkWidget *main_tb, *main_vb; GtkWidget *if_cb, *if_lb, *promisc_cb, *sync_cb, *auto_scroll_cb; + GtkWidget *ifopts_lb, *ifopts_bt; GList *if_list; int err; char err_str[PCAP_ERRBUF_SIZE]; @@ -69,7 +99,7 @@ capture_prefs_show(void) gtk_widget_show(main_tb); /* Default device */ - if_lb = gtk_label_new("Interface:"); + if_lb = gtk_label_new("Default interface:"); gtk_table_attach_defaults(GTK_TABLE(main_tb), if_lb, 0, 1, 0, 1); gtk_misc_set_alignment(GTK_MISC(if_lb), 1.0, 0.5); gtk_widget_show(if_lb); @@ -90,20 +120,30 @@ capture_prefs_show(void) free_interface_list(if_list); + /* Interface options */ + ifopts_lb = gtk_label_new("Interface options:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), ifopts_lb, 0, 1, 1, 2); + gtk_misc_set_alignment(GTK_MISC(ifopts_lb), 1.0, 0.5); + gtk_widget_show(ifopts_lb); + + ifopts_bt = gtk_button_new_with_label("Edit..."); + SIGNAL_CONNECT(ifopts_bt, "clicked", ifopts_edit_cb, NULL); + gtk_table_attach_defaults(GTK_TABLE(main_tb), ifopts_bt, 1, 2, 1, 2 ); + /* Promiscuous mode */ - promisc_cb = create_preference_check_button(main_tb, 1, + promisc_cb = create_preference_check_button(main_tb, 2, "Capture packets in promiscuous mode:", NULL, prefs.capture_prom_mode); OBJECT_SET_DATA(main_vb, PROM_MODE_KEY, promisc_cb); /* Real-time capture */ - sync_cb = create_preference_check_button(main_tb, 2, + sync_cb = create_preference_check_button(main_tb, 3, "Update list of packets in real time:", NULL, prefs.capture_real_time); OBJECT_SET_DATA(main_vb, CAPTURE_REAL_TIME_KEY, sync_cb); /* Auto-scroll real-time capture */ - auto_scroll_cb = create_preference_check_button(main_tb, 3, + auto_scroll_cb = create_preference_check_button(main_tb, 4, "Automatic scrolling in live capture:", NULL, prefs.capture_auto_scroll); OBJECT_SET_DATA(main_vb, AUTO_SCROLL_KEY, auto_scroll_cb); @@ -154,8 +194,832 @@ capture_prefs_apply(GtkWidget *w _U_) } void -capture_prefs_destroy(GtkWidget *w _U_) +capture_prefs_destroy(GtkWidget *w) +{ + GtkWidget *caller = gtk_widget_get_toplevel(w); + GtkWidget *dlg; + + /* Is there an interface descriptions dialog associated with this + Preferences dialog? */ + dlg = OBJECT_GET_DATA(caller, DEVOPTS_DIALOG_PTR_KEY); + + if (dlg != NULL) { + /* Yes. Destroy it. */ + gtk_widget_destroy(dlg); + } +} + +/* Create an edit interface options dialog. */ +static void +ifopts_edit_cb(GtkWidget *w, gpointer data _U_) +{ + GtkWidget *ifopts_edit_dlg, *old_scr_win, *if_scr_win, *main_hb, *main_tb, + *old_opts_fr, *opts_fr, + *old_clist, *if_clist, *if_descr_lb, *if_hide_lb, + *bbox, *ok_bt, *cancel_bt; + gchar *old_titles[3] = { "Interface", "Description", "Hide?" }; + gchar *if_title[1] = { "Interface" }; + + GtkWidget *caller = gtk_widget_get_toplevel(w); + + /* Has an edit dialog box already been opened for that top-level + widget? */ + ifopts_edit_dlg = OBJECT_GET_DATA(caller, DEVOPTS_DIALOG_PTR_KEY); + if (ifopts_edit_dlg != NULL) { + /* Yes. Just re-activate that dialog box. */ + reactivate_window(ifopts_edit_dlg); + return; + } + + /* create a new dialog */ + ifopts_edit_dlg = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(ifopts_edit_dlg), + "Ethereal: Preferences: Interface Options"); + SIGNAL_CONNECT(ifopts_edit_dlg, "destroy", ifopts_edit_destroy_cb, NULL); + gtk_container_border_width(GTK_CONTAINER(GTK_DIALOG(ifopts_edit_dlg)->vbox), + 5); + + /* + * XXX - What code can be put here, or somewhere else, to get the Ethereal + * icon loaded for this window? + */ + + /* create old options frame */ + old_opts_fr = gtk_frame_new("Previously saved options"); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(ifopts_edit_dlg)->vbox), + old_opts_fr); + gtk_widget_show(old_opts_fr); + + /* create a scrolled window to pack the old options CList widget into */ + old_scr_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(old_scr_win), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_container_border_width(GTK_CONTAINER(old_scr_win), 3); + gtk_container_add(GTK_CONTAINER(old_opts_fr), old_scr_win); + gtk_widget_show(old_scr_win); + + /* create old options CList (previously saved options) */ + old_clist = gtk_clist_new_with_titles(3, old_titles); + gtk_clist_set_column_width(GTK_CLIST(old_clist), 0, 200); + gtk_clist_set_column_width(GTK_CLIST(old_clist), 1, 200); + gtk_clist_set_column_width(GTK_CLIST(old_clist), 2, 40); + gtk_clist_column_titles_passive(GTK_CLIST(old_clist)); + gtk_container_add(GTK_CONTAINER(old_scr_win), old_clist); + + /* add text to old options cells */ + ifopts_old_options_add(GTK_CLIST(old_clist)); + gtk_widget_show(old_clist); + + /* create new options CList to hold currently edited values */ + /* XXX - Since this is an "invisible" widget used only as a table + * for storing newly edited interface options, do we need to manually + * deallocate/free it? (It's never added to a window with + * gtk_container_add().) */ + new_clist = gtk_clist_new(3); + + /* create edit options frame */ + opts_fr = gtk_frame_new("Edit interface options"); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(ifopts_edit_dlg)->vbox), + opts_fr); + gtk_widget_show(opts_fr); + + main_hb = gtk_hbox_new(TRUE, 5); + gtk_container_border_width(GTK_CONTAINER(main_hb), 3); + gtk_container_add(GTK_CONTAINER(opts_fr), main_hb); + gtk_widget_show(main_hb); + + /* create a scrolled window to pack the interface CList widget into */ + if_scr_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(if_scr_win), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_box_pack_start(GTK_BOX(main_hb), if_scr_win, TRUE, TRUE, 0); + gtk_widget_show(if_scr_win); + + /* create interface CList */ + if_clist = gtk_clist_new_with_titles(1, if_title); + SIGNAL_CONNECT(if_clist, "select_row", ifopts_edit_ifsel_cb, if_clist); + SIGNAL_CONNECT(if_clist, "unselect_row", ifopts_edit_ifunsel_cb, if_clist); + gtk_clist_set_column_width(GTK_CLIST(if_clist), 0, 75); + gtk_clist_column_titles_passive(GTK_CLIST(if_clist)); + gtk_clist_set_selection_mode(GTK_CLIST(if_clist), GTK_SELECTION_SINGLE); + gtk_container_add(GTK_CONTAINER(if_scr_win), if_clist); + + /* initialize variable that saves the last selected row in "if_clist" */ + ifrow = -1; + + /* add text to interface cell */ + ifopts_if_clist_add(GTK_CLIST(if_clist)); + gtk_widget_show(if_clist); + + /* table to hold description text entry and hide button */ + main_tb = gtk_table_new(DEVICES_OPTS_ROWS, 2, FALSE); + gtk_box_pack_start(GTK_BOX(main_hb), main_tb, TRUE, FALSE, 10); + gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10); + gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10); + gtk_widget_show(main_tb); + + /* create interface description label and text entry */ + if_descr_lb = gtk_label_new("Description:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_lb, 0, 1, 0, 1); + gtk_misc_set_alignment(GTK_MISC(if_descr_lb), 1.0, 0.5); + gtk_widget_show(if_descr_lb); + + if_descr_te = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(if_descr_te), IF_OPTS_MAX_DESCR_LEN); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_te, 1, 2, 0, 1); + gtk_widget_show(if_descr_te); + + /* create hide interface label and button */ + if_hide_lb = gtk_label_new("Hide interface?:"); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_hide_lb, 0, 1, 1, 2); + gtk_misc_set_alignment(GTK_MISC(if_hide_lb), 1.0, 0.5); + gtk_widget_show(if_hide_lb); + + if_hide_cb = gtk_check_button_new(); + gtk_table_attach_defaults(GTK_TABLE(main_tb), if_hide_cb, 1, 2, 1, 2); + gtk_widget_show(if_hide_cb); + + /* 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), 10); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(ifopts_edit_dlg)->action_area), bbox, + TRUE, FALSE, 0); + gtk_widget_show(bbox); + +#if GTK_MAJOR_VERSION < 2 + ok_bt = gtk_button_new_with_label ("OK"); +#else + ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK); +#endif + + /* Connect the OK button to ifdescr_edit_ok_cb function */ + SIGNAL_CONNECT(ok_bt, "clicked", ifopts_edit_ok_cb, ifopts_edit_dlg); + GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT); + gtk_container_add(GTK_CONTAINER(bbox), ok_bt); + gtk_widget_grab_default(ok_bt); + gtk_widget_show(ok_bt); + +#if GTK_MAJOR_VERSION < 2 + cancel_bt = gtk_button_new_with_label ("Cancel"); +#else + cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL); +#endif + /* Connect the Cancel button to destroy the widget */ + SIGNAL_CONNECT(cancel_bt, "clicked", ifopts_edit_close_cb, ifopts_edit_dlg); + GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT); + gtk_container_add(GTK_CONTAINER(bbox), cancel_bt); + gtk_widget_show(cancel_bt); + + /* Call a handler when we're destroyed, so we can inform + our caller, if any, that we've been destroyed. */ + SIGNAL_CONNECT(ifopts_edit_dlg, "destroy", ifopts_edit_destroy_cb, NULL); + + /* Set the DEVOPTS_CALLER_PTR_KEY for the new dialog to point to + our caller. */ + OBJECT_SET_DATA(ifopts_edit_dlg, DEVOPTS_CALLER_PTR_KEY, caller); + + /* Set the DEVOPTS_DIALOG_PTR_KEY for the caller to point to us */ + OBJECT_SET_DATA(caller, DEVOPTS_DIALOG_PTR_KEY, ifopts_edit_dlg); + + /* Catch the "key_press_event" signal in the window, so that we can + catch the ESC key being pressed and act as if the "Cancel" button + had been selected. */ + /*dlg_set_cancel(ifopts_edit_dlg, cancel_bt);*/ + + gtk_widget_show(ifopts_edit_dlg); +} + +/* + * User selected "OK". Create/write preferences strings. + */ +static void +ifopts_edit_ok_cb(GtkWidget *w _U_, gpointer parent_w) +{ + + /* + * Update option values in "new" CList for the last selected interface. + * (Is there a function that returns the currently selected row?) + */ + if (ifrow != -1) + ifopts_edit_ifunsel_cb(NULL, ifrow, 0, NULL, NULL); + + /* create/write new interfaces description string */ + ifopts_write_new_descr(); + + /* create/write new "hidden" interfaces string */ + ifopts_write_new_hide(); + + /* Now nuke this window. */ + gtk_grab_remove(GTK_WIDGET(parent_w)); + gtk_widget_destroy(GTK_WIDGET(parent_w)); +} + +static void +ifopts_edit_close_cb(GtkWidget *close_bt _U_, gpointer parent_w) { + gtk_grab_remove(GTK_WIDGET(parent_w)); + gtk_widget_destroy(GTK_WIDGET(parent_w)); +} + +static void +ifopts_edit_destroy_cb(GtkWidget *win, gpointer data _U_) +{ + GtkWidget *caller; + + /* Get the widget that requested that we be popped up, if any. + (It should arrange to destroy us if it's destroyed, so + that we don't get a pointer to a non-existent window here.) */ + caller = OBJECT_GET_DATA(win, DEVOPTS_CALLER_PTR_KEY); + + if (caller != NULL) { + /* Tell it we no longer exist. */ + OBJECT_SET_DATA(caller, DEVOPTS_DIALOG_PTR_KEY, NULL); + } + + /* Now nuke this window. */ + gtk_grab_remove(GTK_WIDGET(win)); + gtk_widget_destroy(GTK_WIDGET(win)); +} + +/* + * Interface selected callback; update displayed widgets. + */ +static void +ifopts_edit_ifsel_cb(GtkWidget *clist _U_, + gint row, + gint column _U_, + GdkEventButton *event _U_, + gpointer data _U_) +{ + gchar *text; + + /* get/display the interface description from "new" CList */ + gtk_clist_get_text(GTK_CLIST(new_clist), row, 1, &text); + gtk_entry_set_text(GTK_ENTRY(if_descr_te), text); + + /* get/display the "hidden" button state from "new" CList */ + gtk_clist_get_text(GTK_CLIST(new_clist), row, 2, &text); + if (*text == '1') + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_hide_cb), TRUE); + else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(if_hide_cb), FALSE); + + /* save currently selected row so we can update its values on "OK". */ + ifrow = row; +} + +/* + * Interface unselected callback; update "new" CList values. + * + * NOTE: + * This is also called from "ifopts_edit_ok_cb" to update values in + * the "new" CList for the last selected interface; only "row" is passed + * as a valid value. Others are "NULL" or "0". + */ +static void +ifopts_edit_ifunsel_cb(GtkWidget *clist _U_, + gint row, + gint column _U_, + GdkEventButton *event _U_, + gpointer data _U_) +{ + gchar *text; + gchar state[2] = { '\0' }; + + /* get interface description and set value in "new" CList */ + text = gtk_editable_get_chars(GTK_EDITABLE(if_descr_te), 0, -1); + /* replace any reserved formatting characters "()," with spaces */ + g_strdelimit(text, "(),", ' '); + gtk_clist_set_text(GTK_CLIST(new_clist), row, 1, text); + g_free(text); + + /* get "hidden" button state and set value in "new" CList */ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(if_hide_cb)) == TRUE) + state[0] = '1'; + else + state[0] = '0'; + gtk_clist_set_text(GTK_CLIST(new_clist), row, 2, state); +} + +/* + * Add previously saved options to cells in "old" CList. + */ +static void +ifopts_old_options_add(GtkCList *clist) +{ + gchar *p; + gchar *ifnm; + gchar *desc; + gchar *pr_descr; + gchar *pr_hide; + gchar *text[3] = { '\0' }; + gint row; + gint ct; + + /* add interface descriptions and "hidden" yes/no text */ + if (prefs.capture_devices_descr != NULL) { + /* create working copy of device descriptions */ + pr_descr = g_strdup(prefs.capture_devices_descr); + p = pr_descr; + ifnm = p; + + while (*p != '\0') { + /* found comma, start of next interface(description) */ + if (*p == ',') { + /* add existing text */ + if (text[0] != NULL) { + row = gtk_clist_append(GTK_CLIST(clist), text); + gtk_clist_set_selectable(GTK_CLIST(clist), row, FALSE); + ifopts_options_free(text); + } + p++; + /* reset interface name pointer to start of new name */ + ifnm = p; + } + /* found left parenthesis, start of description */ + else if (*p == '(') { + /* terminate and set interface name text */ + *p = '\0'; + text[0] = g_strdup(ifnm); + /* check if interface is "hidden" */ + if (prefs.capture_devices_hide != NULL) { + if (strstr(prefs.capture_devices_hide, ifnm) != NULL) + text[2] = g_strdup("Yes"); + else + text[2] = g_strdup("No"); + } + else + text[2] = g_strdup("No"); + *p = '('; + p++; + /* if syntax error */ + if ((*p == '\0') || (*p == ',') || (*p == '(') || (*p == ')')) { + ifopts_options_free(text); + break; + } + /* save pointer to beginning of description */ + desc = p; + p++; + /* if syntax error */ + if ((*p == '\0') || (*p == ',') || (*p == '(') || (*p == ')')) { + ifopts_options_free(text); + break; + } + /* skip to end of description */ + while (*p != '\0') { + /* end of description */ + if (*p == ')') { + /* terminate and set description text */ + *p = '\0'; + text[1] = g_strdup(desc); + *p = ')'; + p++; + break; + } + p++; + } + /* if we reached last interface description, add text */ + if (*p == '\0') { + if (text[0] != NULL) { + row = gtk_clist_append(GTK_CLIST(clist), text); + gtk_clist_set_selectable(GTK_CLIST(clist), row, FALSE); + ifopts_options_free(text); + } + } + } + else + p++; + } + + g_free(pr_descr); + } + + /* + * Only add "hidden" interface yes/no text here; since we may not have + * any descriptions, but have "hidden" interfaces. + */ + if (prefs.capture_devices_hide != NULL) { + /* create working copy of hidden interfaces */ + pr_hide = g_strdup(prefs.capture_devices_hide); + p = pr_hide; + ifnm = p; + ct = 0; + + while (*p != '\0') { + /* found comma, start of next interface */ + if ((*p == ',') && (ct > 0)) { + /* terminate and set text */ + *p = '\0'; + text[0] = g_strdup(ifnm); + /* set empty description */ + text[1] = NULL; + /* set "hidden" text */ + text[2] = g_strdup("Yes"); + /* add text if not previously added */ + if (!ifopts_old_options_chk(GTK_CLIST(clist), text[0])) { + row = gtk_clist_append(GTK_CLIST(clist), text); + gtk_clist_set_selectable(GTK_CLIST(clist), row, FALSE); + } + ifopts_options_free(text); + *p = ','; + p++; + ifnm = p; + ct = 0; + } + p++; + ct++; + } + + /* if we reached last "hidden" interface in list */ + if (ct > 0) { + /* set text */ + text[0] = g_strdup(ifnm); + /* set empty description */ + text[1] = NULL; + /* set "hidden" text */ + text[2] = g_strdup("Yes"); + /* add text if not previously added */ + if (!ifopts_old_options_chk(GTK_CLIST(clist), text[0])) { + row = gtk_clist_append(GTK_CLIST(clist), text); + gtk_clist_set_selectable(GTK_CLIST(clist), row, FALSE); + } + ifopts_options_free(text); + } + + g_free(pr_hide); + } +} + +/* + * Check to see if interface has already been added to "old" options CList. + * Returns TRUE if it has, FALSE if it hasn't. + */ +static gboolean +ifopts_old_options_chk(GtkCList *clist, gchar *ifname) +{ + gint i; + gchar *ifnm; + + /* get interface name for each row */ + for (i = 0; ;i++) { + if (gtk_clist_get_text(GTK_CLIST(clist), i, 0, &ifnm) != 1) + break; + if (strcmp(ifnm, ifname) == 0) + return TRUE; + } + + return FALSE; +} + +/* + * Add any old options that apply to cells in "new" CList. The "new" CList + * is never displayed. It's used only as a table to store values as they're + * edited by the user. + * + * NOTE: Be careful here since interfaces may have been removed from the + * machine or disabled and no longer apply. + */ +static void +ifopts_new_options_add(GtkCList *clist, gchar *ifname) +{ + gchar *p; + gchar *ifnm; + gchar *desc; + gchar *pr_descr; + gchar *text[3] = { '\0' }; + + /* add interface descriptions and "hidden" flag */ + if (prefs.capture_devices_descr != NULL) { + /* create working copy of device descriptions */ + pr_descr = g_strdup(prefs.capture_devices_descr); + + /* if we find a description for this interface */ + if ((ifnm = strstr(pr_descr, ifname)) != NULL) { + p = ifnm; + while (*p != '\0') { + /* found left parenthesis, start of description */ + if (*p == '(') { + /* set interface name text */ + text[0] = g_strdup(ifname); + /* check if interface is "hidden" */ + if (prefs.capture_devices_hide != NULL) { + if (strstr(prefs.capture_devices_hide, ifname) != NULL) + text[2] = g_strdup("1"); + else + text[2] = g_strdup("0"); + } + else + text[2] = g_strdup("0"); + p++; + /* if syntax error */ + if ((*p == '\0') || (*p == ',') || (*p == '(') || (*p == ')')) { + ifopts_options_free(text); + break; + } + /* save pointer to beginning of description */ + desc = p; + p++; + /* if syntax error */ + if ((*p == '\0') || (*p == ',') || (*p == '(') || (*p == ')')) { + ifopts_options_free(text); + break; + } + /* skip to end of description */ + while (*p != '\0') { + /* end of description */ + if (*p == ')') { + /* terminate and set description text */ + *p = '\0'; + text[1] = g_strdup(desc); + /* add row to CList */ + gtk_clist_append(GTK_CLIST(clist), text); + ifopts_options_free(text); + break; + } + p++; + } + /* get out */ + break; + } + else + p++; + } + } + /* if there's no description for this interface */ + else { + /* set interface name */ + text[0] = g_strdup(ifname); + /* set empty description */ + text[1] = NULL; + /* check if interface is "hidden" */ + if (prefs.capture_devices_hide != NULL) { + if (strstr(prefs.capture_devices_hide, ifname) != NULL) + text[2] = g_strdup("1"); + else + text[2] = g_strdup("0"); + } + else + text[2] = g_strdup("0"); + + /* add row to CList */ + gtk_clist_append(GTK_CLIST(clist), text); + ifopts_options_free(text); + } + + g_free(pr_descr); + } + /* + * If we do not have any descriptions, but have "hidden" interfaces. + */ + else if (prefs.capture_devices_hide != NULL) { + /* set interface name */ + text[0] = g_strdup(ifname); + /* set empty description */ + text[1] = NULL; + /* check if interface is "hidden" */ + if (strstr(prefs.capture_devices_hide, ifname) != NULL) + text[2] = g_strdup("1"); + else + text[2] = g_strdup("0"); + + /* add row to CList */ + gtk_clist_append(GTK_CLIST(clist), text); + ifopts_options_free(text); + } + /* + * If we have no descriptions and no "hidden" interfaces. + */ + else { + /* set interface name */ + text[0] = g_strdup(ifname); + /* set empty description */ + text[1] = NULL; + /* interface is not "hidden" */ + text[2] = g_strdup("0"); + + /* add row to CList */ + gtk_clist_append(GTK_CLIST(clist), text); + ifopts_options_free(text); + } +} + +static void +ifopts_options_free(gchar *text[]) +{ + gint i; + + for (i=0; i < IF_OPTS_CLIST_COLS; i++) { + if (text[i] != NULL) { + g_free(text[i]); + text[i] = NULL; + } + } +} + +/* + * Add interfaces to displayed interfaces CList. Also, fill "new" options CList. + */ +static void +ifopts_if_clist_add(GtkCList *clist) +{ + GList *if_list; + int err; + char err_str[PCAP_ERRBUF_SIZE]; + gchar *text[1]; + guint i; + guint nitems; + + if_list = get_interface_list(&err, err_str); + if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) { + simple_dialog(ESD_TYPE_WARN, NULL, "Can't get list of interfaces: %s", + err_str); + return; + } + + /* Seems we need to be at list head for g_list_length()? */ + if_list = g_list_first(if_list); + nitems = g_list_length(if_list); + + /* add interface name text to CList */ + for (i=0; i < nitems; i++) { + text[0] = g_list_nth_data(if_list, i); + /* should never happen, but just in case */ + if (text[0] == NULL) + continue; + gtk_clist_append(GTK_CLIST(clist), text); + /* fill "new" options CList with previously saved values */ + ifopts_new_options_add(GTK_CLIST(new_clist), text[0]); + } + + free_interface_list(if_list); +} + +/* + * Create/write new interfaces description string based on "new" CList. + */ +static void +ifopts_write_new_descr(void) +{ + gint i; + gint first_if = 1; /* flag to check if 1st in list */ + gchar *ifnm; + gchar *desc; + gchar *tmp_descr; + gchar *new_descr; + + /* new preferences interfaces description string */ + new_descr = g_malloc0(MAX_VAL_LEN); + if (new_descr == NULL) { + simple_dialog(ESD_TYPE_WARN, NULL, "Error (1) saving interface " + "descriptions: malloc failure"); + return; + } + + /* + * current row's interface description string + * (leave space for parens, comma and terminator) + */ + /* + * XXX - Currently, MAX_WIN_IF_NAME_LEN is 511. This should be large + * enough for *nix. ;o) + */ + tmp_descr = g_malloc0(IF_OPTS_MAX_DESCR_LEN + MAX_WIN_IF_NAME_LEN + 4); + if (tmp_descr == NULL) { + simple_dialog(ESD_TYPE_WARN, NULL, "Error (2) saving interface " + "descriptions: malloc failure"); + g_free(new_descr); + return; + } + + /* get description for each row (interface) */ + for (i = 0; ;i++) { + /* get description */ + if (gtk_clist_get_text(GTK_CLIST(new_clist), i, 1, &desc) != 1) + break; + /* if no description, skip this interface */ + if (strlen(desc) == 0) + continue; + /* get interface name */ + gtk_clist_get_text(GTK_CLIST(new_clist), i, 0, &ifnm); + + /* + * create/cat interface description to new string + * (leave space for parens, comma and terminator) + */ + if ((strlen(ifnm) + strlen(desc) + 4 + + strlen(new_descr)) < MAX_VAL_LEN) { + if (first_if == 1) + snprintf(tmp_descr, IF_OPTS_MAX_DESCR_LEN+MAX_WIN_IF_NAME_LEN+4, + "%s(%s)", ifnm, desc); + else + snprintf(tmp_descr, IF_OPTS_MAX_DESCR_LEN+MAX_WIN_IF_NAME_LEN+4, + ",%s(%s)", ifnm, desc); + strcat(new_descr, tmp_descr); + /* set first-in-list flag to false */ + first_if = 0; + } + /* interface name + description is too large */ + else { + simple_dialog(ESD_TYPE_WARN, NULL, "Error saving interface " + "description for:\n%s\n(too long)", ifnm); + continue; + } + } + + /* write new description string to preferences */ + if (strlen(new_descr) > 0) { + g_free(prefs.capture_devices_descr); + prefs.capture_devices_descr = new_descr; + } + /* no descriptions */ + else { + g_free(prefs.capture_devices_descr); + g_free(new_descr); + prefs.capture_devices_descr = NULL; + } +} + +/* + * Create/write new "hidden" interfaces string based on "new" CList. + */ +static void +ifopts_write_new_hide(void) +{ + gint i; + gint first_if = 1; /* flag to check if 1st in list */ + gchar *ifnm; + gchar *hide; + gchar *tmp_hide; + gchar *new_hide; + + /* new preferences "hidden" interfaces string */ + new_hide = g_malloc0(MAX_VAL_LEN); + if (new_hide == NULL) { + simple_dialog(ESD_TYPE_WARN, NULL, "Error (1) saving \"hidden\" " + "interfaces: malloc failure"); + return; + } + + /* + * current row's interface name if "hidden" + * (leave space for comma and terminator) + */ + /* + * XXX - Currently, MAX_WIN_IF_NAME_LEN is 511. This should be large + * enough for *nix. ;o) + */ + tmp_hide = g_malloc0(MAX_WIN_IF_NAME_LEN + 2); + if (tmp_hide == NULL) { + simple_dialog(ESD_TYPE_WARN, NULL, "Error (2) saving \"hidden\" " + "interfaces: malloc failure"); + g_free(new_hide); + return; + } + + /* get "hidden" flag for each row (interface) */ + for (i = 0; ;i++) { + /* get flag */ + if (gtk_clist_get_text(GTK_CLIST(new_clist), i, 2, &hide) != 1) + break; + /* if flag is not "1", skip this interface */ + if (*hide == '0') + continue; + /* get interface name */ + gtk_clist_get_text(GTK_CLIST(new_clist), i, 0, &ifnm); + + /* + * create/cat interface to new string + * (leave space for comma and terminator) + */ + if ((strlen(ifnm) + 2 + strlen(new_hide)) < MAX_VAL_LEN) { + if (first_if == 1) + snprintf(tmp_hide, MAX_WIN_IF_NAME_LEN+2, "%s", ifnm); + else + snprintf(tmp_hide, MAX_WIN_IF_NAME_LEN+2, ",%s", ifnm); + strcat(new_hide, tmp_hide); + /* set first-in-list flag to false */ + first_if = 0; + } + /* interface name is too large */ + else { + simple_dialog(ESD_TYPE_WARN, NULL, "Error saving \"hidden\" " + "interface for:\n%s\n(too long)", ifnm); + continue; + } + } + + /* write new "hidden" string to preferences */ + if (strlen(new_hide) > 0) { + g_free(prefs.capture_devices_hide); + prefs.capture_devices_hide = new_hide; + } + /* no "hidden" interfaces */ + else { + g_free(prefs.capture_devices_hide); + g_free(new_hide); + prefs.capture_devices_hide = NULL; + } } #endif /* HAVE_LIBPCAP */ diff --git a/pcap-util.c b/pcap-util.c index 364971f285..318dfb3976 100644 --- a/pcap-util.c +++ b/pcap-util.c @@ -1,7 +1,7 @@ /* pcap-util.c * Utility routines for packet capture * - * $Id: pcap-util.c,v 1.14 2003/07/06 00:07:58 guy Exp $ + * $Id: pcap-util.c,v 1.15 2003/09/08 21:44:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -398,7 +398,6 @@ search_for_if_cb(gpointer data, gpointer user_data) search_user_data->found = TRUE; } #else /* Windows */ -#define MAX_WIN_IF_NAME_LEN 511 GList * get_interface_list(int *err, char *err_str) { GList *il = NULL; diff --git a/pcap-util.h b/pcap-util.h index 64f99f32e3..38a6495646 100644 --- a/pcap-util.h +++ b/pcap-util.h @@ -1,7 +1,7 @@ /* pcap-util.h * Utility definitions for packet capture * - * $Id: pcap-util.h,v 1.2 2002/08/28 21:00:40 jmayer Exp $ + * $Id: pcap-util.h,v 1.3 2003/09/08 21:44:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -33,6 +33,7 @@ extern "C" { int get_pcap_linktype(pcap_t *pch, char *devname); +#define MAX_WIN_IF_NAME_LEN 511 GList *get_interface_list(int *err, char *err_str); /* Error values from "get_interface_list()". */ @@ -1,7 +1,7 @@ /* prefs.c * Routines for handling preferences * - * $Id: prefs.c,v 1.105 2003/08/26 05:56:43 guy Exp $ + * $Id: prefs.c,v 1.106 2003/09/08 21:44:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -842,8 +842,6 @@ print.file: /a/very/long/path/ * */ -#define MAX_VAR_LEN 48 -#define MAX_VAL_LEN 1024 #define DEF_NUM_COLS 6 @@ -981,6 +979,8 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return, /* set the default values for the capture dialog box */ prefs.capture_device = NULL; + prefs.capture_devices_descr = NULL; + prefs.capture_devices_hide = NULL; prefs.capture_prom_mode = TRUE; prefs.capture_real_time = FALSE; prefs.capture_auto_scroll = FALSE; @@ -1273,10 +1273,12 @@ prefs_set_pref(char *prefarg) #define PRS_CAP_NAME_RESOLVE "capture.name_resolve" /* values for the capture dialog box */ -#define PRS_CAP_DEVICE "capture.device" -#define PRS_CAP_PROM_MODE "capture.prom_mode" -#define PRS_CAP_REAL_TIME "capture.real_time_update" -#define PRS_CAP_AUTO_SCROLL "capture.auto_scroll" +#define PRS_CAP_DEVICE "capture.device" +#define PRS_CAP_DEVICES_DESCR "capture.devices_descr" +#define PRS_CAP_DEVICES_HIDE "capture.devices_hide" +#define PRS_CAP_PROM_MODE "capture.prom_mode" +#define PRS_CAP_REAL_TIME "capture.real_time_update" +#define PRS_CAP_AUTO_SCROLL "capture.auto_scroll" #define RED_COMPONENT(x) ((((x) >> 16) & 0xff) * 65535 / 255) #define GREEN_COMPONENT(x) ((((x) >> 8) & 0xff) * 65535 / 255) @@ -1535,6 +1537,14 @@ set_pref(gchar *pref_name, gchar *value) if (prefs.capture_device != NULL) g_free(prefs.capture_device); prefs.capture_device = g_strdup(value); + } else if (strcmp(pref_name, PRS_CAP_DEVICES_DESCR) == 0) { + if (prefs.capture_devices_descr != NULL) + g_free(prefs.capture_devices_descr); + prefs.capture_devices_descr = g_strdup(value); + } else if (strcmp(pref_name, PRS_CAP_DEVICES_HIDE) == 0) { + if (prefs.capture_devices_hide != NULL) + g_free(prefs.capture_devices_hide); + prefs.capture_devices_hide = g_strdup(value); } else if (strcmp(pref_name, PRS_CAP_PROM_MODE) == 0) { prefs.capture_prom_mode = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); } else if (strcmp(pref_name, PRS_CAP_REAL_TIME) == 0) { @@ -1945,22 +1955,21 @@ write_prefs(char **pf_path_return) "# This file is regenerated each time preferences are saved within\n" "# Ethereal. Making manual changes should be safe, however.\n" "\n" - "######## Printing ########\n" - "\n", pf); + "######## Printing ########\n", pf); - fprintf (pf, "# Can be one of \"text\" or \"postscript\".\n" - "print.format: %s\n\n", pr_formats[prefs.pr_format]); + fprintf (pf, "\n# Can be one of \"text\" or \"postscript\".\n" + "print.format: %s\n", pr_formats[prefs.pr_format]); - fprintf (pf, "# Can be one of \"command\" or \"file\".\n" - "print.destination: %s\n\n", pr_dests[prefs.pr_dest]); + fprintf (pf, "\n# Can be one of \"command\" or \"file\".\n" + "print.destination: %s\n", pr_dests[prefs.pr_dest]); - fprintf (pf, "# This is the file that gets written to when the " + fprintf (pf, "\n# This is the file that gets written to when the " "destination is set to \"file\"\n" - "%s: %s\n\n", PRS_PRINT_FILE, prefs.pr_file); + "%s: %s\n", PRS_PRINT_FILE, prefs.pr_file); - fprintf (pf, "# Output gets piped to this command when the destination " + fprintf (pf, "\n# Output gets piped to this command when the destination " "is set to \"command\"\n" - "%s: %s\n\n", PRS_PRINT_CMD, prefs.pr_cmd); + "%s: %s\n", PRS_PRINT_CMD, prefs.pr_cmd); clp = prefs.col_list; col_l = NULL; @@ -1970,16 +1979,16 @@ write_prefs(char **pf_path_return) col_l = g_list_append(col_l, cfmt->fmt); clp = clp->next; } - fprintf (pf, "# Packet list column format. Each pair of strings consists " - "of a column title \n# and its format.\n" - "%s: %s\n\n", PRS_COL_FMT, put_string_list(col_l)); + fprintf (pf, "\n# Packet list column format.\n"); + fprintf (pf, "# Each pair of strings consists of a column title and its format.\n"); + fprintf (pf, "%s: %s\n", PRS_COL_FMT, put_string_list(col_l)); /* This frees the list of strings, but not the strings to which it refers; that's what we want, as we haven't copied those strings, we just referred to them. */ g_list_free(col_l); - fprintf (pf, "# TCP stream window color preferences. Each value is a six " - "digit hexadecimal value in the form rrggbb.\n"); + fprintf (pf, "\n# TCP stream window color preferences.\n"); + fprintf (pf, "# Each value is a six digit hexadecimal color value in the form rrggbb.\n"); fprintf (pf, "%s: %02x%02x%02x\n", PRS_STREAM_CL_FG, (prefs.st_client_fg.red * 255 / 65535), (prefs.st_client_fg.green * 255 / 65535), @@ -1997,39 +2006,46 @@ write_prefs(char **pf_path_return) (prefs.st_server_bg.green * 255 / 65535), (prefs.st_server_bg.blue * 255 / 65535)); - fprintf(pf, "\n# Vertical scrollbars should be on right side? TRUE/FALSE\n"); + fprintf(pf, "\n# Vertical scrollbars should be on right side?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_SCROLLBAR_ON_RIGHT ": %s\n", prefs.gui_scrollbar_on_right == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Packet-list selection bar can be used to browse w/o selecting? TRUE/FALSE\n"); + fprintf(pf, "\n# Packet-list selection bar can be used to browse w/o selecting?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_PLIST_SEL_BROWSE ": %s\n", prefs.gui_plist_sel_browse == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Protocol-tree selection bar can be used to browse w/o selecting? TRUE/FALSE\n"); + fprintf(pf, "\n# Protocol-tree selection bar can be used to browse w/o selecting?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_PTREE_SEL_BROWSE ": %s\n", prefs.gui_ptree_sel_browse == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Alternating colors in TreeViews\n"); + fprintf(pf, "\n# Alternating colors in TreeViews?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_ALTERN_COLORS ": %s\n", prefs.gui_altern_colors == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Protocol-tree line style. One of: NONE, SOLID, DOTTED, TABBED\n"); + fprintf(pf, "\n# Protocol-tree line style.\n"); + fprintf(pf, "# One of: NONE, SOLID, DOTTED, TABBED\n"); fprintf(pf, PRS_GUI_PTREE_LINE_STYLE ": %s\n", gui_ptree_line_style_text[prefs.gui_ptree_line_style]); - fprintf(pf, "\n# Protocol-tree expander style. One of: NONE, SQUARE, TRIANGLE, CIRCULAR\n"); + fprintf(pf, "\n# Protocol-tree expander style.\n"); + fprintf(pf, "# One of: NONE, SQUARE, TRIANGLE, CIRCULAR\n"); fprintf(pf, PRS_GUI_PTREE_EXPANDER_STYLE ": %s\n", gui_ptree_expander_style_text[prefs.gui_ptree_expander_style]); - fprintf(pf, "\n# Hex dump highlight style. One of: BOLD, INVERSE\n"); + fprintf(pf, "\n# Hex dump highlight style.\n"); + fprintf(pf, "# One of: BOLD, INVERSE\n"); fprintf(pf, PRS_GUI_HEX_DUMP_HIGHLIGHT_STYLE ": %s\n", gui_hex_dump_highlight_style_text[prefs.gui_hex_dump_highlight_style]); fprintf(pf, "\n# Font name for packet list, protocol tree, and hex dump panes.\n"); fprintf(pf, PRS_GUI_FONT_NAME ": %s\n", prefs.gui_font_name); - fprintf (pf, "\n# Color preferences for a marked frame. Each value is a six " - "digit hexadecimal value in the form rrggbb.\n"); + fprintf (pf, "\n# Color preferences for a marked frame.\n"); + fprintf (pf, "# Each value is a six digit hexadecimal color value in the form rrggbb.\n"); fprintf (pf, "%s: %02x%02x%02x\n", PRS_GUI_MARKED_FG, (prefs.gui_marked_fg.red * 255 / 65535), (prefs.gui_marked_fg.green * 255 / 65535), @@ -2039,15 +2055,18 @@ write_prefs(char **pf_path_return) (prefs.gui_marked_bg.green * 255 / 65535), (prefs.gui_marked_bg.blue * 255 / 65535)); - fprintf(pf, "\n# Save window position at exit? TRUE/FALSE\n"); + fprintf(pf, "\n# Save window position at exit?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_GEOMETRY_SAVE_POSITION ": %s\n", prefs.gui_geometry_save_position == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Save window size at exit? TRUE/FALSE\n"); + fprintf(pf, "\n# Save window size at exit?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_GUI_GEOMETRY_SAVE_SIZE ": %s\n", prefs.gui_geometry_save_size == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Main window geometry. Decimal integers.\n"); + fprintf(pf, "\n# Main window geometry.\n"); + fprintf(pf, "# Decimal integers.\n"); fprintf(pf, PRS_GUI_GEOMETRY_MAIN_X ": %d\n", prefs.gui_geometry_main_x); fprintf(pf, PRS_GUI_GEOMETRY_MAIN_Y ": %d\n", prefs.gui_geometry_main_y); fprintf(pf, PRS_GUI_GEOMETRY_MAIN_WIDTH ": %d\n", @@ -2055,10 +2074,13 @@ write_prefs(char **pf_path_return) fprintf(pf, PRS_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n", prefs.gui_geometry_main_height); - fprintf(pf, "\n# Resolve addresses to names? TRUE/FALSE/{list of address types to resolve}\n"); + fprintf(pf, "\n# Resolve addresses to names?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive), or a list of address types to resolve.\n"); fprintf(pf, PRS_NAME_RESOLVE ": %s\n", name_resolve_to_string(prefs.name_resolve)); - fprintf(pf, "\n# Name resolution concurrency Decimal integer.\n"); + + fprintf(pf, "\n# Name resolution concurrency.\n"); + fprintf(pf, "# A decimal number.\n"); fprintf(pf, PRS_NAME_RESOLVE_CONCURRENCY ": %d\n", prefs.name_resolve_concurrency); @@ -2068,15 +2090,30 @@ write_prefs(char **pf_path_return) fprintf(pf, PRS_CAP_DEVICE ": %s\n", prefs.capture_device); } - fprintf(pf, "\n# Capture in promiscuous mode? TRUE/FALSE\n"); + if (prefs.capture_devices_descr != NULL) { + fprintf(pf, "\n# Interface descriptions.\n"); + fprintf(pf, "# Ex: eth0(eth0 descr),eth1(eth1 descr),...\n"); + fprintf(pf, PRS_CAP_DEVICES_DESCR ": %s\n", prefs.capture_devices_descr); + } + + if (prefs.capture_devices_hide != NULL) { + fprintf(pf, "\n# Hide interface?\n"); + fprintf(pf, "# Ex: eth0,eth3,...\n"); + fprintf(pf, PRS_CAP_DEVICES_HIDE ": %s\n", prefs.capture_devices_hide); + } + + fprintf(pf, "\n# Capture in promiscuous mode?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_CAP_PROM_MODE ": %s\n", prefs.capture_prom_mode == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# Update packet list in real time during capture? TRUE/FALSE\n"); + fprintf(pf, "\n# Update packet list in real time during capture?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_CAP_REAL_TIME ": %s\n", prefs.capture_real_time == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# scroll packet list during capture? TRUE/FALSE\n"); + fprintf(pf, "\n# Scroll packet list during capture?\n"); + fprintf(pf, "# TRUE or FALSE (case-insensitive).\n"); fprintf(pf, PRS_CAP_AUTO_SCROLL ": %s\n", prefs.capture_auto_scroll == TRUE ? "TRUE" : "FALSE"); @@ -2133,6 +2170,8 @@ copy_prefs(e_prefs *dest, e_prefs *src) dest->gui_geometry_main_height = src->gui_geometry_main_height; /* values for the capture dialog box */ dest->capture_device = g_strdup(src->capture_device); + dest->capture_devices_descr = g_strdup(src->capture_devices_descr); + dest->capture_devices_hide = g_strdup(src->capture_devices_hide); dest->capture_prom_mode = src->capture_prom_mode; dest->capture_real_time = src->capture_real_time; dest->capture_auto_scroll = src->capture_auto_scroll; @@ -2162,6 +2201,14 @@ free_prefs(e_prefs *pr) g_free(pr->capture_device); pr->capture_device = NULL; } + if (pr->capture_devices_descr != NULL) { + g_free(pr->capture_devices_descr); + pr->capture_devices_descr = NULL; + } + if (pr->capture_devices_hide != NULL) { + g_free(pr->capture_devices_hide); + pr->capture_devices_hide = NULL; + } } static void @@ -1,7 +1,7 @@ /* prefs.h * Definitions for preference handling routines * - * $Id: prefs.h,v 1.44 2003/08/07 00:41:26 guy Exp $ + * $Id: prefs.h,v 1.45 2003/09/08 21:44:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -35,6 +35,9 @@ #define DEF_WIDTH 750 #define DEF_HEIGHT 550 +#define MAX_VAR_LEN 48 +#define MAX_VAL_LEN 1024 + /* * Convert a string listing name resolution types to a bitmask of * those types. @@ -71,6 +74,8 @@ typedef struct _e_prefs { guint32 name_resolve; gint name_resolve_concurrency; gchar *capture_device; + gchar *capture_devices_descr; + gchar *capture_devices_hide; gboolean capture_prom_mode; gboolean capture_real_time; gboolean capture_auto_scroll; |