struct node *create_node (char *name, struct eq *eq, enum nodetype nodetype) { struct node *n ; char *s ; struct symtab *p ; p = symtab_get (name) ; s = symtab_to_name (p) ; MOBJ_ALLOC_INSERT (n, nodemobj) ; n->name = s ; n->eq = eq ; n->nodetype = nodetype ; n->linklist = NULL ; symtab_to_node (p) = n ; /* add to equipement node list */ n->enext = NULL; n->eprev = NULL; if(eq->enhead == NULL) eq->enhead = n; if(eq->entail != NULL) { eq->entail->enext = n; n->eprev = eq->entail; } eq->entail = n; return n ; }
char *sel_register (int opt, char *arg) { struct sel *sl ; ip_t a ; vlan_t vlanid ; regex_t rc ; char *r ; static char errstr [100] ; errstr [0] = '\0' ; MOBJ_ALLOC_INSERT (sl, selmobj) ; switch (opt) { case 'a' : sl->crittype = CT_ALL ; break ; case 'n' : if (ip_pton (arg, &a)) { sl->crittype = CT_NET ; sl->u.net.addr = a ; } else sprintf (errstr, "'%s' is not a valid cidr", arg) ; break ; case 'e' : case 'E' : if (regcomp (&rc, arg, RE_MODE) == 0) { sl->crittype = CT_REX ; sl->u.rex.allow_deny = (opt == 'e') ; sl->u.rex.rc = rc ; } else sprintf (errstr, "'%s' is not a valid regexp", arg) ; break ; case 't' : sl->crittype = CT_TERM ; break ; case 'm' : sl->crittype = CT_OWN ; break ; case 'v' : vlanid = atoi(arg) ; if (vlanid > 0 && vlanid <= 4094) { sl->crittype = CT_VLAN ; sl->u.vlan.id = vlanid ; } else sprintf (errstr, "'%s' is not a valid vlan id", arg) ; break ; default : sprintf (errstr, "internal error : '-%c' is not a valid option", opt) ; } r = (errstr [0] == '\0') ? NULL : errstr ; return r ; }
void sel_mark (void) { struct sel *sl ; struct node *n ; struct eq *eq ; struct vlan *vlantab ; struct network *net ; int i ; MOBJ *tmobj ; /* temporary mobj to reverse list */ /* * Create temporary list, ordered */ tmobj = mobj_init (sizeof (struct sel), MOBJ_MALLOC) ; for (sl = mobj_head (selmobj) ; sl != NULL ; sl = sl->next) { struct sel *tsl ; MOBJ_ALLOC_INSERT (tsl, tmobj) ; tsl->crittype = sl->crittype ; tsl->u = sl->u ; } /* * Initialize graph : everything must be clear */ vlantab = mobj_data (vlanmobj) ; for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) { n->mark = 0 ; vlan_zero (n->vlanset) ; } for (eq = mobj_head (eqmobj) ; eq != NULL ; eq = eq->next) eq->mark = 0 ; for (i = 0 ; i < MAXVLAN ; i++) vlantab [i].mark = 0 ; for (net = mobj_head (netmobj) ; net != NULL ; net = net->next) net->mark = 0 ; /* * Traverse the selection criteria mobj */ for (sl = mobj_head (tmobj) ; sl != NULL ; sl = sl->next) { switch (sl->crittype) { case CT_ALL : /* * Select all objects in the graph */ for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) n->mark = MK_SELECTED ; for (eq = mobj_head (eqmobj) ; eq != NULL ; eq = eq->next) eq->mark = MK_SELECTED ; for (i = 0 ; i < MAXVLAN ; i++) vlantab [i].mark = MK_SELECTED ; for (net = mobj_head (netmobj) ; net != NULL ; net = net->next) net->mark = MK_SELECTED ; break ; case CT_NET : /* * Select nodes based on network cidr * Select routed networks based on network cidr */ sel_mark_net (&sl->u.net.addr) ; break ; case CT_REX : /* * Select equipements based on regexp */ sel_mark_regexp (&sl->u.rex.rc, sl->u.rex.allow_deny) ; break ; case CT_VLAN : /* * Select nodes based on vlan id */ sel_mark_vlan (sl->u.vlan.id) ; break ; case CT_TERM : /* * Keep only terminal interfaces */ sel_unmark_nonterminal () ; break ; case CT_OWN : /* * Keep only "my" interfaces : those which transport * only "my" networks/Vlans */ sel_unmark_notmine () ; break ; default : break ; } } /* * Selects all equipements where at least one L1 interface is marked */ for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) if (n->nodetype == NT_L1 && MK_ISSELECTED (n)) MK_SELECT (n->eq) ; /* * Select Vlans where L2 node have been selected in the * L2 traversal. */ for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) if (n->nodetype == NT_L2 && MK_ISSET (n, MK_L2TRANSPORT)) MK_SELECT (&vlantab [n->u.l2.vlan]) ; /* * Close the temporary mobj */ sel_free (tmobj) ; }