[vty] Add support for a 'restricted mode' with anonymous vty connections

	* lib/command.h: Add a RESTRICTED_NODE, intended for use with
	  anonymous, 'no login' vtys, to provide a subset of 'view' mode
	  commands.
	* lib/command.c: Add RESTRICTED_NODE bits, nothing special, just
	  following VIEW_NODE.
	* lib/vty.c: (vty_auth) enable authentication should fall back to
	  restricted/view node as appropriate.
	  (vty_create) init vty's to restricted/view node as appropriate,
	  for the 'no login' case.
	  (vty_{no_,}restricted_mode_cmd) config commands to enable
	  'anonymous restricted' in vty configuration.
	  (vty_config_write) 'anonymous restricted' config.
	  (vty_init) Install some commands to restricted mode, and the
	  'anonymous restricted' config commands into VTY_NODE.
	* bgpd/*.c: Install some of the safe(r) BGP commands into
	  'restricted mode', i.e. lookup commands of non-sensitive data.
	  Useful with looking-glass route-servers.
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 4dd5d94..22e48db 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -1319,5 +1319,6 @@
   install_element (BGP_NODE, &no_bgp_scan_time_cmd);
   install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_scan_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);
 }
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4a642e3..9ff6465 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -11787,6 +11787,37 @@
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+  
+  /* Restricted node: VIEW_NODE - (set of dangerous commands) */
+  install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_view_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_view_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community2_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community3_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community4_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community2_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community3_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_community4_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
 
   install_element (ENABLE_NODE, &show_ip_bgp_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
@@ -11971,6 +12002,40 @@
   install_element (VIEW_NODE, &show_bgp_view_rsclient_cmd);
   install_element (VIEW_NODE, &show_bgp_view_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_bgp_view_rsclient_prefix_cmd);
+  
+  /* Restricted:
+   * VIEW_NODE - (set of dangerous commands) - (commands dependent on prev) 
+   */
+  install_element (RESTRICTED_NODE, &show_bgp_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community2_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community2_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community3_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community3_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community4_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community2_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community2_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community3_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community3_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_community4_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_exact_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_neighbor_received_prefix_filter_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_prefix_cmd);
 
   install_element (ENABLE_NODE, &show_bgp_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9086737..9237cb0 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9748,6 +9748,18 @@
   install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd);
 #endif /* HAVE_IPV6 */
+  install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
+#ifdef HAVE_IPV6
+  install_element (RESTRICTED_NODE, &show_bgp_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_summary_cmd);
+#endif /* HAVE_IPV6 */
   install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_summary_cmd);
@@ -9772,6 +9784,11 @@
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbors_peer_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_neighbors_peer_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbors_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbors_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbors_peer_cmd);
@@ -9792,6 +9809,10 @@
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_neighbors_peer_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_neighbors_peer_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_neighbors_peer_cmd);
   install_element (ENABLE_NODE, &show_bgp_neighbors_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_neighbors_cmd);
   install_element (ENABLE_NODE, &show_bgp_neighbors_peer_cmd);
@@ -9813,6 +9834,10 @@
   install_element (VIEW_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
@@ -9823,6 +9848,10 @@
   install_element (VIEW_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_rsclient_summary_cmd);
@@ -9869,6 +9898,7 @@
 
   /* "show bgp memory" commands. */
   install_element (VIEW_NODE, &show_bgp_memory_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
   install_element (ENABLE_NODE, &show_bgp_memory_cmd);
   
   /* Community-list. */
diff --git a/lib/command.c b/lib/command.c
index f3d96ed..4887f94 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -53,6 +53,12 @@
   "%s> ",
 };
 
+struct cmd_node restricted_node =
+{
+  RESTRICTED_NODE,
+  "%s$ ",
+};
+
 struct cmd_node auth_enable_node =
 {
   AUTH_ENABLE_NODE,
@@ -1563,6 +1569,7 @@
        node != VIEW_NODE &&
        node != AUTH_ENABLE_NODE &&
        node != ENABLE_NODE &&
+       node != RESTRICTED_NODE &&
        0 == strcmp( "do", first_word ) )
     return 1;
   return 0;
@@ -2376,6 +2383,7 @@
     {
     case VIEW_NODE:
     case ENABLE_NODE:
+    case RESTRICTED_NODE:
       if (vty_shell (vty))
 	exit (0);
       else
@@ -2431,6 +2439,7 @@
     {
     case VIEW_NODE:
     case ENABLE_NODE:
+    case RESTRICTED_NODE:
       /* Nothing to do. */
       break;
     case CONFIG_NODE:
@@ -3538,6 +3547,7 @@
   install_node (&enable_node, NULL);
   install_node (&auth_node, NULL);
   install_node (&auth_enable_node, NULL);
+  install_node (&restricted_node, NULL);
   install_node (&config_node, config_write_host);
 
   /* Each node's basic commands. */
@@ -3553,6 +3563,15 @@
       install_element (VIEW_NODE, &config_terminal_no_length_cmd);
       install_element (VIEW_NODE, &show_logging_cmd);
       install_element (VIEW_NODE, &echo_cmd);
+
+      install_element (RESTRICTED_NODE, &config_list_cmd);
+      install_element (RESTRICTED_NODE, &config_exit_cmd);
+      install_element (RESTRICTED_NODE, &config_quit_cmd);
+      install_element (RESTRICTED_NODE, &config_help_cmd);
+      install_element (RESTRICTED_NODE, &config_enable_cmd);
+      install_element (RESTRICTED_NODE, &config_terminal_length_cmd);
+      install_element (RESTRICTED_NODE, &config_terminal_no_length_cmd);
+      install_element (RESTRICTED_NODE, &echo_cmd);
     }
 
   if (terminal)
@@ -3620,6 +3639,7 @@
 
       install_element (VIEW_NODE, &show_thread_cpu_cmd);
       install_element (ENABLE_NODE, &show_thread_cpu_cmd);
+      install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
       install_element (VIEW_NODE, &show_work_queues_cmd);
       install_element (ENABLE_NODE, &show_work_queues_cmd);
     }
diff --git a/lib/command.h b/lib/command.h
index a725378..d093df3 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -63,6 +63,7 @@
 enum node_type 
 {
   AUTH_NODE,			/* Authentication mode of vty interface. */
+  RESTRICTED_NODE,		/* Restricted view mode */ 
   VIEW_NODE,			/* View node. Default mode of vty interface. */
   AUTH_ENABLE_NODE,		/* Authentication mode for change enable. */
   ENABLE_NODE,			/* Enable node. */
@@ -100,7 +101,7 @@
   DUMP_NODE,			/* Packet dump node. */
   FORWARDING_NODE,		/* IP forwarding node. */
   PROTOCOL_NODE,                /* protocol filtering node */
-  VTY_NODE			/* Vty node. */
+  VTY_NODE,			/* Vty node. */
 };
 
 /* Node which has some commands and prompt string and configuration
diff --git a/lib/memory.c b/lib/memory.c
index 28b3d89..f5d0cba 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -444,6 +444,16 @@
 void
 memory_init (void)
 {
+  install_element (RESTRICTED_NODE, &show_memory_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_all_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_lib_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_rip_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_ripng_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_bgp_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_ospf_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_ospf6_cmd);
+  install_element (RESTRICTED_NODE, &show_memory_isis_cmd);
+
   install_element (VIEW_NODE, &show_memory_cmd);
   install_element (VIEW_NODE, &show_memory_all_cmd);
   install_element (VIEW_NODE, &show_memory_lib_cmd);
diff --git a/lib/vty.c b/lib/vty.c
index 3208471..14a36c1 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -82,6 +82,10 @@
 /* Login password check. */
 static int no_password_check = 0;
 
+/* Restrict unauthenticated logins? */
+static const u_char restricted_mode_default = 0;
+static u_char restricted_mode = 0;
+
 /* Integrated configuration file path */
 char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
 
@@ -383,7 +387,7 @@
 	      /* AUTH_ENABLE_NODE */
 	      vty->fail = 0;
 	      vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
-	      vty->node = VIEW_NODE;
+	      vty->node = restricted_mode ? RESTRICTED_NODE : VIEW_NODE;
 	    }
 	}
     }
@@ -687,6 +691,7 @@
     {
     case VIEW_NODE:
     case ENABLE_NODE:
+    case RESTRICTED_NODE:
       /* Nothing to do. */
       break;
     case CONFIG_NODE:
@@ -1094,6 +1099,7 @@
     {
     case VIEW_NODE:
     case ENABLE_NODE:
+    case RESTRICTED_NODE:
       /* Nothing to do. */
       break;
     case CONFIG_NODE:
@@ -1613,7 +1619,9 @@
   vty->address = sockunion_su2str (su);
   if (no_password_check)
     {
-      if (host.advanced)
+      if (restricted_mode)
+        vty->node = RESTRICTED_NODE;
+      else if (host.advanced)
 	vty->node = ENABLE_NODE;
       else
 	vty->node = VIEW_NODE;
@@ -2715,6 +2723,26 @@
   return CMD_SUCCESS;
 }
 
+/* initial mode. */
+DEFUN (vty_restricted_mode,
+       vty_restricted_mode_cmd,
+       "anonymous restricted",
+       "Restrict view commands available in anonymous, unauthenticated vty\n")
+{
+  restricted_mode = 1;
+  return CMD_SUCCESS;
+}
+
+DEFUN (vty_no_restricted_mode,
+       vty_no_restricted_mode_cmd,
+       "no anonymous restricted",
+       NO_STR
+       "Enable password checking\n")
+{
+  restricted_mode = 0;
+  return CMD_SUCCESS;
+}
+
 DEFUN (service_advanced_vty,
        service_advanced_vty_cmd,
        "service advanced-vty",
@@ -2812,7 +2840,15 @@
   /* login */
   if (no_password_check)
     vty_out (vty, " no login%s", VTY_NEWLINE);
-
+    
+  if (restricted_mode != restricted_mode_default)
+    {
+      if (restricted_mode_default)
+        vty_out (vty, " no anonymous restricted%s", VTY_NEWLINE);
+      else
+        vty_out (vty, " anonymous restricted%s", VTY_NEWLINE);
+    }
+  
   vty_out (vty, "!%s", VTY_NEWLINE);
 
   return CMD_SUCCESS;
@@ -2923,6 +2959,8 @@
   /* Install bgp top node. */
   install_node (&vty_node, vty_config_write);
 
+  install_element (RESTRICTED_NODE, &config_who_cmd);
+  install_element (RESTRICTED_NODE, &show_history_cmd);
   install_element (VIEW_NODE, &config_who_cmd);
   install_element (VIEW_NODE, &show_history_cmd);
   install_element (ENABLE_NODE, &config_who_cmd);
@@ -2943,6 +2981,8 @@
   install_element (VTY_NODE, &no_vty_access_class_cmd);
   install_element (VTY_NODE, &vty_login_cmd);
   install_element (VTY_NODE, &no_vty_login_cmd);
+  install_element (VTY_NODE, &vty_restricted_mode_cmd);
+  install_element (VTY_NODE, &vty_no_restricted_mode_cmd);
 #ifdef HAVE_IPV6
   install_element (VTY_NODE, &vty_ipv6_access_class_cmd);
   install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd);