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: Wed, 02 Jul 2003 21:01:33 -0400
Hello,

Attached are patch files I've created with "cvs diff" against anon cvs
as of yesterday morning. The patches add an optional interfaces description string to the capture preferences dialog. The description string looks like:

eth0(eth0 descr),eth1(eth1 descr),...

Two new functions added to capture_dlg.c prepend these descriptions to
device names. At work, we have a few machines with a few interfaces
each, and it's always difficult to remember which interface is connected to a certain switch (network). The device descriptions help us quickly identify which network we're going to sniff. For example:

eth0(DMZ net),eth1(internal LAN),eth2(Internet)

If you decide to commit them, someone may want to bless the string
handling as far as Windows is concerned. I don't have a Windows test
machine and I'm not sure if Unicode requires special handling in this case (I don't think so though).

Also, I think I found a memory leak in pcap-util's
free_interface_list(). I think g_list_remove_link() is the wrong
function to use here. It isolates a list element from the current list.
So, only one element was being freed each time it was called. See
attached patch.

This is my first contribution to Ethereal (and using CVS too), so I hope everything is in order. Please let me know if I left something out or should have done it differently. Feedback is welcome.

-Nathan
Index: ./gtk/capture_dlg.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/capture_dlg.c,v
retrieving revision 1.78
diff -u -r1.78 capture_dlg.c
--- ./gtk/capture_dlg.c	15 May 2003 13:38:05 -0000	1.78
+++ ./gtk/capture_dlg.c	1 Jul 2003 20:21:38 -0000
@@ -104,6 +104,12 @@
 static void
 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
 
+GList *
+capture_dev_descr_add(GList *if_list);
+
+char *
+capture_dev_descr_find(gchar *devs_descr, gchar *if_name);
+
 void
 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
 {
@@ -221,8 +227,12 @@
   gtk_widget_show(if_lb);
 
   if_cb = gtk_combo_new();
-  if (if_list != NULL)
+  if (if_list != NULL) {
+    /* 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 +799,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 +1065,102 @@
   gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),
       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb)));
 
+}
+
+/*
+ * Prepend capture device descriptions to interface list.
+ */
+GList *
+capture_dev_descr_add(GList *if_list)
+{
+
+	GList	*if_new_list;
+	char	*tmp_descr;
+	gchar	*tmp_devs_descr;
+	gchar	*tmp_dev_name;
+	guint	i;
+	guint	nitems;
+	
+	if_new_list = NULL;
+		
+	/* 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". Or, if Windows, we'll 
+	   end up with "(descr) 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) {
+			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;
+	
+	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 */
+		if (*p == '(') {
+			lp++;
+			/* save pointer to beginning of description */
+			p2 = p;
+		}
+		if (*p == ')') {
+			/* end of description */
+			break;
+		}
+		p++;
+	}
+	
+	if ((lp == 1) && (p2 != NULL)) {
+		/* set returned pointer to beginning of description */
+		descr = p2;
+		/* insert terminator */
+		*(p+1) = '\0';
+		return descr;
+	}
+	else
+		return NULL;
 }
 
 #endif /* HAVE_LIBPCAP */
Index: ./gtk/capture_prefs.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/capture_prefs.c,v
retrieving revision 1.17
diff -u -r1.17 capture_prefs.c
--- ./gtk/capture_prefs.c	11 Nov 2002 18:57:00 -0000	1.17
+++ ./gtk/capture_prefs.c	1 Jul 2003 18:14:27 -0000
@@ -46,13 +46,15 @@
 #define PROM_MODE_KEY		"prom_mode"
 #define CAPTURE_REAL_TIME_KEY	"capture_real_time"
 #define AUTO_SCROLL_KEY		"auto_scroll"
+#define DEVICES_DESCR_KEY	"devices_descr"
 
-#define CAPTURE_TABLE_ROWS 4
+#define CAPTURE_TABLE_ROWS 5
 GtkWidget*
 capture_prefs_show(void)
 {
 	GtkWidget	*main_tb, *main_vb;
 	GtkWidget	*if_cb, *if_lb, *promisc_cb, *sync_cb, *auto_scroll_cb;
+	GtkWidget	*if_descr_lb, *if_descr_te;
 	GList		*if_list;
 	int		err;
 	char		err_str[PCAP_ERRBUF_SIZE];
@@ -108,6 +110,19 @@
 	    prefs.capture_auto_scroll);
 	OBJECT_SET_DATA(main_vb, AUTO_SCROLL_KEY, auto_scroll_cb);
 
+	/* Interfaces description string */
+	if_descr_lb = gtk_label_new("Interfaces description (ex: eth0(eth0 descr),...):");
+	gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_lb, 0, 1, 4, 5);
+	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();
+	OBJECT_SET_DATA(main_vb, DEVICES_DESCR_KEY, if_descr_te);
+	if (prefs.capture_devices_descr != NULL)
+		gtk_entry_set_text(GTK_ENTRY(if_descr_te), prefs.capture_devices_descr);
+	gtk_table_attach_defaults(GTK_TABLE(main_tb), if_descr_te, 1, 2, 4, 5);
+	gtk_widget_show(if_descr_te);
+
 	/* Show 'em what we got */
 	gtk_widget_show_all(main_vb);
 
@@ -117,13 +132,14 @@
 void
 capture_prefs_fetch(GtkWidget *w)
 {
-	GtkWidget *if_cb, *promisc_cb, *sync_cb, *auto_scroll_cb;
+	GtkWidget *if_cb, *promisc_cb, *sync_cb, *auto_scroll_cb, *if_descr_cb;
 	gchar	*if_text;
 
 	if_cb = (GtkWidget *)OBJECT_GET_DATA(w, DEVICE_KEY);
 	promisc_cb = (GtkWidget *)OBJECT_GET_DATA(w, PROM_MODE_KEY);
 	sync_cb = (GtkWidget *)OBJECT_GET_DATA(w, CAPTURE_REAL_TIME_KEY);
 	auto_scroll_cb = (GtkWidget *)OBJECT_GET_DATA(w, AUTO_SCROLL_KEY);
+	if_descr_cb = (GtkWidget *)OBJECT_GET_DATA(w, DEVICES_DESCR_KEY);
 
 	if (prefs.capture_device != NULL) {
 		g_free(prefs.capture_device);
@@ -146,6 +162,13 @@
 	prefs.capture_real_time = GTK_TOGGLE_BUTTON (sync_cb)->active;
 
 	prefs.capture_auto_scroll = GTK_TOGGLE_BUTTON (auto_scroll_cb)->active;
+	
+	if (prefs.capture_devices_descr != NULL) {
+		g_free(prefs.capture_devices_descr);
+		prefs.capture_devices_descr = NULL;
+	}
+	prefs.capture_devices_descr = g_strdup(gtk_entry_get_text(
+			GTK_ENTRY(if_descr_cb)));
 }
 
 void
Index: pcap-util.c
===================================================================
RCS file: /cvsroot/ethereal/pcap-util.c,v
retrieving revision 1.13
diff -u -r1.13 pcap-util.c
--- pcap-util.c	13 Jun 2003 02:37:42 -0000	1.13
+++ pcap-util.c	1 Jul 2003 18:21:04 -0000
@@ -519,10 +519,8 @@
 void
 free_interface_list(GList *if_list)
 {
-	while (if_list != NULL) {
-		g_free(if_list->data);
-		if_list = g_list_remove_link(if_list, if_list);
-	}
+	g_list_foreach(if_list, free_if_cb, NULL);
+	g_list_free(if_list);
 }
 
 #endif /* HAVE_LIBPCAP */
Index: prefs.c
===================================================================
RCS file: /cvsroot/ethereal/prefs.c,v
retrieving revision 1.101
diff -u -r1.101 prefs.c
--- prefs.c	15 May 2003 07:44:53 -0000	1.101
+++ prefs.c	1 Jul 2003 18:18:44 -0000
@@ -983,6 +983,7 @@
     prefs.capture_real_time   = FALSE;
     prefs.capture_auto_scroll = FALSE;
     prefs.name_resolve        = RESOLV_ALL ^ RESOLV_NETWORK;
+    prefs.capture_devices_descr = NULL;
   }
 
   /* Construct the pathname of the global preferences file. */
@@ -1250,10 +1251,11 @@
 #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_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_DEVICES_DESCR "capture.devices_descr"
 
 #define RED_COMPONENT(x)   ((((x) >> 16) & 0xff) * 65535 / 255)
 #define GREEN_COMPONENT(x) ((((x) >>  8) & 0xff) * 65535 / 255)
@@ -1517,6 +1519,10 @@
     prefs.capture_real_time = ((strcasecmp(value, "true") == 0)?TRUE:FALSE);
   } else if (strcmp(pref_name, PRS_CAP_AUTO_SCROLL) == 0) {
     prefs.capture_auto_scroll = ((strcasecmp(value, "true") == 0)?TRUE:FALSE);
+  } 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);
 
 /* handle the global options */
   } else if (strcmp(pref_name, PRS_NAME_RESOLVE) == 0 ||
@@ -2051,6 +2057,11 @@
   fprintf(pf, PRS_CAP_AUTO_SCROLL ": %s\n",
 		  prefs.capture_auto_scroll == TRUE ? "TRUE" : "FALSE");
 
+  if (prefs.capture_devices_descr != NULL) {
+    fprintf(pf, "\n# Interfaces description. Ex: eth0(eth0 descr),eth1(eth1 descr),...\n");
+    fprintf(pf, PRS_CAP_DEVICES_DESCR ": %s\n", prefs.capture_devices_descr);
+  }
+
   g_list_foreach(modules, write_module_prefs, pf);
 
   fclose(pf);
@@ -2108,6 +2119,7 @@
   dest->capture_real_time = src->capture_real_time;
   dest->capture_auto_scroll = src->capture_auto_scroll;
   dest->name_resolve = src->name_resolve;
+  dest->capture_devices_descr = g_strdup(src->capture_devices_descr);
 
 }
 
@@ -2131,6 +2143,10 @@
   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;
   }
 }
 
Index: prefs.h
===================================================================
RCS file: /cvsroot/ethereal/prefs.h,v
retrieving revision 1.42
diff -u -r1.42 prefs.h
--- prefs.h	20 Dec 2002 01:48:54 -0000	1.42
+++ prefs.h	1 Jul 2003 18:14:01 -0000
@@ -73,6 +73,7 @@
   gboolean capture_prom_mode;
   gboolean capture_real_time;
   gboolean capture_auto_scroll;
+  gchar   *capture_devices_descr;
 } e_prefs;
 
 extern e_prefs prefs;