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