Support for "-N" flag enabling selected forms of name resolution, from
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 31 May 2001 08:36:46 +0000 (08:36 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 31 May 2001 08:36:46 +0000 (08:36 +0000)
Joerg Meyer.

Support for saving to the preferences file the settings for all types of
name resolution.

Do a case-insensitive check for "true" and "false" in Boolean preference
settings.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@3489 f5534014-38df-0310-8fa8-9805f1628bb7

AUTHORS
doc/ethereal.pod.template
doc/tethereal.pod.template
epan/resolv.c
gtk/capture_dlg.c
gtk/display_opts.c
gtk/file_dlg.c
gtk/main.c
prefs.c
prefs.h
tethereal.c

diff --git a/AUTHORS b/AUTHORS
index 53024318a2226284f8fd3b89655af7bfa159f76c..18040fa49e65769b81797d0c7db9f8a33d569c1b 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -75,6 +75,7 @@ Joerg Mayer      <jmayer@loplof.de> {
        Banyan Vines support
        NTP fixes
        DHCP support for Intel PXEclient DHCP requests
+       Support for "-N" flag enabling selected forms of name resolution
 }
 
 Martin Maciaszek <fastjack@i-s-o.net> {
index a651e40ca4bad4674df2e43bd85a189ed3ba0c75..2cbe612b02ce7d802b56757d9d8ca82afc51132d 100644 (file)
@@ -15,6 +15,7 @@ S<[ B<-k> ]>
 S<[ B<-l> ]>
 S<[ B<-m> font ]>
 S<[ B<-n> ]>
+S<[ B<-N> resolving flags ] ...>
 S<[ B<-o> preference setting ] ...>
 S<[ B<-p> ]>
 S<[ B<-P> packet list height ]>
@@ -127,6 +128,14 @@ protocol tree pane from the name of the main text font.
 Disables network object name resolution (such as hostname, TCP and UDP port
 names).
 
+=item -N
+
+Turns on name resolving for particular types of addresses and port
+numbers; the argument is a string that may contain the letters B<m> to
+enable MAC address resolution, B<n> to enable network address
+resolution, and B<t> to enable transport-layer port number resolution. 
+This overrides B<-n> if both B<-N> and B<-n> are present.
+
 =item -o
 
 Sets a preference value, overriding the default value and any value read
@@ -714,8 +723,9 @@ the I<Update list of packets in real time> check box, can specify
 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
 
@@ -726,8 +736,9 @@ date, "Seconds since beginning of capture" for relative time stamps, or
 "Seconds since previous frame" for delta time stamps.  You can also
 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.
+packets or not and whether addresses or port numbers should be
+translated to names in the display on a MAC, network and transport layer
+basis.
 
 =item Plugins
 
index 001277130b74faa151e0198024e5c13f45cf7331..d1c3b9f4e361ad8368cd132e9161c798ff4c4e52 100644 (file)
@@ -14,6 +14,7 @@ S<[ B<-h> ]>
 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 ]>
@@ -163,6 +164,14 @@ standard output buffer containing that data fills up.
 Disables network object name resolution (such as hostname, TCP and UDP port
 names).
 
+=item -N
+
+Turns on name resolving for particular types of addresses and port
+numbers; the argument is a string that may contain the letters B<m> to
+enable MAC address resolution, B<n> to enable network address
+resolution, and B<t> to enable transport-layer port number resolution. 
+This overrides B<-n> if both B<-N> and B<-n> are present.
+
 =item -o
 
 Sets a preference value, overriding the default value and any value read
index 1e87c3508eebde8a2ecf488d234deebcc9d77dd8..b7b3f93db06e9edae02bec37f0ce56fbb6dcafde 100644 (file)
@@ -1,7 +1,7 @@
 /* resolv.c
  * Routines for network object lookup
  *
- * $Id: resolv.c,v 1.9 2001/04/15 03:37:15 guy Exp $
+ * $Id: resolv.c,v 1.10 2001/05/31 08:36:44 guy Exp $
  *
  * Laurent Deniel <deniel@worldnet.fr>
  *
@@ -220,7 +220,7 @@ static guchar *serv_name_lookup(guint port, port_type proto)
   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 @@ static guchar *host_name_lookup(guint addr, gboolean *found)
   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 @@ static guchar *host_name_lookup6(struct e_in6_addr *addr, gboolean *found)
 #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 @@ extern guchar *get_hostname(guint addr)
 {
   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 @@ extern const guchar *get_hostname6(struct e_in6_addr *addr)
   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 @@ extern guchar *get_udp_port(guint port)
   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 @@ extern guchar *get_tcp_port(guint port)
   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 @@ extern guchar *get_sctp_port(guint port)
   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_sctp_port(guint port)
 
 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 @@ guchar *get_ether_name_if_known(const guint8 *addr)
 
   /* 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 void add_ether_byip(guint ip, const guint8 *eth)
 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 @@ extern const guchar *get_manuf_name(const guint8 *addr)
   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 7f52396ca5706a448af1814cabc38d5ec7deb4c5..c7e01acdd7e46429736a80e00aba5b15dc8921ab 100644 (file)
@@ -1,7 +1,7 @@
 /* capture_dlg.c
  * Routines for packet capture windows
  *
- * $Id: capture_dlg.c,v 1.42 2001/05/31 05:33:15 guy Exp $
+ * $Id: capture_dlg.c,v 1.43 2001/05/31 08:36:45 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -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 @@ capture_prep_cb(GtkWidget *w, gpointer d)
                 *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 @@ capture_prep_cb(GtkWidget *w, gpointer d)
   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 @@ capture_prep_cb(GtkWidget *w, gpointer d)
   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 @@ cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data)
 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 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
   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 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
 
   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 d052f23b4e84b72a45b30e458581359acb8e3b0e..44c23c2f3397719cb64ed6e99ebb6be97f2832e3 100644 (file)
@@ -1,7 +1,7 @@
 /* display_opts.c
  * Routines for packet display windows
  *
- * $Id: display_opts.c,v 1.20 2001/04/15 03:37:16 guy Exp $
+ * $Id: display_opts.c,v 1.21 2001/05/31 08:36:45 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -71,7 +71,9 @@ extern GtkWidget *packet_list;
 #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,9 +180,28 @@ display_opt_cb(GtkWidget *w, gpointer d) {
   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);
@@ -267,9 +288,16 @@ get_display_options(GtkWidget *parent_w)
                                             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 ef820469992bf8243a9fdb58ad17b4c4a7d9b8fa..d2d3906480a5c95490f1131fe57f9059b80538ec 100644 (file)
@@ -1,7 +1,7 @@
 /* file_dlg.c
  * Dialog boxes for handling files
  *
- * $Id: file_dlg.c,v 1.38 2001/04/15 03:37:16 guy Exp $
+ * $Id: file_dlg.c,v 1.39 2001/05/31 08:36:46 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -57,7 +57,9 @@ static void select_file_type_cb(GtkWidget *w, gpointer data);
 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
@@ -71,8 +73,9 @@ static GtkWidget *file_open_w;
 void
 file_open_cmd_cb(GtkWidget *w, gpointer data)
 {
-  GtkWidget    *filter_hbox, *filter_bt, *filter_te,
-               *resolv_cb;
+  GtkWidget    *main_vb, *filter_hbox, *filter_bt, *filter_te,
+               *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,33 +94,27 @@ file_open_cmd_cb(GtkWidget *w, gpointer data)
   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);
 
-  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);
-  gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->main_vbox),
-                 resolv_cb, FALSE, FALSE, 5);
-  gtk_widget_show(resolv_cb);
-  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
-                 E_FILE_RESOLVE_KEY,  resolv_cb);
-
-  
-  /* Connect the ok_button to file_open_ok_cb function and pass along a
-     pointer to the file selection box widget */
-  gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION (file_open_w)->ok_button),
-    "clicked", (GtkSignalFunc) file_open_ok_cb, file_open_w);
-
-  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
-      E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
+  /* Container for each row of widgets */
+  main_vb = gtk_vbox_new(FALSE, 3);
+  gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+  gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->action_area),
+    main_vb, FALSE, FALSE, 0);
+  gtk_widget_show(main_vb);
 
   filter_hbox = gtk_hbox_new(FALSE, 1);
   gtk_container_border_width(GTK_CONTAINER(filter_hbox), 0);
-  gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->action_area),
-    filter_hbox, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(main_vb), filter_hbox, FALSE, FALSE, 0);
   gtk_widget_show(filter_hbox);
 
   filter_bt = gtk_button_new_with_label("Filter:");
@@ -134,6 +131,41 @@ file_open_cmd_cb(GtkWidget *w, gpointer data)
   gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
     E_RFILTER_TE_KEY, filter_te);
 
+  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_start(GTK_BOX(main_vb), m_resolv_cb, FALSE, FALSE, 0);
+  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);
+
+  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_start(GTK_BOX(main_vb), n_resolv_cb, FALSE, FALSE, 0);
+  gtk_widget_show(n_resolv_cb);
+  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
+                 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_start(GTK_BOX(main_vb), t_resolv_cb, FALSE, FALSE, 0);
+  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 */
+  gtk_signal_connect(GTK_OBJECT (GTK_FILE_SELECTION(file_open_w)->ok_button),
+    "clicked", (GtkSignalFunc) file_open_ok_cb, file_open_w);
+
+  gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
+      E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
+
   /* Connect the cancel_button to destroy the widget */
   gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
     (file_open_w)->cancel_button), "clicked", (GtkSignalFunc)
@@ -150,7 +182,7 @@ file_open_cmd_cb(GtkWidget *w, gpointer data)
 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 +222,13 @@ file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
   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 83968e04de8df8ec58c537d3f0609b89acf2e99f..774ad399bb5453a6fdd680ecaa6afa3a03997021 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.198 2001/05/01 00:41:46 guy Exp $
+ * $Id: main.c,v 1.199 2001/05/31 08:36:46 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -539,8 +539,8 @@ void expand_all_cb(GtkWidget *widget, gpointer data) {
 
 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 @@ print_usage(void) {
   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
 }
@@ -823,6 +825,7 @@ main(int argc, char *argv[])
   dfilter_t           *rfcode = NULL;
   gboolean             rfilter_parse_failed = FALSE;
   e_prefs             *prefs;
+  char                 badopt;
   char                *bold_font_name;
 
   ethereal_path = argv[0];
@@ -983,7 +986,7 @@ main(int argc, char *argv[])
 #endif
 
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "B:c:f:hi:klm:no:pP:Qr:R:Ss:t:T:w:W:vZ:")) !=  EOF) {
+  while ((opt = getopt(argc, argv, "B:c:f:hi:klm:nN:o:pP:Qr:R:Ss:t:T:w:W:vZ:")) !=  EOF) {
     switch (opt) {
       case 'B':        /* Byte view pane height */
         bv_size = get_positive_int(optarg, "byte view pane height");
@@ -1032,11 +1035,21 @@ main(int argc, char *argv[])
       case 'm':        /* Fixed-width font for the display */
         if (prefs->gui_font_name != NULL)
           g_free(prefs->gui_font_name);
-       prefs->gui_font_name = g_strdup(optarg);
-       break;
+        prefs->gui_font_name = g_strdup(optarg);
+        break;
       case 'n':        /* No name resolution */
-       prefs->name_resolve = 0;
-       break;
+        prefs->name_resolve = PREFS_RESOLV_NONE;
+        break;
+      case 'N':        /* Select what types of addresses/port #s to resolve */
+        if (prefs->name_resolve == PREFS_RESOLV_ALL)
+          prefs->name_resolve = PREFS_RESOLV_NONE;
+        badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
+        if (badopt != '\0') {
+          fprintf(stderr, "ethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
+                       badopt);
+          exit(1);
+        }
+        break;
       case 'o':        /* Override preference from command line */
         switch (prefs_set_pref(optarg)) {
 
diff --git a/prefs.c b/prefs.c
index b3d37757d8f9d6d1463dc9a125bdf6ce8ca94181..1cd49c68e7faa0f0e8927a54fb9c84c33e635288 100644 (file)
--- a/prefs.c
+++ b/prefs.c
@@ -1,7 +1,7 @@
 /* prefs.c
  * Routines for handling preferences
  *
- * $Id: prefs.c,v 1.50 2001/04/15 03:37:13 guy Exp $
+ * $Id: prefs.c,v 1.51 2001/05/31 08:36:41 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -615,8 +615,7 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return,
     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;
   }
 
   /* Read the global preferences file, if it exists. */
@@ -873,6 +872,66 @@ prefs_set_pref(char *prefarg)
 static gchar *pr_formats[] = { "text", "postscript" };
 static gchar *pr_dests[]   = { "command", "file" };
 
+typedef struct {
+  char    letter;
+  guint32 value;
+} name_resolve_opt_t;
+
+static name_resolve_opt_t name_resolve_opt[] = {
+  { 'm', PREFS_RESOLV_MAC },
+  { 'n', PREFS_RESOLV_NETWORK },
+  { 't', PREFS_RESOLV_TRANSPORT },
+};
+
+#define N_NAME_RESOLVE_OPT     (sizeof name_resolve_opt / sizeof name_resolve_opt[0])
+
+static char *
+name_resolve_to_string(guint32 name_resolve)
+{
+  static char string[N_NAME_RESOLVE_OPT+1];
+  char *p;
+  int i;
+  gboolean all_opts_set = TRUE;
+
+  if (name_resolve == PREFS_RESOLV_NONE)
+    return "FALSE";
+  p = &string[0];
+  for (i = 0; i < N_NAME_RESOLVE_OPT; i++) {
+    if (name_resolve & name_resolve_opt[i].value)
+      *p++ =  name_resolve_opt[i].letter;
+    else
+      all_opts_set = FALSE;
+  }
+  *p = '\0';
+  if (all_opts_set)
+    return "TRUE";
+  return string;
+}
+
+char
+string_to_name_resolve(char *string, guint32 *name_resolve)
+{
+  char c;
+  int i;
+
+  *name_resolve = 0;
+  while ((c = *string++) != '\0') {
+    for (i = 0; i < N_NAME_RESOLVE_OPT; i++) {
+      if (c == name_resolve_opt[i].letter) {
+        *name_resolve |= name_resolve_opt[i].value;
+        break;
+      }
+    }
+    if (i == N_NAME_RESOLVE_OPT) {
+      /*
+       * Unrecognized letter.
+       */
+      return c;
+    }
+  }
+  return '\0';
+}
+
 static int
 set_pref(gchar *pref_name, gchar *value)
 {
@@ -953,21 +1012,21 @@ set_pref(gchar *pref_name, gchar *value)
     prefs.st_server_bg.green = GREEN_COMPONENT(cval);
     prefs.st_server_bg.blue  = BLUE_COMPONENT(cval);
   } else if (strcmp(pref_name, PRS_GUI_SCROLLBAR_ON_RIGHT) == 0) {
-    if (strcmp(value, "TRUE") == 0) {
+    if (strcasecmp(value, "true") == 0) {
            prefs.gui_scrollbar_on_right = TRUE;
     }
     else {
            prefs.gui_scrollbar_on_right = FALSE;
     }
   } else if (strcmp(pref_name, PRS_GUI_PLIST_SEL_BROWSE) == 0) {
-    if (strcmp(value, "TRUE") == 0) {
+    if (strcasecmp(value, "true") == 0) {
            prefs.gui_plist_sel_browse = TRUE;
     }
     else {
            prefs.gui_plist_sel_browse = FALSE;
     }
   } else if (strcmp(pref_name, PRS_GUI_PTREE_SEL_BROWSE) == 0) {
-    if (strcmp(value, "TRUE") == 0) {
+    if (strcasecmp(value, "true") == 0) {
            prefs.gui_ptree_sel_browse = TRUE;
     }
     else {
@@ -1001,18 +1060,32 @@ set_pref(gchar *pref_name, gchar *value)
 
 /* handle the capture options */ 
   } else if (strcmp(pref_name, PRS_CAP_PROM_MODE) == 0) {
-    prefs.capture_prom_mode = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); 
+    prefs.capture_prom_mode = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); 
  
   } else if (strcmp(pref_name, PRS_CAP_REAL_TIME) == 0) {
-    prefs.capture_real_time = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); 
+    prefs.capture_real_time = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); 
 
   } else if (strcmp(pref_name, PRS_CAP_AUTO_SCROLL) == 0) {
-    prefs.capture_auto_scroll = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); 
+    prefs.capture_auto_scroll = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); 
  
+/* handle the global options */
   } 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); 
-
+    /*
+     * "TRUE" and "FALSE", for backwards compatibility, are synonyms for
+     * PREFS_RESOLV_ALL and PREFS_RESOLV_NONE.
+     *
+     * Otherwise, we treat it as a list of name types we want to resolve.
+     */
+    if (strcasecmp(value, "true") == 0)
+      prefs.name_resolve = PREFS_RESOLV_ALL;
+    else if (strcasecmp(value, "false") == 0)
+      prefs.name_resolve = PREFS_RESOLV_NONE;
+    else {
+      prefs.name_resolve = PREFS_RESOLV_NONE;  /* start out with none set */
+      if (string_to_name_resolve(value, &prefs.name_resolve) != '\0')
+        return PREFS_SET_SYNTAX_ERR;
+    }
   } else {
     /* To which module does this preference belong? */
     dotp = strchr(pref_name, '.');
@@ -1337,9 +1410,9 @@ write_prefs(char **pf_path_return)
     (prefs.gui_marked_bg.green * 255 / 65535),
     (prefs.gui_marked_bg.blue * 255 / 65535));
 
-  fprintf(pf, "\n# Resolve addresses to names? TRUE/FALSE\n");
+  fprintf(pf, "\n# Resolve addresses to names? TRUE/FALSE/{list of address types to resolve}\n");
   fprintf(pf, PRS_NAME_RESOLVE ": %s\n",
-                 prefs.name_resolve == TRUE ? "TRUE" : "FALSE");
+                 name_resolve_to_string(prefs.name_resolve));
 
 /* write the capture options */
   fprintf(pf, "\n# Capture in promiscuous mode? TRUE/FALSE\n");
diff --git a/prefs.h b/prefs.h
index 580012a02ce2f44039c2806cbd822eb0ff486fcb..a7daa2b4b823f0a518ac2333eac47df91d459303 100644 (file)
--- a/prefs.h
+++ b/prefs.h
@@ -1,7 +1,7 @@
 /* prefs.h
  * Definitions for preference handling routines
  *
- * $Id: prefs.h,v 1.29 2001/04/15 03:37:13 guy Exp $
+ * $Id: prefs.h,v 1.30 2001/05/31 08:36:41 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #define PR_DEST_CMD  0
 #define PR_DEST_FILE 1
 
+/* 32 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
+
+/*
+ * Convert a string listing name resolution types to a bitmask of
+ * those types.
+ *
+ * Set "*name_resolve" to the bitmask, and return '\0', on success;
+ * return the bad character in the string on error.
+ */
+char string_to_name_resolve(char *string, guint32 *name_resolve);
+
 typedef struct _e_prefs {
   gint     pr_format;
   gint     pr_dest;
@@ -50,11 +68,10 @@ typedef struct _e_prefs {
   gchar   *gui_font_name;
   color_t  gui_marked_fg;
   color_t  gui_marked_bg;
-  gboolean name_resolve;
+  guint32  name_resolve;
   gboolean capture_prom_mode;
   gboolean capture_real_time;
   gboolean capture_auto_scroll;
-
 } e_prefs;
 
 extern e_prefs prefs;
index 171c36407d236163d8c342e8b8a63192150f153d..6a6fc71b7c059ae21b2c56d136c05c8a9cde1b9b 100644 (file)
@@ -1,6 +1,6 @@
 /* tethereal.c
  *
- * $Id: tethereal.c,v 1.82 2001/04/20 21:50:06 guy Exp $
+ * $Id: tethereal.c,v 1.83 2001/05/31 08:36:41 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -151,14 +151,14 @@ print_usage(void)
   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++) {
@@ -223,10 +223,11 @@ main(int argc, char *argv[])
 #else
   gboolean             capture_option_specified = FALSE;
 #endif
-  int                 out_file_type = WTAP_FILE_PCAP;
+  int                  out_file_type = WTAP_FILE_PCAP;
   gchar               *cf_name = NULL, *rfilter = NULL;
   dfilter_t           *rfcode = NULL;
   e_prefs             *prefs;
+  char                 badopt;
 
   /* Register all dissectors; we must do this before checking for the
      "-G" flag, as the "-G" flag dumps a list of fields registered
@@ -336,7 +337,7 @@ main(int argc, char *argv[])
 #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 +418,18 @@ main(int argc, char *argv[])
        line_buffered = TRUE;
        break;
       case 'n':        /* No name resolution */
-       prefs->name_resolve = 0;
-       break;
+        prefs->name_resolve = PREFS_RESOLV_NONE;
+        break;
+      case 'N':        /* Select what types of addresses/port #s to resolve */
+        if (prefs->name_resolve == PREFS_RESOLV_ALL)
+          prefs->name_resolve = PREFS_RESOLV_NONE;
+        badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
+        if (badopt != '\0') {
+          fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
+                       badopt);
+          exit(1);
+        }
+        break;
       case 'o':        /* Override preference from command line */
         switch (prefs_set_pref(optarg)) {