1/* Virtual terminal [aka TeletYpe] interface routine 2 Copyright (C) 1997 Kunihiro Ishiguro 3 4This file is part of GNU Zebra. 5 6GNU Zebra is free software; you can redistribute it and/or modify it 7under the terms of the GNU General Public License as published by the 8Free Software Foundation; either version 2, or (at your option) any 9later version. 10 11GNU Zebra is distributed in the hope that it will be useful, but 12WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GNU Zebra; see the file COPYING. If not, write to the Free 18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 1902111-1307, USA. */ 20 21#ifndef _ZEBRA_VTY_H 22#define _ZEBRA_VTY_H 23 24#include "thread.h" 25#include "log.h" 26#include "sockunion.h" 27 28#define VTY_BUFSIZ 512 29#define VTY_MAXHIST 20 30 31/* VTY struct. */ 32struct vty 33{ 34 /* File descripter of this vty. */ 35 int fd; 36 37 /* Is this vty connect to file or not */ 38 enum {VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV} type; 39 40 /* Node status of this vty */ 41 int node; 42 43 /* Failure count */ 44 int fail; 45 46 /* Output buffer. */ 47 struct buffer *obuf; 48 49 /* Command input buffer */ 50 char *buf; 51 52 /* Command cursor point */ 53 int cp; 54 55 /* Command length */ 56 int length; 57 58 /* Command max length. */ 59 int max; 60 61 /* Histry of command */ 62 char *hist[VTY_MAXHIST]; 63 64 /* History lookup current point */ 65 int hp; 66 67 /* History insert end point */ 68 int hindex; 69 70 /* For current referencing point of interface, route-map, 71 access-list etc... */ 72 void *index; 73 74 /* For multiple level index treatment such as key chain and key. */ 75 void *index_sub; 76 77 /* For escape character. */ 78 unsigned char escape; 79 80 /* Current vty status. */ 81 enum {VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE} status; 82 83 /* IAC handling: was the last character received the 84 IAC (interpret-as-command) escape character (and therefore the next 85 character will be the command code)? Refer to Telnet RFC 854. */ 86 unsigned char iac; 87 88 /* IAC SB (option subnegotiation) handling */ 89 unsigned char iac_sb_in_progress; 90 /* At the moment, we care only about the NAWS (window size) negotiation, 91 and that requires just a 5-character buffer (RFC 1073): 92 <NAWS char> <16-bit width> <16-bit height> */ 93#define TELNET_NAWS_SB_LEN 5 94 unsigned char sb_buf[TELNET_NAWS_SB_LEN]; 95 /* How many subnegotiation characters have we received? We just drop 96 those that do not fit in the buffer. */ 97 size_t sb_len; 98 99 /* Window width/height. */ 100 int width; 101 int height; 102 103 /* Configure lines. */ 104 int lines; 105 106 /* Terminal monitor. */ 107 int monitor; 108 109 /* In configure mode. */ 110 int config; 111 112 /* Read and write thread. */ 113 struct thread *t_read; 114 struct thread *t_write; 115 116 /* Timeout seconds and thread. */ 117 unsigned long v_timeout; 118 struct thread *t_timeout; 119 120 /* What address is this vty comming from. */ 121 char address[SU_ADDRSTRLEN]; 122}; 123 124/* Integrated configuration file. */ 125#define INTEGRATE_DEFAULT_CONFIG "Quagga.conf" 126 127/* Small macro to determine newline is newline only or linefeed needed. */ 128#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n") 129 130/* Default time out value */ 131#define VTY_TIMEOUT_DEFAULT 600 132 133/* Vty read buffer size. */ 134#define VTY_READ_BUFSIZ 512 135 136/* Directory separator. */ 137#ifndef DIRECTORY_SEP 138#define DIRECTORY_SEP '/' 139#endif /* DIRECTORY_SEP */ 140 141#ifndef IS_DIRECTORY_SEP 142#define IS_DIRECTORY_SEP(c) ((c) == DIRECTORY_SEP) 143#endif 144 145/* GCC have printf type attribute check. */ 146#ifdef __GNUC__ 147#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) 148#else 149#define PRINTF_ATTRIBUTE(a,b) 150#endif /* __GNUC__ */ 151 152/* Utility macros to convert VTY argument to unsigned long */ 153#define VTY_GET_ULONG(NAME,V,STR) \ 154do { \ 155 char *endptr = NULL; \ 156 errno = 0; \ 157 (V) = strtoul ((STR), &endptr, 10); \ 158 if (*(STR) == '-' || *endptr != '\0' || errno) \ 159 { \ 160 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \ 161 return CMD_WARNING; \ 162 } \ 163} while (0) 164 165/* 166 * The logic below ((TMPL) <= ((MIN) && (TMPL) != (MIN)) is 167 * done to circumvent the compiler complaining about 168 * comparing unsigned numbers against zero, if MIN is zero. 169 * NB: The compiler isn't smart enough to supress the warning 170 * if you write (MIN) != 0 && tmpl < (MIN). 171 */ 172#define VTY_GET_INTEGER_RANGE_HEART(NAME,TMPL,STR,MIN,MAX) \ 173do { \ 174 VTY_GET_ULONG(NAME, (TMPL), STR); \ 175 if ( ((TMPL) <= (MIN) && (TMPL) != (MIN)) || (TMPL) > (MAX) ) \ 176 { \ 177 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE);\ 178 return CMD_WARNING; \ 179 } \ 180} while (0) 181 182#define VTY_GET_INTEGER_RANGE(NAME,V,STR,MIN,MAX) \ 183do { \ 184 unsigned long tmpl; \ 185 VTY_GET_INTEGER_RANGE_HEART(NAME,tmpl,STR,MIN,MAX); \ 186 (V) = tmpl; \ 187} while (0) 188 189#define VTY_CHECK_INTEGER_RANGE(NAME,STR,MIN,MAX) \ 190do { \ 191 unsigned long tmpl; \ 192 VTY_GET_INTEGER_RANGE_HEART(NAME,tmpl,STR,MIN,MAX); \ 193} while (0) 194 195#define VTY_GET_INTEGER(NAME,V,STR) \ 196 VTY_GET_INTEGER_RANGE(NAME,V,STR,0U,UINT32_MAX) 197 198#define VTY_GET_IPV4_ADDRESS(NAME,V,STR) \ 199do { \ 200 int retv; \ 201 retv = inet_aton ((STR), &(V)); \ 202 if (!retv) \ 203 { \ 204 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \ 205 return CMD_WARNING; \ 206 } \ 207} while (0) 208 209#define VTY_GET_IPV4_PREFIX(NAME,V,STR) \ 210do { \ 211 int retv; \ 212 retv = str2prefix_ipv4 ((STR), &(V)); \ 213 if (retv <= 0) \ 214 { \ 215 vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \ 216 return CMD_WARNING; \ 217 } \ 218} while (0) 219 220#define VTY_WARN_EXPERIMENTAL() \ 221do { \ 222 vty_out (vty, "%% WARNING: this command is experimental. Both its name and" \ 223 " parameters may%s%% change in a future version of Quagga," \ 224 " possibly breaking your configuration!%s", \ 225 VTY_NEWLINE, VTY_NEWLINE); \ 226} while (0) 227 228/* Exported variables */ 229extern char integrate_default[]; 230 231/* Prototypes. */ 232extern void vty_init (struct thread_master *); 233extern void vty_init_vtysh (void); 234extern void vty_terminate (void); 235extern void vty_reset (void); 236extern struct vty *vty_new (void); 237extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); 238extern void vty_read_config (char *, char *); 239extern void vty_time_print (struct vty *, int); 240extern void vty_serv_sock (const char *, unsigned short, const char *); 241extern void vty_close (struct vty *); 242extern char *vty_get_cwd (void); 243extern void vty_log (const char *level, const char *proto, 244 const char *fmt, struct timestamp_control *, va_list); 245extern int vty_config_lock (struct vty *); 246extern int vty_config_unlock (struct vty *); 247extern int vty_shell (struct vty *); 248extern int vty_shell_serv (struct vty *); 249extern void vty_hello (struct vty *); 250 251/* Send a fixed-size message to all vty terminal monitors; this should be 252 an async-signal-safe function. */ 253extern void vty_log_fixed (char *buf, size_t len); 254 255#endif /* _ZEBRA_VTY_H */ 256