1/* Virtual terminal interface shell.
2 * Copyright (C) 2000 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include <sys/un.h>
25#include <setjmp.h>
26#include <sys/wait.h>
27#include <sys/resource.h>
28#include <sys/stat.h>
29
30#include <readline/readline.h>
31#include <readline/history.h>
32
33#include "command.h"
34#include "memory.h"
35#include "vtysh/vtysh.h"
36#include "log.h"
37#include "bgpd/bgp_vty.h"
38
39/* Struct VTY. */
40struct vty *vty;
41
42/* VTY shell pager name. */
43char *vtysh_pager_name = NULL;
44
45/* VTY shell client structure. */
46struct vtysh_client
47{
48  int fd;
49  const char *name;
50  int flag;
51  const char *path;
52} vtysh_client[] =
53{
54  { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
55  { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
56  { .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
57  { .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
58  { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
59  { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
60  { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
61  { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH},
62  { .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH},
63};
64
65
66/* We need direct access to ripd to implement vtysh_exit_ripd_only. */
67static struct vtysh_client *ripd_client = NULL;
68
69
70/* Using integrated config from Quagga.conf. Default is no. */
71int vtysh_writeconfig_integrated = 0;
72
73extern char config_default[];
74
75static void
76vclient_close (struct vtysh_client *vclient)
77{
78  if (vclient->fd >= 0)
79    {
80      fprintf(stderr,
81	      "Warning: closing connection to %s because of an I/O error!\n",
82	      vclient->name);
83      close (vclient->fd);
84      vclient->fd = -1;
85    }
86}
87
88/* Following filled with debug code to trace a problematic condition
89 * under load - it SHOULD handle it. */
90#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
91static int
92vtysh_client_config (struct vtysh_client *vclient, char *line)
93{
94  int ret;
95  char *buf;
96  size_t bufsz;
97  char *pbuf;
98  size_t left;
99  char *eoln;
100  int nbytes;
101  int i;
102  int readln;
103
104  if (vclient->fd < 0)
105    return CMD_SUCCESS;
106
107  ret = write (vclient->fd, line, strlen (line) + 1);
108  if (ret <= 0)
109    {
110      vclient_close (vclient);
111      return CMD_SUCCESS;
112    }
113
114  /* Allow enough room for buffer to read more than a few pages from socket. */
115  bufsz = 5 * getpagesize() + 1;
116  buf = XMALLOC(MTYPE_TMP, bufsz);
117  memset(buf, 0, bufsz);
118  pbuf = buf;
119
120  while (1)
121    {
122      if (pbuf >= ((buf + bufsz) -1))
123	{
124	  fprintf (stderr, ERR_WHERE_STRING \
125		   "warning - pbuf beyond buffer end.\n");
126	  return CMD_WARNING;
127	}
128
129      readln = (buf + bufsz) - pbuf - 1;
130      nbytes = read (vclient->fd, pbuf, readln);
131
132      if (nbytes <= 0)
133	{
134
135	  if (errno == EINTR)
136	    continue;
137
138	  fprintf(stderr, ERR_WHERE_STRING "(%u)", errno);
139	  perror("");
140
141	  if (errno == EAGAIN || errno == EIO)
142	    continue;
143
144	  vclient_close (vclient);
145	  XFREE(MTYPE_TMP, buf);
146	  return CMD_SUCCESS;
147	}
148
149      pbuf[nbytes] = '\0';
150
151      if (nbytes >= 4)
152	{
153	  i = nbytes - 4;
154	  if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')
155	    {
156	      ret = pbuf[i + 3];
157	      break;
158	    }
159	}
160      pbuf += nbytes;
161
162      /* See if a line exists in buffer, if so parse and consume it, and
163       * reset read position. */
164      if ((eoln = strrchr(buf, '\n')) == NULL)
165	continue;
166
167      if (eoln >= ((buf + bufsz) - 1))
168	{
169	  fprintf (stderr, ERR_WHERE_STRING \
170		   "warning - eoln beyond buffer end.\n");
171	}
172      vtysh_config_parse(buf);
173
174      eoln++;
175      left = (size_t)(buf + bufsz - eoln);
176      memmove(buf, eoln, left);
177      buf[bufsz-1] = '\0';
178      pbuf = buf + strlen(buf);
179    }
180
181  /* Parse anything left in the buffer. */
182
183  vtysh_config_parse (buf);
184
185  XFREE(MTYPE_TMP, buf);
186  return ret;
187}
188
189static int
190vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
191{
192  int ret;
193  char buf[1001];
194  int nbytes;
195  int i;
196  int numnulls = 0;
197
198  if (vclient->fd < 0)
199    return CMD_SUCCESS;
200
201  ret = write (vclient->fd, line, strlen (line) + 1);
202  if (ret <= 0)
203    {
204      vclient_close (vclient);
205      return CMD_SUCCESS;
206    }
207
208  while (1)
209    {
210      nbytes = read (vclient->fd, buf, sizeof(buf)-1);
211
212      if (nbytes <= 0 && errno != EINTR)
213	{
214	  vclient_close (vclient);
215	  return CMD_SUCCESS;
216	}
217
218      if (nbytes > 0)
219	{
220	  if ((numnulls == 3) && (nbytes == 1))
221	    return buf[0];
222
223	  buf[nbytes] = '\0';
224	  fputs (buf, fp);
225	  fflush (fp);
226
227	  /* check for trailling \0\0\0<ret code>,
228	   * even if split across reads
229	   * (see lib/vty.c::vtysh_read)
230	   */
231          if (nbytes >= 4)
232            {
233              i = nbytes-4;
234              numnulls = 0;
235            }
236          else
237            i = 0;
238
239          while (i < nbytes && numnulls < 3)
240            {
241              if (buf[i++] == '\0')
242                numnulls++;
243              else
244                numnulls = 0;
245            }
246
247          /* got 3 or more trailing NULs? */
248          if ((numnulls >= 3) && (i < nbytes))
249            return (buf[nbytes-1]);
250	}
251    }
252}
253
254void
255vtysh_exit_ripd_only (void)
256{
257  if (ripd_client)
258    vtysh_client_execute (ripd_client, "exit", stdout);
259}
260
261
262void
263vtysh_pager_init (void)
264{
265  char *pager_defined;
266
267  pager_defined = getenv ("VTYSH_PAGER");
268
269  if (pager_defined)
270    vtysh_pager_name = strdup (pager_defined);
271  else
272    vtysh_pager_name = strdup ("more");
273}
274
275/* Command execution over the vty interface. */
276static int
277vtysh_execute_func (const char *line, int pager)
278{
279  int ret, cmd_stat;
280  u_int i;
281  vector vline;
282  struct cmd_element *cmd;
283  FILE *fp = NULL;
284  int closepager = 0;
285  int tried = 0;
286  int saved_ret, saved_node;
287
288  /* Split readline string up into the vector. */
289  vline = cmd_make_strvec (line);
290
291  if (vline == NULL)
292    return CMD_SUCCESS;
293
294  saved_ret = ret = cmd_execute_command (vline, vty, &cmd, 1);
295  saved_node = vty->node;
296
297  /* If command doesn't succeeded in current node, try to walk up in node tree.
298   * Changing vty->node is enough to try it just out without actual walkup in
299   * the vtysh. */
300  while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON && ret != CMD_WARNING
301	 && vty->node > CONFIG_NODE)
302    {
303      vty->node = node_parent(vty->node);
304      ret = cmd_execute_command (vline, vty, &cmd, 1);
305      tried++;
306    }
307
308  vty->node = saved_node;
309
310  /* If command succeeded in any other node than current (tried > 0) we have
311   * to move into node in the vtysh where it succeeded. */
312  if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)
313    {
314      if ((saved_node == BGP_VPNV4_NODE || saved_node == BGP_IPV4_NODE
315	   || saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE
316	   || saved_node == BGP_IPV6M_NODE)
317	  && (tried == 1))
318	{
319	  vtysh_execute("exit-address-family");
320	}
321      else if ((saved_node == KEYCHAIN_KEY_NODE) && (tried == 1))
322	{
323	  vtysh_execute("exit");
324	}
325      else if (tried)
326	{
327	  vtysh_execute ("end");
328	  vtysh_execute ("configure terminal");
329	}
330    }
331  /* If command didn't succeed in any node, continue with return value from
332   * first try. */
333  else if (tried)
334    {
335      ret = saved_ret;
336    }
337
338  cmd_free_strvec (vline);
339
340  cmd_stat = ret;
341  switch (ret)
342    {
343    case CMD_WARNING:
344      if (vty->type == VTY_FILE)
345	fprintf (stdout,"Warning...\n");
346      break;
347    case CMD_ERR_AMBIGUOUS:
348      fprintf (stdout,"%% Ambiguous command.\n");
349      break;
350    case CMD_ERR_NO_MATCH:
351      fprintf (stdout,"%% Unknown command.\n");
352      break;
353    case CMD_ERR_INCOMPLETE:
354      fprintf (stdout,"%% Command incomplete.\n");
355      break;
356    case CMD_SUCCESS_DAEMON:
357      {
358	/* FIXME: Don't open pager for exit commands. popen() causes problems
359	 * if exited from vtysh at all. This hack shouldn't cause any problem
360	 * but is really ugly. */
361	if (pager && vtysh_pager_name && (strncmp(line, "exit", 4) != 0))
362	  {
363	    fp = popen (vtysh_pager_name, "w");
364	    if (fp == NULL)
365	      {
366		perror ("popen failed for pager");
367		fp = stdout;
368	      }
369	    else
370	      closepager=1;
371	  }
372	else
373	  fp = stdout;
374
375	if (! strcmp(cmd->string,"configure terminal"))
376	  {
377	    for (i = 0; i < array_size(vtysh_client); i++)
378	      {
379	        cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
380		if (cmd_stat == CMD_WARNING)
381		  break;
382	      }
383
384	    if (cmd_stat)
385	      {
386		line = "end";
387		vline = cmd_make_strvec (line);
388
389		if (vline == NULL)
390		  {
391		    if (pager && vtysh_pager_name && fp && closepager)
392		      {
393			if (pclose (fp) == -1)
394			  {
395			    perror ("pclose failed for pager");
396			  }
397			fp = NULL;
398		      }
399		    return CMD_SUCCESS;
400		  }
401
402		ret = cmd_execute_command (vline, vty, &cmd, 1);
403		cmd_free_strvec (vline);
404		if (ret != CMD_SUCCESS_DAEMON)
405		  break;
406	      }
407	    else
408	      if (cmd->func)
409		{
410		  (*cmd->func) (cmd, vty, 0, NULL);
411		  break;
412		}
413	  }
414
415	cmd_stat = CMD_SUCCESS;
416	for (i = 0; i < array_size(vtysh_client); i++)
417	  {
418	    if (cmd->daemon & vtysh_client[i].flag)
419	      {
420	        cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
421		if (cmd_stat != CMD_SUCCESS)
422		  break;
423	      }
424	  }
425	if (cmd_stat != CMD_SUCCESS)
426	  break;
427
428	if (cmd->func)
429	  (*cmd->func) (cmd, vty, 0, NULL);
430      }
431    }
432  if (pager && vtysh_pager_name && fp && closepager)
433    {
434      if (pclose (fp) == -1)
435	{
436	  perror ("pclose failed for pager");
437	}
438      fp = NULL;
439    }
440  return cmd_stat;
441}
442
443int
444vtysh_execute_no_pager (const char *line)
445{
446  return vtysh_execute_func (line, 0);
447}
448
449int
450vtysh_execute (const char *line)
451{
452  return vtysh_execute_func (line, 1);
453}
454
455/* Configration make from file. */
456int
457vtysh_config_from_file (struct vty *vty, FILE *fp)
458{
459  int ret;
460  vector vline;
461  struct cmd_element *cmd;
462
463  while (fgets (vty->buf, VTY_BUFSIZ, fp))
464    {
465      if (vty->buf[0] == '!' || vty->buf[1] == '#')
466	continue;
467
468      vline = cmd_make_strvec (vty->buf);
469
470      /* In case of comment line. */
471      if (vline == NULL)
472	continue;
473
474      /* Execute configuration command : this is strict match. */
475      ret = cmd_execute_command_strict (vline, vty, &cmd);
476
477      /* Try again with setting node to CONFIG_NODE. */
478      if (ret != CMD_SUCCESS
479	  && ret != CMD_SUCCESS_DAEMON
480	  && ret != CMD_WARNING)
481	{
482	  if (vty->node == KEYCHAIN_KEY_NODE)
483	    {
484	      vty->node = KEYCHAIN_NODE;
485	      vtysh_exit_ripd_only ();
486	      ret = cmd_execute_command_strict (vline, vty, &cmd);
487
488	      if (ret != CMD_SUCCESS
489		  && ret != CMD_SUCCESS_DAEMON
490		  && ret != CMD_WARNING)
491		{
492		  vtysh_exit_ripd_only ();
493		  vty->node = CONFIG_NODE;
494		  ret = cmd_execute_command_strict (vline, vty, &cmd);
495		}
496	    }
497	  else
498	    {
499	      vtysh_execute ("end");
500	      vtysh_execute ("configure terminal");
501	      vty->node = CONFIG_NODE;
502	      ret = cmd_execute_command_strict (vline, vty, &cmd);
503	    }
504	}
505
506      cmd_free_strvec (vline);
507
508      switch (ret)
509	{
510	case CMD_WARNING:
511	  if (vty->type == VTY_FILE)
512	    fprintf (stdout,"Warning...\n");
513	  break;
514	case CMD_ERR_AMBIGUOUS:
515	  fprintf (stdout,"%% Ambiguous command.\n");
516	  break;
517	case CMD_ERR_NO_MATCH:
518	  fprintf (stdout,"%% Unknown command: %s", vty->buf);
519	  break;
520	case CMD_ERR_INCOMPLETE:
521	  fprintf (stdout,"%% Command incomplete.\n");
522	  break;
523	case CMD_SUCCESS_DAEMON:
524	  {
525	    u_int i;
526	    int cmd_stat = CMD_SUCCESS;
527
528	    for (i = 0; i < array_size(vtysh_client); i++)
529	      {
530	        if (cmd->daemon & vtysh_client[i].flag)
531		  {
532		    cmd_stat = vtysh_client_execute (&vtysh_client[i],
533						     vty->buf, stdout);
534		    if (cmd_stat != CMD_SUCCESS)
535		      break;
536		  }
537	      }
538	    if (cmd_stat != CMD_SUCCESS)
539	      break;
540
541	    if (cmd->func)
542	      (*cmd->func) (cmd, vty, 0, NULL);
543	  }
544	}
545    }
546  return CMD_SUCCESS;
547}
548
549/* We don't care about the point of the cursor when '?' is typed. */
550int
551vtysh_rl_describe (void)
552{
553  int ret;
554  unsigned int i;
555  vector vline;
556  vector describe;
557  int width;
558  struct cmd_token *token;
559
560  vline = cmd_make_strvec (rl_line_buffer);
561
562  /* In case of '> ?'. */
563  if (vline == NULL)
564    {
565      vline = vector_init (1);
566      vector_set (vline, '\0');
567    }
568  else
569    if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
570      vector_set (vline, '\0');
571
572  describe = cmd_describe_command (vline, vty, &ret);
573
574  fprintf (stdout,"\n");
575
576  /* Ambiguous and no match error. */
577  switch (ret)
578    {
579    case CMD_ERR_AMBIGUOUS:
580      cmd_free_strvec (vline);
581      fprintf (stdout,"%% Ambiguous command.\n");
582      rl_on_new_line ();
583      return 0;
584      break;
585    case CMD_ERR_NO_MATCH:
586      cmd_free_strvec (vline);
587      fprintf (stdout,"%% There is no matched command.\n");
588      rl_on_new_line ();
589      return 0;
590      break;
591    }
592
593  /* Get width of command string. */
594  width = 0;
595  for (i = 0; i < vector_active (describe); i++)
596    if ((token = vector_slot (describe, i)) != NULL)
597      {
598	int len;
599
600	if (token->cmd[0] == '\0')
601	  continue;
602
603	len = strlen (token->cmd);
604	if (token->cmd[0] == '.')
605	  len--;
606
607	if (width < len)
608	  width = len;
609      }
610
611  for (i = 0; i < vector_active (describe); i++)
612    if ((token = vector_slot (describe, i)) != NULL)
613      {
614	if (token->cmd[0] == '\0')
615	  continue;
616
617	if (! token->desc)
618	  fprintf (stdout,"  %-s\n",
619		   token->cmd[0] == '.' ? token->cmd + 1 : token->cmd);
620	else
621	  fprintf (stdout,"  %-*s  %s\n",
622		   width,
623		   token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
624		   token->desc);
625      }
626
627  cmd_free_strvec (vline);
628  vector_free (describe);
629
630  rl_on_new_line();
631
632  return 0;
633}
634
635/* Result of cmd_complete_command() call will be stored here
636 * and used in new_completion() in order to put the space in
637 * correct places only. */
638int complete_status;
639
640static char *
641command_generator (const char *text, int state)
642{
643  vector vline;
644  static char **matched = NULL;
645  static int index = 0;
646
647  /* First call. */
648  if (! state)
649    {
650      index = 0;
651
652      if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
653	return NULL;
654
655      vline = cmd_make_strvec (rl_line_buffer);
656      if (vline == NULL)
657	return NULL;
658
659      if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
660	vector_set (vline, '\0');
661
662      matched = cmd_complete_command (vline, vty, &complete_status);
663    }
664
665  if (matched && matched[index])
666    return matched[index++];
667
668  return NULL;
669}
670
671static char **
672new_completion (char *text, int start, int end)
673{
674  char **matches;
675
676  matches = rl_completion_matches (text, command_generator);
677
678  if (matches)
679    {
680      rl_point = rl_end;
681      if (complete_status != CMD_COMPLETE_FULL_MATCH)
682        /* only append a space on full match */
683        rl_completion_append_character = '\0';
684    }
685
686  return matches;
687}
688
689#if 0
690/* This function is not actually being used. */
691static char **
692vtysh_completion (char *text, int start, int end)
693{
694  int ret;
695  vector vline;
696  char **matched = NULL;
697
698  if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
699    return NULL;
700
701  vline = cmd_make_strvec (rl_line_buffer);
702  if (vline == NULL)
703    return NULL;
704
705  /* In case of 'help \t'. */
706  if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
707    vector_set (vline, '\0');
708
709  matched = cmd_complete_command (vline, vty, &ret);
710
711  cmd_free_strvec (vline);
712
713  return (char **) matched;
714}
715#endif
716
717/* Vty node structures. */
718static struct cmd_node bgp_node =
719{
720  BGP_NODE,
721  "%s(config-router)# ",
722};
723
724static struct cmd_node rip_node =
725{
726  RIP_NODE,
727  "%s(config-router)# ",
728};
729
730static struct cmd_node isis_node =
731{
732  ISIS_NODE,
733  "%s(config-router)# ",
734};
735
736static struct cmd_node interface_node =
737{
738  INTERFACE_NODE,
739  "%s(config-if)# ",
740};
741
742static struct cmd_node rmap_node =
743{
744  RMAP_NODE,
745  "%s(config-route-map)# "
746};
747
748static struct cmd_node zebra_node =
749{
750  ZEBRA_NODE,
751  "%s(config-router)# "
752};
753
754static struct cmd_node bgp_vpnv4_node =
755{
756  BGP_VPNV4_NODE,
757  "%s(config-router-af)# "
758};
759
760static struct cmd_node bgp_ipv4_node =
761{
762  BGP_IPV4_NODE,
763  "%s(config-router-af)# "
764};
765
766static struct cmd_node bgp_ipv4m_node =
767{
768  BGP_IPV4M_NODE,
769  "%s(config-router-af)# "
770};
771
772static struct cmd_node bgp_ipv6_node =
773{
774  BGP_IPV6_NODE,
775  "%s(config-router-af)# "
776};
777
778static struct cmd_node bgp_ipv6m_node =
779{
780  BGP_IPV6M_NODE,
781  "%s(config-router-af)# "
782};
783
784static struct cmd_node ospf_node =
785{
786  OSPF_NODE,
787  "%s(config-router)# "
788};
789
790static struct cmd_node ripng_node =
791{
792  RIPNG_NODE,
793  "%s(config-router)# "
794};
795
796static struct cmd_node ospf6_node =
797{
798  OSPF6_NODE,
799  "%s(config-ospf6)# "
800};
801
802static struct cmd_node babel_node =
803{
804  BABEL_NODE,
805  "%s(config-babel)# "
806};
807
808static struct cmd_node keychain_node =
809{
810  KEYCHAIN_NODE,
811  "%s(config-keychain)# "
812};
813
814static struct cmd_node keychain_key_node =
815{
816  KEYCHAIN_KEY_NODE,
817  "%s(config-keychain-key)# "
818};
819
820/* Defined in lib/vty.c */
821extern struct cmd_node vty_node;
822
823/* When '^Z' is received from vty, move down to the enable mode. */
824int
825vtysh_end (void)
826{
827  switch (vty->node)
828    {
829    case VIEW_NODE:
830    case ENABLE_NODE:
831      /* Nothing to do. */
832      break;
833    default:
834      vty->node = ENABLE_NODE;
835      break;
836    }
837  return CMD_SUCCESS;
838}
839
840DEFUNSH (VTYSH_ALL,
841	 vtysh_end_all,
842	 vtysh_end_all_cmd,
843	 "end",
844	 "End current mode and change to enable mode\n")
845{
846  return vtysh_end ();
847}
848
849DEFUNSH (VTYSH_BGPD,
850	 router_bgp,
851	 router_bgp_cmd,
852	 "router bgp " CMD_AS_RANGE,
853	 ROUTER_STR
854	 BGP_STR
855	 AS_STR)
856{
857  vty->node = BGP_NODE;
858  return CMD_SUCCESS;
859}
860
861ALIAS_SH (VTYSH_BGPD,
862	  router_bgp,
863	  router_bgp_view_cmd,
864	  "router bgp " CMD_AS_RANGE " view WORD",
865	  ROUTER_STR
866	  BGP_STR
867	  AS_STR
868	  "BGP view\n"
869	  "view name\n")
870
871DEFUNSH (VTYSH_BGPD,
872	 address_family_vpnv4,
873	 address_family_vpnv4_cmd,
874	 "address-family vpnv4",
875	 "Enter Address Family command mode\n"
876	 "Address family\n")
877{
878  vty->node = BGP_VPNV4_NODE;
879  return CMD_SUCCESS;
880}
881
882DEFUNSH (VTYSH_BGPD,
883	 address_family_vpnv4_unicast,
884	 address_family_vpnv4_unicast_cmd,
885	 "address-family vpnv4 unicast",
886	 "Enter Address Family command mode\n"
887	 "Address family\n"
888	 "Address Family Modifier\n")
889{
890  vty->node = BGP_VPNV4_NODE;
891  return CMD_SUCCESS;
892}
893
894DEFUNSH (VTYSH_BGPD,
895	 address_family_ipv4_unicast,
896	 address_family_ipv4_unicast_cmd,
897	 "address-family ipv4 unicast",
898	 "Enter Address Family command mode\n"
899	 "Address family\n"
900	 "Address Family Modifier\n")
901{
902  vty->node = BGP_IPV4_NODE;
903  return CMD_SUCCESS;
904}
905
906DEFUNSH (VTYSH_BGPD,
907	 address_family_ipv4_multicast,
908	 address_family_ipv4_multicast_cmd,
909	 "address-family ipv4 multicast",
910	 "Enter Address Family command mode\n"
911	 "Address family\n"
912	 "Address Family Modifier\n")
913{
914  vty->node = BGP_IPV4M_NODE;
915  return CMD_SUCCESS;
916}
917
918DEFUNSH (VTYSH_BGPD,
919	 address_family_ipv6,
920	 address_family_ipv6_cmd,
921	 "address-family ipv6",
922	 "Enter Address Family command mode\n"
923	 "Address family\n")
924{
925  vty->node = BGP_IPV6_NODE;
926  return CMD_SUCCESS;
927}
928
929DEFUNSH (VTYSH_BGPD,
930	 address_family_ipv6_unicast,
931	 address_family_ipv6_unicast_cmd,
932	 "address-family ipv6 unicast",
933	 "Enter Address Family command mode\n"
934	 "Address family\n"
935	 "Address Family Modifier\n")
936{
937  vty->node = BGP_IPV6_NODE;
938  return CMD_SUCCESS;
939}
940
941DEFUNSH (VTYSH_BGPD,
942	 address_family_ipv6_multicast,
943	 address_family_ipv6_multicast_cmd,
944	 "address-family ipv6 multicast",
945	 "Enter Address Family command mode\n"
946	 "Address family\n"
947	 "Address Family Modifier\n")
948{
949  vty->node = BGP_IPV6M_NODE;
950  return CMD_SUCCESS;
951}
952
953DEFUNSH (VTYSH_RIPD,
954	 key_chain,
955	 key_chain_cmd,
956	 "key chain WORD",
957	 "Authentication key management\n"
958	 "Key-chain management\n"
959	 "Key-chain name\n")
960{
961  vty->node = KEYCHAIN_NODE;
962  return CMD_SUCCESS;
963}
964
965DEFUNSH (VTYSH_RIPD,
966	 key,
967	 key_cmd,
968	 "key <0-2147483647>",
969	 "Configure a key\n"
970	 "Key identifier number\n")
971{
972  vty->node = KEYCHAIN_KEY_NODE;
973  return CMD_SUCCESS;
974}
975
976DEFUNSH (VTYSH_RIPD,
977	 router_rip,
978	 router_rip_cmd,
979	 "router rip",
980	 ROUTER_STR
981	 "RIP")
982{
983  vty->node = RIP_NODE;
984  return CMD_SUCCESS;
985}
986
987DEFUNSH (VTYSH_RIPNGD,
988	 router_ripng,
989	 router_ripng_cmd,
990	 "router ripng",
991	 ROUTER_STR
992	 "RIPng")
993{
994  vty->node = RIPNG_NODE;
995  return CMD_SUCCESS;
996}
997
998DEFUNSH (VTYSH_OSPFD,
999	 router_ospf,
1000	 router_ospf_cmd,
1001	 "router ospf",
1002	 "Enable a routing process\n"
1003	 "Start OSPF configuration\n")
1004{
1005  vty->node = OSPF_NODE;
1006  return CMD_SUCCESS;
1007}
1008
1009DEFUNSH (VTYSH_OSPF6D,
1010	 router_ospf6,
1011	 router_ospf6_cmd,
1012	 "router ospf6",
1013	 OSPF6_ROUTER_STR
1014	 OSPF6_STR)
1015{
1016  vty->node = OSPF6_NODE;
1017  return CMD_SUCCESS;
1018}
1019
1020DEFUNSH (VTYSH_BABELD,
1021	 router_babel,
1022	 router_babel_cmd,
1023	 "router babel",
1024	 ROUTER_STR
1025	 "Babel")
1026{
1027  vty->node = BABEL_NODE;
1028  return CMD_SUCCESS;
1029}
1030
1031DEFUNSH (VTYSH_ISISD,
1032	 router_isis,
1033	 router_isis_cmd,
1034	 "router isis WORD",
1035	 ROUTER_STR
1036	 "ISO IS-IS\n"
1037	 "ISO Routing area tag")
1038{
1039  vty->node = ISIS_NODE;
1040  return CMD_SUCCESS;
1041}
1042
1043DEFUNSH (VTYSH_RMAP,
1044	 route_map,
1045	 route_map_cmd,
1046	 "route-map WORD (deny|permit) <1-65535>",
1047	 "Create route-map or enter route-map command mode\n"
1048	 "Route map tag\n"
1049	 "Route map denies set operations\n"
1050	 "Route map permits set operations\n"
1051	 "Sequence to insert to/delete from existing route-map entry\n")
1052{
1053  vty->node = RMAP_NODE;
1054  return CMD_SUCCESS;
1055}
1056
1057DEFUNSH (VTYSH_ALL,
1058	 vtysh_line_vty,
1059	 vtysh_line_vty_cmd,
1060	 "line vty",
1061	 "Configure a terminal line\n"
1062	 "Virtual terminal\n")
1063{
1064  vty->node = VTY_NODE;
1065  return CMD_SUCCESS;
1066}
1067
1068DEFUNSH (VTYSH_ALL,
1069	 vtysh_enable,
1070	 vtysh_enable_cmd,
1071	 "enable",
1072	 "Turn on privileged mode command\n")
1073{
1074  vty->node = ENABLE_NODE;
1075  return CMD_SUCCESS;
1076}
1077
1078DEFUNSH (VTYSH_ALL,
1079	 vtysh_disable,
1080	 vtysh_disable_cmd,
1081	 "disable",
1082	 "Turn off privileged mode command\n")
1083{
1084  if (vty->node == ENABLE_NODE)
1085    vty->node = VIEW_NODE;
1086  return CMD_SUCCESS;
1087}
1088
1089DEFUNSH (VTYSH_ALL,
1090	 vtysh_config_terminal,
1091	 vtysh_config_terminal_cmd,
1092	 "configure terminal",
1093	 "Configuration from vty interface\n"
1094	 "Configuration terminal\n")
1095{
1096  vty->node = CONFIG_NODE;
1097  return CMD_SUCCESS;
1098}
1099
1100static int
1101vtysh_exit (struct vty *vty)
1102{
1103  switch (vty->node)
1104    {
1105    case VIEW_NODE:
1106    case ENABLE_NODE:
1107      exit (0);
1108      break;
1109    case CONFIG_NODE:
1110      vty->node = ENABLE_NODE;
1111      break;
1112    case INTERFACE_NODE:
1113    case ZEBRA_NODE:
1114    case BGP_NODE:
1115    case RIP_NODE:
1116    case RIPNG_NODE:
1117    case OSPF_NODE:
1118    case OSPF6_NODE:
1119    case BABEL_NODE:
1120    case ISIS_NODE:
1121    case MASC_NODE:
1122    case RMAP_NODE:
1123    case VTY_NODE:
1124    case KEYCHAIN_NODE:
1125      vtysh_execute("end");
1126      vtysh_execute("configure terminal");
1127      vty->node = CONFIG_NODE;
1128      break;
1129    case BGP_VPNV4_NODE:
1130    case BGP_IPV4_NODE:
1131    case BGP_IPV4M_NODE:
1132    case BGP_IPV6_NODE:
1133    case BGP_IPV6M_NODE:
1134      vty->node = BGP_NODE;
1135      break;
1136    case KEYCHAIN_KEY_NODE:
1137      vty->node = KEYCHAIN_NODE;
1138      break;
1139    default:
1140      break;
1141    }
1142  return CMD_SUCCESS;
1143}
1144
1145DEFUNSH (VTYSH_ALL,
1146	 vtysh_exit_all,
1147	 vtysh_exit_all_cmd,
1148	 "exit",
1149	 "Exit current mode and down to previous mode\n")
1150{
1151  return vtysh_exit (vty);
1152}
1153
1154ALIAS (vtysh_exit_all,
1155       vtysh_quit_all_cmd,
1156       "quit",
1157       "Exit current mode and down to previous mode\n")
1158
1159DEFUNSH (VTYSH_BGPD,
1160	 exit_address_family,
1161	 exit_address_family_cmd,
1162	 "exit-address-family",
1163	 "Exit from Address Family configuration mode\n")
1164{
1165  if (vty->node == BGP_IPV4_NODE
1166      || vty->node == BGP_IPV4M_NODE
1167      || vty->node == BGP_VPNV4_NODE
1168      || vty->node == BGP_IPV6_NODE
1169      || vty->node == BGP_IPV6M_NODE)
1170    vty->node = BGP_NODE;
1171  return CMD_SUCCESS;
1172}
1173
1174DEFUNSH (VTYSH_ZEBRA,
1175	 vtysh_exit_zebra,
1176	 vtysh_exit_zebra_cmd,
1177	 "exit",
1178	 "Exit current mode and down to previous mode\n")
1179{
1180  return vtysh_exit (vty);
1181}
1182
1183ALIAS (vtysh_exit_zebra,
1184       vtysh_quit_zebra_cmd,
1185       "quit",
1186       "Exit current mode and down to previous mode\n")
1187
1188DEFUNSH (VTYSH_RIPD,
1189	 vtysh_exit_ripd,
1190	 vtysh_exit_ripd_cmd,
1191	 "exit",
1192	 "Exit current mode and down to previous mode\n")
1193{
1194  return vtysh_exit (vty);
1195}
1196
1197ALIAS (vtysh_exit_ripd,
1198       vtysh_quit_ripd_cmd,
1199       "quit",
1200       "Exit current mode and down to previous mode\n")
1201
1202DEFUNSH (VTYSH_RIPNGD,
1203	 vtysh_exit_ripngd,
1204	 vtysh_exit_ripngd_cmd,
1205	 "exit",
1206	 "Exit current mode and down to previous mode\n")
1207{
1208  return vtysh_exit (vty);
1209}
1210
1211ALIAS (vtysh_exit_ripngd,
1212       vtysh_quit_ripngd_cmd,
1213       "quit",
1214       "Exit current mode and down to previous mode\n")
1215
1216DEFUNSH (VTYSH_RMAP,
1217	 vtysh_exit_rmap,
1218	 vtysh_exit_rmap_cmd,
1219	 "exit",
1220	 "Exit current mode and down to previous mode\n")
1221{
1222  return vtysh_exit (vty);
1223}
1224
1225ALIAS (vtysh_exit_rmap,
1226       vtysh_quit_rmap_cmd,
1227       "quit",
1228       "Exit current mode and down to previous mode\n")
1229
1230DEFUNSH (VTYSH_BGPD,
1231	 vtysh_exit_bgpd,
1232	 vtysh_exit_bgpd_cmd,
1233	 "exit",
1234	 "Exit current mode and down to previous mode\n")
1235{
1236  return vtysh_exit (vty);
1237}
1238
1239ALIAS (vtysh_exit_bgpd,
1240       vtysh_quit_bgpd_cmd,
1241       "quit",
1242       "Exit current mode and down to previous mode\n")
1243
1244DEFUNSH (VTYSH_OSPFD,
1245	 vtysh_exit_ospfd,
1246	 vtysh_exit_ospfd_cmd,
1247	 "exit",
1248	 "Exit current mode and down to previous mode\n")
1249{
1250  return vtysh_exit (vty);
1251}
1252
1253ALIAS (vtysh_exit_ospfd,
1254       vtysh_quit_ospfd_cmd,
1255       "quit",
1256       "Exit current mode and down to previous mode\n")
1257
1258DEFUNSH (VTYSH_OSPF6D,
1259	 vtysh_exit_ospf6d,
1260	 vtysh_exit_ospf6d_cmd,
1261	 "exit",
1262	 "Exit current mode and down to previous mode\n")
1263{
1264  return vtysh_exit (vty);
1265}
1266
1267ALIAS (vtysh_exit_ospf6d,
1268       vtysh_quit_ospf6d_cmd,
1269       "quit",
1270       "Exit current mode and down to previous mode\n")
1271
1272DEFUNSH (VTYSH_ISISD,
1273	 vtysh_exit_isisd,
1274	 vtysh_exit_isisd_cmd,
1275	 "exit",
1276	 "Exit current mode and down to previous mode\n")
1277{
1278  return vtysh_exit (vty);
1279}
1280
1281ALIAS (vtysh_exit_isisd,
1282       vtysh_quit_isisd_cmd,
1283       "quit",
1284       "Exit current mode and down to previous mode\n")
1285
1286DEFUNSH (VTYSH_ALL,
1287         vtysh_exit_line_vty,
1288         vtysh_exit_line_vty_cmd,
1289         "exit",
1290         "Exit current mode and down to previous mode\n")
1291{
1292  return vtysh_exit (vty);
1293}
1294
1295ALIAS (vtysh_exit_line_vty,
1296       vtysh_quit_line_vty_cmd,
1297       "quit",
1298       "Exit current mode and down to previous mode\n")
1299
1300DEFUNSH (VTYSH_INTERFACE,
1301	 vtysh_interface,
1302	 vtysh_interface_cmd,
1303	 "interface IFNAME",
1304	 "Select an interface to configure\n"
1305	 "Interface's name\n")
1306{
1307  vty->node = INTERFACE_NODE;
1308  return CMD_SUCCESS;
1309}
1310
1311/* TODO Implement "no interface command in isisd. */
1312DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
1313       vtysh_no_interface_cmd,
1314       "no interface IFNAME",
1315       NO_STR
1316       "Delete a pseudo interface's configuration\n"
1317       "Interface's name\n")
1318
1319/* TODO Implement interface description commands in ripngd, ospf6d
1320 * and isisd. */
1321DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
1322       interface_desc_cmd,
1323       "description .LINE",
1324       "Interface specific description\n"
1325       "Characters describing this interface\n")
1326
1327DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
1328       no_interface_desc_cmd,
1329       "no description",
1330       NO_STR
1331       "Interface specific description\n")
1332
1333DEFUNSH (VTYSH_INTERFACE,
1334	 vtysh_exit_interface,
1335	 vtysh_exit_interface_cmd,
1336	 "exit",
1337	 "Exit current mode and down to previous mode\n")
1338{
1339  return vtysh_exit (vty);
1340}
1341
1342ALIAS (vtysh_exit_interface,
1343       vtysh_quit_interface_cmd,
1344       "quit",
1345       "Exit current mode and down to previous mode\n")
1346
1347/* Memory */
1348DEFUN (vtysh_show_memory,
1349       vtysh_show_memory_cmd,
1350       "show memory",
1351       SHOW_STR
1352       "Memory statistics\n")
1353{
1354  unsigned int i;
1355  int ret = CMD_SUCCESS;
1356  char line[] = "show memory\n";
1357
1358  for (i = 0; i < array_size(vtysh_client); i++)
1359    if ( vtysh_client[i].fd >= 0 )
1360      {
1361        fprintf (stdout, "Memory statistics for %s:\n",
1362                 vtysh_client[i].name);
1363        ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
1364        fprintf (stdout,"\n");
1365      }
1366
1367  return ret;
1368}
1369
1370/* Logging commands. */
1371DEFUN (vtysh_show_logging,
1372       vtysh_show_logging_cmd,
1373       "show logging",
1374       SHOW_STR
1375       "Show current logging configuration\n")
1376{
1377  unsigned int i;
1378  int ret = CMD_SUCCESS;
1379  char line[] = "show logging\n";
1380
1381  for (i = 0; i < array_size(vtysh_client); i++)
1382    if ( vtysh_client[i].fd >= 0 )
1383      {
1384        fprintf (stdout,"Logging configuration for %s:\n",
1385                 vtysh_client[i].name);
1386        ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
1387        fprintf (stdout,"\n");
1388      }
1389
1390  return ret;
1391}
1392
1393DEFUNSH (VTYSH_ALL,
1394	 vtysh_log_stdout,
1395	 vtysh_log_stdout_cmd,
1396	 "log stdout",
1397	 "Logging control\n"
1398	 "Set stdout logging level\n")
1399{
1400  return CMD_SUCCESS;
1401}
1402
1403DEFUNSH (VTYSH_ALL,
1404	 vtysh_log_stdout_level,
1405	 vtysh_log_stdout_level_cmd,
1406	 "log stdout "LOG_LEVELS,
1407	 "Logging control\n"
1408	 "Set stdout logging level\n"
1409	 LOG_LEVEL_DESC)
1410{
1411  return CMD_SUCCESS;
1412}
1413
1414DEFUNSH (VTYSH_ALL,
1415	 no_vtysh_log_stdout,
1416	 no_vtysh_log_stdout_cmd,
1417	 "no log stdout [LEVEL]",
1418	 NO_STR
1419	 "Logging control\n"
1420	 "Cancel logging to stdout\n"
1421	 "Logging level\n")
1422{
1423  return CMD_SUCCESS;
1424}
1425
1426DEFUNSH (VTYSH_ALL,
1427	 vtysh_log_file,
1428	 vtysh_log_file_cmd,
1429	 "log file FILENAME",
1430	 "Logging control\n"
1431	 "Logging to file\n"
1432	 "Logging filename\n")
1433{
1434  return CMD_SUCCESS;
1435}
1436
1437DEFUNSH (VTYSH_ALL,
1438	 vtysh_log_file_level,
1439	 vtysh_log_file_level_cmd,
1440	 "log file FILENAME "LOG_LEVELS,
1441	 "Logging control\n"
1442	 "Logging to file\n"
1443	 "Logging filename\n"
1444	 LOG_LEVEL_DESC)
1445{
1446  return CMD_SUCCESS;
1447}
1448
1449DEFUNSH (VTYSH_ALL,
1450	 no_vtysh_log_file,
1451	 no_vtysh_log_file_cmd,
1452	 "no log file [FILENAME]",
1453	 NO_STR
1454	 "Logging control\n"
1455	 "Cancel logging to file\n"
1456	 "Logging file name\n")
1457{
1458  return CMD_SUCCESS;
1459}
1460
1461ALIAS_SH (VTYSH_ALL,
1462	  no_vtysh_log_file,
1463	  no_vtysh_log_file_level_cmd,
1464	  "no log file FILENAME LEVEL",
1465	  NO_STR
1466	  "Logging control\n"
1467	  "Cancel logging to file\n"
1468	  "Logging file name\n"
1469	  "Logging level\n")
1470
1471DEFUNSH (VTYSH_ALL,
1472	 vtysh_log_monitor,
1473	 vtysh_log_monitor_cmd,
1474	 "log monitor",
1475	 "Logging control\n"
1476	 "Set terminal line (monitor) logging level\n")
1477{
1478  return CMD_SUCCESS;
1479}
1480
1481DEFUNSH (VTYSH_ALL,
1482	 vtysh_log_monitor_level,
1483	 vtysh_log_monitor_level_cmd,
1484	 "log monitor "LOG_LEVELS,
1485	 "Logging control\n"
1486	 "Set terminal line (monitor) logging level\n"
1487	 LOG_LEVEL_DESC)
1488{
1489  return CMD_SUCCESS;
1490}
1491
1492DEFUNSH (VTYSH_ALL,
1493	 no_vtysh_log_monitor,
1494	 no_vtysh_log_monitor_cmd,
1495	 "no log monitor [LEVEL]",
1496	 NO_STR
1497	 "Logging control\n"
1498	 "Disable terminal line (monitor) logging\n"
1499	 "Logging level\n")
1500{
1501  return CMD_SUCCESS;
1502}
1503
1504DEFUNSH (VTYSH_ALL,
1505	 vtysh_log_syslog,
1506	 vtysh_log_syslog_cmd,
1507	 "log syslog",
1508	 "Logging control\n"
1509	 "Set syslog logging level\n")
1510{
1511  return CMD_SUCCESS;
1512}
1513
1514DEFUNSH (VTYSH_ALL,
1515	 vtysh_log_syslog_level,
1516	 vtysh_log_syslog_level_cmd,
1517	 "log syslog "LOG_LEVELS,
1518	 "Logging control\n"
1519	 "Set syslog logging level\n"
1520	 LOG_LEVEL_DESC)
1521{
1522  return CMD_SUCCESS;
1523}
1524
1525DEFUNSH (VTYSH_ALL,
1526	 no_vtysh_log_syslog,
1527	 no_vtysh_log_syslog_cmd,
1528	 "no log syslog [LEVEL]",
1529	 NO_STR
1530	 "Logging control\n"
1531	 "Cancel logging to syslog\n"
1532	 "Logging level\n")
1533{
1534  return CMD_SUCCESS;
1535}
1536
1537DEFUNSH (VTYSH_ALL,
1538	 vtysh_log_facility,
1539	 vtysh_log_facility_cmd,
1540	 "log facility "LOG_FACILITIES,
1541	 "Logging control\n"
1542	 "Facility parameter for syslog messages\n"
1543	 LOG_FACILITY_DESC)
1544
1545{
1546  return CMD_SUCCESS;
1547}
1548
1549DEFUNSH (VTYSH_ALL,
1550	 no_vtysh_log_facility,
1551	 no_vtysh_log_facility_cmd,
1552	 "no log facility [FACILITY]",
1553	 NO_STR
1554	 "Logging control\n"
1555	 "Reset syslog facility to default (daemon)\n"
1556	 "Syslog facility\n")
1557
1558{
1559  return CMD_SUCCESS;
1560}
1561
1562DEFUNSH_DEPRECATED (VTYSH_ALL,
1563		    vtysh_log_trap,
1564		    vtysh_log_trap_cmd,
1565		    "log trap "LOG_LEVELS,
1566		    "Logging control\n"
1567		    "(Deprecated) Set logging level and default for all destinations\n"
1568		    LOG_LEVEL_DESC)
1569
1570{
1571  return CMD_SUCCESS;
1572}
1573
1574DEFUNSH_DEPRECATED (VTYSH_ALL,
1575		    no_vtysh_log_trap,
1576		    no_vtysh_log_trap_cmd,
1577		    "no log trap [LEVEL]",
1578		    NO_STR
1579		    "Logging control\n"
1580		    "Permit all logging information\n"
1581		    "Logging level\n")
1582{
1583  return CMD_SUCCESS;
1584}
1585
1586DEFUNSH (VTYSH_ALL,
1587	 vtysh_log_record_priority,
1588	 vtysh_log_record_priority_cmd,
1589	 "log record-priority",
1590	 "Logging control\n"
1591	 "Log the priority of the message within the message\n")
1592{
1593  return CMD_SUCCESS;
1594}
1595
1596DEFUNSH (VTYSH_ALL,
1597	 no_vtysh_log_record_priority,
1598	 no_vtysh_log_record_priority_cmd,
1599	 "no log record-priority",
1600	 NO_STR
1601	 "Logging control\n"
1602	 "Do not log the priority of the message within the message\n")
1603{
1604  return CMD_SUCCESS;
1605}
1606
1607DEFUNSH (VTYSH_ALL,
1608	 vtysh_log_timestamp_precision,
1609	 vtysh_log_timestamp_precision_cmd,
1610	 "log timestamp precision <0-6>",
1611	 "Logging control\n"
1612	 "Timestamp configuration\n"
1613	 "Set the timestamp precision\n"
1614	 "Number of subsecond digits\n")
1615{
1616  return CMD_SUCCESS;
1617}
1618
1619DEFUNSH (VTYSH_ALL,
1620	 no_vtysh_log_timestamp_precision,
1621	 no_vtysh_log_timestamp_precision_cmd,
1622	 "no log timestamp precision",
1623	 NO_STR
1624	 "Logging control\n"
1625	 "Timestamp configuration\n"
1626	 "Reset the timestamp precision to the default value of 0\n")
1627{
1628  return CMD_SUCCESS;
1629}
1630
1631DEFUNSH (VTYSH_ALL,
1632	 vtysh_service_password_encrypt,
1633	 vtysh_service_password_encrypt_cmd,
1634	 "service password-encryption",
1635	 "Set up miscellaneous service\n"
1636	 "Enable encrypted passwords\n")
1637{
1638  return CMD_SUCCESS;
1639}
1640
1641DEFUNSH (VTYSH_ALL,
1642	 no_vtysh_service_password_encrypt,
1643	 no_vtysh_service_password_encrypt_cmd,
1644	 "no service password-encryption",
1645	 NO_STR
1646	 "Set up miscellaneous service\n"
1647	 "Enable encrypted passwords\n")
1648{
1649  return CMD_SUCCESS;
1650}
1651
1652DEFUNSH (VTYSH_ALL,
1653	 vtysh_config_password,
1654	 vtysh_password_cmd,
1655	 "password (8|) WORD",
1656	 "Assign the terminal connection password\n"
1657	 "Specifies a HIDDEN password will follow\n"
1658	 "dummy string \n"
1659	 "The HIDDEN line password string\n")
1660{
1661  return CMD_SUCCESS;
1662}
1663
1664DEFUNSH (VTYSH_ALL,
1665	 vtysh_password_text,
1666	 vtysh_password_text_cmd,
1667	 "password LINE",
1668	 "Assign the terminal connection password\n"
1669	 "The UNENCRYPTED (cleartext) line password\n")
1670{
1671  return CMD_SUCCESS;
1672}
1673
1674DEFUNSH (VTYSH_ALL,
1675	 vtysh_config_enable_password,
1676	 vtysh_enable_password_cmd,
1677	 "enable password (8|) WORD",
1678	 "Modify enable password parameters\n"
1679	 "Assign the privileged level password\n"
1680	 "Specifies a HIDDEN password will follow\n"
1681	 "dummy string \n"
1682	 "The HIDDEN 'enable' password string\n")
1683{
1684  return CMD_SUCCESS;
1685}
1686
1687DEFUNSH (VTYSH_ALL,
1688	 vtysh_enable_password_text,
1689	 vtysh_enable_password_text_cmd,
1690	 "enable password LINE",
1691	 "Modify enable password parameters\n"
1692	 "Assign the privileged level password\n"
1693	 "The UNENCRYPTED (cleartext) 'enable' password\n")
1694{
1695  return CMD_SUCCESS;
1696}
1697
1698DEFUNSH (VTYSH_ALL,
1699	 no_vtysh_config_enable_password,
1700	 no_vtysh_enable_password_cmd,
1701	 "no enable password",
1702	 NO_STR
1703	 "Modify enable password parameters\n"
1704	 "Assign the privileged level password\n")
1705{
1706  return CMD_SUCCESS;
1707}
1708
1709DEFUN (vtysh_write_terminal,
1710       vtysh_write_terminal_cmd,
1711       "write terminal",
1712       "Write running configuration to memory, network, or terminal\n"
1713       "Write to terminal\n")
1714{
1715  u_int i;
1716  int ret;
1717  char line[] = "write terminal\n";
1718  FILE *fp = NULL;
1719
1720  if (vtysh_pager_name)
1721    {
1722      fp = popen (vtysh_pager_name, "w");
1723      if (fp == NULL)
1724	{
1725	  perror ("popen");
1726	  exit (1);
1727	}
1728    }
1729  else
1730    fp = stdout;
1731
1732  vty_out (vty, "Building configuration...%s", VTY_NEWLINE);
1733  vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
1734	   VTY_NEWLINE);
1735  vty_out (vty, "!%s", VTY_NEWLINE);
1736
1737  for (i = 0; i < array_size(vtysh_client); i++)
1738    ret = vtysh_client_config (&vtysh_client[i], line);
1739
1740  /* Integrate vtysh specific configuration. */
1741  vtysh_config_write ();
1742
1743  vtysh_config_dump (fp);
1744
1745  if (vtysh_pager_name && fp)
1746    {
1747      fflush (fp);
1748      if (pclose (fp) == -1)
1749	{
1750	  perror ("pclose");
1751	  exit (1);
1752	}
1753      fp = NULL;
1754    }
1755
1756  vty_out (vty, "end%s", VTY_NEWLINE);
1757
1758  return CMD_SUCCESS;
1759}
1760
1761DEFUN (vtysh_integrated_config,
1762       vtysh_integrated_config_cmd,
1763       "service integrated-vtysh-config",
1764       "Set up miscellaneous service\n"
1765       "Write configuration into integrated file\n")
1766{
1767  vtysh_writeconfig_integrated = 1;
1768  return CMD_SUCCESS;
1769}
1770
1771DEFUN (no_vtysh_integrated_config,
1772       no_vtysh_integrated_config_cmd,
1773       "no service integrated-vtysh-config",
1774       NO_STR
1775       "Set up miscellaneous service\n"
1776       "Write configuration into integrated file\n")
1777{
1778  vtysh_writeconfig_integrated = 0;
1779  return CMD_SUCCESS;
1780}
1781
1782static int
1783write_config_integrated(void)
1784{
1785  u_int i;
1786  int ret;
1787  char line[] = "write terminal\n";
1788  FILE *fp;
1789  char *integrate_sav = NULL;
1790
1791  integrate_sav = malloc (strlen (integrate_default) +
1792			  strlen (CONF_BACKUP_EXT) + 1);
1793  strcpy (integrate_sav, integrate_default);
1794  strcat (integrate_sav, CONF_BACKUP_EXT);
1795
1796  fprintf (stdout,"Building Configuration...\n");
1797
1798  /* Move current configuration file to backup config file. */
1799  unlink (integrate_sav);
1800  rename (integrate_default, integrate_sav);
1801  free (integrate_sav);
1802
1803  fp = fopen (integrate_default, "w");
1804  if (fp == NULL)
1805    {
1806      fprintf (stdout,"%% Can't open configuration file %s.\n",
1807	       integrate_default);
1808      return CMD_SUCCESS;
1809    }
1810
1811  for (i = 0; i < array_size(vtysh_client); i++)
1812    ret = vtysh_client_config (&vtysh_client[i], line);
1813
1814  vtysh_config_dump (fp);
1815
1816  fclose (fp);
1817
1818  if (chmod (integrate_default, CONFIGFILE_MASK) != 0)
1819    {
1820      fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n",
1821	integrate_default, safe_strerror(errno), errno);
1822      return CMD_WARNING;
1823    }
1824
1825  fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default);
1826
1827  fprintf (stdout,"[OK]\n");
1828
1829  return CMD_SUCCESS;
1830}
1831
1832DEFUN (vtysh_write_memory,
1833       vtysh_write_memory_cmd,
1834       "write memory",
1835       "Write running configuration to memory, network, or terminal\n"
1836       "Write configuration to the file (same as write file)\n")
1837{
1838  int ret = CMD_SUCCESS;
1839  char line[] = "write memory\n";
1840  u_int i;
1841
1842  /* If integrated Quagga.conf explicitely set. */
1843  if (vtysh_writeconfig_integrated)
1844    return write_config_integrated();
1845
1846  fprintf (stdout,"Building Configuration...\n");
1847
1848  for (i = 0; i < array_size(vtysh_client); i++)
1849    ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
1850
1851  fprintf (stdout,"[OK]\n");
1852
1853  return ret;
1854}
1855
1856ALIAS (vtysh_write_memory,
1857       vtysh_copy_runningconfig_startupconfig_cmd,
1858       "copy running-config startup-config",
1859       "Copy from one file to another\n"
1860       "Copy from current system configuration\n"
1861       "Copy to startup configuration\n")
1862
1863ALIAS (vtysh_write_memory,
1864       vtysh_write_file_cmd,
1865       "write file",
1866       "Write running configuration to memory, network, or terminal\n"
1867       "Write configuration to the file (same as write memory)\n")
1868
1869ALIAS (vtysh_write_memory,
1870       vtysh_write_cmd,
1871       "write",
1872       "Write running configuration to memory, network, or terminal\n")
1873
1874ALIAS (vtysh_write_terminal,
1875       vtysh_show_running_config_cmd,
1876       "show running-config",
1877       SHOW_STR
1878       "Current operating configuration\n")
1879
1880DEFUN (vtysh_terminal_length,
1881       vtysh_terminal_length_cmd,
1882       "terminal length <0-512>",
1883       "Set terminal line parameters\n"
1884       "Set number of lines on a screen\n"
1885       "Number of lines on screen (0 for no pausing)\n")
1886{
1887  int lines;
1888  char *endptr = NULL;
1889  char default_pager[10];
1890
1891  lines = strtol (argv[0], &endptr, 10);
1892  if (lines < 0 || lines > 512 || *endptr != '\0')
1893    {
1894      vty_out (vty, "length is malformed%s", VTY_NEWLINE);
1895      return CMD_WARNING;
1896    }
1897
1898  if (vtysh_pager_name)
1899    {
1900      free (vtysh_pager_name);
1901      vtysh_pager_name = NULL;
1902    }
1903
1904  if (lines != 0)
1905    {
1906      snprintf(default_pager, 10, "more -%i", lines);
1907      vtysh_pager_name = strdup (default_pager);
1908    }
1909
1910  return CMD_SUCCESS;
1911}
1912
1913DEFUN (vtysh_terminal_no_length,
1914       vtysh_terminal_no_length_cmd,
1915       "terminal no length",
1916       "Set terminal line parameters\n"
1917       NO_STR
1918       "Set number of lines on a screen\n")
1919{
1920  if (vtysh_pager_name)
1921    {
1922      free (vtysh_pager_name);
1923      vtysh_pager_name = NULL;
1924    }
1925
1926  vtysh_pager_init();
1927  return CMD_SUCCESS;
1928}
1929
1930DEFUN (vtysh_show_daemons,
1931       vtysh_show_daemons_cmd,
1932       "show daemons",
1933       SHOW_STR
1934       "Show list of running daemons\n")
1935{
1936  u_int i;
1937
1938  for (i = 0; i < array_size(vtysh_client); i++)
1939    if ( vtysh_client[i].fd >= 0 )
1940      vty_out(vty, " %s", vtysh_client[i].name);
1941  vty_out(vty, "%s", VTY_NEWLINE);
1942
1943  return CMD_SUCCESS;
1944}
1945
1946/* Execute command in child process. */
1947static int
1948execute_command (const char *command, int argc, const char *arg1,
1949		 const char *arg2)
1950{
1951  int ret;
1952  pid_t pid;
1953  int status;
1954
1955  /* Call fork(). */
1956  pid = fork ();
1957
1958  if (pid < 0)
1959    {
1960      /* Failure of fork(). */
1961      fprintf (stderr, "Can't fork: %s\n", safe_strerror (errno));
1962      exit (1);
1963    }
1964  else if (pid == 0)
1965    {
1966      /* This is child process. */
1967      switch (argc)
1968	{
1969	case 0:
1970	  ret = execlp (command, command, (const char *)NULL);
1971	  break;
1972	case 1:
1973	  ret = execlp (command, command, arg1, (const char *)NULL);
1974	  break;
1975	case 2:
1976	  ret = execlp (command, command, arg1, arg2, (const char *)NULL);
1977	  break;
1978	}
1979
1980      /* When execlp suceed, this part is not executed. */
1981      fprintf (stderr, "Can't execute %s: %s\n", command, safe_strerror (errno));
1982      exit (1);
1983    }
1984  else
1985    {
1986      /* This is parent. */
1987      execute_flag = 1;
1988      ret = wait4 (pid, &status, 0, NULL);
1989      execute_flag = 0;
1990    }
1991  return 0;
1992}
1993
1994DEFUN (vtysh_ping,
1995       vtysh_ping_cmd,
1996       "ping WORD",
1997       "Send echo messages\n"
1998       "Ping destination address or hostname\n")
1999{
2000  execute_command ("ping", 1, argv[0], NULL);
2001  return CMD_SUCCESS;
2002}
2003
2004ALIAS (vtysh_ping,
2005       vtysh_ping_ip_cmd,
2006       "ping ip WORD",
2007       "Send echo messages\n"
2008       "IP echo\n"
2009       "Ping destination address or hostname\n")
2010
2011DEFUN (vtysh_traceroute,
2012       vtysh_traceroute_cmd,
2013       "traceroute WORD",
2014       "Trace route to destination\n"
2015       "Trace route to destination address or hostname\n")
2016{
2017  execute_command ("traceroute", 1, argv[0], NULL);
2018  return CMD_SUCCESS;
2019}
2020
2021ALIAS (vtysh_traceroute,
2022       vtysh_traceroute_ip_cmd,
2023       "traceroute ip WORD",
2024       "Trace route to destination\n"
2025       "IP trace\n"
2026       "Trace route to destination address or hostname\n")
2027
2028#ifdef HAVE_IPV6
2029DEFUN (vtysh_ping6,
2030       vtysh_ping6_cmd,
2031       "ping ipv6 WORD",
2032       "Send echo messages\n"
2033       "IPv6 echo\n"
2034       "Ping destination address or hostname\n")
2035{
2036  execute_command ("ping6", 1, argv[0], NULL);
2037  return CMD_SUCCESS;
2038}
2039
2040DEFUN (vtysh_traceroute6,
2041       vtysh_traceroute6_cmd,
2042       "traceroute ipv6 WORD",
2043       "Trace route to destination\n"
2044       "IPv6 trace\n"
2045       "Trace route to destination address or hostname\n")
2046{
2047  execute_command ("traceroute6", 1, argv[0], NULL);
2048  return CMD_SUCCESS;
2049}
2050#endif
2051
2052DEFUN (vtysh_telnet,
2053       vtysh_telnet_cmd,
2054       "telnet WORD",
2055       "Open a telnet connection\n"
2056       "IP address or hostname of a remote system\n")
2057{
2058  execute_command ("telnet", 1, argv[0], NULL);
2059  return CMD_SUCCESS;
2060}
2061
2062DEFUN (vtysh_telnet_port,
2063       vtysh_telnet_port_cmd,
2064       "telnet WORD PORT",
2065       "Open a telnet connection\n"
2066       "IP address or hostname of a remote system\n"
2067       "TCP Port number\n")
2068{
2069  execute_command ("telnet", 2, argv[0], argv[1]);
2070  return CMD_SUCCESS;
2071}
2072
2073DEFUN (vtysh_ssh,
2074       vtysh_ssh_cmd,
2075       "ssh WORD",
2076       "Open an ssh connection\n"
2077       "[user@]host\n")
2078{
2079  execute_command ("ssh", 1, argv[0], NULL);
2080  return CMD_SUCCESS;
2081}
2082
2083DEFUN (vtysh_start_shell,
2084       vtysh_start_shell_cmd,
2085       "start-shell",
2086       "Start UNIX shell\n")
2087{
2088  execute_command ("sh", 0, NULL, NULL);
2089  return CMD_SUCCESS;
2090}
2091
2092DEFUN (vtysh_start_bash,
2093       vtysh_start_bash_cmd,
2094       "start-shell bash",
2095       "Start UNIX shell\n"
2096       "Start bash\n")
2097{
2098  execute_command ("bash", 0, NULL, NULL);
2099  return CMD_SUCCESS;
2100}
2101
2102DEFUN (vtysh_start_zsh,
2103       vtysh_start_zsh_cmd,
2104       "start-shell zsh",
2105       "Start UNIX shell\n"
2106       "Start Z shell\n")
2107{
2108  execute_command ("zsh", 0, NULL, NULL);
2109  return CMD_SUCCESS;
2110}
2111
2112static void
2113vtysh_install_default (enum node_type node)
2114{
2115  install_element (node, &config_list_cmd);
2116}
2117
2118/* Making connection to protocol daemon. */
2119static int
2120vtysh_connect (struct vtysh_client *vclient)
2121{
2122  int ret;
2123  int sock, len;
2124  struct sockaddr_un addr;
2125  struct stat s_stat;
2126
2127  /* Stat socket to see if we have permission to access it. */
2128  ret = stat (vclient->path, &s_stat);
2129  if (ret < 0 && errno != ENOENT)
2130    {
2131      fprintf  (stderr, "vtysh_connect(%s): stat = %s\n",
2132		vclient->path, safe_strerror(errno));
2133      exit(1);
2134    }
2135
2136  if (ret >= 0)
2137    {
2138      if (! S_ISSOCK(s_stat.st_mode))
2139	{
2140	  fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
2141		   vclient->path);
2142	  exit (1);
2143	}
2144
2145    }
2146
2147  sock = socket (AF_UNIX, SOCK_STREAM, 0);
2148  if (sock < 0)
2149    {
2150#ifdef DEBUG
2151      fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path,
2152	      safe_strerror(errno));
2153#endif /* DEBUG */
2154      return -1;
2155    }
2156
2157  memset (&addr, 0, sizeof (struct sockaddr_un));
2158  addr.sun_family = AF_UNIX;
2159  strncpy (addr.sun_path, vclient->path, strlen (vclient->path));
2160#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2161  len = addr.sun_len = SUN_LEN(&addr);
2162#else
2163  len = sizeof (addr.sun_family) + strlen (addr.sun_path);
2164#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2165
2166  ret = connect (sock, (struct sockaddr *) &addr, len);
2167  if (ret < 0)
2168    {
2169#ifdef DEBUG
2170      fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path,
2171	      safe_strerror(errno));
2172#endif /* DEBUG */
2173      close (sock);
2174      return -1;
2175    }
2176  vclient->fd = sock;
2177
2178  return 0;
2179}
2180
2181int
2182vtysh_connect_all(const char *daemon_name)
2183{
2184  u_int i;
2185  int rc = 0;
2186  int matches = 0;
2187
2188  for (i = 0; i < array_size(vtysh_client); i++)
2189    {
2190      if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))
2191	{
2192	  matches++;
2193	  if (vtysh_connect(&vtysh_client[i]) == 0)
2194	    rc++;
2195	  /* We need direct access to ripd in vtysh_exit_ripd_only. */
2196	  if (vtysh_client[i].flag == VTYSH_RIPD)
2197	    ripd_client = &vtysh_client[i];
2198	}
2199    }
2200  if (!matches)
2201    fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
2202  return rc;
2203}
2204
2205/* To disable readline's filename completion. */
2206static char *
2207vtysh_completion_entry_function (const char *ignore, int invoking_key)
2208{
2209  return NULL;
2210}
2211
2212void
2213vtysh_readline_init (void)
2214{
2215  /* readline related settings. */
2216  rl_bind_key ('?', (rl_command_func_t *) vtysh_rl_describe);
2217  rl_completion_entry_function = vtysh_completion_entry_function;
2218  rl_attempted_completion_function = (rl_completion_func_t *)new_completion;
2219}
2220
2221char *
2222vtysh_prompt (void)
2223{
2224  static struct utsname names;
2225  static char buf[100];
2226  const char*hostname;
2227  extern struct host host;
2228
2229  hostname = host.name;
2230
2231  if (!hostname)
2232    {
2233      if (!names.nodename[0])
2234	uname (&names);
2235      hostname = names.nodename;
2236    }
2237
2238  snprintf (buf, sizeof buf, cmd_prompt (vty->node), hostname);
2239
2240  return buf;
2241}
2242
2243void
2244vtysh_init_vty (void)
2245{
2246  /* Make vty structure. */
2247  vty = vty_new ();
2248  vty->type = VTY_SHELL;
2249  vty->node = VIEW_NODE;
2250
2251  /* Initialize commands. */
2252  cmd_init (0);
2253
2254  /* Install nodes. */
2255  install_node (&bgp_node, NULL);
2256  install_node (&rip_node, NULL);
2257  install_node (&interface_node, NULL);
2258  install_node (&rmap_node, NULL);
2259  install_node (&zebra_node, NULL);
2260  install_node (&bgp_vpnv4_node, NULL);
2261  install_node (&bgp_ipv4_node, NULL);
2262  install_node (&bgp_ipv4m_node, NULL);
2263/* #ifdef HAVE_IPV6 */
2264  install_node (&bgp_ipv6_node, NULL);
2265  install_node (&bgp_ipv6m_node, NULL);
2266/* #endif */
2267  install_node (&ospf_node, NULL);
2268/* #ifdef HAVE_IPV6 */
2269  install_node (&ripng_node, NULL);
2270  install_node (&ospf6_node, NULL);
2271/* #endif */
2272  install_node (&babel_node, NULL);
2273  install_node (&keychain_node, NULL);
2274  install_node (&keychain_key_node, NULL);
2275  install_node (&isis_node, NULL);
2276  install_node (&vty_node, NULL);
2277
2278  vtysh_install_default (VIEW_NODE);
2279  vtysh_install_default (ENABLE_NODE);
2280  vtysh_install_default (CONFIG_NODE);
2281  vtysh_install_default (BGP_NODE);
2282  vtysh_install_default (RIP_NODE);
2283  vtysh_install_default (INTERFACE_NODE);
2284  vtysh_install_default (RMAP_NODE);
2285  vtysh_install_default (ZEBRA_NODE);
2286  vtysh_install_default (BGP_VPNV4_NODE);
2287  vtysh_install_default (BGP_IPV4_NODE);
2288  vtysh_install_default (BGP_IPV4M_NODE);
2289  vtysh_install_default (BGP_IPV6_NODE);
2290  vtysh_install_default (BGP_IPV6M_NODE);
2291  vtysh_install_default (OSPF_NODE);
2292  vtysh_install_default (RIPNG_NODE);
2293  vtysh_install_default (OSPF6_NODE);
2294  vtysh_install_default (BABEL_NODE);
2295  vtysh_install_default (ISIS_NODE);
2296  vtysh_install_default (KEYCHAIN_NODE);
2297  vtysh_install_default (KEYCHAIN_KEY_NODE);
2298  vtysh_install_default (VTY_NODE);
2299
2300  install_element (VIEW_NODE, &vtysh_enable_cmd);
2301  install_element (ENABLE_NODE, &vtysh_config_terminal_cmd);
2302  install_element (ENABLE_NODE, &vtysh_disable_cmd);
2303
2304  /* "exit" command. */
2305  install_element (VIEW_NODE, &vtysh_exit_all_cmd);
2306  install_element (VIEW_NODE, &vtysh_quit_all_cmd);
2307  install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
2308  /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
2309  install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
2310  install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
2311  install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
2312  install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
2313  install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
2314  install_element (RIPNG_NODE, &vtysh_quit_ripngd_cmd);
2315  install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd);
2316  install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd);
2317  install_element (OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
2318  install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
2319  install_element (BGP_NODE, &vtysh_exit_bgpd_cmd);
2320  install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
2321  install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
2322  install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
2323  install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
2324  install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
2325  install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
2326  install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
2327  install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
2328  install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
2329  install_element (BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
2330  install_element (BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
2331  install_element (ISIS_NODE, &vtysh_exit_isisd_cmd);
2332  install_element (ISIS_NODE, &vtysh_quit_isisd_cmd);
2333  install_element (KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
2334  install_element (KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
2335  install_element (KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
2336  install_element (KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd);
2337  install_element (RMAP_NODE, &vtysh_exit_rmap_cmd);
2338  install_element (RMAP_NODE, &vtysh_quit_rmap_cmd);
2339  install_element (VTY_NODE, &vtysh_exit_line_vty_cmd);
2340  install_element (VTY_NODE, &vtysh_quit_line_vty_cmd);
2341
2342  /* "end" command. */
2343  install_element (CONFIG_NODE, &vtysh_end_all_cmd);
2344  install_element (ENABLE_NODE, &vtysh_end_all_cmd);
2345  install_element (RIP_NODE, &vtysh_end_all_cmd);
2346  install_element (RIPNG_NODE, &vtysh_end_all_cmd);
2347  install_element (OSPF_NODE, &vtysh_end_all_cmd);
2348  install_element (OSPF6_NODE, &vtysh_end_all_cmd);
2349  install_element (BABEL_NODE, &vtysh_end_all_cmd);
2350  install_element (BGP_NODE, &vtysh_end_all_cmd);
2351  install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
2352  install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
2353  install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
2354  install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
2355  install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);
2356  install_element (ISIS_NODE, &vtysh_end_all_cmd);
2357  install_element (KEYCHAIN_NODE, &vtysh_end_all_cmd);
2358  install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
2359  install_element (RMAP_NODE, &vtysh_end_all_cmd);
2360  install_element (VTY_NODE, &vtysh_end_all_cmd);
2361
2362  install_element (INTERFACE_NODE, &interface_desc_cmd);
2363  install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2364  install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
2365  install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
2366  install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
2367  install_element (CONFIG_NODE, &router_rip_cmd);
2368#ifdef HAVE_IPV6
2369  install_element (CONFIG_NODE, &router_ripng_cmd);
2370#endif
2371  install_element (CONFIG_NODE, &router_ospf_cmd);
2372#ifdef HAVE_IPV6
2373  install_element (CONFIG_NODE, &router_ospf6_cmd);
2374#endif
2375  install_element (CONFIG_NODE, &router_babel_cmd);
2376  install_element (CONFIG_NODE, &router_isis_cmd);
2377  install_element (CONFIG_NODE, &router_bgp_cmd);
2378  install_element (CONFIG_NODE, &router_bgp_view_cmd);
2379  install_element (BGP_NODE, &address_family_vpnv4_cmd);
2380  install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
2381  install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
2382  install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
2383#ifdef HAVE_IPV6
2384  install_element (BGP_NODE, &address_family_ipv6_cmd);
2385  install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
2386#endif
2387  install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
2388  install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
2389  install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
2390  install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
2391  install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
2392  install_element (CONFIG_NODE, &key_chain_cmd);
2393  install_element (CONFIG_NODE, &route_map_cmd);
2394  install_element (CONFIG_NODE, &vtysh_line_vty_cmd);
2395  install_element (KEYCHAIN_NODE, &key_cmd);
2396  install_element (KEYCHAIN_NODE, &key_chain_cmd);
2397  install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
2398  install_element (CONFIG_NODE, &vtysh_interface_cmd);
2399  install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
2400  install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
2401  install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
2402  install_element (ENABLE_NODE, &vtysh_write_file_cmd);
2403  install_element (ENABLE_NODE, &vtysh_write_cmd);
2404
2405  /* "write terminal" command. */
2406  install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
2407
2408  install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);
2409  install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);
2410
2411  /* "write memory" command. */
2412  install_element (ENABLE_NODE, &vtysh_write_memory_cmd);
2413
2414  install_element (VIEW_NODE, &vtysh_terminal_length_cmd);
2415  install_element (ENABLE_NODE, &vtysh_terminal_length_cmd);
2416  install_element (VIEW_NODE, &vtysh_terminal_no_length_cmd);
2417  install_element (ENABLE_NODE, &vtysh_terminal_no_length_cmd);
2418  install_element (VIEW_NODE, &vtysh_show_daemons_cmd);
2419  install_element (ENABLE_NODE, &vtysh_show_daemons_cmd);
2420
2421  install_element (VIEW_NODE, &vtysh_ping_cmd);
2422  install_element (VIEW_NODE, &vtysh_ping_ip_cmd);
2423  install_element (VIEW_NODE, &vtysh_traceroute_cmd);
2424  install_element (VIEW_NODE, &vtysh_traceroute_ip_cmd);
2425#ifdef HAVE_IPV6
2426  install_element (VIEW_NODE, &vtysh_ping6_cmd);
2427  install_element (VIEW_NODE, &vtysh_traceroute6_cmd);
2428#endif
2429  install_element (VIEW_NODE, &vtysh_telnet_cmd);
2430  install_element (VIEW_NODE, &vtysh_telnet_port_cmd);
2431  install_element (VIEW_NODE, &vtysh_ssh_cmd);
2432  install_element (ENABLE_NODE, &vtysh_ping_cmd);
2433  install_element (ENABLE_NODE, &vtysh_ping_ip_cmd);
2434  install_element (ENABLE_NODE, &vtysh_traceroute_cmd);
2435  install_element (ENABLE_NODE, &vtysh_traceroute_ip_cmd);
2436#ifdef HAVE_IPV6
2437  install_element (ENABLE_NODE, &vtysh_ping6_cmd);
2438  install_element (ENABLE_NODE, &vtysh_traceroute6_cmd);
2439#endif
2440  install_element (ENABLE_NODE, &vtysh_telnet_cmd);
2441  install_element (ENABLE_NODE, &vtysh_telnet_port_cmd);
2442  install_element (ENABLE_NODE, &vtysh_ssh_cmd);
2443  install_element (ENABLE_NODE, &vtysh_start_shell_cmd);
2444  install_element (ENABLE_NODE, &vtysh_start_bash_cmd);
2445  install_element (ENABLE_NODE, &vtysh_start_zsh_cmd);
2446
2447  install_element (VIEW_NODE, &vtysh_show_memory_cmd);
2448  install_element (ENABLE_NODE, &vtysh_show_memory_cmd);
2449
2450  /* Logging */
2451  install_element (ENABLE_NODE, &vtysh_show_logging_cmd);
2452  install_element (VIEW_NODE, &vtysh_show_logging_cmd);
2453  install_element (CONFIG_NODE, &vtysh_log_stdout_cmd);
2454  install_element (CONFIG_NODE, &vtysh_log_stdout_level_cmd);
2455  install_element (CONFIG_NODE, &no_vtysh_log_stdout_cmd);
2456  install_element (CONFIG_NODE, &vtysh_log_file_cmd);
2457  install_element (CONFIG_NODE, &vtysh_log_file_level_cmd);
2458  install_element (CONFIG_NODE, &no_vtysh_log_file_cmd);
2459  install_element (CONFIG_NODE, &no_vtysh_log_file_level_cmd);
2460  install_element (CONFIG_NODE, &vtysh_log_monitor_cmd);
2461  install_element (CONFIG_NODE, &vtysh_log_monitor_level_cmd);
2462  install_element (CONFIG_NODE, &no_vtysh_log_monitor_cmd);
2463  install_element (CONFIG_NODE, &vtysh_log_syslog_cmd);
2464  install_element (CONFIG_NODE, &vtysh_log_syslog_level_cmd);
2465  install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd);
2466  install_element (CONFIG_NODE, &vtysh_log_trap_cmd);
2467  install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd);
2468  install_element (CONFIG_NODE, &vtysh_log_facility_cmd);
2469  install_element (CONFIG_NODE, &no_vtysh_log_facility_cmd);
2470  install_element (CONFIG_NODE, &vtysh_log_record_priority_cmd);
2471  install_element (CONFIG_NODE, &no_vtysh_log_record_priority_cmd);
2472  install_element (CONFIG_NODE, &vtysh_log_timestamp_precision_cmd);
2473  install_element (CONFIG_NODE, &no_vtysh_log_timestamp_precision_cmd);
2474
2475  install_element (CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
2476  install_element (CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
2477
2478  install_element (CONFIG_NODE, &vtysh_password_cmd);
2479  install_element (CONFIG_NODE, &vtysh_password_text_cmd);
2480  install_element (CONFIG_NODE, &vtysh_enable_password_cmd);
2481  install_element (CONFIG_NODE, &vtysh_enable_password_text_cmd);
2482  install_element (CONFIG_NODE, &no_vtysh_enable_password_cmd);
2483
2484}
2485