blob: f54a2e8472dec14490104d5819b9889b6987e565 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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
37/* Struct VTY. */
38struct vty *vty;
39
40/* VTY shell pager name. */
41char *vtysh_pager_name = NULL;
42
43/* VTY shell client structure. */
44struct vtysh_client
45{
46 int fd;
47} vtysh_client[VTYSH_INDEX_MAX];
48
49/* When '^Z' is received from vty, move down to the enable mode. */
50int
51vtysh_end ()
52{
53 switch (vty->node)
54 {
55 case VIEW_NODE:
56 case ENABLE_NODE:
57 /* Nothing to do. */
58 break;
59 default:
60 vty->node = ENABLE_NODE;
61 break;
62 }
63 return CMD_SUCCESS;
64}
65
66DEFUNSH (VTYSH_ALL,
67 vtysh_end_all,
68 vtysh_end_all_cmd,
69 "end",
70 "End current mode and down to previous mode\n")
71{
72 return vtysh_end (vty);
73}
74
75DEFUNSH (VTYSH_ALL,
76 vtysh_log_stdout,
77 vtysh_log_stdout_cmd,
78 "log stdout",
79 "Logging control\n"
80 "Logging goes to stdout\n")
81{
82 return CMD_SUCCESS;
83}
84
85DEFUNSH (VTYSH_ALL,
86 no_vtysh_log_stdout,
87 no_vtysh_log_stdout_cmd,
88 "no log stdout",
89 NO_STR
90 "Logging control\n"
91 "Logging goes to stdout\n")
92{
93 return CMD_SUCCESS;
94}
95
96DEFUNSH (VTYSH_ALL,
97 vtysh_log_file,
98 vtysh_log_file_cmd,
99 "log file FILENAME",
100 "Logging control\n"
101 "Logging to file\n"
102 "Logging filename\n")
103{
104 return CMD_SUCCESS;
105}
106
107DEFUNSH (VTYSH_ALL,
108 no_vtysh_log_file,
109 no_vtysh_log_file_cmd,
110 "no log file [FILENAME]",
111 NO_STR
112 "Logging control\n"
113 "Cancel logging to file\n"
114 "Logging file name\n")
115{
116 return CMD_SUCCESS;
117}
118
119DEFUNSH (VTYSH_ALL,
120 vtysh_log_syslog,
121 vtysh_log_syslog_cmd,
122 "log syslog",
123 "Logging control\n"
124 "Logging goes to syslog\n")
125{
126 return CMD_SUCCESS;
127}
128
129DEFUNSH (VTYSH_ALL,
130 no_vtysh_log_syslog,
131 no_vtysh_log_syslog_cmd,
132 "no log syslog",
133 NO_STR
134 "Logging control\n"
135 "Cancel logging to syslog\n")
136{
137 return CMD_SUCCESS;
138}
139
140DEFUNSH (VTYSH_ALL,
141 vtysh_log_trap,
142 vtysh_log_trap_cmd,
143 "log trap (emergencies|alerts|critical|errors|warnings|notifications|informational|debugging)",
144 "Logging control\n"
145 "Limit logging to specifed level\n")
146{
147 return CMD_SUCCESS;
148}
149
150DEFUNSH (VTYSH_ALL,
151 no_vtysh_log_trap,
152 no_vtysh_log_trap_cmd,
153 "no log trap",
154 NO_STR
155 "Logging control\n"
156 "Permit all logging information\n")
157{
158 return CMD_SUCCESS;
159}
160
161DEFUNSH (VTYSH_ALL,
162 vtysh_log_record_priority,
163 vtysh_log_record_priority_cmd,
164 "log record-priority",
165 "Logging control\n"
166 "Log the priority of the message within the message\n")
167{
168 return CMD_SUCCESS;
169}
170
171DEFUNSH (VTYSH_ALL,
172 no_vtysh_log_record_priority,
173 no_vtysh_log_record_priority_cmd,
174 "no log record-priority",
175 NO_STR
176 "Logging control\n"
177 "Do not log the priority of the message within the message\n")
178{
179 return CMD_SUCCESS;
180}
181
182void
183vclient_close (struct vtysh_client *vclient)
184{
185 if (vclient->fd > 0)
186 close (vclient->fd);
187 vclient->fd = -1;
188}
189
190
191/* Following filled with debug code to trace a problematic condition
192 under load - it SHOULD handle it.
193*/
194#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
195int
196vtysh_client_config (struct vtysh_client *vclient, char *line)
197{
198 int ret;
199 char *buf;
200 size_t bufsz;
201 char *pbuf;
202 size_t left;
203 char *eoln;
204 int nbytes;
205 int i;
206 int readln;
207
208 if (vclient->fd < 0)
209 return CMD_SUCCESS;
210
211 ret = write (vclient->fd, line, strlen (line) + 1);
212 if (ret <= 0)
213 {
214 vclient_close (vclient);
215 return CMD_SUCCESS;
216 }
217
218 /* Allow enough room for buffer to read more than a few pages from socket
219 */
paule3d29b52003-01-23 18:05:42 +0000220 bufsz = 5 * getpagesize() + 1;
paul718e3742002-12-13 20:15:29 +0000221 buf = XMALLOC(MTYPE_TMP, bufsz);
222 memset(buf, 0, bufsz);
223 pbuf = buf;
224
225 while (1)
226 {
227 if (pbuf >= ((buf + bufsz) -1))
228 {
229 fprintf (stderr, ERR_WHERE_STRING \
230 "warning - pbuf beyond buffer end.\n");
231 return CMD_WARNING;
232 }
233
234 readln = (buf + bufsz) - pbuf - 1;
235 nbytes = read (vclient->fd, pbuf, readln);
236
237 if (nbytes <= 0)
238 {
239
240 if (errno == EINTR)
241 continue;
242
243 fprintf(stderr, ERR_WHERE_STRING "(%u)", errno);
244 perror("");
245
246 if (errno == EAGAIN || errno == EIO)
247 continue;
248
249 vclient_close (vclient);
250 XFREE(MTYPE_TMP, buf);
251 return CMD_SUCCESS;
252 }
253
254 pbuf[nbytes] = '\0';
255
256 if (nbytes >= 4)
257 {
258 i = nbytes - 4;
259 if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')
260 {
261 ret = pbuf[i + 3];
262 break;
263 }
264 }
265 pbuf += nbytes;
266
267 /* See if a line exists in buffer, if so parse and consume it, and
268 reset read position */
269 if ((eoln = strrchr(buf, '\n')) == NULL)
270 continue;
271
272 if (eoln >= ((buf + bufsz) - 1))
273 {
274 fprintf (stderr, ERR_WHERE_STRING \
275 "warning - eoln beyond buffer end.\n");
276 }
277 vtysh_config_parse(buf);
278
279 eoln++;
280 left = (size_t)(buf + bufsz - eoln);
281 memmove(buf, eoln, left);
282 buf[bufsz-1] = '\0';
283 pbuf = buf + strlen(buf);
284 }
285
286 /* parse anything left in the buffer */
287 vtysh_config_parse (buf);
288
289 XFREE(MTYPE_TMP, buf);
290 return ret;
291}
292
293int
294vtysh_client_execute (struct vtysh_client *vclient, char *line, FILE *fp)
295{
296 int ret;
297 char buf[1001];
298 int nbytes;
299 int i;
300
301 if (vclient->fd < 0)
302 return CMD_SUCCESS;
303
304 ret = write (vclient->fd, line, strlen (line) + 1);
305 if (ret <= 0)
306 {
307 vclient_close (vclient);
308 return CMD_SUCCESS;
309 }
310
311 while (1)
312 {
313 nbytes = read (vclient->fd, buf, sizeof(buf)-1);
314
315 if (nbytes <= 0 && errno != EINTR)
316 {
317 vclient_close (vclient);
318 return CMD_SUCCESS;
319 }
320
321 if (nbytes > 0)
322 {
323 buf[nbytes] = '\0';
324 fprintf (fp, "%s", buf);
325 fflush (fp);
326
327 if (nbytes >= 4)
328 {
329 i = nbytes - 4;
330 if (buf[i] == '\0' && buf[i + 1] == '\0' && buf[i + 2] == '\0')
331 {
332 ret = buf[i + 3];
333 break;
334 }
335 }
336 }
337 }
338 return ret;
339}
340
341void
342vtysh_exit_ripd_only ()
343{
344 vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP], "exit", stdout);
345}
346
347
348void
349vtysh_pager_init ()
350{
351 vtysh_pager_name = getenv ("VTYSH_PAGER");
352 if (! vtysh_pager_name)
353 vtysh_pager_name = "more";
354}
355
356/* Command execution over the vty interface. */
357void
358vtysh_execute_func (char *line, int pager)
359{
360 int ret, cmd_stat;
361 vector vline;
362 struct cmd_element *cmd;
363 FILE *fp = NULL;
364
365 /* Split readline string up into the vector */
366 vline = cmd_make_strvec (line);
367
368 if (vline == NULL)
369 return;
370
371 ret = cmd_execute_command (vline, vty, &cmd);
372
373 cmd_free_strvec (vline);
374
375 switch (ret)
376 {
377 case CMD_WARNING:
378 if (vty->type == VTY_FILE)
paul4fc01e62002-12-13 20:49:00 +0000379 fprintf (stdout,"Warning...\n");
paul718e3742002-12-13 20:15:29 +0000380 break;
381 case CMD_ERR_AMBIGUOUS:
paul4fc01e62002-12-13 20:49:00 +0000382 fprintf (stdout,"%% Ambiguous command.\n");
paul718e3742002-12-13 20:15:29 +0000383 break;
384 case CMD_ERR_NO_MATCH:
paul4fc01e62002-12-13 20:49:00 +0000385 fprintf (stdout,"%% Unknown command.\n");
paul718e3742002-12-13 20:15:29 +0000386 break;
387 case CMD_ERR_INCOMPLETE:
paul4fc01e62002-12-13 20:49:00 +0000388 fprintf (stdout,"%% Command incomplete.\n");
paul718e3742002-12-13 20:15:29 +0000389 break;
390 case CMD_SUCCESS_DAEMON:
391 {
392 if (pager && vtysh_pager_name)
393 {
paul4fc01e62002-12-13 20:49:00 +0000394 fp = popen (vtysh_pager_name, "w");
paul718e3742002-12-13 20:15:29 +0000395 if (fp == NULL)
396 {
397 perror ("popen");
398 exit (1);
399 }
400 }
401 else
402 fp = stdout;
403
404 if (! strcmp(cmd->string,"configure terminal"))
405 {
406 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA],
407 line, fp);
408 if (cmd_stat != CMD_WARNING)
409 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP],
410 line, fp);
411 if (cmd_stat != CMD_WARNING)
412 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG], line, fp);
413 if (cmd_stat != CMD_WARNING)
414 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF],
415 line, fp);
416 if (cmd_stat != CMD_WARNING)
417 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6], line, fp);
418 if (cmd_stat != CMD_WARNING)
419 cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP],
420 line, fp);
421 if (cmd_stat)
422 {
423 line = "end";
424 vline = cmd_make_strvec (line);
425
426 if (vline == NULL)
427 {
428 if (pager && vtysh_pager_name && fp)
429 {
430 if (pclose (fp) == -1)
431 {
432 perror ("pclose");
433 exit (1);
434 }
435 fp = NULL;
436 }
437 return;
438 }
439
440 ret = cmd_execute_command (vline, vty, &cmd);
441 cmd_free_strvec (vline);
442 if (ret != CMD_SUCCESS_DAEMON)
443 break;
444 }
445 else
446 if (cmd->func)
447 {
448 (*cmd->func) (cmd, vty, 0, NULL);
449 break;
450 }
451 }
452
453 if (cmd->daemon & VTYSH_ZEBRA)
454 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA], line, fp)
455 != CMD_SUCCESS)
456 break;
457 if (cmd->daemon & VTYSH_RIPD)
458 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP], line, fp)
459 != CMD_SUCCESS)
460 break;
461 if (cmd->daemon & VTYSH_RIPNGD)
462 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG], line, fp)
463 != CMD_SUCCESS)
464 break;
465 if (cmd->daemon & VTYSH_OSPFD)
466 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF], line, fp)
467 != CMD_SUCCESS)
468 break;
469 if (cmd->daemon & VTYSH_OSPF6D)
470 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6], line, fp)
471 != CMD_SUCCESS)
472 break;
473 if (cmd->daemon & VTYSH_BGPD)
474 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP], line, fp)
475 != CMD_SUCCESS)
476 break;
477 if (cmd->func)
478 (*cmd->func) (cmd, vty, 0, NULL);
479 }
480 }
481 if (pager && vtysh_pager_name && fp)
482 {
483 if (pclose (fp) == -1)
484 {
485 perror ("pclose");
486 exit (1);
487 }
488 fp = NULL;
489 }
490}
491
492void
493vtysh_execute_no_pager (char *line)
494{
495 vtysh_execute_func (line, 0);
496}
497
498void
499vtysh_execute (char *line)
500{
501 vtysh_execute_func (line, 1);
502}
503
504/* Configration make from file. */
505int
506vtysh_config_from_file (struct vty *vty, FILE *fp)
507{
508 int ret;
509 vector vline;
510 struct cmd_element *cmd;
511
512 while (fgets (vty->buf, VTY_BUFSIZ, fp))
513 {
514 if (vty->buf[0] == '!' || vty->buf[1] == '#')
515 continue;
516
517 vline = cmd_make_strvec (vty->buf);
518
519 /* In case of comment line */
520 if (vline == NULL)
521 continue;
522
523 /* Execute configuration command : this is strict match */
524 ret = cmd_execute_command_strict (vline, vty, &cmd);
525
526 /* Try again with setting node to CONFIG_NODE */
527 if (ret != CMD_SUCCESS
528 && ret != CMD_SUCCESS_DAEMON
529 && ret != CMD_WARNING)
530 {
531 if (vty->node == KEYCHAIN_KEY_NODE)
532 {
533 vty->node = KEYCHAIN_NODE;
534 vtysh_exit_ripd_only ();
535 ret = cmd_execute_command_strict (vline, vty, &cmd);
536
537 if (ret != CMD_SUCCESS
538 && ret != CMD_SUCCESS_DAEMON
539 && ret != CMD_WARNING)
540 {
541 vtysh_exit_ripd_only ();
542 vty->node = CONFIG_NODE;
543 ret = cmd_execute_command_strict (vline, vty, &cmd);
544 }
545 }
546 else
547 {
548 vtysh_execute ("end");
549 vtysh_execute ("configure terminal");
550 vty->node = CONFIG_NODE;
551 ret = cmd_execute_command_strict (vline, vty, &cmd);
552 }
553 }
554
555 cmd_free_strvec (vline);
556
557 switch (ret)
558 {
559 case CMD_WARNING:
560 if (vty->type == VTY_FILE)
paul4fc01e62002-12-13 20:49:00 +0000561 fprintf (stdout,"Warning...\n");
paul718e3742002-12-13 20:15:29 +0000562 break;
563 case CMD_ERR_AMBIGUOUS:
paul4fc01e62002-12-13 20:49:00 +0000564 fprintf (stdout,"%% Ambiguous command.\n");
paul718e3742002-12-13 20:15:29 +0000565 break;
566 case CMD_ERR_NO_MATCH:
paul4fc01e62002-12-13 20:49:00 +0000567 fprintf (stdout,"%% Unknown command: %s", vty->buf);
paul718e3742002-12-13 20:15:29 +0000568 break;
569 case CMD_ERR_INCOMPLETE:
paul4fc01e62002-12-13 20:49:00 +0000570 fprintf (stdout,"%% Command incomplete.\n");
paul718e3742002-12-13 20:15:29 +0000571 break;
572 case CMD_SUCCESS_DAEMON:
573 {
574 if (cmd->daemon & VTYSH_ZEBRA)
575 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA],
576 vty->buf, stdout) != CMD_SUCCESS)
577 break;
578 if (cmd->daemon & VTYSH_RIPD)
579 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP],
580 vty->buf, stdout) != CMD_SUCCESS)
581 break;
582 if (cmd->daemon & VTYSH_RIPNGD)
583 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG],
584 vty->buf, stdout) != CMD_SUCCESS)
585 break;
586 if (cmd->daemon & VTYSH_OSPFD)
587 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF],
588 vty->buf, stdout) != CMD_SUCCESS)
589 break;
590 if (cmd->daemon & VTYSH_OSPF6D)
591 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6],
592 vty->buf, stdout) != CMD_SUCCESS)
593 break;
594 if (cmd->daemon & VTYSH_BGPD)
595 if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP],
596 vty->buf, stdout) != CMD_SUCCESS)
597 break;
598 if (cmd->func)
599 (*cmd->func) (cmd, vty, 0, NULL);
600 }
601 }
602 }
603 return CMD_SUCCESS;
604}
605
606/* We don't care about the point of the cursor when '?' is typed. */
607int
608vtysh_rl_describe ()
609{
610 int ret;
611 int i;
612 vector vline;
613 vector describe;
614 int width;
615 struct desc *desc;
616
617 vline = cmd_make_strvec (rl_line_buffer);
618
619 /* In case of '> ?'. */
620 if (vline == NULL)
621 {
622 vline = vector_init (1);
623 vector_set (vline, '\0');
624 }
625 else
626 if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
627 vector_set (vline, '\0');
628
629 describe = cmd_describe_command (vline, vty, &ret);
630
paul4fc01e62002-12-13 20:49:00 +0000631 fprintf (stdout,"\n");
paul718e3742002-12-13 20:15:29 +0000632
633 /* Ambiguous and no match error. */
634 switch (ret)
635 {
636 case CMD_ERR_AMBIGUOUS:
637 cmd_free_strvec (vline);
paul4fc01e62002-12-13 20:49:00 +0000638 fprintf (stdout,"%% Ambiguous command.\n");
paul718e3742002-12-13 20:15:29 +0000639 rl_on_new_line ();
640 return 0;
641 break;
642 case CMD_ERR_NO_MATCH:
643 cmd_free_strvec (vline);
paul4fc01e62002-12-13 20:49:00 +0000644 fprintf (stdout,"%% There is no matched command.\n");
paul718e3742002-12-13 20:15:29 +0000645 rl_on_new_line ();
646 return 0;
647 break;
648 }
649
650 /* Get width of command string. */
651 width = 0;
652 for (i = 0; i < vector_max (describe); i++)
653 if ((desc = vector_slot (describe, i)) != NULL)
654 {
655 int len;
656
657 if (desc->cmd[0] == '\0')
658 continue;
659
660 len = strlen (desc->cmd);
661 if (desc->cmd[0] == '.')
662 len--;
663
664 if (width < len)
665 width = len;
666 }
667
668 for (i = 0; i < vector_max (describe); i++)
669 if ((desc = vector_slot (describe, i)) != NULL)
670 {
671 if (desc->cmd[0] == '\0')
672 continue;
673
674 if (! desc->str)
paul4fc01e62002-12-13 20:49:00 +0000675 fprintf (stdout," %-s\n",
paul718e3742002-12-13 20:15:29 +0000676 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd);
677 else
paul4fc01e62002-12-13 20:49:00 +0000678 fprintf (stdout," %-*s %s\n",
paul718e3742002-12-13 20:15:29 +0000679 width,
680 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
681 desc->str);
682 }
683
684 cmd_free_strvec (vline);
685 vector_free (describe);
686
687 rl_on_new_line();
688
689 return 0;
690}
691
692/* result of cmd_complete_command() call will be stored here
693 and used in new_completion() in order to put the space in
694 correct places only */
695int complete_status;
696
697char *
698command_generator (char *text, int state)
699{
700 vector vline;
701 static char **matched = NULL;
702 static int index = 0;
703
704 /* First call. */
705 if (! state)
706 {
707 index = 0;
708
709 if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
710 return NULL;
711
712 vline = cmd_make_strvec (rl_line_buffer);
713 if (vline == NULL)
714 return NULL;
715
716 if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
717 vector_set (vline, '\0');
718
719 matched = cmd_complete_command (vline, vty, &complete_status);
720 }
721
722 if (matched && matched[index])
723 return matched[index++];
724
725 return NULL;
726}
727
728char **
729new_completion (char *text, int start, int end)
730{
731 char **matches;
732
733 matches = completion_matches (text, command_generator);
734
735 if (matches)
736 {
737 rl_point = rl_end;
738 if (complete_status == CMD_COMPLETE_FULL_MATCH)
739 rl_pending_input = ' ';
740 }
741
742 return matches;
743}
744
745char **
746vtysh_completion (char *text, int start, int end)
747{
748 int ret;
749 vector vline;
750 char **matched = NULL;
751
752 if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
753 return NULL;
754
755 vline = cmd_make_strvec (rl_line_buffer);
756 if (vline == NULL)
757 return NULL;
758
759 /* In case of 'help \t'. */
760 if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
761 vector_set (vline, '\0');
762
763 matched = cmd_complete_command (vline, vty, &ret);
764
765 cmd_free_strvec (vline);
766
767 return (char **) matched;
768}
769
770/* BGP node structure. */
771struct cmd_node bgp_node =
772{
773 BGP_NODE,
774 "%s(config-router)# ",
775};
776
777/* BGP node structure. */
778struct cmd_node rip_node =
779{
780 RIP_NODE,
781 "%s(config-router)# ",
782};
783
784struct cmd_node interface_node =
785{
786 INTERFACE_NODE,
787 "%s(config-if)# ",
788};
789
790DEFUNSH (VTYSH_BGPD,
791 router_bgp,
792 router_bgp_cmd,
793 "router bgp <1-65535>",
794 ROUTER_STR
795 BGP_STR
796 AS_STR)
797{
798 vty->node = BGP_NODE;
799 return CMD_SUCCESS;
800}
801
802DEFUNSH (VTYSH_BGPD,
803 address_family_vpnv4,
804 address_family_vpnv4_cmd,
805 "address-family vpnv4",
806 "Enter Address Family command mode\n"
807 "Address family\n")
808{
809 vty->node = BGP_VPNV4_NODE;
810 return CMD_SUCCESS;
811}
812
813DEFUNSH (VTYSH_BGPD,
814 address_family_vpnv4_unicast,
815 address_family_vpnv4_unicast_cmd,
816 "address-family vpnv4 unicast",
817 "Enter Address Family command mode\n"
818 "Address family\n"
819 "Address Family Modifier\n")
820{
821 vty->node = BGP_VPNV4_NODE;
822 return CMD_SUCCESS;
823}
824
825DEFUNSH (VTYSH_BGPD,
826 address_family_ipv4_unicast,
827 address_family_ipv4_unicast_cmd,
828 "address-family ipv4 unicast",
829 "Enter Address Family command mode\n"
830 "Address family\n"
831 "Address Family Modifier\n")
832{
833 vty->node = BGP_IPV4_NODE;
834 return CMD_SUCCESS;
835}
836
837DEFUNSH (VTYSH_BGPD,
838 address_family_ipv4_multicast,
839 address_family_ipv4_multicast_cmd,
840 "address-family ipv4 multicast",
841 "Enter Address Family command mode\n"
842 "Address family\n"
843 "Address Family Modifier\n")
844{
845 vty->node = BGP_IPV4M_NODE;
846 return CMD_SUCCESS;
847}
848
849DEFUNSH (VTYSH_BGPD,
850 address_family_ipv6,
851 address_family_ipv6_cmd,
852 "address-family ipv6",
853 "Enter Address Family command mode\n"
854 "Address family\n")
855{
856 vty->node = BGP_IPV6_NODE;
857 return CMD_SUCCESS;
858}
859
860DEFUNSH (VTYSH_BGPD,
861 address_family_ipv6_unicast,
862 address_family_ipv6_unicast_cmd,
863 "address-family ipv6 unicast",
864 "Enter Address Family command mode\n"
865 "Address family\n"
866 "Address Family Modifier\n")
867{
868 vty->node = BGP_IPV6_NODE;
869 return CMD_SUCCESS;
870}
871
872DEFUNSH (VTYSH_RIPD,
873 key_chain,
874 key_chain_cmd,
875 "key chain WORD",
876 "Authentication key management\n"
877 "Key-chain management\n"
878 "Key-chain name\n")
879{
880 vty->node = KEYCHAIN_NODE;
881 return CMD_SUCCESS;
882}
883
884DEFUNSH (VTYSH_RIPD,
885 key,
886 key_cmd,
887 "key <0-2147483647>",
888 "Configure a key\n"
889 "Key identifier number\n")
890{
891 vty->node = KEYCHAIN_KEY_NODE;
892 return CMD_SUCCESS;
893}
894
895DEFUNSH (VTYSH_RIPD,
896 router_rip,
897 router_rip_cmd,
898 "router rip",
899 ROUTER_STR
900 "RIP")
901{
902 vty->node = RIP_NODE;
903 return CMD_SUCCESS;
904}
905
906DEFUNSH (VTYSH_RIPNGD,
907 router_ripng,
908 router_ripng_cmd,
909 "router ripng",
910 ROUTER_STR
911 "RIPng")
912{
913 vty->node = RIPNG_NODE;
914 return CMD_SUCCESS;
915}
916
917DEFUNSH (VTYSH_OSPFD,
918 router_ospf,
919 router_ospf_cmd,
920 "router ospf",
921 "Enable a routing process\n"
922 "Start OSPF configuration\n")
923{
924 vty->node = OSPF_NODE;
925 return CMD_SUCCESS;
926}
927
928DEFUNSH (VTYSH_OSPF6D,
929 router_ospf6,
930 router_ospf6_cmd,
931 "router ospf6",
932 OSPF6_ROUTER_STR
933 OSPF6_STR)
934{
935 vty->node = OSPF6_NODE;
936 return CMD_SUCCESS;
937}
938
939DEFUNSH (VTYSH_RMAP,
940 route_map,
941 route_map_cmd,
942 "route-map WORD (deny|permit) <1-65535>",
943 "Create route-map or enter route-map command mode\n"
944 "Route map tag\n"
945 "Route map denies set operations\n"
946 "Route map permits set operations\n"
947 "Sequence to insert to/delete from existing route-map entry\n")
948{
949 vty->node = RMAP_NODE;
950 return CMD_SUCCESS;
951}
952
953/* Enable command */
954DEFUNSH (VTYSH_ALL,
955 vtysh_enable,
956 vtysh_enable_cmd,
957 "enable",
958 "Turn on privileged mode command\n")
959{
960 vty->node = ENABLE_NODE;
961 return CMD_SUCCESS;
962}
963
964/* Disable command */
965DEFUNSH (VTYSH_ALL,
966 vtysh_disable,
967 vtysh_disable_cmd,
968 "disable",
969 "Turn off privileged mode command\n")
970{
971 if (vty->node == ENABLE_NODE)
972 vty->node = VIEW_NODE;
973 return CMD_SUCCESS;
974}
975
976/* Configration from terminal */
977DEFUNSH (VTYSH_ALL,
978 vtysh_config_terminal,
979 vtysh_config_terminal_cmd,
980 "configure terminal",
981 "Configuration from vty interface\n"
982 "Configuration terminal\n")
983{
984 vty->node = CONFIG_NODE;
985 return CMD_SUCCESS;
986}
987
988int
989vtysh_exit (struct vty *vty)
990{
991 switch (vty->node)
992 {
993 case VIEW_NODE:
994 case ENABLE_NODE:
995 exit (0);
996 break;
997 case CONFIG_NODE:
998 vty->node = ENABLE_NODE;
999 break;
1000 case INTERFACE_NODE:
1001 case ZEBRA_NODE:
1002 case BGP_NODE:
1003 case RIP_NODE:
1004 case RIPNG_NODE:
1005 case OSPF_NODE:
1006 case OSPF6_NODE:
1007 case MASC_NODE:
1008 case RMAP_NODE:
1009 case VTY_NODE:
1010 case KEYCHAIN_NODE:
1011 vty->node = CONFIG_NODE;
1012 break;
1013 case BGP_VPNV4_NODE:
1014 case BGP_IPV4_NODE:
1015 case BGP_IPV4M_NODE:
1016 case BGP_IPV6_NODE:
1017 vty->node = BGP_NODE;
1018 break;
1019 case KEYCHAIN_KEY_NODE:
1020 vty->node = KEYCHAIN_NODE;
1021 break;
1022 default:
1023 break;
1024 }
1025 return CMD_SUCCESS;
1026}
1027
1028DEFUNSH (VTYSH_ALL,
1029 vtysh_exit_all,
1030 vtysh_exit_all_cmd,
1031 "exit",
1032 "Exit current mode and down to previous mode\n")
1033{
1034 return vtysh_exit (vty);
1035}
1036
1037ALIAS (vtysh_exit_all,
1038 vtysh_quit_all_cmd,
1039 "quit",
1040 "Exit current mode and down to previous mode\n")
1041
1042DEFUNSH (VTYSH_BGPD,
1043 exit_address_family,
1044 exit_address_family_cmd,
1045 "exit-address-family",
1046 "Exit from Address Family configuration mode\n")
1047{
1048 if (vty->node == BGP_IPV4_NODE
1049 || vty->node == BGP_IPV4M_NODE
1050 || vty->node == BGP_VPNV4_NODE
1051 || vty->node == BGP_IPV6_NODE)
1052 vty->node = BGP_NODE;
1053 return CMD_SUCCESS;
1054}
1055
1056DEFUNSH (VTYSH_ZEBRA,
1057 vtysh_exit_zebra,
1058 vtysh_exit_zebra_cmd,
1059 "exit",
1060 "Exit current mode and down to previous mode\n")
1061{
1062 return vtysh_exit (vty);
1063}
1064
1065ALIAS (vtysh_exit_zebra,
1066 vtysh_quit_zebra_cmd,
1067 "quit",
1068 "Exit current mode and down to previous mode\n")
1069
1070DEFUNSH (VTYSH_RIPD,
1071 vtysh_exit_ripd,
1072 vtysh_exit_ripd_cmd,
1073 "exit",
1074 "Exit current mode and down to previous mode\n")
1075{
1076 return vtysh_exit (vty);
1077}
1078
1079ALIAS (vtysh_exit_ripd,
1080 vtysh_quit_ripd_cmd,
1081 "quit",
1082 "Exit current mode and down to previous mode\n")
1083
paul68980082003-03-25 05:07:42 +00001084DEFUNSH (VTYSH_RIPNGD,
1085 vtysh_exit_ripngd,
1086 vtysh_exit_ripngd_cmd,
1087 "exit",
1088 "Exit current mode and down to previous mode\n")
1089{
1090 return vtysh_exit (vty);
1091}
1092
1093ALIAS (vtysh_exit_ripngd,
1094 vtysh_quit_ripngd_cmd,
1095 "quit",
1096 "Exit current mode and down to previous mode\n")
1097
paul718e3742002-12-13 20:15:29 +00001098DEFUNSH (VTYSH_RMAP,
1099 vtysh_exit_rmap,
1100 vtysh_exit_rmap_cmd,
1101 "exit",
1102 "Exit current mode and down to previous mode\n")
1103{
1104 return vtysh_exit (vty);
1105}
1106
1107ALIAS (vtysh_exit_rmap,
1108 vtysh_quit_rmap_cmd,
1109 "quit",
1110 "Exit current mode and down to previous mode\n")
1111
1112DEFUNSH (VTYSH_BGPD,
1113 vtysh_exit_bgpd,
1114 vtysh_exit_bgpd_cmd,
1115 "exit",
1116 "Exit current mode and down to previous mode\n")
1117{
1118 return vtysh_exit (vty);
1119}
1120
1121ALIAS (vtysh_exit_bgpd,
1122 vtysh_quit_bgpd_cmd,
1123 "quit",
1124 "Exit current mode and down to previous mode\n")
1125
1126DEFUNSH (VTYSH_OSPFD,
1127 vtysh_exit_ospfd,
1128 vtysh_exit_ospfd_cmd,
1129 "exit",
1130 "Exit current mode and down to previous mode\n")
1131{
1132 return vtysh_exit (vty);
1133}
1134
1135ALIAS (vtysh_exit_ospfd,
1136 vtysh_quit_ospfd_cmd,
1137 "quit",
1138 "Exit current mode and down to previous mode\n")
1139
paul68980082003-03-25 05:07:42 +00001140DEFUNSH (VTYSH_OSPF6D,
1141 vtysh_exit_ospf6d,
1142 vtysh_exit_ospf6d_cmd,
1143 "exit",
1144 "Exit current mode and down to previous mode\n")
1145{
1146 return vtysh_exit (vty);
1147}
1148
1149ALIAS (vtysh_exit_ospf6d,
1150 vtysh_quit_ospf6d_cmd,
1151 "quit",
1152 "Exit current mode and down to previous mode\n")
1153
1154DEFUNSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D,
paul718e3742002-12-13 20:15:29 +00001155 vtysh_interface,
1156 vtysh_interface_cmd,
1157 "interface IFNAME",
1158 "Select an interface to configure\n"
1159 "Interface's name\n")
1160{
1161 vty->node = INTERFACE_NODE;
1162 return CMD_SUCCESS;
1163}
1164
paul338a9912003-03-01 15:44:10 +00001165DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
1166 interface_desc_cmd,
1167 "description .LINE",
1168 "Interface specific description\n"
1169 "Characters describing this interface\n")
1170
paul718e3742002-12-13 20:15:29 +00001171DEFSH (VTYSH_RIPD|VTYSH_BGPD,
1172 set_ip_nexthop_cmd,
1173 "set ip next-hop A.B.C.D",
1174 SET_STR
1175 IP_STR
1176 "Next hop address\n"
1177 "IP address of next hop\n")
1178
1179DEFSH (VTYSH_RMAP,
1180 set_metric_cmd,
1181 "set metric <0-4294967295>",
1182 SET_STR
1183 "Metric value for destination routing protocol\n"
1184 "Metric value\n")
1185
paul68980082003-03-25 05:07:42 +00001186DEFUNSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D,
paul718e3742002-12-13 20:15:29 +00001187 vtysh_exit_interface,
1188 vtysh_exit_interface_cmd,
1189 "exit",
1190 "Exit current mode and down to previous mode\n")
1191{
1192 return vtysh_exit (vty);
1193}
1194
1195ALIAS (vtysh_exit_interface,
1196 vtysh_quit_interface_cmd,
1197 "quit",
1198 "Exit current mode and down to previous mode\n")
1199
1200DEFUN (vtysh_write_terminal,
1201 vtysh_write_terminal_cmd,
1202 "write terminal",
1203 "Write running configuration to memory, network, or terminal\n"
1204 "Write to terminal\n")
1205{
1206 int ret;
1207 char line[] = "write terminal\n";
1208 FILE *fp = NULL;
1209
1210 if (vtysh_pager_name)
1211 {
paul4fc01e62002-12-13 20:49:00 +00001212 fp = popen (vtysh_pager_name, "w");
paul718e3742002-12-13 20:15:29 +00001213 if (fp == NULL)
1214 {
1215 perror ("popen");
1216 exit (1);
1217 }
1218 }
1219 else
1220 fp = stdout;
1221
1222 vty_out (vty, "Building configuration...%s", VTY_NEWLINE);
1223 vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
1224 VTY_NEWLINE);
1225
1226 vtysh_config_write (fp);
1227
1228 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_ZEBRA], line);
1229 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIP], line);
1230 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIPNG], line);
1231 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF], line);
1232 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF6], line);
1233 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_BGP], line);
1234
1235 vtysh_config_dump (fp);
1236
1237 if (vtysh_pager_name && fp)
1238 {
1239 fflush (fp);
1240 if (pclose (fp) == -1)
1241 {
1242 perror ("pclose");
1243 exit (1);
1244 }
1245 fp = NULL;
1246 }
1247
1248 return CMD_SUCCESS;
1249}
1250
paul4fc01e62002-12-13 20:49:00 +00001251struct vtysh_writeconfig_t {
1252 int daemon;
1253 int integrated;
1254} vtysh_wc = {-1,0};
1255
1256DEFUN (vtysh_write_config,
1257 vtysh_write_config_cmd,
1258 "write-config (daemon|integrated)",
1259 "Specify config files to write to\n"
1260 "Write per daemon file\n"
1261 "Write integrated file\n"
1262)
1263{
1264 if (!strncmp(argv[0],"d",1)) {
1265 vtysh_wc.daemon = 1;
1266 } else if (!strncmp(argv[0],"i",1)) {
1267 vtysh_wc.integrated = 1;
1268 }
1269 return CMD_SUCCESS;
1270}
1271
1272DEFUN (no_vtysh_write_config,
1273 no_vtysh_write_config_cmd,
1274 "no write-config (daemon|integrated)",
1275 "Negate per daemon and/or integrated config files\n"
1276)
1277{
1278 if (!strncmp(argv[0],"d",1)) {
1279 vtysh_wc.daemon = 0;
1280 } else if (!strncmp(argv[0],"i",1)) {
1281 vtysh_wc.integrated = 0;
1282 }
1283 return CMD_SUCCESS;
1284}
1285
1286int write_config_integrated(void)
paul718e3742002-12-13 20:15:29 +00001287{
1288 int ret;
1289 mode_t old_umask;
1290 char line[] = "write terminal\n";
1291 FILE *fp;
1292 char *integrate_sav = NULL;
1293
1294 /* config files have 0600 perms... */
1295 old_umask = umask (0077);
1296
1297 integrate_sav = malloc (strlen (integrate_default)
1298 + strlen (CONF_BACKUP_EXT) + 1);
1299 strcpy (integrate_sav, integrate_default);
1300 strcat (integrate_sav, CONF_BACKUP_EXT);
1301
1302
paul4fc01e62002-12-13 20:49:00 +00001303 fprintf (stdout,"Building Configuration...\n");
paul718e3742002-12-13 20:15:29 +00001304
1305 /* Move current configuration file to backup config file */
1306 unlink (integrate_sav);
1307 rename (integrate_default, integrate_sav);
paul5087df52003-01-25 06:56:09 +00001308 free (integrate_sav);
paul4fc01e62002-12-13 20:49:00 +00001309
paul718e3742002-12-13 20:15:29 +00001310 fp = fopen (integrate_default, "w");
1311 if (fp == NULL)
1312 {
paul4fc01e62002-12-13 20:49:00 +00001313 fprintf (stdout,"%% Can't open configuration file %s.\n", integrate_default);
paul718e3742002-12-13 20:15:29 +00001314 umask (old_umask);
1315 return CMD_SUCCESS;
1316 }
paul718e3742002-12-13 20:15:29 +00001317
1318 vtysh_config_write (fp);
1319
1320 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_ZEBRA], line);
1321 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIP], line);
1322 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIPNG], line);
1323 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF], line);
1324 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF6], line);
1325 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_BGP], line);
1326
1327 vtysh_config_dump (fp);
1328
1329 fclose (fp);
1330
paul4fc01e62002-12-13 20:49:00 +00001331 fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default);
1332
1333 fprintf (stdout,"[OK]\n");
1334
paul718e3742002-12-13 20:15:29 +00001335 umask (old_umask);
1336 return CMD_SUCCESS;
1337}
1338
paul4fc01e62002-12-13 20:49:00 +00001339DEFUN (vtysh_write_memory,
1340 vtysh_write_memory_cmd,
1341 "write memory",
1342 "Write running configuration to memory, network, or terminal\n"
1343 "Write configuration to the file (same as write file)\n")
1344{
1345 int ret;
1346 char line[] = "write memory\n";
1347
1348 /* if integrated Zebra.conf explicitely set */
1349 if (vtysh_wc.integrated == 1) {
1350 ret = write_config_integrated();
1351 }
1352
1353 if (!vtysh_wc.daemon) {
1354 return ret;
1355 }
1356
1357 fprintf (stdout,"Building Configuration...\n");
1358
1359 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA], line, stdout);
1360 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP], line, stdout);
1361 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG], line, stdout);
1362 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF], line, stdout);
1363 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6], line, stdout);
1364 ret = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP], line, stdout);
1365
1366 fprintf (stdout,"[OK]\n");
1367
1368 return CMD_SUCCESS;
1369}
1370
paul718e3742002-12-13 20:15:29 +00001371ALIAS (vtysh_write_memory,
1372 vtysh_copy_runningconfig_startupconfig_cmd,
1373 "copy running-config startup-config",
1374 "Copy from one file to another\n"
1375 "Copy from current system configuration\n"
1376 "Copy to startup configuration\n")
1377
1378ALIAS (vtysh_write_memory,
1379 vtysh_write_file_cmd,
1380 "write file",
1381 "Write running configuration to memory, network, or terminal\n"
1382 "Write configuration to the file (same as write memory)\n")
1383
1384ALIAS (vtysh_write_terminal,
1385 vtysh_show_running_config_cmd,
1386 "show running-config",
1387 SHOW_STR
1388 "Current operating configuration\n")
1389
1390/* Execute command in child process. */
1391int
1392execute_command (char *command, int argc, char *arg1, char *arg2)
1393{
1394 int ret;
1395 pid_t pid;
1396 int status;
1397
1398 /* Call fork(). */
1399 pid = fork ();
1400
1401 if (pid < 0)
1402 {
1403 /* Failure of fork(). */
1404 fprintf (stderr, "Can't fork: %s\n", strerror (errno));
1405 exit (1);
1406 }
1407 else if (pid == 0)
1408 {
1409 /* This is child process. */
1410 switch (argc)
1411 {
1412 case 0:
1413 ret = execlp (command, command, NULL);
1414 break;
1415 case 1:
1416 ret = execlp (command, command, arg1, NULL);
1417 break;
1418 case 2:
1419 ret = execlp (command, command, arg1, arg2, NULL);
1420 break;
1421 }
1422
1423 /* When execlp suceed, this part is not executed. */
1424 fprintf (stderr, "Can't execute %s: %s\n", command, strerror (errno));
1425 exit (1);
1426 }
1427 else
1428 {
1429 /* This is parent. */
1430 execute_flag = 1;
1431 ret = wait4 (pid, &status, 0, NULL);
1432 execute_flag = 0;
1433 }
1434 return 0;
1435}
1436
1437DEFUN (vtysh_ping,
1438 vtysh_ping_cmd,
1439 "ping WORD",
1440 "send echo messages\n"
1441 "Ping destination address or hostname\n")
1442{
1443 execute_command ("ping", 1, argv[0], NULL);
1444 return CMD_SUCCESS;
1445}
1446
1447DEFUN (vtysh_traceroute,
1448 vtysh_traceroute_cmd,
1449 "traceroute WORD",
1450 "Trace route to destination\n"
1451 "Trace route to destination address or hostname\n")
1452{
1453 execute_command ("traceroute", 1, argv[0], NULL);
1454 return CMD_SUCCESS;
1455}
1456
1457DEFUN (vtysh_telnet,
1458 vtysh_telnet_cmd,
1459 "telnet WORD",
1460 "Open a telnet connection\n"
1461 "IP address or hostname of a remote system\n")
1462{
1463 execute_command ("telnet", 1, argv[0], NULL);
1464 return CMD_SUCCESS;
1465}
1466
1467DEFUN (vtysh_telnet_port,
1468 vtysh_telnet_port_cmd,
1469 "telnet WORD PORT",
1470 "Open a telnet connection\n"
1471 "IP address or hostname of a remote system\n"
1472 "TCP Port number\n")
1473{
1474 execute_command ("telnet", 2, argv[0], argv[1]);
1475 return CMD_SUCCESS;
1476}
1477
paul5087df52003-01-25 06:56:09 +00001478DEFUN (vtysh_ssh,
1479 vtysh_ssh_cmd,
1480 "ssh WORD",
1481 "Open an ssh connection\n"
1482 "[user@]host\n")
1483{
1484 execute_command ("ssh", 1, argv[0], NULL);
1485 return CMD_SUCCESS;
1486}
1487
paul718e3742002-12-13 20:15:29 +00001488DEFUN (vtysh_start_shell,
1489 vtysh_start_shell_cmd,
1490 "start-shell",
1491 "Start UNIX shell\n")
1492{
1493 execute_command ("sh", 0, NULL, NULL);
1494 return CMD_SUCCESS;
1495}
1496
1497DEFUN (vtysh_start_bash,
1498 vtysh_start_bash_cmd,
1499 "start-shell bash",
1500 "Start UNIX shell\n"
1501 "Start bash\n")
1502{
1503 execute_command ("bash", 0, NULL, NULL);
1504 return CMD_SUCCESS;
1505}
1506
1507DEFUN (vtysh_start_zsh,
1508 vtysh_start_zsh_cmd,
1509 "start-shell zsh",
1510 "Start UNIX shell\n"
1511 "Start Z shell\n")
1512{
1513 execute_command ("zsh", 0, NULL, NULL);
1514 return CMD_SUCCESS;
1515}
1516
1517/* Route map node structure. */
1518struct cmd_node rmap_node =
1519{
1520 RMAP_NODE,
1521 "%s(config-route-map)# "
1522};
1523
1524/* Zebra node structure. */
1525struct cmd_node zebra_node =
1526{
1527 ZEBRA_NODE,
1528 "%s(config-router)# "
1529};
1530
1531struct cmd_node bgp_vpnv4_node =
1532{
1533 BGP_VPNV4_NODE,
1534 "%s(config-router-af)# "
1535};
1536
1537struct cmd_node bgp_ipv4_node =
1538{
1539 BGP_IPV4_NODE,
1540 "%s(config-router-af)# "
1541};
1542
1543struct cmd_node bgp_ipv4m_node =
1544{
1545 BGP_IPV4M_NODE,
1546 "%s(config-router-af)# "
1547};
1548
1549struct cmd_node bgp_ipv6_node =
1550{
1551 BGP_IPV6_NODE,
1552 "%s(config-router-af)# "
1553};
1554
1555struct cmd_node ospf_node =
1556{
1557 OSPF_NODE,
1558 "%s(config-router)# "
1559};
1560
1561/* RIPng node structure. */
1562struct cmd_node ripng_node =
1563{
1564 RIPNG_NODE,
1565 "%s(config-router)# "
1566};
1567
1568/* OSPF6 node structure. */
1569struct cmd_node ospf6_node =
1570{
1571 OSPF6_NODE,
1572 "%s(config-ospf6)# "
1573};
1574
1575struct cmd_node keychain_node =
1576{
1577 KEYCHAIN_NODE,
1578 "%s(config-keychain)# "
1579};
1580
1581struct cmd_node keychain_key_node =
1582{
1583 KEYCHAIN_KEY_NODE,
1584 "%s(config-keychain-key)# "
1585};
1586
1587void
1588vtysh_install_default (enum node_type node)
1589{
1590 install_element (node, &config_list_cmd);
1591}
1592
1593/* Making connection to protocol daemon. */
1594int
1595vtysh_connect (struct vtysh_client *vclient, char *path)
1596{
1597 int ret;
1598 int sock, len;
1599 struct sockaddr_un addr;
1600 struct stat s_stat;
1601 uid_t euid;
1602 gid_t egid;
1603
1604 memset (vclient, 0, sizeof (struct vtysh_client));
1605 vclient->fd = -1;
1606
1607 /* Stat socket to see if we have permission to access it. */
1608 euid = geteuid();
1609 egid = getegid();
1610 ret = stat (path, &s_stat);
1611 if (ret < 0 && errno != ENOENT)
1612 {
1613 fprintf (stderr, "vtysh_connect(%s): stat = %s\n",
1614 path, strerror(errno));
1615 exit(1);
1616 }
1617
1618 if (ret >= 0)
1619 {
1620 if (! S_ISSOCK(s_stat.st_mode))
1621 {
1622 fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
1623 path);
1624 exit (1);
1625 }
1626
1627 if (euid != s_stat.st_uid
1628 || !(s_stat.st_mode & S_IWUSR)
1629 || !(s_stat.st_mode & S_IRUSR))
1630 {
1631 fprintf (stderr, "vtysh_connect(%s): No permission to access socket\n",
1632 path);
1633 exit (1);
1634 }
1635 }
1636
1637 sock = socket (AF_UNIX, SOCK_STREAM, 0);
1638 if (sock < 0)
1639 {
1640#ifdef DEBUG
1641 fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path, strerror(errno));
1642#endif /* DEBUG */
1643 return -1;
1644 }
1645
1646 memset (&addr, 0, sizeof (struct sockaddr_un));
1647 addr.sun_family = AF_UNIX;
1648 strncpy (addr.sun_path, path, strlen (path));
1649#ifdef HAVE_SUN_LEN
1650 len = addr.sun_len = SUN_LEN(&addr);
1651#else
1652 len = sizeof (addr.sun_family) + strlen (addr.sun_path);
1653#endif /* HAVE_SUN_LEN */
1654
1655 ret = connect (sock, (struct sockaddr *) &addr, len);
1656 if (ret < 0)
1657 {
1658#ifdef DEBUG
1659 fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path, strerror(errno));
1660#endif /* DEBUG */
1661 close (sock);
1662 return -1;
1663 }
1664 vclient->fd = sock;
1665
1666 return 0;
1667}
1668
1669void
1670vtysh_connect_all()
1671{
1672 /* Clear each daemons client structure. */
1673 vtysh_connect (&vtysh_client[VTYSH_INDEX_ZEBRA], ZEBRA_PATH);
1674 vtysh_connect (&vtysh_client[VTYSH_INDEX_RIP], RIP_PATH);
1675 vtysh_connect (&vtysh_client[VTYSH_INDEX_RIPNG], RIPNG_PATH);
1676 vtysh_connect (&vtysh_client[VTYSH_INDEX_OSPF], OSPF_PATH);
1677 vtysh_connect (&vtysh_client[VTYSH_INDEX_OSPF6], OSPF6_PATH);
1678 vtysh_connect (&vtysh_client[VTYSH_INDEX_BGP], BGP_PATH);
1679}
1680
1681
1682/* To disable readline's filename completion */
1683int
paul68980082003-03-25 05:07:42 +00001684vtysh_completion_entry_function (int ignore, int invoking_key)
paul718e3742002-12-13 20:15:29 +00001685{
1686 return 0;
1687}
1688
1689void
1690vtysh_readline_init ()
1691{
1692 /* readline related settings. */
1693 rl_bind_key ('?', vtysh_rl_describe);
paul68980082003-03-25 05:07:42 +00001694 rl_completion_entry_function = vtysh_completion_entry_function;
paul718e3742002-12-13 20:15:29 +00001695 rl_attempted_completion_function = (CPPFunction *)new_completion;
1696 /* do not append space after completion. It will be appended
1697 in new_completion() function explicitly */
1698 rl_completion_append_character = '\0';
1699}
1700
1701char *
1702vtysh_prompt ()
1703{
1704 struct utsname names;
1705 static char buf[100];
1706 const char*hostname;
1707 extern struct host host;
1708
1709 hostname = host.name;
1710
1711 if (!hostname)
1712 {
1713 uname (&names);
1714 hostname = names.nodename;
1715 }
1716
1717 snprintf (buf, sizeof buf, cmd_prompt (vty->node), hostname);
1718
1719 return buf;
1720}
1721
1722void
1723vtysh_init_vty ()
1724{
1725 /* Make vty structure. */
1726 vty = vty_new ();
1727 vty->type = VTY_SHELL;
1728 vty->node = VIEW_NODE;
1729
1730 /* Initialize commands. */
1731 cmd_init (0);
1732
1733 /* Install nodes. */
1734 install_node (&bgp_node, NULL);
1735 install_node (&rip_node, NULL);
1736 install_node (&interface_node, NULL);
1737 install_node (&rmap_node, NULL);
1738 install_node (&zebra_node, NULL);
1739 install_node (&bgp_vpnv4_node, NULL);
1740 install_node (&bgp_ipv4_node, NULL);
1741 install_node (&bgp_ipv4m_node, NULL);
1742/* #ifdef HAVE_IPV6 */
1743 install_node (&bgp_ipv6_node, NULL);
1744/* #endif */
1745 install_node (&ospf_node, NULL);
1746/* #ifdef HAVE_IPV6 */
1747 install_node (&ripng_node, NULL);
1748 install_node (&ospf6_node, NULL);
1749/* #endif */
1750 install_node (&keychain_node, NULL);
1751 install_node (&keychain_key_node, NULL);
1752
1753 vtysh_install_default (VIEW_NODE);
1754 vtysh_install_default (ENABLE_NODE);
1755 vtysh_install_default (CONFIG_NODE);
1756 vtysh_install_default (BGP_NODE);
1757 vtysh_install_default (RIP_NODE);
1758 vtysh_install_default (INTERFACE_NODE);
1759 vtysh_install_default (RMAP_NODE);
1760 vtysh_install_default (ZEBRA_NODE);
1761 vtysh_install_default (BGP_VPNV4_NODE);
1762 vtysh_install_default (BGP_IPV4_NODE);
1763 vtysh_install_default (BGP_IPV4M_NODE);
1764 vtysh_install_default (BGP_IPV6_NODE);
1765 vtysh_install_default (OSPF_NODE);
1766 vtysh_install_default (RIPNG_NODE);
1767 vtysh_install_default (OSPF6_NODE);
1768 vtysh_install_default (KEYCHAIN_NODE);
1769 vtysh_install_default (KEYCHAIN_KEY_NODE);
1770
1771 install_element (VIEW_NODE, &vtysh_enable_cmd);
1772 install_element (ENABLE_NODE, &vtysh_config_terminal_cmd);
1773 install_element (ENABLE_NODE, &vtysh_disable_cmd);
1774
1775 /* "exit" command. */
1776 install_element (VIEW_NODE, &vtysh_exit_all_cmd);
1777 install_element (VIEW_NODE, &vtysh_quit_all_cmd);
1778 install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
1779 /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
1780 install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
1781 install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
1782 install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
1783 install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
paul68980082003-03-25 05:07:42 +00001784 install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
1785 install_element (RIPNG_NODE, &vtysh_quit_ripngd_cmd);
paul718e3742002-12-13 20:15:29 +00001786 install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd);
1787 install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd);
paul68980082003-03-25 05:07:42 +00001788 install_element (OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
1789 install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
paul718e3742002-12-13 20:15:29 +00001790 install_element (BGP_NODE, &vtysh_exit_bgpd_cmd);
1791 install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
1792 install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
1793 install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
1794 install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
1795 install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
1796 install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
1797 install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
1798 install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
1799 install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
1800 install_element (KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
1801 install_element (KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
1802 install_element (KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
1803 install_element (KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd);
1804 install_element (RMAP_NODE, &vtysh_exit_rmap_cmd);
1805 install_element (RMAP_NODE, &vtysh_quit_rmap_cmd);
1806
1807 /* "end" command. */
1808 install_element (CONFIG_NODE, &vtysh_end_all_cmd);
1809 install_element (ENABLE_NODE, &vtysh_end_all_cmd);
1810 install_element (RIP_NODE, &vtysh_end_all_cmd);
1811 install_element (RIPNG_NODE, &vtysh_end_all_cmd);
1812 install_element (OSPF_NODE, &vtysh_end_all_cmd);
1813 install_element (OSPF6_NODE, &vtysh_end_all_cmd);
1814 install_element (BGP_NODE, &vtysh_end_all_cmd);
1815 install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
1816 install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
1817 install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
1818 install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
1819 install_element (KEYCHAIN_NODE, &vtysh_end_all_cmd);
1820 install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
1821 install_element (RMAP_NODE, &vtysh_end_all_cmd);
1822
paul338a9912003-03-01 15:44:10 +00001823 install_element (INTERFACE_NODE, &interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001824 install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
1825 install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
1826 install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
1827 install_element (CONFIG_NODE, &router_rip_cmd);
1828#ifdef HAVE_IPV6
1829 install_element (CONFIG_NODE, &router_ripng_cmd);
1830#endif
1831 install_element (CONFIG_NODE, &router_ospf_cmd);
1832#ifdef HAVE_IPV6
1833 install_element (CONFIG_NODE, &router_ospf6_cmd);
1834#endif
1835 install_element (CONFIG_NODE, &router_bgp_cmd);
1836 install_element (BGP_NODE, &address_family_vpnv4_cmd);
1837 install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
1838 install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
1839 install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
1840#ifdef HAVE_IPV6
1841 install_element (BGP_NODE, &address_family_ipv6_cmd);
1842 install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
1843#endif
1844 install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
1845 install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
1846 install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
1847 install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
1848 install_element (CONFIG_NODE, &key_chain_cmd);
1849 install_element (CONFIG_NODE, &route_map_cmd);
1850 install_element (KEYCHAIN_NODE, &key_cmd);
1851 install_element (KEYCHAIN_NODE, &key_chain_cmd);
1852 install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
1853 install_element (CONFIG_NODE, &vtysh_interface_cmd);
1854 install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
1855 install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
1856 install_element (ENABLE_NODE, &vtysh_write_file_cmd);
1857
1858 /* write terminal command */
1859 install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
1860 install_element (CONFIG_NODE, &vtysh_write_terminal_cmd);
1861 install_element (BGP_NODE, &vtysh_write_terminal_cmd);
1862 install_element (BGP_VPNV4_NODE, &vtysh_write_terminal_cmd);
1863 install_element (BGP_IPV4_NODE, &vtysh_write_terminal_cmd);
1864 install_element (BGP_IPV4M_NODE, &vtysh_write_terminal_cmd);
1865 install_element (BGP_IPV6_NODE, &vtysh_write_terminal_cmd);
1866 install_element (RIP_NODE, &vtysh_write_terminal_cmd);
1867 install_element (RIPNG_NODE, &vtysh_write_terminal_cmd);
1868 install_element (OSPF_NODE, &vtysh_write_terminal_cmd);
1869 install_element (OSPF6_NODE, &vtysh_write_terminal_cmd);
1870 install_element (INTERFACE_NODE, &vtysh_write_terminal_cmd);
1871 install_element (RMAP_NODE, &vtysh_write_terminal_cmd);
1872 install_element (KEYCHAIN_NODE, &vtysh_write_terminal_cmd);
1873 install_element (KEYCHAIN_KEY_NODE, &vtysh_write_terminal_cmd);
1874
1875 /* write memory command */
1876 install_element (ENABLE_NODE, &vtysh_write_memory_cmd);
1877 install_element (CONFIG_NODE, &vtysh_write_memory_cmd);
1878 install_element (BGP_NODE, &vtysh_write_memory_cmd);
1879 install_element (BGP_VPNV4_NODE, &vtysh_write_memory_cmd);
1880 install_element (BGP_IPV4_NODE, &vtysh_write_memory_cmd);
1881 install_element (BGP_IPV4M_NODE, &vtysh_write_memory_cmd);
1882 install_element (BGP_IPV6_NODE, &vtysh_write_memory_cmd);
1883 install_element (RIP_NODE, &vtysh_write_memory_cmd);
1884 install_element (RIPNG_NODE, &vtysh_write_memory_cmd);
1885 install_element (OSPF_NODE, &vtysh_write_memory_cmd);
1886 install_element (OSPF6_NODE, &vtysh_write_memory_cmd);
1887 install_element (INTERFACE_NODE, &vtysh_write_memory_cmd);
1888 install_element (RMAP_NODE, &vtysh_write_memory_cmd);
1889 install_element (KEYCHAIN_NODE, &vtysh_write_memory_cmd);
1890 install_element (KEYCHAIN_KEY_NODE, &vtysh_write_memory_cmd);
1891
1892 install_element (VIEW_NODE, &vtysh_ping_cmd);
1893 install_element (VIEW_NODE, &vtysh_traceroute_cmd);
1894 install_element (VIEW_NODE, &vtysh_telnet_cmd);
1895 install_element (VIEW_NODE, &vtysh_telnet_port_cmd);
paul5087df52003-01-25 06:56:09 +00001896 install_element (VIEW_NODE, &vtysh_ssh_cmd);
paul718e3742002-12-13 20:15:29 +00001897 install_element (ENABLE_NODE, &vtysh_ping_cmd);
1898 install_element (ENABLE_NODE, &vtysh_traceroute_cmd);
1899 install_element (ENABLE_NODE, &vtysh_telnet_cmd);
1900 install_element (ENABLE_NODE, &vtysh_telnet_port_cmd);
1901 install_element (ENABLE_NODE, &vtysh_start_shell_cmd);
1902 install_element (ENABLE_NODE, &vtysh_start_bash_cmd);
1903 install_element (ENABLE_NODE, &vtysh_start_zsh_cmd);
1904
1905 install_element (RMAP_NODE, &set_metric_cmd);
1906 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
1907
1908 install_element (CONFIG_NODE, &vtysh_log_stdout_cmd);
1909 install_element (CONFIG_NODE, &no_vtysh_log_stdout_cmd);
1910 install_element (CONFIG_NODE, &vtysh_log_file_cmd);
1911 install_element (CONFIG_NODE, &no_vtysh_log_file_cmd);
1912 install_element (CONFIG_NODE, &vtysh_log_syslog_cmd);
1913 install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd);
1914 install_element (CONFIG_NODE, &vtysh_log_trap_cmd);
1915 install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd);
1916 install_element (CONFIG_NODE, &vtysh_log_record_priority_cmd);
1917 install_element (CONFIG_NODE, &no_vtysh_log_record_priority_cmd);
paul4fc01e62002-12-13 20:49:00 +00001918 install_element (CONFIG_NODE, &vtysh_write_config_cmd);
1919 install_element (CONFIG_NODE, &no_vtysh_write_config_cmd);
paul718e3742002-12-13 20:15:29 +00001920}