back to topotato report
topotato coverage report
Current view: top level - lib - vty.h (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 4 4 100.0 %
Date: 2023-02-24 19:38:44 Functions: 0 0 -

          Line data    Source code
       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 along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #ifndef _ZEBRA_VTY_H
      22             : #define _ZEBRA_VTY_H
      23             : 
      24             : #include <sys/types.h>
      25             : #ifdef HAVE_LIBPCRE2_POSIX
      26             : #ifndef _FRR_PCRE2_POSIX
      27             : #define _FRR_PCRE2_POSIX
      28             : #include <pcre2posix.h>
      29             : #endif /* _FRR_PCRE2_POSIX */
      30             : #elif defined(HAVE_LIBPCREPOSIX)
      31             : #include <pcreposix.h>
      32             : #else
      33             : #include <regex.h>
      34             : #endif /* HAVE_LIBPCRE2_POSIX */
      35             : 
      36             : #include "thread.h"
      37             : #include "log.h"
      38             : #include "sockunion.h"
      39             : #include "qobj.h"
      40             : #include "compiler.h"
      41             : #include "northbound.h"
      42             : #include "zlog_live.h"
      43             : 
      44             : #ifdef __cplusplus
      45             : extern "C" {
      46             : #endif
      47             : 
      48             : struct json_object;
      49             : 
      50             : #define VTY_BUFSIZ 4096
      51             : #define VTY_MAXHIST 20
      52             : #define VTY_MAXDEPTH 8
      53             : 
      54             : #define VTY_MAXCFGCHANGES 16
      55             : 
      56             : struct vty_error {
      57             :         char error_buf[VTY_BUFSIZ];
      58             :         uint32_t line_num;
      59             : };
      60             : 
      61             : struct vty_cfg_change {
      62             :         char xpath[XPATH_MAXLEN];
      63             :         enum nb_operation operation;
      64             :         const char *value;
      65             : };
      66             : 
      67             : PREDECL_DLIST(vtys);
      68             : 
      69             : /* VTY struct. */
      70             : struct vty {
      71             :         struct vtys_item itm;
      72             : 
      73             :         /* File descripter of this vty. */
      74             :         int fd;
      75             : 
      76             :         /* output FD, to support stdin/stdout combination */
      77             :         int wfd;
      78             : 
      79             :         /* File output, used for VTYSH only */
      80             :         FILE *of;
      81             :         FILE *of_saved;
      82             : 
      83             :         /* whether we are using pager or not */
      84             :         bool is_paged;
      85             : 
      86             :         /* Is this vty connect to file or not */
      87             :         enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type;
      88             : 
      89             :         /* Node status of this vty */
      90             :         int node;
      91             : 
      92             :         /* Failure count */
      93             :         int fail;
      94             : 
      95             :         /* Output filer regex */
      96             :         bool filter;
      97             :         regex_t include;
      98             : 
      99             :         /* Line buffer */
     100             :         struct buffer *lbuf;
     101             : 
     102             :         /* Output buffer. */
     103             :         struct buffer *obuf;
     104             : 
     105             :         /* Command input buffer */
     106             :         char *buf;
     107             : 
     108             :         /* Command input error buffer */
     109             :         struct list *error;
     110             : 
     111             :         /* Command cursor point */
     112             :         int cp;
     113             : 
     114             :         /* Command length */
     115             :         int length;
     116             : 
     117             :         /* Command max length. */
     118             :         int max;
     119             : 
     120             :         /* Histry of command */
     121             :         char *hist[VTY_MAXHIST];
     122             : 
     123             :         /* History lookup current point */
     124             :         int hp;
     125             : 
     126             :         /* History insert end point */
     127             :         int hindex;
     128             : 
     129             :         /* Changes enqueued to be applied in the candidate configuration. */
     130             :         size_t num_cfg_changes;
     131             :         struct vty_cfg_change cfg_changes[VTY_MAXCFGCHANGES];
     132             : 
     133             :         /* XPath of the current node */
     134             :         int xpath_index;
     135             :         char xpath[VTY_MAXDEPTH][XPATH_MAXLEN];
     136             : 
     137             :         /* In configure mode. */
     138             :         bool config;
     139             : 
     140             :         /* Private candidate configuration mode. */
     141             :         bool private_config;
     142             : 
     143             :         /* Candidate configuration. */
     144             :         struct nb_config *candidate_config;
     145             : 
     146             :         /* Base candidate configuration. */
     147             :         struct nb_config *candidate_config_base;
     148             : 
     149             :         /* Dynamic transaction information. */
     150             :         bool pending_allowed;
     151             :         bool pending_commit;
     152             :         char *pending_cmds_buf;
     153             :         size_t pending_cmds_buflen;
     154             :         size_t pending_cmds_bufpos;
     155             : 
     156             :         /* Confirmed-commit timeout and rollback configuration. */
     157             :         struct thread *t_confirmed_commit_timeout;
     158             :         struct nb_config *confirmed_commit_rollback;
     159             : 
     160             :         /* qobj object ID (replacement for "index") */
     161             :         uint64_t qobj_index;
     162             : 
     163             :         /* qobj second-level object ID (replacement for "index_sub") */
     164             :         uint64_t qobj_index_sub;
     165             : 
     166             :         /* For escape character. */
     167             :         unsigned char escape;
     168             : 
     169             :         /* Current vty status. */
     170             :         enum {
     171             :                 VTY_NORMAL,
     172             :                 VTY_CLOSE,
     173             :                 VTY_MORE,
     174             :                 VTY_MORELINE,
     175             :                 VTY_PASSFD,
     176             :         } status;
     177             : 
     178             :         /* vtysh socket/fd passing (for terminal monitor) */
     179             :         int pass_fd;
     180             : 
     181             :         /* CLI command return value (likely CMD_SUCCESS) when pass_fd != -1 */
     182             :         uint8_t pass_fd_status[4];
     183             : 
     184             :         /* live logging target / terminal monitor */
     185             :         struct zlog_live_cfg live_log;
     186             : 
     187             :         /* IAC handling: was the last character received the
     188             :            IAC (interpret-as-command) escape character (and therefore the next
     189             :            character will be the command code)?  Refer to Telnet RFC 854. */
     190             :         unsigned char iac;
     191             : 
     192             :         /* IAC SB (option subnegotiation) handling */
     193             :         unsigned char iac_sb_in_progress;
     194             : /* At the moment, we care only about the NAWS (window size) negotiation,
     195             :    and that requires just a 5-character buffer (RFC 1073):
     196             :      <NAWS char> <16-bit width> <16-bit height> */
     197             : #define TELNET_NAWS_SB_LEN 5
     198             :         unsigned char sb_buf[TELNET_NAWS_SB_LEN];
     199             :         /* How many subnegotiation characters have we received?  We just drop
     200             :            those that do not fit in the buffer. */
     201             :         size_t sb_len;
     202             : 
     203             :         /* Window width/height. */
     204             :         int width;
     205             :         int height;
     206             : 
     207             :         /* Configure lines. */
     208             :         int lines;
     209             : 
     210             :         /* Read and write thread. */
     211             :         struct thread *t_read;
     212             :         struct thread *t_write;
     213             : 
     214             :         /* Timeout seconds and thread. */
     215             :         unsigned long v_timeout;
     216             :         struct thread *t_timeout;
     217             : 
     218             :         /* What address is this vty comming from. */
     219             :         char address[SU_ADDRSTRLEN];
     220             : 
     221             :         /* "frame" output.  This is buffered and will be printed if some
     222             :          * actual output follows, or will be discarded if the frame ends
     223             :          * without any output. */
     224             :         size_t frame_pos;
     225             :         char frame[1024];
     226             : };
     227             : 
     228         253 : static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
     229             : {
     230         253 :         vty->node = node;
     231         253 :         vty->qobj_index = id;
     232         186 : }
     233             : 
     234             : /* note: VTY_PUSH_CONTEXT(..., NULL) doesn't work, since it will try to
     235             :  * dereference "NULL->qobj_node.nid" */
     236             : #define VTY_PUSH_CONTEXT(nodeval, ptr)                                         \
     237             :         vty_push_context(vty, nodeval, QOBJ_ID_0SAFE(ptr))
     238             : #define VTY_PUSH_CONTEXT_NULL(nodeval) vty_push_context(vty, nodeval, 0ULL)
     239             : #define VTY_PUSH_CONTEXT_SUB(nodeval, ptr)                                     \
     240             :         do {                                                                   \
     241             :                 vty->node = nodeval;                                           \
     242             :                 /* qobj_index stays untouched */                               \
     243             :                 vty->qobj_index_sub = QOBJ_ID_0SAFE(ptr);                      \
     244             :         } while (0)
     245             : 
     246             : /* can return NULL if context is invalid! */
     247             : #define VTY_GET_CONTEXT(structname)                                            \
     248             :         QOBJ_GET_TYPESAFE(vty->qobj_index, structname)
     249             : #define VTY_GET_CONTEXT_SUB(structname)                                        \
     250             :         QOBJ_GET_TYPESAFE(vty->qobj_index_sub, structname)
     251             : 
     252             : /* will return if ptr is NULL. */
     253             : #define VTY_CHECK_CONTEXT(ptr)                                                 \
     254             :         if (!ptr) {                                                            \
     255             :                 vty_out(vty,                                                   \
     256             :                         "Current configuration object was deleted "            \
     257             :                         "by another process.\n");                              \
     258             :                 return CMD_WARNING;                                            \
     259             :         }
     260             : 
     261             : /* struct structname *ptr = <context>;   ptr will never be NULL. */
     262             : #define VTY_DECLVAR_CONTEXT(structname, ptr)                                   \
     263             :         struct structname *ptr = VTY_GET_CONTEXT(structname);                  \
     264             :         VTY_CHECK_CONTEXT(ptr);
     265             : #define VTY_DECLVAR_CONTEXT_SUB(structname, ptr)                               \
     266             :         struct structname *ptr = VTY_GET_CONTEXT_SUB(structname);              \
     267             :         VTY_CHECK_CONTEXT(ptr);
     268             : #define VTY_DECLVAR_INSTANCE_CONTEXT(structname, ptr)                          \
     269             :         if (vty->qobj_index == 0)                                              \
     270             :                 return CMD_NOT_MY_INSTANCE;                                    \
     271             :         struct structname *ptr = VTY_GET_CONTEXT(structname);                  \
     272             :         VTY_CHECK_CONTEXT(ptr);
     273             : 
     274             : #define VTY_DECLVAR_CONTEXT_VRF(vrfptr)                                        \
     275             :         struct vrf *vrfptr;                                                    \
     276             :         if (vty->node == CONFIG_NODE)                                          \
     277             :                 vrfptr = vrf_lookup_by_id(VRF_DEFAULT);                        \
     278             :         else                                                                   \
     279             :                 vrfptr = VTY_GET_CONTEXT(vrf);                                 \
     280             :         VTY_CHECK_CONTEXT(vrfptr);                                             \
     281             :         MACRO_REQUIRE_SEMICOLON() /* end */
     282             : 
     283             : /* XPath macros. */
     284             : #define VTY_PUSH_XPATH(nodeval, value)                                         \
     285             :         do {                                                                   \
     286             :                 if (vty->xpath_index >= VTY_MAXDEPTH) {                        \
     287             :                         vty_out(vty, "%% Reached maximum CLI depth (%u)\n",    \
     288             :                                 VTY_MAXDEPTH);                                 \
     289             :                         return CMD_WARNING;                                    \
     290             :                 }                                                              \
     291             :                 vty->node = nodeval;                                           \
     292             :                 strlcpy(vty->xpath[vty->xpath_index], value,                   \
     293             :                         sizeof(vty->xpath[0]));                                \
     294             :                 vty->xpath_index++;                                            \
     295             :         } while (0)
     296             : 
     297             : #define VTY_CURR_XPATH vty->xpath[vty->xpath_index - 1]
     298             : 
     299             : #define VTY_CHECK_XPATH                                                        \
     300             :         do {                                                                   \
     301             :                 if (vty->type != VTY_FILE && !vty->private_config              \
     302             :                     && vty->xpath_index > 0                                    \
     303             :                     && !yang_dnode_exists(vty->candidate_config->dnode,        \
     304             :                                           VTY_CURR_XPATH)) {                   \
     305             :                         vty_out(vty,                                           \
     306             :                                 "Current configuration object was deleted "    \
     307             :                                 "by another process.\n\n");                    \
     308             :                         return CMD_WARNING;                                    \
     309             :                 }                                                              \
     310             :         } while (0)
     311             : 
     312             : struct vty_arg {
     313             :         const char *name;
     314             :         const char *value;
     315             :         const char **argv;
     316             :         int argc;
     317             : };
     318             : 
     319             : /* Integrated configuration file. */
     320             : #define INTEGRATE_DEFAULT_CONFIG "frr.conf"
     321             : 
     322             : /* Default time out value */
     323             : #define VTY_TIMEOUT_DEFAULT 600
     324             : 
     325             : /* Vty read buffer size. */
     326             : #define VTY_READ_BUFSIZ 512
     327             : 
     328             : /* Directory separator. */
     329             : #ifndef DIRECTORY_SEP
     330             : #define DIRECTORY_SEP '/'
     331             : #endif /* DIRECTORY_SEP */
     332             : 
     333             : #ifndef IS_DIRECTORY_SEP
     334             : #define IS_DIRECTORY_SEP(c) ((c) == DIRECTORY_SEP)
     335             : #endif
     336             : 
     337             : /* Prototypes. */
     338             : extern void vty_init(struct thread_master *, bool do_command_logging);
     339             : extern void vty_init_vtysh(void);
     340             : extern void vty_terminate(void);
     341             : extern void vty_reset(void);
     342             : extern struct vty *vty_new(void);
     343             : extern struct vty *vty_stdio(void (*atclose)(int isexit));
     344             : 
     345             : /* - vty_frame() output goes to a buffer (for context-begin markers)
     346             :  * - vty_out() will first print this buffer, and clear it
     347             :  * - vty_endframe() clears the buffer without printing it, and prints an
     348             :  *   extra string if the buffer was empty before (for context-end markers)
     349             :  */
     350             : extern int vty_out(struct vty *, const char *, ...) PRINTFRR(2, 3);
     351             : extern void vty_frame(struct vty *, const char *, ...) PRINTFRR(2, 3);
     352             : extern void vty_endframe(struct vty *, const char *);
     353             : extern bool vty_set_include(struct vty *vty, const char *regexp);
     354             : /* returns CMD_SUCCESS so you can do a one-line "return vty_json(...)"
     355             :  * NULL check and json_object_free() is included.
     356             :  *
     357             :  * _no_pretty means do not add a bunch of newlines and dump the output
     358             :  * as densely as possible.
     359             :  */
     360             : extern int vty_json(struct vty *vty, struct json_object *json);
     361             : extern int vty_json_no_pretty(struct vty *vty, struct json_object *json);
     362             : 
     363             : /* post fd to be passed to the vtysh client
     364             :  * fd is owned by the VTY code after this and will be closed when done
     365             :  */
     366             : extern void vty_pass_fd(struct vty *vty, int fd);
     367             : 
     368             : extern bool vty_read_config(struct nb_config *config, const char *config_file,
     369             :                             char *config_default_dir);
     370             : extern void vty_time_print(struct vty *, int);
     371             : extern void vty_serv_sock(const char *, unsigned short, const char *);
     372             : extern void vty_close(struct vty *);
     373             : extern char *vty_get_cwd(void);
     374             : extern void vty_update_xpath(const char *oldpath, const char *newpath);
     375             : extern int vty_config_enter(struct vty *vty, bool private_config,
     376             :                             bool exclusive);
     377             : extern void vty_config_exit(struct vty *);
     378             : extern int vty_config_node_exit(struct vty *);
     379             : extern int vty_shell(struct vty *);
     380             : extern int vty_shell_serv(struct vty *);
     381             : extern void vty_hello(struct vty *);
     382             : 
     383             : /* ^Z / SIGTSTP handling */
     384             : extern void vty_stdio_suspend(void);
     385             : extern void vty_stdio_resume(void);
     386             : extern void vty_stdio_close(void);
     387             : 
     388             : #ifdef __cplusplus
     389             : }
     390             : #endif
     391             : 
     392             : #endif /* _ZEBRA_VTY_H */

Generated by: LCOV version v1.16-topotato