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 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 */ 220 bufsz = 5 * sysconf(_SC_PAGESIZE) + 1; 221 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) 379 printf ("Warning...\n"); 380 break; 381 case CMD_ERR_AMBIGUOUS: 382 printf ("%% Ambiguous command.\n"); 383 break; 384 case CMD_ERR_NO_MATCH: 385 printf ("%% Unknown command.\n"); 386 break; 387 case CMD_ERR_INCOMPLETE: 388 printf ("%% Command incomplete.\n"); 389 break; 390 case CMD_SUCCESS_DAEMON: 391 { 392 if (pager && vtysh_pager_name) 393 { 394 fp = popen ("more", "w"); 395 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) 561 printf ("Warning...\n"); 562 break; 563 case CMD_ERR_AMBIGUOUS: 564 printf ("%% Ambiguous command.\n"); 565 break; 566 case CMD_ERR_NO_MATCH: 567 printf ("%% Unknown command: %s", vty->buf); 568 break; 569 case CMD_ERR_INCOMPLETE: 570 printf ("%% Command incomplete.\n"); 571 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 631 printf ("\n"); 632 633 /* Ambiguous and no match error. */ 634 switch (ret) 635 { 636 case CMD_ERR_AMBIGUOUS: 637 cmd_free_strvec (vline); 638 printf ("%% Ambiguous command.\n"); 639 rl_on_new_line (); 640 return 0; 641 break; 642 case CMD_ERR_NO_MATCH: 643 cmd_free_strvec (vline); 644 printf ("%% There is no matched command.\n"); 645 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) 675 printf (" %-s\n", 676 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd); 677 else 678 printf (" %-*s %s\n", 679 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 1084DEFUNSH (VTYSH_RMAP, 1085 vtysh_exit_rmap, 1086 vtysh_exit_rmap_cmd, 1087 "exit", 1088 "Exit current mode and down to previous mode\n") 1089{ 1090 return vtysh_exit (vty); 1091} 1092 1093ALIAS (vtysh_exit_rmap, 1094 vtysh_quit_rmap_cmd, 1095 "quit", 1096 "Exit current mode and down to previous mode\n") 1097 1098DEFUNSH (VTYSH_BGPD, 1099 vtysh_exit_bgpd, 1100 vtysh_exit_bgpd_cmd, 1101 "exit", 1102 "Exit current mode and down to previous mode\n") 1103{ 1104 return vtysh_exit (vty); 1105} 1106 1107ALIAS (vtysh_exit_bgpd, 1108 vtysh_quit_bgpd_cmd, 1109 "quit", 1110 "Exit current mode and down to previous mode\n") 1111 1112DEFUNSH (VTYSH_OSPFD, 1113 vtysh_exit_ospfd, 1114 vtysh_exit_ospfd_cmd, 1115 "exit", 1116 "Exit current mode and down to previous mode\n") 1117{ 1118 return vtysh_exit (vty); 1119} 1120 1121ALIAS (vtysh_exit_ospfd, 1122 vtysh_quit_ospfd_cmd, 1123 "quit", 1124 "Exit current mode and down to previous mode\n") 1125 1126DEFUNSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD, 1127 vtysh_interface, 1128 vtysh_interface_cmd, 1129 "interface IFNAME", 1130 "Select an interface to configure\n" 1131 "Interface's name\n") 1132{ 1133 vty->node = INTERFACE_NODE; 1134 return CMD_SUCCESS; 1135} 1136 1137DEFSH (VTYSH_RIPD|VTYSH_BGPD, 1138 set_ip_nexthop_cmd, 1139 "set ip next-hop A.B.C.D", 1140 SET_STR 1141 IP_STR 1142 "Next hop address\n" 1143 "IP address of next hop\n") 1144 1145DEFSH (VTYSH_RMAP, 1146 set_metric_cmd, 1147 "set metric <0-4294967295>", 1148 SET_STR 1149 "Metric value for destination routing protocol\n" 1150 "Metric value\n") 1151 1152DEFUNSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD, 1153 vtysh_exit_interface, 1154 vtysh_exit_interface_cmd, 1155 "exit", 1156 "Exit current mode and down to previous mode\n") 1157{ 1158 return vtysh_exit (vty); 1159} 1160 1161ALIAS (vtysh_exit_interface, 1162 vtysh_quit_interface_cmd, 1163 "quit", 1164 "Exit current mode and down to previous mode\n") 1165 1166DEFUN (vtysh_write_terminal, 1167 vtysh_write_terminal_cmd, 1168 "write terminal", 1169 "Write running configuration to memory, network, or terminal\n" 1170 "Write to terminal\n") 1171{ 1172 int ret; 1173 char line[] = "write terminal\n"; 1174 FILE *fp = NULL; 1175 1176 if (vtysh_pager_name) 1177 { 1178 fp = popen ("more", "w"); 1179 if (fp == NULL) 1180 { 1181 perror ("popen"); 1182 exit (1); 1183 } 1184 } 1185 else 1186 fp = stdout; 1187 1188 vty_out (vty, "Building configuration...%s", VTY_NEWLINE); 1189 vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE, 1190 VTY_NEWLINE); 1191 1192 vtysh_config_write (fp); 1193 1194 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_ZEBRA], line); 1195 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIP], line); 1196 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIPNG], line); 1197 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF], line); 1198 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF6], line); 1199 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_BGP], line); 1200 1201 vtysh_config_dump (fp); 1202 1203 if (vtysh_pager_name && fp) 1204 { 1205 fflush (fp); 1206 if (pclose (fp) == -1) 1207 { 1208 perror ("pclose"); 1209 exit (1); 1210 } 1211 fp = NULL; 1212 } 1213 1214 return CMD_SUCCESS; 1215} 1216 1217DEFUN (vtysh_write_memory, 1218 vtysh_write_memory_cmd, 1219 "write memory", 1220 "Write running configuration to memory, network, or terminal\n" 1221 "Write configuration to the file (same as write file)\n") 1222{ 1223 int ret; 1224 mode_t old_umask; 1225 char line[] = "write terminal\n"; 1226 FILE *fp; 1227 char *integrate_sav = NULL; 1228 1229 /* config files have 0600 perms... */ 1230 old_umask = umask (0077); 1231 1232 integrate_sav = malloc (strlen (integrate_default) 1233 + strlen (CONF_BACKUP_EXT) + 1); 1234 strcpy (integrate_sav, integrate_default); 1235 strcat (integrate_sav, CONF_BACKUP_EXT); 1236 1237 1238 printf ("Building Configuration...\n"); 1239 1240 /* Move current configuration file to backup config file */ 1241 unlink (integrate_sav); 1242 rename (integrate_default, integrate_sav); 1243 1244 fp = fopen (integrate_default, "w"); 1245 if (fp == NULL) 1246 { 1247 printf ("%% Can't open configuration file %s.\n", integrate_default); 1248 umask (old_umask); 1249 return CMD_SUCCESS; 1250 } 1251 else 1252 printf ("[OK]\n"); 1253 1254 1255 vtysh_config_write (fp); 1256 1257 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_ZEBRA], line); 1258 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIP], line); 1259 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_RIPNG], line); 1260 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF], line); 1261 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_OSPF6], line); 1262 ret = vtysh_client_config (&vtysh_client[VTYSH_INDEX_BGP], line); 1263 1264 vtysh_config_dump (fp); 1265 1266 fclose (fp); 1267 1268 umask (old_umask); 1269 return CMD_SUCCESS; 1270} 1271 1272ALIAS (vtysh_write_memory, 1273 vtysh_copy_runningconfig_startupconfig_cmd, 1274 "copy running-config startup-config", 1275 "Copy from one file to another\n" 1276 "Copy from current system configuration\n" 1277 "Copy to startup configuration\n") 1278 1279ALIAS (vtysh_write_memory, 1280 vtysh_write_file_cmd, 1281 "write file", 1282 "Write running configuration to memory, network, or terminal\n" 1283 "Write configuration to the file (same as write memory)\n") 1284 1285ALIAS (vtysh_write_terminal, 1286 vtysh_show_running_config_cmd, 1287 "show running-config", 1288 SHOW_STR 1289 "Current operating configuration\n") 1290 1291/* Execute command in child process. */ 1292int 1293execute_command (char *command, int argc, char *arg1, char *arg2) 1294{ 1295 int ret; 1296 pid_t pid; 1297 int status; 1298 1299 /* Call fork(). */ 1300 pid = fork (); 1301 1302 if (pid < 0) 1303 { 1304 /* Failure of fork(). */ 1305 fprintf (stderr, "Can't fork: %s\n", strerror (errno)); 1306 exit (1); 1307 } 1308 else if (pid == 0) 1309 { 1310 /* This is child process. */ 1311 switch (argc) 1312 { 1313 case 0: 1314 ret = execlp (command, command, NULL); 1315 break; 1316 case 1: 1317 ret = execlp (command, command, arg1, NULL); 1318 break; 1319 case 2: 1320 ret = execlp (command, command, arg1, arg2, NULL); 1321 break; 1322 } 1323 1324 /* When execlp suceed, this part is not executed. */ 1325 fprintf (stderr, "Can't execute %s: %s\n", command, strerror (errno)); 1326 exit (1); 1327 } 1328 else 1329 { 1330 /* This is parent. */ 1331 execute_flag = 1; 1332 ret = wait4 (pid, &status, 0, NULL); 1333 execute_flag = 0; 1334 } 1335 return 0; 1336} 1337 1338DEFUN (vtysh_ping, 1339 vtysh_ping_cmd, 1340 "ping WORD", 1341 "send echo messages\n" 1342 "Ping destination address or hostname\n") 1343{ 1344 execute_command ("ping", 1, argv[0], NULL); 1345 return CMD_SUCCESS; 1346} 1347 1348DEFUN (vtysh_traceroute, 1349 vtysh_traceroute_cmd, 1350 "traceroute WORD", 1351 "Trace route to destination\n" 1352 "Trace route to destination address or hostname\n") 1353{ 1354 execute_command ("traceroute", 1, argv[0], NULL); 1355 return CMD_SUCCESS; 1356} 1357 1358DEFUN (vtysh_telnet, 1359 vtysh_telnet_cmd, 1360 "telnet WORD", 1361 "Open a telnet connection\n" 1362 "IP address or hostname of a remote system\n") 1363{ 1364 execute_command ("telnet", 1, argv[0], NULL); 1365 return CMD_SUCCESS; 1366} 1367 1368DEFUN (vtysh_telnet_port, 1369 vtysh_telnet_port_cmd, 1370 "telnet WORD PORT", 1371 "Open a telnet connection\n" 1372 "IP address or hostname of a remote system\n" 1373 "TCP Port number\n") 1374{ 1375 execute_command ("telnet", 2, argv[0], argv[1]); 1376 return CMD_SUCCESS; 1377} 1378 1379DEFUN (vtysh_start_shell, 1380 vtysh_start_shell_cmd, 1381 "start-shell", 1382 "Start UNIX shell\n") 1383{ 1384 execute_command ("sh", 0, NULL, NULL); 1385 return CMD_SUCCESS; 1386} 1387 1388DEFUN (vtysh_start_bash, 1389 vtysh_start_bash_cmd, 1390 "start-shell bash", 1391 "Start UNIX shell\n" 1392 "Start bash\n") 1393{ 1394 execute_command ("bash", 0, NULL, NULL); 1395 return CMD_SUCCESS; 1396} 1397 1398DEFUN (vtysh_start_zsh, 1399 vtysh_start_zsh_cmd, 1400 "start-shell zsh", 1401 "Start UNIX shell\n" 1402 "Start Z shell\n") 1403{ 1404 execute_command ("zsh", 0, NULL, NULL); 1405 return CMD_SUCCESS; 1406} 1407 1408/* Route map node structure. */ 1409struct cmd_node rmap_node = 1410{ 1411 RMAP_NODE, 1412 "%s(config-route-map)# " 1413}; 1414 1415/* Zebra node structure. */ 1416struct cmd_node zebra_node = 1417{ 1418 ZEBRA_NODE, 1419 "%s(config-router)# " 1420}; 1421 1422struct cmd_node bgp_vpnv4_node = 1423{ 1424 BGP_VPNV4_NODE, 1425 "%s(config-router-af)# " 1426}; 1427 1428struct cmd_node bgp_ipv4_node = 1429{ 1430 BGP_IPV4_NODE, 1431 "%s(config-router-af)# " 1432}; 1433 1434struct cmd_node bgp_ipv4m_node = 1435{ 1436 BGP_IPV4M_NODE, 1437 "%s(config-router-af)# " 1438}; 1439 1440struct cmd_node bgp_ipv6_node = 1441{ 1442 BGP_IPV6_NODE, 1443 "%s(config-router-af)# " 1444}; 1445 1446struct cmd_node ospf_node = 1447{ 1448 OSPF_NODE, 1449 "%s(config-router)# " 1450}; 1451 1452/* RIPng node structure. */ 1453struct cmd_node ripng_node = 1454{ 1455 RIPNG_NODE, 1456 "%s(config-router)# " 1457}; 1458 1459/* OSPF6 node structure. */ 1460struct cmd_node ospf6_node = 1461{ 1462 OSPF6_NODE, 1463 "%s(config-ospf6)# " 1464}; 1465 1466struct cmd_node keychain_node = 1467{ 1468 KEYCHAIN_NODE, 1469 "%s(config-keychain)# " 1470}; 1471 1472struct cmd_node keychain_key_node = 1473{ 1474 KEYCHAIN_KEY_NODE, 1475 "%s(config-keychain-key)# " 1476}; 1477 1478void 1479vtysh_install_default (enum node_type node) 1480{ 1481 install_element (node, &config_list_cmd); 1482} 1483 1484/* Making connection to protocol daemon. */ 1485int 1486vtysh_connect (struct vtysh_client *vclient, char *path) 1487{ 1488 int ret; 1489 int sock, len; 1490 struct sockaddr_un addr; 1491 struct stat s_stat; 1492 uid_t euid; 1493 gid_t egid; 1494 1495 memset (vclient, 0, sizeof (struct vtysh_client)); 1496 vclient->fd = -1; 1497 1498 /* Stat socket to see if we have permission to access it. */ 1499 euid = geteuid(); 1500 egid = getegid(); 1501 ret = stat (path, &s_stat); 1502 if (ret < 0 && errno != ENOENT) 1503 { 1504 fprintf (stderr, "vtysh_connect(%s): stat = %s\n", 1505 path, strerror(errno)); 1506 exit(1); 1507 } 1508 1509 if (ret >= 0) 1510 { 1511 if (! S_ISSOCK(s_stat.st_mode)) 1512 { 1513 fprintf (stderr, "vtysh_connect(%s): Not a socket\n", 1514 path); 1515 exit (1); 1516 } 1517 1518 if (euid != s_stat.st_uid 1519 || !(s_stat.st_mode & S_IWUSR) 1520 || !(s_stat.st_mode & S_IRUSR)) 1521 { 1522 fprintf (stderr, "vtysh_connect(%s): No permission to access socket\n", 1523 path); 1524 exit (1); 1525 } 1526 } 1527 1528 sock = socket (AF_UNIX, SOCK_STREAM, 0); 1529 if (sock < 0) 1530 { 1531#ifdef DEBUG 1532 fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path, strerror(errno)); 1533#endif /* DEBUG */ 1534 return -1; 1535 } 1536 1537 memset (&addr, 0, sizeof (struct sockaddr_un)); 1538 addr.sun_family = AF_UNIX; 1539 strncpy (addr.sun_path, path, strlen (path)); 1540#ifdef HAVE_SUN_LEN 1541 len = addr.sun_len = SUN_LEN(&addr); 1542#else 1543 len = sizeof (addr.sun_family) + strlen (addr.sun_path); 1544#endif /* HAVE_SUN_LEN */ 1545 1546 ret = connect (sock, (struct sockaddr *) &addr, len); 1547 if (ret < 0) 1548 { 1549#ifdef DEBUG 1550 fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path, strerror(errno)); 1551#endif /* DEBUG */ 1552 close (sock); 1553 return -1; 1554 } 1555 vclient->fd = sock; 1556 1557 return 0; 1558} 1559 1560void 1561vtysh_connect_all() 1562{ 1563 /* Clear each daemons client structure. */ 1564 vtysh_connect (&vtysh_client[VTYSH_INDEX_ZEBRA], ZEBRA_PATH); 1565 vtysh_connect (&vtysh_client[VTYSH_INDEX_RIP], RIP_PATH); 1566 vtysh_connect (&vtysh_client[VTYSH_INDEX_RIPNG], RIPNG_PATH); 1567 vtysh_connect (&vtysh_client[VTYSH_INDEX_OSPF], OSPF_PATH); 1568 vtysh_connect (&vtysh_client[VTYSH_INDEX_OSPF6], OSPF6_PATH); 1569 vtysh_connect (&vtysh_client[VTYSH_INDEX_BGP], BGP_PATH); 1570} 1571 1572 1573/* To disable readline's filename completion */ 1574int 1575vtysh_completion_entry_fucntion (int ignore, int invoking_key) 1576{ 1577 return 0; 1578} 1579 1580void 1581vtysh_readline_init () 1582{ 1583 /* readline related settings. */ 1584 rl_bind_key ('?', vtysh_rl_describe); 1585 rl_completion_entry_function = vtysh_completion_entry_fucntion; 1586 rl_attempted_completion_function = (CPPFunction *)new_completion; 1587 /* do not append space after completion. It will be appended 1588 in new_completion() function explicitly */ 1589 rl_completion_append_character = '\0'; 1590} 1591 1592char * 1593vtysh_prompt () 1594{ 1595 struct utsname names; 1596 static char buf[100]; 1597 const char*hostname; 1598 extern struct host host; 1599 1600 hostname = host.name; 1601 1602 if (!hostname) 1603 { 1604 uname (&names); 1605 hostname = names.nodename; 1606 } 1607 1608 snprintf (buf, sizeof buf, cmd_prompt (vty->node), hostname); 1609 1610 return buf; 1611} 1612 1613void 1614vtysh_init_vty () 1615{ 1616 /* Make vty structure. */ 1617 vty = vty_new (); 1618 vty->type = VTY_SHELL; 1619 vty->node = VIEW_NODE; 1620 1621 /* Initialize commands. */ 1622 cmd_init (0); 1623 1624 /* Install nodes. */ 1625 install_node (&bgp_node, NULL); 1626 install_node (&rip_node, NULL); 1627 install_node (&interface_node, NULL); 1628 install_node (&rmap_node, NULL); 1629 install_node (&zebra_node, NULL); 1630 install_node (&bgp_vpnv4_node, NULL); 1631 install_node (&bgp_ipv4_node, NULL); 1632 install_node (&bgp_ipv4m_node, NULL); 1633/* #ifdef HAVE_IPV6 */ 1634 install_node (&bgp_ipv6_node, NULL); 1635/* #endif */ 1636 install_node (&ospf_node, NULL); 1637/* #ifdef HAVE_IPV6 */ 1638 install_node (&ripng_node, NULL); 1639 install_node (&ospf6_node, NULL); 1640/* #endif */ 1641 install_node (&keychain_node, NULL); 1642 install_node (&keychain_key_node, NULL); 1643 1644 vtysh_install_default (VIEW_NODE); 1645 vtysh_install_default (ENABLE_NODE); 1646 vtysh_install_default (CONFIG_NODE); 1647 vtysh_install_default (BGP_NODE); 1648 vtysh_install_default (RIP_NODE); 1649 vtysh_install_default (INTERFACE_NODE); 1650 vtysh_install_default (RMAP_NODE); 1651 vtysh_install_default (ZEBRA_NODE); 1652 vtysh_install_default (BGP_VPNV4_NODE); 1653 vtysh_install_default (BGP_IPV4_NODE); 1654 vtysh_install_default (BGP_IPV4M_NODE); 1655 vtysh_install_default (BGP_IPV6_NODE); 1656 vtysh_install_default (OSPF_NODE); 1657 vtysh_install_default (RIPNG_NODE); 1658 vtysh_install_default (OSPF6_NODE); 1659 vtysh_install_default (KEYCHAIN_NODE); 1660 vtysh_install_default (KEYCHAIN_KEY_NODE); 1661 1662 install_element (VIEW_NODE, &vtysh_enable_cmd); 1663 install_element (ENABLE_NODE, &vtysh_config_terminal_cmd); 1664 install_element (ENABLE_NODE, &vtysh_disable_cmd); 1665 1666 /* "exit" command. */ 1667 install_element (VIEW_NODE, &vtysh_exit_all_cmd); 1668 install_element (VIEW_NODE, &vtysh_quit_all_cmd); 1669 install_element (CONFIG_NODE, &vtysh_exit_all_cmd); 1670 /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */ 1671 install_element (ENABLE_NODE, &vtysh_exit_all_cmd); 1672 install_element (ENABLE_NODE, &vtysh_quit_all_cmd); 1673 install_element (RIP_NODE, &vtysh_exit_ripd_cmd); 1674 install_element (RIP_NODE, &vtysh_quit_ripd_cmd); 1675 install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd); 1676 install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd); 1677 install_element (BGP_NODE, &vtysh_exit_bgpd_cmd); 1678 install_element (BGP_NODE, &vtysh_quit_bgpd_cmd); 1679 install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd); 1680 install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd); 1681 install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd); 1682 install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd); 1683 install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd); 1684 install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd); 1685 install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd); 1686 install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd); 1687 install_element (KEYCHAIN_NODE, &vtysh_exit_ripd_cmd); 1688 install_element (KEYCHAIN_NODE, &vtysh_quit_ripd_cmd); 1689 install_element (KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd); 1690 install_element (KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd); 1691 install_element (RMAP_NODE, &vtysh_exit_rmap_cmd); 1692 install_element (RMAP_NODE, &vtysh_quit_rmap_cmd); 1693 1694 /* "end" command. */ 1695 install_element (CONFIG_NODE, &vtysh_end_all_cmd); 1696 install_element (ENABLE_NODE, &vtysh_end_all_cmd); 1697 install_element (RIP_NODE, &vtysh_end_all_cmd); 1698 install_element (RIPNG_NODE, &vtysh_end_all_cmd); 1699 install_element (OSPF_NODE, &vtysh_end_all_cmd); 1700 install_element (OSPF6_NODE, &vtysh_end_all_cmd); 1701 install_element (BGP_NODE, &vtysh_end_all_cmd); 1702 install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd); 1703 install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd); 1704 install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd); 1705 install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd); 1706 install_element (KEYCHAIN_NODE, &vtysh_end_all_cmd); 1707 install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd); 1708 install_element (RMAP_NODE, &vtysh_end_all_cmd); 1709 1710 install_element (INTERFACE_NODE, &vtysh_end_all_cmd); 1711 install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd); 1712 install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd); 1713 install_element (CONFIG_NODE, &router_rip_cmd); 1714#ifdef HAVE_IPV6 1715 install_element (CONFIG_NODE, &router_ripng_cmd); 1716#endif 1717 install_element (CONFIG_NODE, &router_ospf_cmd); 1718#ifdef HAVE_IPV6 1719 install_element (CONFIG_NODE, &router_ospf6_cmd); 1720#endif 1721 install_element (CONFIG_NODE, &router_bgp_cmd); 1722 install_element (BGP_NODE, &address_family_vpnv4_cmd); 1723 install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd); 1724 install_element (BGP_NODE, &address_family_ipv4_unicast_cmd); 1725 install_element (BGP_NODE, &address_family_ipv4_multicast_cmd); 1726#ifdef HAVE_IPV6 1727 install_element (BGP_NODE, &address_family_ipv6_cmd); 1728 install_element (BGP_NODE, &address_family_ipv6_unicast_cmd); 1729#endif 1730 install_element (BGP_VPNV4_NODE, &exit_address_family_cmd); 1731 install_element (BGP_IPV4_NODE, &exit_address_family_cmd); 1732 install_element (BGP_IPV4M_NODE, &exit_address_family_cmd); 1733 install_element (BGP_IPV6_NODE, &exit_address_family_cmd); 1734 install_element (CONFIG_NODE, &key_chain_cmd); 1735 install_element (CONFIG_NODE, &route_map_cmd); 1736 install_element (KEYCHAIN_NODE, &key_cmd); 1737 install_element (KEYCHAIN_NODE, &key_chain_cmd); 1738 install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd); 1739 install_element (CONFIG_NODE, &vtysh_interface_cmd); 1740 install_element (ENABLE_NODE, &vtysh_show_running_config_cmd); 1741 install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd); 1742 install_element (ENABLE_NODE, &vtysh_write_file_cmd); 1743 1744 /* write terminal command */ 1745 install_element (ENABLE_NODE, &vtysh_write_terminal_cmd); 1746 install_element (CONFIG_NODE, &vtysh_write_terminal_cmd); 1747 install_element (BGP_NODE, &vtysh_write_terminal_cmd); 1748 install_element (BGP_VPNV4_NODE, &vtysh_write_terminal_cmd); 1749 install_element (BGP_IPV4_NODE, &vtysh_write_terminal_cmd); 1750 install_element (BGP_IPV4M_NODE, &vtysh_write_terminal_cmd); 1751 install_element (BGP_IPV6_NODE, &vtysh_write_terminal_cmd); 1752 install_element (RIP_NODE, &vtysh_write_terminal_cmd); 1753 install_element (RIPNG_NODE, &vtysh_write_terminal_cmd); 1754 install_element (OSPF_NODE, &vtysh_write_terminal_cmd); 1755 install_element (OSPF6_NODE, &vtysh_write_terminal_cmd); 1756 install_element (INTERFACE_NODE, &vtysh_write_terminal_cmd); 1757 install_element (RMAP_NODE, &vtysh_write_terminal_cmd); 1758 install_element (KEYCHAIN_NODE, &vtysh_write_terminal_cmd); 1759 install_element (KEYCHAIN_KEY_NODE, &vtysh_write_terminal_cmd); 1760 1761 /* write memory command */ 1762 install_element (ENABLE_NODE, &vtysh_write_memory_cmd); 1763 install_element (CONFIG_NODE, &vtysh_write_memory_cmd); 1764 install_element (BGP_NODE, &vtysh_write_memory_cmd); 1765 install_element (BGP_VPNV4_NODE, &vtysh_write_memory_cmd); 1766 install_element (BGP_IPV4_NODE, &vtysh_write_memory_cmd); 1767 install_element (BGP_IPV4M_NODE, &vtysh_write_memory_cmd); 1768 install_element (BGP_IPV6_NODE, &vtysh_write_memory_cmd); 1769 install_element (RIP_NODE, &vtysh_write_memory_cmd); 1770 install_element (RIPNG_NODE, &vtysh_write_memory_cmd); 1771 install_element (OSPF_NODE, &vtysh_write_memory_cmd); 1772 install_element (OSPF6_NODE, &vtysh_write_memory_cmd); 1773 install_element (INTERFACE_NODE, &vtysh_write_memory_cmd); 1774 install_element (RMAP_NODE, &vtysh_write_memory_cmd); 1775 install_element (KEYCHAIN_NODE, &vtysh_write_memory_cmd); 1776 install_element (KEYCHAIN_KEY_NODE, &vtysh_write_memory_cmd); 1777 1778 install_element (VIEW_NODE, &vtysh_ping_cmd); 1779 install_element (VIEW_NODE, &vtysh_traceroute_cmd); 1780 install_element (VIEW_NODE, &vtysh_telnet_cmd); 1781 install_element (VIEW_NODE, &vtysh_telnet_port_cmd); 1782 install_element (ENABLE_NODE, &vtysh_ping_cmd); 1783 install_element (ENABLE_NODE, &vtysh_traceroute_cmd); 1784 install_element (ENABLE_NODE, &vtysh_telnet_cmd); 1785 install_element (ENABLE_NODE, &vtysh_telnet_port_cmd); 1786 install_element (ENABLE_NODE, &vtysh_start_shell_cmd); 1787 install_element (ENABLE_NODE, &vtysh_start_bash_cmd); 1788 install_element (ENABLE_NODE, &vtysh_start_zsh_cmd); 1789 1790 install_element (RMAP_NODE, &set_metric_cmd); 1791 install_element (RMAP_NODE, &set_ip_nexthop_cmd); 1792 1793 install_element (CONFIG_NODE, &vtysh_log_stdout_cmd); 1794 install_element (CONFIG_NODE, &no_vtysh_log_stdout_cmd); 1795 install_element (CONFIG_NODE, &vtysh_log_file_cmd); 1796 install_element (CONFIG_NODE, &no_vtysh_log_file_cmd); 1797 install_element (CONFIG_NODE, &vtysh_log_syslog_cmd); 1798 install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd); 1799 install_element (CONFIG_NODE, &vtysh_log_trap_cmd); 1800 install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd); 1801 install_element (CONFIG_NODE, &vtysh_log_record_priority_cmd); 1802 install_element (CONFIG_NODE, &no_vtysh_log_record_priority_cmd); 1803} 1804