/* Get the ctrl_cmd_element that matches this command */ static struct ctrl_cmd_element *ctrl_cmd_get_element_match(vector vline, vector node) { int index, j; const char *desc; struct ctrl_cmd_element *cmd_el; struct ctrl_cmd_struct *cmd_desc; char *str; for (index = 0; index < vector_active(node); index++) { if ((cmd_el = vector_slot(node, index))) { cmd_desc = &cmd_el->strcmd; if (cmd_desc->nr_commands > vector_active(vline)) continue; for (j =0; j < vector_active(vline); j++) { str = vector_slot(vline, j); desc = cmd_desc->command[j]; if (desc[0] == '*') return cmd_el; /* Partial match */ if (strcmp(desc, str) != 0) break; } /* We went through all the elements and all matched */ if (j == cmd_desc->nr_commands) return cmd_el; } } return NULL; }
/* Check ambiguous match */ static int is_cmd_ambiguous (char *command, vector v, int index, enum match_type type) { unsigned int i; unsigned int j; const char *str = NULL; struct cmd_element *cmd_element; const char *matched = NULL; vector descvec; struct desc *desc; for (i = 0; i < vector_active (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { int match = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_active (descvec); j++) if ((desc = vector_slot (descvec, j))) { enum match_type ret; str = desc->cmd; switch (type) { case exact_match: if (!(CMD_OPTION (str) || CMD_VARIABLE (str)) && strcmp (command, str) == 0) match++; break; case extend_match: if (CMD_OPTION (str) || CMD_VARIABLE (str)) match++; break; case ipv4_match: if (CMD_IPV4 (str)) match++; break; case ipv4_prefix_match: if ((ret = cmd_ipv4_prefix_match (command)) != no_match) { if (ret == partly_match) return 2; /* There is incomplete match. */ match++; } break; } } if (!match) vector_slot (v, i) = NULL; } return 0; }
/* Display configuration to file pointer. */ void vtysh_config_dump (FILE *fp) { struct listnode *node, *nnode; struct listnode *mnode, *mnnode; struct config *config; struct list *master; char *line; unsigned int i; for (ALL_LIST_ELEMENTS (config_top, node, nnode, line)) { fprintf (fp, "%s\n", line); fflush (fp); } fprintf (fp, "!\n"); fflush (fp); for (i = 0; i < vector_active (configvec); i++) if ((master = vector_slot (configvec, i)) != NULL) { for (ALL_LIST_ELEMENTS (master, node, nnode, config)) { fprintf (fp, "%s\n", config->name); fflush (fp); for (ALL_LIST_ELEMENTS (config->line, mnode, mnnode, line)) { fprintf (fp, "%s\n", line); fflush (fp); } if (! NO_DELIMITER (i)) { fprintf (fp, "!\n"); fflush (fp); } } if (NO_DELIMITER (i)) { fprintf (fp, "!\n"); fflush (fp); } } for (i = 0; i < vector_active (configvec); i++) if ((master = vector_slot (configvec, i)) != NULL) { list_delete (master); vector_slot (configvec, i) = NULL; } list_delete_all_node (config_top); }
void frrstr_filter_vec(vector v, regex_t *filter) { regmatch_t ignored[1]; for (unsigned int i = 0; i < vector_active(v); i++) { if (regexec(filter, vector_slot(v, i), 0, ignored, 0)) { XFREE(MTYPE_TMP, vector_slot(v, i)); vector_unset(v, i); } } }
/* Utility function for looking up passive interface settings. */ static int ripng_passive_interface_lookup (const char *ifname) { unsigned int i; char *str; for (i = 0; i < vector_active (Vripng_passive_interface); i++) if ((str = vector_slot (Vripng_passive_interface, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1; }
/* Lookup function. */ static int ripng_enable_if_lookup (const char *ifname) { unsigned int i; char *str; for (i = 0; i < vector_active (ripng_enable_if); i++) if ((str = vector_slot (ripng_enable_if, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1; }
/* Utility function for looking up passive interface settings. */ static int rip_passive_nondefault_lookup (const char *ifname) { unsigned int i; char *str; for (i = 0; i < vector_active (Vrip_passive_nondefault); i++) if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1; }
/* Free all configured RIP passive-interface settings. */ void ripng_passive_interface_clean (void) { unsigned int i; char *str; for (i = 0; i < vector_active (Vripng_passive_interface); i++) if ((str = vector_slot (Vripng_passive_interface, i)) != NULL) { free (str); vector_slot (Vripng_passive_interface, i) = NULL; } ripng_passive_interface_apply_all (); }
/* Write RIPng enable network and interface to the vty. */ int ripng_network_write (struct vty *vty, int config_mode) { unsigned int i; const char *ifname; struct route_node *node; char buf[BUFSIZ]; /* Write enable network. */ for (node = route_top (ripng_enable_network); node; node = route_next (node)) if (node->info) { struct prefix *p = &node->p; vty_out (vty, "%s%s/%d%s", config_mode ? " network " : " ", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen, VTY_NEWLINE); } /* Write enable interface. */ for (i = 0; i < vector_active (ripng_enable_if); i++) if ((ifname = vector_slot (ripng_enable_if, i)) != NULL) vty_out (vty, "%s%s%s", config_mode ? " network " : " ", ifname, VTY_NEWLINE); /* Write passive interface. */ if (config_mode) for (i = 0; i < vector_active (Vripng_passive_interface); i++) if ((ifname = vector_slot (Vripng_passive_interface, i)) != NULL) vty_out (vty, " passive-interface %s%s", ifname, VTY_NEWLINE); return 0; }
/* Count mandantory string vector size. This is to determine inputed command has enough command length. */ static int cmd_cmdsize (vector strvec) { unsigned int i; int size = 0; vector descvec; struct desc *desc; for (i = 0; i < vector_active (strvec); i++) if ((descvec = vector_slot (strvec, i)) != NULL) { if ((vector_active (descvec)) == 1 && (desc = vector_slot (descvec, 0)) != NULL) { if (desc->cmd == NULL || CMD_OPTION (desc->cmd)) return size; else size++; } else size++; } return size; }
void frrstr_strvec_free(vector v) { unsigned int i; char *cp; if (!v) return; for (i = 0; i < vector_active(v); i++) { cp = vector_slot(v, i); XFREE(MTYPE_TMP, cp); } vector_free(v); }
/* Clear all network and neighbor configuration */ void ripng_clean_network () { unsigned int i; char *str; struct route_node *rn; /* ripng_enable_network */ for (rn = route_top (ripng_enable_network); rn; rn = route_next (rn)) if (rn->info) { rn->info = NULL; route_unlock_node(rn); } /* ripng_enable_if */ for (i = 0; i < vector_active (ripng_enable_if); i++) if ((str = vector_slot (ripng_enable_if, i)) != NULL) { free (str); vector_slot (ripng_enable_if, i) = NULL; } }
/* Execute command by argument readline. */ int cmd_execute_command_strict (vector vline, struct vty *vty, struct cmd_element **cmd) { unsigned int i; unsigned int index; vector cmd_vector; enum match_type match = 0; struct cmd_element *cmd_element; struct cmd_element *matched_element; unsigned int matched_count, incomplete_count; int argc; const char *argv[CMD_ARGC_MAX]; int varflag; char * command; cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node)); for(index = 0; index < vector_active(vline); index++) { if((command = vector_slot(vline, index))) { int ret; match = cmd_filter_by_string(vector_slot(vline, index), cmd_vector, index); if(match == vararg_match) break; ret = is_cmd_ambiguous (command, cmd_vector, index, match); if (ret == 1) { vector_free (cmd_vector); return CMD_ERR_AMBIGUOUS; } if (ret == 2) { vector_free (cmd_vector); return CMD_ERR_NO_MATCH; } } } /* Check matched count. */ matched_element = NULL; matched_count = 0; incomplete_count = 0; for (i = 0; i < vector_active (cmd_vector); i++) if (vector_slot (cmd_vector, i) != NULL) { cmd_element = vector_slot (cmd_vector, i); if (match == vararg_match || index >= cmd_element->cmdsize) { matched_element = cmd_element; matched_count++; } else incomplete_count++; } /* Finish of using cmd_vector. */ vector_free (cmd_vector); /* To execute command, matched_count must be 1. */ if (matched_count == 0) { if (incomplete_count) return CMD_ERR_INCOMPLETE; else return CMD_ERR_NO_MATCH; } if (matched_count > 1) return CMD_ERR_AMBIGUOUS; /* Argument treatment */ varflag = 0; argc = 0; for (i = 0; i < vector_active (vline); i++) { if (varflag) argv[argc++] = vector_slot (vline, i); else { vector descvec = vector_slot (matched_element->strvec, i); if (vector_active (descvec) == 1) { struct desc *desc = vector_slot (descvec, 0); if (CMD_VARARG (desc->cmd)) varflag = 1; if (varflag || CMD_VARIABLE (desc->cmd) || CMD_OPTION (desc->cmd)) argv[argc++] = vector_slot (vline, i); } else argv[argc++] = vector_slot (vline, i); } if (argc >= CMD_ARGC_MAX) return CMD_ERR_EXEED_ARGC_MAX; } /* For vtysh execution. */ if (cmd) *cmd = matched_element; if (matched_element->daemon) return CMD_SUCCESS_DAEMON; /* Now execute matched command */ return (*matched_element->func) (matched_element, vty, argc, argv); }
/* Filter vector by command character with index. */ static enum match_type cmd_filter_by_string (char *command, vector v, unsigned int index) { unsigned int i; const char *str; struct cmd_element *cmd_element; enum match_type match_type; vector descvec; struct desc * desc; match_type = no_match; /* If command and cmd_element string does not match set NULL to vector */ for (i = 0; i < vector_active (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { /* If given index is bigger than max string vector of command, set NULL */ if (index >= vector_active (cmd_element->strvec)) vector_slot (v, i) = NULL; else { unsigned int j; int matched = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_active (descvec); j++) if ((desc = vector_slot (descvec, j))) { str = desc->cmd; if (CMD_VARARG (str)) { if (match_type < vararg_match) match_type = vararg_match; matched++; } else if (CMD_IPV4 (str)) { if (cmd_ipv4_match (command) == exact_match) { if (match_type < ipv4_match) match_type = ipv4_match; matched++; } } else if (CMD_IPV4_PREFIX (str)) { if (cmd_ipv4_prefix_match (command) == exact_match) { if (match_type < ipv4_prefix_match) match_type = ipv4_prefix_match; matched++; } } else if (CMD_OPTION (str) || CMD_VARIABLE (str)) { if (match_type < extend_match) match_type = extend_match; matched++; } else { if (strcmp (command, str) == 0) { match_type = exact_match; matched++; } } } if(!matched) vector_slot(v,i) = NULL; } } return match_type; }