Ethereal-dev: [Ethereal-dev] Name resolving patch including etheral

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Joerg Mayer <jmayer@xxxxxxxxx>
Date: Sat, 12 May 2001 15:27:44 +0200
Hello,

this patch is an attempt to implement a finer grained name resolution.
The problem: ip name resolving is not available, but I still want portnames
and manufacturer ids to be resolved.
The solution: Add an option -N resolving-flags which overrides -n if present.

In this patch I've implemented 3 flags: m (mac), n (network) and
t (transport). In order to resolve everything but ip, you'd type -N mt.

This version implements this feature in both ethereal and thethereal.
Two words of warning: I don't know how to program gtk, so the added buttons
are the result of copy paste, which shows very much with the file open
dialog, which is just ugly. What is still missing is name resolving in the
context menu in the decoded packet window because I simply didn't have the
time to look at how this is handled so far.

I haven't received any feedback on my earlier posting when I sent the
tethereal only version of this patch. Please give me at least the feedback
whether you think this featuer useful or unnecessary so I won't waste any
more time on this.


  Thanks
      Jörg
-- 
Joerg Mayer                                          <jmayer@xxxxxxxxx>
I found out that "pro" means "instead of" (as in proconsul). Now I know
what proactive means.
Changelog: <jmayer@xxxxxxxxx>
	- Add name resolving on an individual level for
	  mac, network and transport layer addresses.

Index: ethereal/prefs.c
===================================================================
RCS file: /cvsroot/ethereal/prefs.c,v
retrieving revision 1.50
diff -u -u -r1.50 prefs.c
--- prefs.c	2001/04/15 03:37:13	1.50
+++ prefs.c	2001/05/12 13:03:50
@@ -615,7 +615,7 @@
     prefs.capture_prom_mode   =     0;
     prefs.capture_real_time   =     0;
     prefs.capture_auto_scroll =     0;
-    prefs.name_resolve=     1;
+    prefs.name_resolve= PREFS_RESOLV_ALL;
 
   }
 
@@ -1011,7 +1011,7 @@
  
   } else if (strcmp(pref_name, PRS_NAME_RESOLVE) == 0 ||
 	     strcmp(pref_name, PRS_CAP_NAME_RESOLVE) == 0) {
-    prefs.name_resolve = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); 
+    prefs.name_resolve = ((strcmp(value, "TRUE") == 0)?PREFS_RESOLV_ALL:PREFS_RESOLV_NONE); 
 
   } else {
     /* To which module does this preference belong? */
@@ -1339,7 +1339,7 @@
 
   fprintf(pf, "\n# Resolve addresses to names? TRUE/FALSE\n");
   fprintf(pf, PRS_NAME_RESOLVE ": %s\n",
-		  prefs.name_resolve == TRUE ? "TRUE" : "FALSE");
+		  prefs.name_resolve == PREFS_RESOLV_ALL ? "TRUE" : "FALSE");
 
 /* write the capture options */
   fprintf(pf, "\n# Capture in promiscuous mode? TRUE/FALSE\n");
Index: ethereal/prefs.h
===================================================================
RCS file: /cvsroot/ethereal/prefs.h,v
retrieving revision 1.29
diff -u -u -r1.29 prefs.h
--- prefs.h	2001/04/15 03:37:13	1.29
+++ prefs.h	2001/05/12 13:03:50
@@ -33,6 +33,15 @@
 #define PR_DEST_CMD  0
 #define PR_DEST_FILE 1
 
+/* 31 types are sufficient (as are 640k of RAM) */
+/* FIXME: Maybe MANUF/m, IP/i, IP6/6, IPX/x, UDP+TCP/t etc would be
+   more useful/consistent */
+#define PREFS_RESOLV_NONE	0x0
+#define PREFS_RESOLV_MAC	0x1
+#define PREFS_RESOLV_NETWORK	0x2
+#define PREFS_RESOLV_TRANSPORT	0x4
+#define PREFS_RESOLV_ALL	0xFFFFFFFF	
+
 typedef struct _e_prefs {
   gint     pr_format;
   gint     pr_dest;
@@ -50,7 +59,7 @@
   gchar   *gui_font_name;
   color_t  gui_marked_fg;
   color_t  gui_marked_bg;
-  gboolean name_resolve;
+  gint     name_resolve;
   gboolean capture_prom_mode;
   gboolean capture_real_time;
   gboolean capture_auto_scroll;
Index: ethereal/tethereal.c
===================================================================
RCS file: /cvsroot/ethereal/tethereal.c,v
retrieving revision 1.82
diff -u -u -r1.82 tethereal.c
--- tethereal.c	2001/04/20 21:50:06	1.82
+++ tethereal.c	2001/05/12 13:03:52
@@ -151,14 +151,14 @@
   fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
 	comp_info_str->str);
 #ifdef HAVE_LIBPCAP
-  fprintf(stderr, "t%s [ -DvVhlp ] [ -c count ] [ -f <capture filter> ]\n", PACKAGE);
-  fprintf(stderr, "\t[ -F <capture file type> ] [ -i interface ] [ -n ]\n");
-  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
-  fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
+  fprintf(stderr, "t%s [ -DvVhlp ] [ -c <count> ] [ -f <capture filter> ]\n", PACKAGE);
+  fprintf(stderr, "\t[ -F <capture file type> ] [ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
+  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
+  fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
 #else
-  fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ]\n", PACKAGE);
-  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
-  fprintf(stderr, "\t[ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
+  fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
+  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
+  fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
 #endif
   fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
@@ -336,7 +336,7 @@
 #endif
     
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "c:Df:F:hi:lno:pr:R:s:t:vw:Vx")) != EOF) {
+  while ((opt = getopt(argc, argv, "c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != EOF) {
     switch (opt) {
       case 'c':        /* Capture xxx packets */
 #ifdef HAVE_LIBPCAP
@@ -417,8 +417,30 @@
 	line_buffered = TRUE;
 	break;
       case 'n':        /* No name resolution */
-	prefs->name_resolve = 0;
+	prefs->name_resolve = PREFS_RESOLV_NONE;
 	break;
+      case 'N':        /* No name resolution */
+	if (prefs->name_resolve == PREFS_RESOLV_ALL) {
+	  prefs->name_resolve = PREFS_RESOLV_NONE;
+        }
+	for (; *optarg; optarg++) {
+	  switch (*optarg) {
+	  case 'm':
+	    prefs->name_resolve |= PREFS_RESOLV_MAC;
+	    break;
+	  case 'n':
+	    prefs->name_resolve |= PREFS_RESOLV_NETWORK;
+	    break;
+	  case 't':
+	    prefs->name_resolve |= PREFS_RESOLV_TRANSPORT;
+	    break;
+	  default:
+            fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c', valid are: m,n,t\n",
+			*optarg);
+            exit(1);
+	  }
+        }
+	break;
       case 'o':        /* Override preference from command line */
         switch (prefs_set_pref(optarg)) {
 
Index: ethereal/doc/ethereal.pod.template
===================================================================
RCS file: /cvsroot/ethereal/doc/ethereal.pod.template,v
retrieving revision 1.175
diff -u -u -r1.175 ethereal.pod.template
--- ethereal.pod.template	2001/05/11 23:24:10	1.175
+++ ethereal.pod.template	2001/05/12 13:03:54
@@ -16,6 +16,7 @@
 S<[ B<-m> font ]>
 S<[ B<-n> ]>
 S<[ B<-o> preference setting ] ...>
+S<[ B<-N> resolving flags ] ...>
 S<[ B<-p> ]>
 S<[ B<-P> packet list height ]>
 S<[ B<-Q> ]>
@@ -127,6 +128,12 @@
 Disables network object name resolution (such as hostname, TCP and UDP port
 names).
 
+=item -N
+ 
+Flags to turn on specific name resolving for MAC B<m>, network B<n> and
+transport B<t> layer addresses. This overrides -n if both -N and -n are
+present.
+
 =item -o
 
 Sets a preference value, overriding the default value and any value read
@@ -714,8 +721,9 @@
 whether in such a capture the packet list pane should scroll to show the
 most recently captured packets with the I<Automatic scrolling in live
 capture> check box, and can specify whether addresses should be
-translated to names in the display with the I<Enable name resolution>
-check box.
+translated to names in the display with the I<Enable mac name resolution>,
+I<Enable network name resolution> and I<Enable transport name resolution>
+check boxes.
 
 =item Display Options
 
@@ -727,7 +735,7 @@
 specify whether, when the display is updated as packets are captured,
 the list should automatically scroll to show the most recently captured
 packets or not and whether addresses should be translated to names in
-the display.
+the display on a mac, network and transport layer basis.
 
 =item Plugins
 
Index: ethereal/doc/tethereal.pod.template
===================================================================
RCS file: /cvsroot/ethereal/doc/tethereal.pod.template,v
retrieving revision 1.27
diff -u -u -r1.27 tethereal.pod.template
--- tethereal.pod.template	2001/03/27 06:16:11	1.27
+++ tethereal.pod.template	2001/05/12 13:03:54
@@ -14,6 +14,7 @@
 S<[ B<-i> interface ]> 
 S<[ B<-l> ]>
 S<[ B<-n> ]>
+S<[ B<-N> resolving flags ] ...>
 S<[ B<-o> preference setting ] ...>
 S<[ B<-p> ]>
 S<[ B<-r> infile ]>
@@ -162,6 +163,12 @@
 
 Disables network object name resolution (such as hostname, TCP and UDP port
 names).
+
+=item -N
+
+Flags to turn on specific name resolving for MAC B<m>, network B<n> and
+transport B<t> layer addresses. This overrides -n if both -N and -n are
+present.
 
 =item -o
 
Index: ethereal/epan/resolv.c
===================================================================
RCS file: /cvsroot/ethereal/epan/resolv.c,v
retrieving revision 1.9
diff -u -u -r1.9 resolv.c
--- resolv.c	2001/04/15 03:37:15	1.9
+++ resolv.c	2001/05/12 13:03:55
@@ -220,7 +220,7 @@
   tp->addr = port;
   tp->next = NULL;
 
-  if (!prefs.name_resolve || 
+  if (!(prefs.name_resolve & PREFS_RESOLV_TRANSPORT) || 
       (servp = getservbyport(htons(port), serv_proto)) == NULL) {
     /* unknown port */
     sprintf(tp->name, "%d", port);
@@ -279,7 +279,7 @@
   tp->addr = addr;
   tp->next = NULL;
 
-  if (prefs.name_resolve) {
+  if (prefs.name_resolve & PREFS_RESOLV_NETWORK) {
 #ifdef AVOID_DNS_TIMEOUT
     
     /* Quick hack to avoid DNS/YP timeout */
@@ -319,7 +319,7 @@
 #ifdef INET6
   struct hostent *hostp;
 
-  if (prefs.name_resolve) {
+  if (prefs.name_resolve & PREFS_RESOLV_NETWORK) {
 #ifdef AVOID_DNS_TIMEOUT
     
     /* Quick hack to avoid DNS/YP timeout */
@@ -1036,7 +1036,7 @@
 {
   gboolean found;
 
-  if (!prefs.name_resolve)
+  if (!(prefs.name_resolve & PREFS_RESOLV_NETWORK))
     return ip_to_str((guint8 *)&addr);
 
   return host_name_lookup(addr, &found);
@@ -1047,7 +1047,7 @@
   gboolean found;
 
 #ifdef INET6
-  if (!prefs.name_resolve)
+  if (!(prefs.name_resolve & PREFS_RESOLV_NETWORK))
     return ip6_to_str(addr);
   if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
     return ip6_to_str(addr);
@@ -1100,7 +1100,7 @@
   static gchar  str[3][MAXNAMELEN];
   static gchar *cur;
 
-  if (!prefs.name_resolve) {
+  if (!(prefs.name_resolve & PREFS_RESOLV_TRANSPORT)) {
     if (cur == &str[0][0]) {
       cur = &str[1][0];
     } else if (cur == &str[1][0]) {  
@@ -1121,7 +1121,7 @@
   static gchar  str[3][MAXNAMELEN];
   static gchar *cur;
 
-  if (!prefs.name_resolve) {
+  if (!(prefs.name_resolve & PREFS_RESOLV_TRANSPORT)) {
     if (cur == &str[0][0]) {
       cur = &str[1][0];
     } else if (cur == &str[1][0]) {  
@@ -1142,7 +1142,7 @@
   static gchar  str[3][MAXNAMELEN];
   static gchar *cur;
 
-  if (!prefs.name_resolve) {
+  if (!(prefs.name_resolve & PREFS_RESOLV_TRANSPORT)) {
     if (cur == &str[0][0]) {
       cur = &str[1][0];
     } else if (cur == &str[1][0]) {  
@@ -1160,7 +1160,7 @@
 
 extern guchar *get_ether_name(const guint8 *addr)
 {
-  if (!prefs.name_resolve)
+  if (!(prefs.name_resolve & PREFS_RESOLV_MAC))
     return ether_to_str((guint8 *)addr);
 
   if (!eth_resolution_initialized) {
@@ -1184,7 +1184,7 @@
 
   /* Initialize ether structs if we're the first
    * ether-related function called */
-  if (!prefs.name_resolve)
+  if (!(prefs.name_resolve & PREFS_RESOLV_MAC))
     return NULL;
   
   if (!eth_resolution_initialized) {
@@ -1268,7 +1268,7 @@
 extern const guchar *get_ipxnet_name(const guint32 addr)
 {
 
-  if (!prefs.name_resolve) {
+  if (!(prefs.name_resolve & PREFS_RESOLV_NETWORK)) {
 	  return ipxnet_to_str_punct(addr, '\0');
   }
 
@@ -1306,12 +1306,12 @@
   static gchar *cur;
   hashmanuf_t  *manufp;
 
-  if (prefs.name_resolve && !eth_resolution_initialized) {
+  if ((prefs.name_resolve & PREFS_RESOLV_MAC) && !eth_resolution_initialized) {
     initialize_ethers();
     eth_resolution_initialized = 1;
   }
 
-  if (!prefs.name_resolve || ((manufp = manuf_name_lookup(addr)) == NULL)) {
+  if (!(prefs.name_resolve & PREFS_RESOLV_MAC) || ((manufp = manuf_name_lookup(addr)) == NULL)) {
     if (cur == &str[0][0]) {
       cur = &str[1][0];
     } else if (cur == &str[1][0]) {  
Index: ethereal/gtk/capture_dlg.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/capture_dlg.c,v
retrieving revision 1.41
diff -u -u -r1.41 capture_dlg.c
--- capture_dlg.c	2001/04/15 03:37:16	1.41
+++ capture_dlg.c	2001/05/12 13:03:56
@@ -72,7 +72,9 @@
 #define E_CAP_PROMISC_KEY     "cap_promisc"
 #define E_CAP_SYNC_KEY        "cap_sync"
 #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
-#define E_CAP_RESOLVE_KEY     "cap_resolve"
+#define E_CAP_M_RESOLVE_KEY   "cap_m_resolve"
+#define E_CAP_N_RESOLVE_KEY   "cap_n_resolve"
+#define E_CAP_T_RESOLVE_KEY   "cap_t_resolve"
 
 #define E_FS_CALLER_PTR_KEY       "fs_caller_ptr"
 #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
@@ -121,7 +123,8 @@
                 *file_bt, *file_te,
                 *caplen_hb, *table,
                 *bbox, *ok_bt, *cancel_bt, *snap_lb,
-                *snap_sb, *promisc_cb, *sync_cb, *auto_scroll_cb, *resolv_cb;
+                *snap_sb, *promisc_cb, *sync_cb, *auto_scroll_cb,
+		*m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
   GtkAccelGroup *accel_group;
   GtkAdjustment *adj;
   GList         *if_list, *count_list = NULL;
@@ -276,11 +279,26 @@
   gtk_container_add(GTK_CONTAINER(main_vb), auto_scroll_cb);
   gtk_widget_show(auto_scroll_cb);
 
-  resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
-		"Enable _name resolution", accel_group);
-  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(resolv_cb), prefs.name_resolve);
-  gtk_container_add(GTK_CONTAINER(main_vb), resolv_cb);
-  gtk_widget_show(resolv_cb);
+  m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		"Enable _mac name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
+		prefs.name_resolve & PREFS_RESOLV_MAC);
+  gtk_container_add(GTK_CONTAINER(main_vb), m_resolv_cb);
+  gtk_widget_show(m_resolv_cb);
+
+  n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		"Enable _network name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
+		prefs.name_resolve & PREFS_RESOLV_NETWORK);
+  gtk_container_add(GTK_CONTAINER(main_vb), n_resolv_cb);
+  gtk_widget_show(n_resolv_cb);
+
+  t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		"Enable _transport name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
+		prefs.name_resolve & PREFS_RESOLV_TRANSPORT);
+  gtk_container_add(GTK_CONTAINER(main_vb), t_resolv_cb);
+  gtk_widget_show(t_resolv_cb);
   
   /* Button row: OK and cancel buttons */
   bbox = gtk_hbutton_box_new();
@@ -313,7 +331,9 @@
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_PROMISC_KEY, promisc_cb);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SYNC_KEY,  sync_cb);
   gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
-  gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RESOLVE_KEY,  resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
 
   /* Catch the "activate" signal on the frame number and file name text
      entries, so that if the user types Return there, we act as if the
@@ -435,7 +455,7 @@
 static void
 capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
   GtkWidget *if_cb, *filter_te, *file_te, *count_cb, *snap_sb, *promisc_cb,
-            *sync_cb, *auto_scroll_cb, *resolv_cb;
+            *sync_cb, *auto_scroll_cb, *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
   gchar *if_text;
   gchar *if_name;
   gchar *filter_text;
@@ -449,7 +469,9 @@
   promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_PROMISC_KEY);
   sync_cb   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
   auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
-  resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RESOLVE_KEY);
+  m_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY);
+  n_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
+  t_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
 
   if_text =
     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
@@ -502,7 +524,10 @@
 
   prefs.capture_auto_scroll = GTK_TOGGLE_BUTTON (auto_scroll_cb)->active;
 
-  prefs.name_resolve = GTK_TOGGLE_BUTTON (resolv_cb)->active;
+  prefs.name_resolve = PREFS_RESOLV_NONE;
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (m_resolv_cb)->active ? PREFS_RESOLV_MAC : PREFS_RESOLV_NONE);
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (n_resolv_cb)->active ? PREFS_RESOLV_NETWORK : PREFS_RESOLV_NONE);
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (t_resolv_cb)->active ? PREFS_RESOLV_TRANSPORT : PREFS_RESOLV_NONE);
 
   gtk_widget_destroy(GTK_WIDGET(parent_w));
 
Index: ethereal/gtk/display_opts.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/display_opts.c,v
retrieving revision 1.20
diff -u -u -r1.20 display_opts.c
--- display_opts.c	2001/04/15 03:37:16	1.20
+++ display_opts.c	2001/05/12 13:03:56
@@ -71,7 +71,9 @@
 #define E_DISPLAY_TIME_REL_KEY   "display_time_rel"
 #define E_DISPLAY_TIME_DELTA_KEY "display_time_delta"
 #define E_DISPLAY_AUTO_SCROLL_KEY "display_auto_scroll"
-#define E_DISPLAY_NAME_RESOLUTION_KEY "display_name_resolution"
+#define E_DISPLAY_M_NAME_RESOLUTION_KEY "display_mac_name_resolution"
+#define E_DISPLAY_N_NAME_RESOLUTION_KEY "display_network_name_resolution"
+#define E_DISPLAY_T_NAME_RESOLUTION_KEY "display_transport_name_resolution"
 
 static void display_opt_ok_cb(GtkWidget *, gpointer);
 static void display_opt_apply_cb(GtkWidget *, gpointer);
@@ -178,13 +180,32 @@
   gtk_widget_show(button);
 
   button = dlg_check_button_new_with_label_with_mnemonic(
-  		"Enable _name resolution", accel_group);
-  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), prefs.name_resolve);
-  gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_NAME_RESOLUTION_KEY,
+  		"Enable _mac name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
+		prefs.name_resolve & PREFS_RESOLV_MAC);
+  gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_M_NAME_RESOLUTION_KEY,
+		      button);
+  gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
+  gtk_widget_show(button);
+    
+  button = dlg_check_button_new_with_label_with_mnemonic(
+  		"Enable _network name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
+		prefs.name_resolve & PREFS_RESOLV_NETWORK);
+  gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_N_NAME_RESOLUTION_KEY,
 		      button);
   gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
   gtk_widget_show(button);
     
+  button = dlg_check_button_new_with_label_with_mnemonic(
+  		"Enable _transport name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
+		prefs.name_resolve & PREFS_RESOLV_TRANSPORT);
+  gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_T_NAME_RESOLUTION_KEY,
+		      button);
+  gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
+  gtk_widget_show(button);
+    
   /* Button row: OK, Apply, and Cancel buttons */
   bbox = gtk_hbutton_box_new();
   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
@@ -267,9 +288,16 @@
 					     E_DISPLAY_AUTO_SCROLL_KEY);
   prefs.capture_auto_scroll = (GTK_TOGGLE_BUTTON (button)->active);
 
+  prefs.name_resolve = PREFS_RESOLV_NONE;
+  button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
+					     E_DISPLAY_M_NAME_RESOLUTION_KEY);
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (button)->active ? PREFS_RESOLV_MAC : PREFS_RESOLV_NONE);
+  button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
+					     E_DISPLAY_N_NAME_RESOLUTION_KEY);
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (button)->active ? PREFS_RESOLV_NETWORK : PREFS_RESOLV_NONE);
   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
-					     E_DISPLAY_NAME_RESOLUTION_KEY);
-  prefs.name_resolve = (GTK_TOGGLE_BUTTON (button)->active);
+					     E_DISPLAY_T_NAME_RESOLUTION_KEY);
+  prefs.name_resolve |= (GTK_TOGGLE_BUTTON (button)->active ? PREFS_RESOLV_TRANSPORT : PREFS_RESOLV_NONE);
 
 }
 
Index: ethereal/gtk/file_dlg.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/file_dlg.c,v
retrieving revision 1.38
diff -u -u -r1.38 file_dlg.c
--- file_dlg.c	2001/04/15 03:37:16	1.38
+++ file_dlg.c	2001/05/12 13:03:57
@@ -57,7 +57,9 @@
 static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
 static void file_save_as_destroy_cb(GtkWidget *win, gpointer user_data);
 
-#define E_FILE_RESOLVE_KEY	  "file_dlg_resolve_key"
+#define E_FILE_M_RESOLVE_KEY	  "file_dlg_mac_resolve_key"
+#define E_FILE_N_RESOLVE_KEY	  "file_dlg_network_resolve_key"
+#define E_FILE_T_RESOLVE_KEY	  "file_dlg_transport_resolve_key"
 
 /*
  * Keep a static pointer to the current "Open Capture File" window, if
@@ -72,7 +74,8 @@
 file_open_cmd_cb(GtkWidget *w, gpointer data)
 {
   GtkWidget	*filter_hbox, *filter_bt, *filter_te,
-  		*resolv_cb;
+  		*m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
+  GtkAccelGroup *accel_group;                                                         
   /* No Apply button, and "OK" just sets our text widget, it doesn't
      activate it (i.e., it doesn't cause us to try to open the file). */
   static construct_args_t args = {
@@ -91,20 +94,46 @@
   gtk_signal_connect(GTK_OBJECT(file_open_w), "destroy",
 	GTK_SIGNAL_FUNC(file_open_destroy_cb), NULL);
 
+  /* Accelerator group for the accelerators (or, as they're called in
+     Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
+     Ctrl+<key> is an accelerator). */
+  accel_group = gtk_accel_group_new();
+  gtk_window_add_accel_group(GTK_WINDOW(file_open_w), accel_group);
+
   /* If we've opened a file, start out by showing the files in the directory
      in which that file resided. */
   if (last_open_dir)
     gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_open_w), last_open_dir);
+
+  m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		  "Enable _mac name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
+	prefs.name_resolve & PREFS_RESOLV_MAC);
+  gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->main_vbox),
+		  m_resolv_cb, FALSE, FALSE, 5);
+  gtk_widget_show(m_resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
+		  E_FILE_M_RESOLVE_KEY, m_resolv_cb);
 
-  resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
-		  "Enable name resolution", NULL);
-  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(resolv_cb), prefs.name_resolve);
+  n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		  "Enable _network name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
+	prefs.name_resolve & PREFS_RESOLV_NETWORK);
   gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->main_vbox),
-		  resolv_cb, FALSE, FALSE, 5);
-  gtk_widget_show(resolv_cb);
+		  n_resolv_cb, FALSE, FALSE, 5);
+  gtk_widget_show(n_resolv_cb);
   gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
-		  E_FILE_RESOLVE_KEY,  resolv_cb);
+		  E_FILE_N_RESOLVE_KEY, n_resolv_cb);
 
+  t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
+		  "Enable _transport name resolution", accel_group);
+  gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
+	prefs.name_resolve & PREFS_RESOLV_TRANSPORT);
+  gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->main_vbox),
+		  t_resolv_cb, FALSE, FALSE, 5);
+  gtk_widget_show(t_resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
+		  E_FILE_T_RESOLVE_KEY, t_resolv_cb);
   
   /* Connect the ok_button to file_open_ok_cb function and pass along a
      pointer to the file selection box widget */
@@ -150,7 +179,7 @@
 static void
 file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
   gchar     *cf_name, *rfilter, *s;
-  GtkWidget *filter_te, *resolv_cb;
+  GtkWidget *filter_te, *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
   dfilter_t *rfcode = NULL;
   int        err;
 
@@ -190,8 +219,13 @@
   cfile.rfcode = rfcode;
 
   /* Set the global resolving variable */
-  resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_RESOLVE_KEY);
-  prefs.name_resolve = GTK_TOGGLE_BUTTON (resolv_cb)->active;
+  prefs.name_resolve = 0;
+  m_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_M_RESOLVE_KEY);
+  prefs.name_resolve |= GTK_TOGGLE_BUTTON (m_resolv_cb)->active ? PREFS_RESOLV_MAC : PREFS_RESOLV_NONE;
+  n_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_N_RESOLVE_KEY);
+  prefs.name_resolve |= GTK_TOGGLE_BUTTON (n_resolv_cb)->active ? PREFS_RESOLV_NETWORK : PREFS_RESOLV_NONE;
+  t_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_T_RESOLVE_KEY);
+  prefs.name_resolve |= GTK_TOGGLE_BUTTON (t_resolv_cb)->active ? PREFS_RESOLV_TRANSPORT : PREFS_RESOLV_NONE;
 
   /* We've crossed the Rubicon; get rid of the file selection box. */
   gtk_widget_hide(GTK_WIDGET (fs));
Index: ethereal/gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.198
diff -u -u -r1.198 main.c
--- main.c	2001/05/01 00:41:46	1.198
+++ main.c	2001/05/12 13:03:59
@@ -539,8 +539,8 @@
 
 void resolve_name_cb(GtkWidget *widget, gpointer data) {
   if (cfile.protocol_tree) {
-    int tmp = prefs.name_resolve;
-    prefs.name_resolve = 1;
+    gint tmp = prefs.name_resolve;
+    prefs.name_resolve = PREFS_RESOLV_ALL;
     gtk_clist_clear ( GTK_CLIST(tree_view) );
     proto_tree_draw(cfile.protocol_tree, tree_view);
     prefs.name_resolve = tmp;
@@ -730,17 +730,19 @@
   fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n",
 	  comp_info_str->str);
 #ifdef HAVE_LIBPCAP
-  fprintf(stderr, "%s [ -vh ] [ -klpQS ] [ -B <byte view height> ] [ -c count ]\n",
+  fprintf(stderr, "%s [ -vh ] [ -klpQS ] [ -B <byte view height> ] [ -c <count> ]\n",
 	  PACKAGE);
-  fprintf(stderr, "\t[ -f <capture filter> ] [ -i interface ] [ -m <medium font> ] \n");
-  fprintf(stderr, "\t[ -n ] [ -o <preference setting> ] ... [ -P <packet list height> ]\n");
-  fprintf(stderr, "\t[ -r infile ] [ -R <read filter> ] [ -s snaplen ] \n");
-  fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ] [ -w savefile ]\n");
+  fprintf(stderr, "\t[ -f <capture filter> ] [ -i <interface> ] [ -m <medium font> ] \n");
+  fprintf(stderr, "\t[ -n ] [ -N <resolving> ]\n");
+  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -P <packet list height> ]\n");
+  fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -s <snaplen> ] \n");
+  fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ] [ -w <savefile> ]\n");
 #else
-  fprintf(stderr, "%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ] [ -n ]\n",
+  fprintf(stderr, "%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ]\n";
+  fprintf(stderr, "\t[ -n ] [ -N <resolving> ]\n",
 	  PACKAGE);
   fprintf(stderr, "\t[ -o <preference setting> ... [ -P <packet list height> ]\n");
-  fprintf(stderr, "\t[ -r infile ] [ -R <read filter> ] [ -t <time stamp format> ]\n");
+  fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -t <time stamp format> ]\n");
   fprintf(stderr, "\t[ -T <tree view height> ]\n");
 #endif
 }
@@ -1035,8 +1037,30 @@
 	prefs->gui_font_name = g_strdup(optarg);
 	break;
       case 'n':        /* No name resolution */
-	prefs->name_resolve = 0;
+	prefs->name_resolve = PREFS_RESOLV_NONE;
 	break;
+      case 'N':        /* No name resolution */                                       
+	if (prefs->name_resolve == PREFS_RESOLV_ALL) {
+	  prefs->name_resolve = PREFS_RESOLV_NONE;
+	}
+	for (; *optarg; optarg++) {
+	  switch (*optarg) {
+	  case 'm':
+	    prefs->name_resolve |= PREFS_RESOLV_MAC;
+	    break;
+	  case 'n':
+	    prefs->name_resolve |= PREFS_RESOLV_NETWORK;
+	    break;
+	  case 't':
+	    prefs->name_resolve |= PREFS_RESOLV_TRANSPORT;
+	    break;
+	  default:
+	    fprintf(stderr, "ethereal: -N specifies unknown resolving option '%c', valid are: m,n,t\n",
+			*optarg);
+	    exit(1);
+	  }
+	}
+	break;
       case 'o':        /* Override preference from command line */
         switch (prefs_set_pref(optarg)) {