| version 1.1.1.1, 2012/02/21 17:26:12 | version 1.1.1.3, 2016/11/02 10:09:10 | 
| Line 68  enum node_type | Line 68  enum node_type | 
 | AUTH_ENABLE_NODE,             /* Authentication mode for change enable. */ | AUTH_ENABLE_NODE,             /* Authentication mode for change enable. */ | 
 | ENABLE_NODE,                  /* Enable node. */ | ENABLE_NODE,                  /* Enable node. */ | 
 | CONFIG_NODE,                  /* Config node. Default mode of config file. */ | CONFIG_NODE,                  /* Config node. Default mode of config file. */ | 
 |  | VRF_NODE,                     /* VRF node. */ | 
 | SERVICE_NODE,                 /* Service node. */ | SERVICE_NODE,                 /* Service node. */ | 
 | DEBUG_NODE,                   /* Debug node. */ | DEBUG_NODE,                   /* Debug node. */ | 
 | AAA_NODE,                     /* AAA node. */ | AAA_NODE,                     /* AAA node. */ | 
| Line 78  enum node_type | Line 79  enum node_type | 
 | TABLE_NODE,                   /* rtm_table selection node. */ | TABLE_NODE,                   /* rtm_table selection node. */ | 
 | RIP_NODE,                     /* RIP protocol mode node. */ | RIP_NODE,                     /* RIP protocol mode node. */ | 
 | RIPNG_NODE,                   /* RIPng protocol mode node. */ | RIPNG_NODE,                   /* RIPng protocol mode node. */ | 
 |  | BABEL_NODE,                   /* Babel protocol mode node. */ | 
 | BGP_NODE,                     /* BGP protocol mode which includes BGP4+ */ | BGP_NODE,                     /* BGP protocol mode which includes BGP4+ */ | 
 | BGP_VPNV4_NODE,               /* BGP MPLS-VPN PE exchange. */ | BGP_VPNV4_NODE,               /* BGP MPLS-VPN PE exchange. */ | 
 |  | BGP_VPNV6_NODE,               /* BGP MPLS-VPN PE exchange. */ | 
 | BGP_IPV4_NODE,                /* BGP IPv4 unicast address family.  */ | BGP_IPV4_NODE,                /* BGP IPv4 unicast address family.  */ | 
 | BGP_IPV4M_NODE,               /* BGP IPv4 multicast address family.  */ | BGP_IPV4M_NODE,               /* BGP IPv4 multicast address family.  */ | 
 | BGP_IPV6_NODE,                /* BGP IPv6 address family */ | BGP_IPV6_NODE,                /* BGP IPv6 address family */ | 
 | BGP_IPV6M_NODE,               /* BGP IPv6 multicast address family. */ | BGP_IPV6M_NODE,               /* BGP IPv6 multicast address family. */ | 
 |  | BGP_ENCAP_NODE,               /* BGP ENCAP SAFI */ | 
 |  | BGP_ENCAPV6_NODE,             /* BGP ENCAP SAFI */ | 
 | OSPF_NODE,                    /* OSPF protocol mode */ | OSPF_NODE,                    /* OSPF protocol mode */ | 
 | OSPF6_NODE,                   /* OSPF protocol for IPv6 mode */ | OSPF6_NODE,                   /* OSPF protocol for IPv6 mode */ | 
 | ISIS_NODE,                    /* ISIS protocol mode */ | ISIS_NODE,                    /* ISIS protocol mode */ | 
 |  | PIM_NODE,                     /* PIM protocol mode */ | 
 | MASC_NODE,                    /* MASC for multicast.  */ | MASC_NODE,                    /* MASC for multicast.  */ | 
 | IRDP_NODE,                    /* ICMP Router Discovery Protocol mode. */ | IRDP_NODE,                    /* ICMP Router Discovery Protocol mode. */ | 
 | IP_NODE,                      /* Static ip route node. */ | IP_NODE,                      /* Static ip route node. */ | 
| Line 137  struct cmd_element | Line 143  struct cmd_element | 
 | int (*func) (struct cmd_element *, struct vty *, int, const char *[]); | int (*func) (struct cmd_element *, struct vty *, int, const char *[]); | 
 | const char *doc;                      /* Documentation of this command. */ | const char *doc;                      /* Documentation of this command. */ | 
 | int daemon;                   /* Daemon to which this command belong. */ | int daemon;                   /* Daemon to which this command belong. */ | 
| vector strvec;               /* Pointing out each description vector. */ | vector tokens;               /* Vector of cmd_tokens */ | 
| unsigned int cmdsize;         /* Command index count. */ |  | 
| char *config;                 /* Configuration string */ |  | 
| vector subconfig;              /* Sub configuration string */ |  | 
 | u_char attr;                  /* Command attributes */ | u_char attr;                  /* Command attributes */ | 
 | }; | }; | 
 |  |  | 
 |  |  | 
 |  | enum cmd_token_type | 
 |  | { | 
 |  | TOKEN_TERMINAL = 0, | 
 |  | TOKEN_MULTIPLE, | 
 |  | TOKEN_KEYWORD, | 
 |  | }; | 
 |  |  | 
 |  | enum cmd_terminal_type | 
 |  | { | 
 |  | _TERMINAL_BUG = 0, | 
 |  | TERMINAL_LITERAL, | 
 |  | TERMINAL_OPTION, | 
 |  | TERMINAL_VARIABLE, | 
 |  | TERMINAL_VARARG, | 
 |  | TERMINAL_RANGE, | 
 |  | TERMINAL_IPV4, | 
 |  | TERMINAL_IPV4_PREFIX, | 
 |  | TERMINAL_IPV6, | 
 |  | TERMINAL_IPV6_PREFIX, | 
 |  | }; | 
 |  |  | 
 |  | /* argument to be recorded on argv[] if it's not a literal */ | 
 |  | #define TERMINAL_RECORD(t) ((t) >= TERMINAL_OPTION) | 
 |  |  | 
 | /* Command description structure. */ | /* Command description structure. */ | 
| struct desc | struct cmd_token | 
 | { | { | 
 |  | enum cmd_token_type type; | 
 |  | enum cmd_terminal_type terminal; | 
 |  |  | 
 |  | /* Used for type == MULTIPLE */ | 
 |  | vector multiple; /* vector of cmd_token, type == FINAL */ | 
 |  |  | 
 |  | /* Used for type == KEYWORD */ | 
 |  | vector keyword; /* vector of vector of cmd_tokens */ | 
 |  |  | 
 |  | /* Used for type == TERMINAL */ | 
 | char *cmd;                    /* Command string. */ | char *cmd;                    /* Command string. */ | 
| char *str;                    /* Command's description. */ | char *desc;                    /* Command's description. */ | 
 | }; | }; | 
 |  |  | 
 | /* Return value of the commands. */ | /* Return value of the commands. */ | 
| Line 191  struct desc | Line 229  struct desc | 
 | int argc __attribute__ ((unused)), \ | int argc __attribute__ ((unused)), \ | 
 | const char *argv[] __attribute__ ((unused)) ) | const char *argv[] __attribute__ ((unused)) ) | 
 |  |  | 
| /* DEFUN for vty command interafce. Little bit hacky ;-). */ | /* DEFUN for vty command interafce. Little bit hacky ;-). | 
|  | * | 
|  | * DEFUN(funcname, cmdname, cmdstr, helpstr) | 
|  | * | 
|  | * funcname | 
|  | * ======== | 
|  | * | 
|  | * Name of the function that will be defined. | 
|  | * | 
|  | * cmdname | 
|  | * ======= | 
|  | * | 
|  | * Name of the struct that will be defined for the command. | 
|  | * | 
|  | * cmdstr | 
|  | * ====== | 
|  | * | 
|  | * The cmdstr defines the command syntax. It is used by the vty subsystem | 
|  | * and vtysh to perform matching and completion in the cli. So you have to take | 
|  | * care to construct it adhering to the following grammar. The names used | 
|  | * for the production rules losely represent the names used in lib/command.c | 
|  | * | 
|  | * cmdstr = cmd_token , { " " , cmd_token } ; | 
|  | * | 
|  | * cmd_token = cmd_terminal | 
|  | *           | cmd_multiple | 
|  | *           | cmd_keyword ; | 
|  | * | 
|  | * cmd_terminal_fixed = fixed_string | 
|  | *                    | variable | 
|  | *                    | range | 
|  | *                    | ipv4 | 
|  | *                    | ipv4_prefix | 
|  | *                    | ipv6 | 
|  | *                    | ipv6_prefix ; | 
|  | * | 
|  | * cmd_terminal = cmd_terminal_fixed | 
|  | *              | option | 
|  | *              | vararg ; | 
|  | * | 
|  | * multiple_part = cmd_terminal_fixed ; | 
|  | * cmd_multiple = "(" , multiple_part , ( "|" | { "|" , multiple_part } ) , ")" ; | 
|  | * | 
|  | * keyword_part = fixed_string , { " " , ( cmd_terminal_fixed | cmd_multiple ) } ; | 
|  | * cmd_keyword = "{" , keyword_part , { "|" , keyword_part } , "}" ; | 
|  | * | 
|  | * lowercase = "a" | ... | "z" ; | 
|  | * uppercase = "A" | ... | "Z" ; | 
|  | * digit = "0" | ... | "9" ; | 
|  | * number = digit , { digit } ; | 
|  | * | 
|  | * fixed_string = (lowercase | digit) , { lowercase | digit | uppercase | "-" | "_" } ; | 
|  | * variable = uppercase , { uppercase | "_" } ; | 
|  | * range = "<" , number , "-" , number , ">" ; | 
|  | * ipv4 = "A.B.C.D" ; | 
|  | * ipv4_prefix = "A.B.C.D/M" ; | 
|  | * ipv6 = "X:X::X:X" ; | 
|  | * ipv6_prefix = "X:X::X:X/M" ; | 
|  | * option = "[" , variable , "]" ; | 
|  | * vararg = "." , variable ; | 
|  | * | 
|  | * To put that all in a textual description: A cmdstr is a sequence of tokens, | 
|  | * separated by spaces. | 
|  | * | 
|  | * Terminal Tokens: | 
|  | * | 
|  | * A very simple cmdstring would be something like: "show ip bgp". It consists | 
|  | * of three Terminal Tokens, each containing a fixed string. When this command | 
|  | * is called, no arguments will be passed down to the function implementing it, | 
|  | * as it only consists of fixed strings. | 
|  | * | 
|  | * Apart from fixed strings, Terminal Tokens can also contain variables: | 
|  | * An example would be "show ip bgp A.B.C.D". This command expects an IPv4 | 
|  | * as argument. As this is a variable, the IP address entered by the user will | 
|  | * be passed down as an argument. Apart from two exceptions, the other options | 
|  | * for Terminal Tokens behave exactly as we just discussed and only make a | 
|  | * difference for the CLI. The two exceptions will be discussed in the next | 
|  | * paragraphs. | 
|  | * | 
|  | * A Terminal Token can contain a so called option match. This is a simple | 
|  | * string variable that the user may omit. An example would be: | 
|  | * "show interface [IFNAME]". If the user calls this without an interface as | 
|  | * argument, no arguments will be passed down to the function implementing | 
|  | * this command. Otherwise, the interface name will be provided to the function | 
|  | * as a regular argument. | 
|  |  | 
|  | * Also, a Terminal Token can contain a so called vararg. This is used e.g. in | 
|  | * "show ip bgp regexp .LINE". The last token is a vararg match and will | 
|  | * consume all the arguments the user inputs on the command line and append | 
|  | * those to the list of arguments passed down to the function implementing this | 
|  | * command. (Therefore, it doesn't make much sense to have any tokens after a | 
|  | * vararg because the vararg will already consume all the words the user entered | 
|  | * in the CLI) | 
|  | * | 
|  | * Multiple Tokens: | 
|  | * | 
|  | * The Multiple Token type can be used if there are multiple possibilities what | 
|  | * arguments may be used for a command, but it should map to the same function | 
|  | * nonetheless. An example would be "ip route A.B.C.D/M (reject|blackhole)" | 
|  | * In that case both "reject" and "blackhole" would be acceptable as last | 
|  | * arguments. The words matched by Multiple Tokens are always added to the | 
|  | * argument list, even if they are matched by fixed strings. Such a Multiple | 
|  | * Token can contain almost any type of token that would also be acceptable | 
|  | * for a Terminal Token, the exception are optional variables and varag. | 
|  | * | 
|  | * There is one special case that is used in some places of Quagga that should be | 
|  | * pointed out here shortly. An example would be "password (8|) WORD". This | 
|  | * construct is used to have fixed strings communicated as arguments. (The "8" | 
|  | * will be passed down as an argument in this case) It does not mean that | 
|  | * the "8" is optional. Another historic and possibly surprising property of | 
|  | * this construct is that it consumes two parts of helpstr. (Help | 
|  | * strings will be explained later) | 
|  | * | 
|  | * Keyword Tokens: | 
|  | * | 
|  | * There are commands that take a lot of different and possibly optional arguments. | 
|  | * An example from ospf would be the "default-information originate" command. This | 
|  | * command takes a lot of optional arguments that may be provided in any order. | 
|  | * To accomodate such commands, the Keyword Token has been implemented. | 
|  | * Using the keyword token, the "default-information originate" command and all | 
|  | * its possible options can be represented using this single cmdstr: | 
|  | * "default-information originate \ | 
|  | *  {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}" | 
|  | * | 
|  | * Keywords always start with a fixed string and may be followed by arguments. | 
|  | * Except optional variables and vararg, everything is permitted here. | 
|  | * | 
|  | * For the special case of a keyword without arguments, either NULL or the | 
|  | * keyword itself will be pushed as an argument, depending on whether the | 
|  | * keyword is present. | 
|  | * For the other keywords, arguments will be only pushed for | 
|  | * variables/Multiple Tokens. If the keyword is not present, the arguments that | 
|  | * would have been pushed will be substituted by NULL. | 
|  | * | 
|  | * A few examples: | 
|  | *   "default information originate metric-type 1 metric 1000" | 
|  | * would yield the following arguments: | 
|  | *   { NULL, "1000", "1", NULL } | 
|  | * | 
|  | *   "default information originate always route-map RMAP-DEFAULT" | 
|  | * would yield the following arguments: | 
|  | *   { "always", NULL, NULL, "RMAP-DEFAULT" } | 
|  | * | 
|  | * helpstr | 
|  | * ======= | 
|  | * | 
|  | * The helpstr is used to show a short explantion for the commands that | 
|  | * are available when the user presses '?' on the CLI. It is the concatenation | 
|  | * of the helpstrings for all the tokens that make up the command. | 
|  | * | 
|  | * There should be one helpstring for each token in the cmdstr except those | 
|  | * containing other tokens, like Multiple or Keyword Tokens. For those, there | 
|  | * will only be the helpstrings of the contained tokens. | 
|  | * | 
|  | * The individual helpstrings are expected to be in the same order as their | 
|  | * respective Tokens appear in the cmdstr. They should each be terminated with | 
|  | * a linefeed. The last helpstring should be terminated with a linefeed as well. | 
|  | * | 
|  | * Care should also be taken to avoid having similar tokens with different | 
|  | * helpstrings. Imagine e.g. the commands "show ip ospf" and "show ip bgp". | 
|  | * they both contain a helpstring for "show", but only one will be displayed | 
|  | * when the user enters "sh?". If those two helpstrings differ, it is not | 
|  | * defined which one will be shown and the behavior is therefore unpredictable. | 
|  | */ | 
 | #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ | #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ | 
 | DEFUN_CMD_FUNC_DECL(funcname) \ | DEFUN_CMD_FUNC_DECL(funcname) \ | 
 | DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ | DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ | 
| Line 258  struct desc | Line 459  struct desc | 
 |  |  | 
 | #endif /* VTYSH_EXTRACT_PL */ | #endif /* VTYSH_EXTRACT_PL */ | 
 |  |  | 
| /* Some macroes */ | /* | 
| #define CMD_OPTION(S)   ((S[0]) == '[') | * Sometimes #defines create maximum values that | 
| #define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<')) | * need to have strings created from them that | 
| #define CMD_VARARG(S)   ((S[0]) == '.') | * allow the parser to match against them. | 
| #define CMD_RANGE(S)     ((S[0] == '<')) | * These macros allow that. | 
|  | */ | 
|  | #define CMD_CREATE_STR(s)  CMD_CREATE_STR_HELPER(s) | 
|  | #define CMD_CREATE_STR_HELPER(s) #s | 
|  | #define CMD_RANGE_STR(a,s) "<" CMD_CREATE_STR(a) "-" CMD_CREATE_STR(s) ">" | 
 |  |  | 
 | #define CMD_IPV4(S)        ((strcmp ((S), "A.B.C.D") == 0)) |  | 
 | #define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0)) |  | 
 | #define CMD_IPV6(S)        ((strcmp ((S), "X:X::X:X") == 0)) |  | 
 | #define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0)) |  | 
 |  |  | 
 | /* Common descriptions. */ | /* Common descriptions. */ | 
 | #define SHOW_STR "Show running system information\n" | #define SHOW_STR "Show running system information\n" | 
| Line 329  struct desc | Line 530  struct desc | 
 | extern void install_node (struct cmd_node *, int (*) (struct vty *)); | extern void install_node (struct cmd_node *, int (*) (struct vty *)); | 
 | extern void install_default (enum node_type); | extern void install_default (enum node_type); | 
 | extern void install_element (enum node_type, struct cmd_element *); | extern void install_element (enum node_type, struct cmd_element *); | 
 | extern void sort_node (void); |  | 
 |  |  | 
 | /* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated | /* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated | 
 | string with a space between each element (allocated using | string with a space between each element (allocated using | 
| Line 340  extern vector cmd_make_strvec (const char *); | Line 540  extern vector cmd_make_strvec (const char *); | 
 | extern void cmd_free_strvec (vector); | extern void cmd_free_strvec (vector); | 
 | extern vector cmd_describe_command (vector, struct vty *, int *status); | extern vector cmd_describe_command (vector, struct vty *, int *status); | 
 | extern char **cmd_complete_command (vector, struct vty *, int *status); | extern char **cmd_complete_command (vector, struct vty *, int *status); | 
 |  | extern char **cmd_complete_command_lib (vector, struct vty *, int *status, int islib); | 
 | extern const char *cmd_prompt (enum node_type); | extern const char *cmd_prompt (enum node_type); | 
| extern int config_from_file (struct vty *, FILE *); | extern int command_config_read_one_line (struct vty *vty, struct cmd_element **, int use_config_node); | 
|  | extern int config_from_file (struct vty *, FILE *, unsigned int *line_num); | 
 | extern enum node_type node_parent (enum node_type); | extern enum node_type node_parent (enum node_type); | 
 | extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int); | extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int); | 
 | extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **); | extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **); | 
 | extern void config_replace_string (struct cmd_element *, char *, ...); |  | 
 | extern void cmd_init (int); | extern void cmd_init (int); | 
 | extern void cmd_terminate (void); | extern void cmd_terminate (void); | 
 |  |  |