📄 vty.c
字号:
vty->buf); vty_close (vty); exit (1); } vty_close (vty);}FILE *vty_use_backup_config (char *fullpath){ char *fullpath_sav, *fullpath_tmp; FILE *ret = NULL; struct stat buf; int tmp, sav; int c; char buffer[512]; fullpath_sav = malloc (strlen (fullpath) + strlen (CONF_BACKUP_EXT) + 1); strcpy (fullpath_sav, fullpath); strcat (fullpath_sav, CONF_BACKUP_EXT); if (stat (fullpath_sav, &buf) == -1) { free (fullpath_sav); return NULL; } fullpath_tmp = malloc (strlen (fullpath) + 8); sprintf (fullpath_tmp, "%s.XXXXXX", fullpath); /* Open file to configuration write. */ tmp = mkstemp (fullpath_tmp); if (tmp < 0) { free (fullpath_sav); free (fullpath_tmp); return NULL; } sav = open (fullpath_sav, O_RDONLY); if (sav < 0) { free (fullpath_sav); free (fullpath_tmp); unlink (fullpath_tmp); return NULL; } while((c = read (sav, buffer, 512)) > 0) write (tmp, buffer, c); close (sav); close (tmp); if (link (fullpath_tmp, fullpath) == 0) ret = fopen (fullpath, "r"); unlink (fullpath_tmp); free (fullpath_sav); free (fullpath_tmp); return fopen (fullpath, "r");}/* Read up configuration file from file_name. */voidvty_read_config (char *config_file, char *config_current_dir, char *config_default_dir){ char *cwd; FILE *confp = NULL; char *fullpath; /* If -f flag specified. */ if (config_file != NULL) { if (! IS_DIRECTORY_SEP (config_file[0])) { cwd = getcwd (NULL, MAXPATHLEN); fullpath = XMALLOC (MTYPE_TMP, strlen (cwd) + strlen (config_file) + 2); sprintf (fullpath, "%s/%s", cwd, config_file); } else fullpath = config_file; confp = fopen (fullpath, "r"); if (confp == NULL) { confp = vty_use_backup_config (fullpath); if (confp) fprintf (stderr, "WARNING: using backup configuration file!\n"); else { fprintf (stderr, "can't open configuration file [%s]\n", config_file); exit(1); } } } else { /* Relative path configuration file open. */ if (config_current_dir) { confp = fopen (config_current_dir, "r"); if (confp == NULL) { confp = vty_use_backup_config (config_current_dir); if (confp) fprintf (stderr, "WARNING: using backup configuration file!\n"); } } /* If there is no relative path exists, open system default file. */ if (confp == NULL) {#ifdef VTYSH int ret; struct stat conf_stat; /* !!!!PLEASE LEAVE!!!! This is NEEDED for use with vtysh -b, or else you can get a real configuration food fight with a lot garbage in the merged configuration file it creates coming from the per daemon configuration files. This also allows the daemons to start if there default configuration file is not present or ignore them, as needed when using vtysh -b to configure the daemons at boot - MAG */ /* Stat for vtysh Zebra.conf, if found startup and wait for boot configuration */ if ( strstr(config_default_dir, "vtysh") == NULL) { ret = stat (integrate_default, &conf_stat); if (ret >= 0) { return; } }#endif /* VTYSH */ confp = fopen (config_default_dir, "r"); if (confp == NULL) { confp = vty_use_backup_config (config_default_dir); if (confp) { fprintf (stderr, "WARNING: using backup configuration file!\n"); fullpath = config_default_dir; } else { fprintf (stderr, "can't open configuration file [%s]\n", config_default_dir); exit (1); } } else fullpath = config_default_dir; } else { /* Rleative path configuration file. */ cwd = getcwd (NULL, MAXPATHLEN); fullpath = XMALLOC (MTYPE_TMP, strlen (cwd) + strlen (config_current_dir) + 2); sprintf (fullpath, "%s/%s", cwd, config_current_dir); } } vty_read_file (confp); fclose (confp); host_config_set (fullpath);}/* Small utility function which output log to the VTY. */voidvty_log (const char *proto_str, const char *format, va_list va){ int i; struct vty *vty; for (i = 0; i < vector_max (vtyvec); i++) if ((vty = vector_slot (vtyvec, i)) != NULL) if (vty->monitor) vty_log_out (vty, proto_str, format, va);}intvty_config_lock (struct vty *vty){ if (vty_config == 0) { vty->config = 1; vty_config = 1; } return vty->config;}intvty_config_unlock (struct vty *vty){ if (vty_config == 1 && vty->config == 1) { vty->config = 0; vty_config = 0; } return vty->config;}/* Master of the threads. */extern struct thread_master *master;/* struct thread_master *master; */static voidvty_event (enum event event, int sock, struct vty *vty){ struct thread *vty_serv_thread; switch (event) { case VTY_SERV: vty_serv_thread = thread_add_read (master, vty_accept, vty, sock); vector_set_index (Vvty_serv_thread, sock, vty_serv_thread); break;#ifdef VTYSH case VTYSH_SERV: thread_add_read (master, vtysh_accept, vty, sock); break; case VTYSH_READ: thread_add_read (master, vtysh_read, vty, sock); break;#endif /* VTYSH */ case VTY_READ: vty->t_read = thread_add_read (master, vty_read, vty, sock); /* Time out treatment. */ if (vty->v_timeout) { if (vty->t_timeout) thread_cancel (vty->t_timeout); vty->t_timeout = thread_add_timer (master, vty_timeout, vty, vty->v_timeout); } break; case VTY_WRITE: if (! vty->t_write) vty->t_write = thread_add_write (master, vty_flush, vty, sock); break; case VTY_TIMEOUT_RESET: if (vty->t_timeout) { thread_cancel (vty->t_timeout); vty->t_timeout = NULL; } if (vty->v_timeout) { vty->t_timeout = thread_add_timer (master, vty_timeout, vty, vty->v_timeout); } break; }}DEFUN (config_who, config_who_cmd, "who", "Display who is on vty\n"){ int i; struct vty *v; for (i = 0; i < vector_max (vtyvec); i++) if ((v = vector_slot (vtyvec, i)) != NULL) vty_out (vty, "%svty[%d] connected from %s.%s", v->config ? "*" : " ", i, v->address, VTY_NEWLINE); return CMD_SUCCESS;}/* Move to vty configuration mode. */DEFUN (line_vty, line_vty_cmd, "line vty", "Configure a terminal line\n" "Virtual terminal\n"){ vty->node = VTY_NODE; return CMD_SUCCESS;}/* Set time out value. */intexec_timeout (struct vty *vty, char *min_str, char *sec_str){ unsigned long timeout = 0; /* min_str and sec_str are already checked by parser. So it must be all digit string. */ if (min_str) { timeout = strtol (min_str, NULL, 10); timeout *= 60; } if (sec_str) timeout += strtol (sec_str, NULL, 10); vty_timeout_val = timeout; vty->v_timeout = timeout; vty_event (VTY_TIMEOUT_RESET, 0, vty); return CMD_SUCCESS;}DEFUN (exec_timeout_min, exec_timeout_min_cmd, "exec-timeout <0-35791>", "Set timeout value\n" "Timeout value in minutes\n"){ return exec_timeout (vty, argv[0], NULL);}DEFUN (exec_timeout_sec, exec_timeout_sec_cmd, "exec-timeout <0-35791> <0-2147483>", "Set the EXEC timeout\n" "Timeout in minutes\n" "Timeout in seconds\n"){ return exec_timeout (vty, argv[0], argv[1]);}DEFUN (no_exec_timeout, no_exec_timeout_cmd, "no exec-timeout", NO_STR "Set the EXEC timeout\n"){ return exec_timeout (vty, NULL, NULL);}/* Set vty access class. */DEFUN (vty_access_class, vty_access_class_cmd, "access-class WORD", "Filter connections based on an IP access list\n" "IP access list\n"){ if (vty_accesslist_name) XFREE(MTYPE_VTY, vty_accesslist_name); vty_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]); return CMD_SUCCESS;}/* Clear vty access class. */DEFUN (no_vty_access_class, no_vty_access_class_cmd, "no access-class [WORD]", NO_STR "Filter connections based on an IP access list\n" "IP access list\n"){ if (! vty_accesslist_name || (argc && strcmp(vty_accesslist_name, argv[0]))) { vty_out (vty, "Access-class is not currently applied to vty%s", VTY_NEWLINE); return CMD_WARNING; } XFREE(MTYPE_VTY, vty_accesslist_name); vty_accesslist_name = NULL; return CMD_SUCCESS;}#ifdef HAVE_IPV6/* Set vty access class. */DEFUN (vty_ipv6_access_class, vty_ipv6_access_class_cmd, "ipv6 access-class WORD", IPV6_STR "Filter connections based on an IP access list\n" "IPv6 access list\n"){ if (vty_ipv6_accesslist_name) XFREE(MTYPE_VTY, vty_ipv6_accesslist_name); vty_ipv6_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]); return CMD_SUCCESS;}/* Clear vty access class. */DEFUN (no_vty_ipv6_access_class, no_vty_ipv6_access_class_cmd, "no ipv6 access-class [WORD]", NO_STR IPV6_STR "Filter connections based on an IP access list\n" "IPv6 access list\n"){ if (! vty_ipv6_accesslist_name || (argc && strcmp(vty_ipv6_accesslist_name, argv[0]))) { vty_out (vty, "IPv6 access-class is not currently applied to vty%s", VTY_NEWLINE); return CMD_WARNING; } XFREE(MTYPE_VTY, vty_ipv6_accesslist_name); vty_ipv6_accesslist_name = NULL; return CMD_SUCCESS;}#endif /* HAVE_IPV6 *//* vty login. */DEFUN (vty_login, vty_login_cmd, "login", "Enable password checking\n"){ no_password_check = 0; return CMD_SUCCESS;}DEFUN (no_vty_login, no_vty_login_cmd, "no login", NO_STR "Enable password checking\n"){ no_password_check = 1; return CMD_SUCCESS;}DEFUN (service_advanced_vty, service_advanced_vty_cmd, "service advanced-vty", "Set up miscellaneous service\n" "Enable advanced mode vty interface\n"){ host.advanced = 1; return CMD_SUCCESS;}DEFUN (no_service_advanced_vty, no_service_advanced_vty_cmd, "no service advanced-vty", NO_STR "Set up miscellaneous service\n" "Enable advanced mode vty interface\n"){ host.advanced = 0; return CMD_SUCCESS;}DEFUN (terminal_monitor, terminal_monitor_cmd, "terminal monitor", "Set terminal line parameters\n" "Copy debug output to the current terminal line\n"){ vty->monitor = 1; return CMD_SUCCESS;}DEFUN (terminal_no_monitor, terminal_no_monitor_cmd, "terminal no monitor", "Set terminal line parameters\n" NO_STR "Copy debug output to the current terminal line\n"){ vty->monitor = 0; return CMD_SUCCESS;}DEFUN (show_history, show_history_cmd, "show history", SHOW_STR "Display the session command history\n"){ int index; for (index = vty->hindex + 1; index != vty->hindex;) { if (index == VTY_MAXHIST) { index = 0; continue; } if (vty->hist[index] != NULL) vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE); index++; } return CMD_SUCCESS;}/* Display current configuration. */intvty_config_write (struct vty *vty){ vty_out (vty, "line vty%s", VTY_NEWLINE); if (vty_accesslist_name) vty_out (vty, " access-class %s%s", vty_accesslist_name, VTY_NEWLINE); if (vty_ipv6_accesslist_name) vty_out (vty, " ipv6 access-class %s%s", vty_ipv6_accesslist_name, VTY_NEWLINE); /* exec-timeout */ if (vty_timeout_val != VTY_TIMEOUT_DEFAULT) vty_out (vty, " exec-timeout %ld %ld%s", vty_timeout_val / 60, vty_timeout_val % 60, VTY_NEWLINE); /* login */ if (no_password_check) vty_out (vty, " no login%s", VTY_NEWLINE); vty_out (vty, "!%s", VTY_NEWLINE); return CMD_SUCCESS;}struct cmd_node vty_node = { VTY_NODE, "%s(config-line)# ", };/* Reset all VTY status. */voidvty_reset (){ int i; struct vty *vty; struct thread *vty_serv_thread; for (i = 0; i < vector_max (vtyvec); i++) if ((vty = vector_slot (vtyvec, i)) != NULL) { buffer_reset (vty->obuf); vty->status = VTY_CLOSE; vty_close (vty); } for (i = 0; i < vector_max (Vvty_serv_thread); i++) if ((vty_serv_thread = vector_slot (Vvty_serv_thread, i)) != NULL) { thread_cancel (vty_serv_thread); vector_slot (Vvty_serv_thread, i) = NULL; close (i); } vty_timeout_val = VTY_TIMEOUT_DEFAULT; if (vty_accesslist_name) { XFREE(MTYPE_VTY, vty_accesslist_name); vty_accesslist_name = NULL; } if (vty_ipv6_accesslist_name) { XFREE(MTYPE_VTY, vty_ipv6_accesslist_name); vty_ipv6_accesslist_name = NULL; }}/* for ospf6d easy temprary reload function *//* vty_reset + close accept socket */voidvty_finish (){ int i; struct vty *vty; struct thread *vty_serv_thread; for (i = 0; i < vector_max (vtyvec); i++) if ((vty = vector_slot (vtyvec, i)) != NULL) { buffer_reset (vty->obuf); vty->status = VTY_CLOSE; vty_close (vty); } for (i = 0; i < vector_max (Vvty_serv_thread); i++) if ((vty_serv_thread = vector_slot (Vvty_serv_thread, i)) != NULL) { thread_cancel (vty_serv_thread); vector_slot (Vvty_serv_thread, i) = NULL; close (i); } vty_timeout_val = VTY_TIMEOUT_DEFAULT; if (vty_accesslist_name) { XFREE(MTYPE_VTY, vty_accesslist_name); vty_accesslist_name = NULL; } if (vty_ipv6_accesslist_name) { XFREE(MTYPE_VTY, vty_ipv6_accesslist_name); vty_ipv6_accesslist_name = NULL; }}voidvty_save_cwd (){ char *cwd; cwd = getcwd (NULL, MAXPATHLEN); vty_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1); strcpy (vty_cwd, cwd);}char *vty_get_cwd (){ return vty_cwd;}intvty_shell (struct vty *vty){ return vty->type == VTY_SHELL ? 1 : 0;}intvty_shell_serv (struct vty *vty){ return vty->type == VTY_SHELL_SERV ? 1 : 0;}voidvty_init_vtysh (){ vtyvec = vector_init (VECTOR_MIN_SIZE);}/* Install vty's own commands like `who' command. */voidvty_init (){ /* For further configuration read, preserve current directory. */ vty_save_cwd (); vtyvec = vector_init (VECTOR_MIN_SIZE); /* Initilize server thread vector. */ Vvty_serv_thread = vector_init (VECTOR_MIN_SIZE); /* Install bgp top node. */ install_node (&vty_node, vty_config_write); install_element (VIEW_NODE, &config_who_cmd); install_element (VIEW_NODE, &show_history_cmd); install_element (ENABLE_NODE, &config_who_cmd); install_element (CONFIG_NODE, &line_vty_cmd); install_element (CONFIG_NODE, &service_advanced_vty_cmd); install_element (CONFIG_NODE, &no_service_advanced_vty_cmd); install_element (CONFIG_NODE, &show_history_cmd); install_element (ENABLE_NODE, &terminal_monitor_cmd); install_element (ENABLE_NODE, &terminal_no_monitor_cmd); install_element (ENABLE_NODE, &show_history_cmd); install_default (VTY_NODE); install_element (VTY_NODE, &exec_timeout_min_cmd); install_element (VTY_NODE, &exec_timeout_sec_cmd); install_element (VTY_NODE, &no_exec_timeout_cmd); install_element (VTY_NODE, &vty_access_class_cmd); install_element (VTY_NODE, &no_vty_access_class_cmd); install_element (VTY_NODE, &vty_login_cmd); install_element (VTY_NODE, &no_vty_login_cmd);#ifdef HAVE_IPV6 install_element (VTY_NODE, &vty_ipv6_access_class_cmd); install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd);#endif /* HAVE_IPV6 */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -