Ethereal-dev: [Ethereal-dev] patches to add interface descriptions
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Nathan Jennings <njen@xxxxxxxxxxxxx>
Date: Mon, 08 Sep 2003 00:50:58 -0400
Hello,Attached are diff files I've created against 0.9.14. The patches allow the edit/display of optional, user-defined interface descriptions via the capture preferences dialog. The descriptions are shown in the drop-down list of interfaces in the capture dialog.
I submitted this a couple of months ago and got some good suggestions from Guy and Olivier. I've implemented them both; GUI edit/display of descriptions (Guy) and the ability to "hide" an interface (Olivier). I think it's much better now. :o)
I have two thoughts/questions:1) I'm not sure if Windows/Unicode requires special string handling in the code I've submitted. If so, my patches do not handle it.
2) In "capture_prefs.c", I use a CList widget that's never added to a window and displayed (I don't call "gtk_container_add()" for it). I use it as a table to store option values as they're edited by the user. Do I need to manually deallocate/free this widget somehow?
I've tested this on FreeBSD 4.7, GTK/GLIB 1.2.10 and FreeBSD 4.7, GTK/GLIB 2.0.6. Portions of it have been tested on Linux 2.4 with GTK/GLIB 1.2.10.
Please let me know if I left something out or should have done it differently. Feedback is welcome.
-Nathan
--- ../ethereal-0.9.14/gtk/capture_dlg.c Sat May 17 12:33:02 2003 +++ gtk/capture_dlg.c Sun Aug 3 00:10:35 2003 @@ -104,6 +104,15 @@ static void capture_prep_destroy_cb(GtkWidget *win, gpointer user_data); +static GList * +capture_dev_descr_add(GList *if_list); + +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 @@ 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 @@ 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; @@ -1053,6 +1071,147 @@ gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb))); +} + +/* + * 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. + */ +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 */
--- ../ethereal-0.9.14/gtk/capture_prefs.c Tue Nov 12 20:57:44 2002 +++ gtk/capture_prefs.c Sun Sep 7 21:53:40 2003 @@ -28,6 +28,7 @@ #ifdef HAVE_LIBPCAP +#include <string.h> #include <gtk/gtk.h> #include <pcap.h> @@ -38,21 +39,34 @@ #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 */ -#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 +83,7 @@ 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 +104,30 @@ 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 +178,827 @@ } 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. */ +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. + */ +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)); +} + +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)); +} + +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. + */ +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". + */ +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. + */ +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]) == 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]) == 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 "1" if it has. + */ +gint 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 1; + } + +return 0; +} + +/* + * 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. + */ +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); + } +} + +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. + */ +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. + */ +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. + */ +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 */
--- ../ethereal-0.9.14/gtk/capture_prefs.h Wed Aug 28 20:40:08 2002 +++ gtk/capture_prefs.h Sun Sep 7 01:13:48 2003 @@ -29,5 +29,18 @@ void capture_prefs_fetch(GtkWidget *w); void capture_prefs_apply(GtkWidget *w); void capture_prefs_destroy(GtkWidget *w); +void ifopts_edit_cb(GtkWidget *w, gpointer data); +void ifopts_edit_ok_cb(GtkWidget *w, gpointer parent_w); +void ifopts_edit_close_cb(GtkWidget *close_bt, gpointer parent_w); +void ifopts_edit_destroy_cb(GtkWidget *win, gpointer data); +void ifopts_edit_ifsel_cb(GtkWidget *clist, gint row, gint column, GdkEventButton *event, gpointer data); +void ifopts_edit_ifunsel_cb(GtkWidget *clist, gint row, gint column, GdkEventButton *event, gpointer data); +void ifopts_old_options_add(GtkCList *clist); +gint ifopts_old_options_chk(GtkCList *clist, gchar *ifname); +void ifopts_new_options_add(GtkCList *clist, gchar *ifname); +void ifopts_options_free(gchar *text[]); +void ifopts_if_clist_add(GtkCList *clist); +void ifopts_write_new_descr(void); +void ifopts_write_new_hide(void); #endif
--- ../ethereal-0.9.14/pcap-util.c Wed Jul 9 21:20:13 2003 +++ pcap-util.c Sat Sep 6 01:21:18 2003 @@ -398,7 +398,6 @@ 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;
--- ../ethereal-0.9.14/pcap-util.h Wed Aug 28 20:40:05 2002 +++ pcap-util.h Sat Sep 6 01:21:47 2003 @@ -33,6 +33,7 @@ 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()". */
--- ../ethereal-0.9.14/prefs.c Mon Jul 21 23:14:28 2003 +++ prefs.c Sat Sep 6 01:23:27 2003 @@ -842,8 +842,6 @@ * */ -#define MAX_VAR_LEN 48 -#define MAX_VAL_LEN 1024 #define DEF_NUM_COLS 6 @@ -979,6 +977,8 @@ /* 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; @@ -1252,10 +1252,12 @@ #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) @@ -1514,6 +1516,14 @@ 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) { @@ -2047,6 +2057,16 @@ fprintf(pf, PRS_CAP_DEVICE ": %s\n", prefs.capture_device); } + if (prefs.capture_devices_descr != NULL) { + fprintf(pf, "\n# Interface descriptions. 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? Ex: eth0,eth3,...\n"); + fprintf(pf, PRS_CAP_DEVICES_HIDE ": %s\n", prefs.capture_devices_hide); + } + fprintf(pf, "\n# Capture in promiscuous mode? TRUE/FALSE\n"); fprintf(pf, PRS_CAP_PROM_MODE ": %s\n", prefs.capture_prom_mode == TRUE ? "TRUE" : "FALSE"); @@ -2112,6 +2132,8 @@ 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; @@ -2140,6 +2162,14 @@ if (pr->capture_device != NULL) { 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; } }
--- ../ethereal-0.9.14/prefs.h Mon Jul 21 23:14:28 2003 +++ prefs.h Sat Sep 6 01:23:50 2003 @@ -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 @@ 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;
- Follow-Ups:
- Re: [Ethereal-dev] patches to add interface descriptions
- From: Guy Harris
- Re: [Ethereal-dev] patches to add interface descriptions
- Prev by Date: Re: [Ethereal-dev] Licensing/Distribution Question
- Next by Date: RE: [Ethereal-dev] Updates to COPS & SNMP dissectors
- Previous by thread: [Ethereal-dev] Updated release schedule for 0.9.15
- Next by thread: Re: [Ethereal-dev] patches to add interface descriptions
- Index(es):