int addr_pton(const char *src, struct addr *dst) { struct hostent *hp; char *ep, tmp[300]; long bits = -1; int i; for (i = 0; i < (int)sizeof(tmp) - 1; i++) { if (src[i] == '/') { tmp[i] = '\0'; if (strchr(&src[i + 1], '.')) { uint32_t m; uint16_t b; /* XXX - mask is specified like /255.0.0.0 */ if (ip_pton(&src[i + 1], &m) != 0) { errno = EINVAL; return (-1); } addr_mtob(&m, sizeof(m), &b); bits = b; } else { bits = strtol(&src[i + 1], &ep, 10); if (ep == src || *ep != '\0' || bits < 0) { errno = EINVAL; return (-1); } } break; } else if ((tmp[i] = src[i]) == '\0') break; } if (ip_pton(tmp, &dst->addr_ip) == 0) { dst->addr_type = ADDR_TYPE_IP; dst->addr_bits = IP_ADDR_BITS; } else if (eth_pton(tmp, &dst->addr_eth) == 0) { dst->addr_type = ADDR_TYPE_ETH; dst->addr_bits = ETH_ADDR_BITS; } else if (ip6_pton(tmp, &dst->addr_ip6) == 0) { dst->addr_type = ADDR_TYPE_IP6; dst->addr_bits = IP6_ADDR_BITS; } else if ((hp = gethostbyname(tmp)) != NULL) { memcpy(&dst->addr_ip, hp->h_addr, IP_ADDR_LEN); dst->addr_type = ADDR_TYPE_IP; dst->addr_bits = IP_ADDR_BITS; } else { errno = EINVAL; return (-1); } if (bits >= 0) { if (bits > dst->addr_bits) { errno = EINVAL; return (-1); } dst->addr_bits = (uint16_t)bits; } return (0); }
static uint32_t check_ip_pton(lua_State* L, const char* p, const char* name) { uint32_t n = 0; if(ip_pton(p, &n) < 0) { return luaL_error(L, "ip_pton failed on %s '%s'", name, p); } 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 ; }
int ip6_pton(const char *p, ip6_addr_t *ip6) { uint16_t data[8], *u = (uint16_t *)ip6->data; int i, j, n, z = -1; char *ep; long l; if (*p == ':') p++; for (n = 0; n < 8; n++) { l = strtol(p, &ep, 16); if (ep == p) { if (ep[0] == ':' && z == -1) { z = n; p++; } else if (ep[0] == '\0') { break; } else { return (-1); } } else if (ep[0] == '.' && n <= 6) { if (ip_pton(p, (ip_addr_t *)(data + n)) < 0) return (-1); n += 2; ep = ""; /* XXX */ break; } else if (l >= 0 && l <= 0xffff) { data[n] = (uint16_t)htons(l); if (ep[0] == '\0') { n++; break; } else if (ep[0] != ':' || ep[1] == '\0') return (-1); p = ep + 1; } else return (-1); } if (n == 0 || *ep != '\0' || (z == -1 && n != 8)) return (-1); for (i = 0; i < z; i++) { u[i] = data[i]; } while (i < 8 - (n - z - 1)) { u[i++] = 0; } for (j = z + 1; i < 8; i++, j++) { u[i] = data[j]; } return (0); }
int main (int argc, char *argv []) { int i ; struct node *n ; struct eq *eq ; ip_t cidr ; int c, err ; char *prog, *errstr ; prog = argv [0] ; err = 0 ; sel_init () ; while ((c = getopt (argc, argv, "an:e:E:tv:m")) != -1) { switch (c) { case 'a' : case 'n' : case 'e' : case 'E' : case 't' : case 'v' : case 'm' : if ((errstr = sel_register (c, optarg)) != NULL) { fprintf (stderr, "%s: %s\n", prog, errstr) ; err = 1 ; } break ; case '?' : default : usage (prog) ; } } if (err) exit (1) ; argc -= optind ; argv += optind ; if (argc == 0) usage (prog) ; /* * Read the graph and select subgraph */ bin_read (stdin, mobjlist) ; sel_mark () ; /* * First pass : mark all L3 nodes matching CIDR arguments */ for (i = 0 ; i < argc ; i++) { if (! ip_pton (argv [i], &cidr)) { fprintf (stderr, "%s: Invalid cidr '%s'\n", prog, argv [i]) ; exit (1) ; } for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) if (n->nodetype == NT_L3 && ip_match (&n->u.l3.addr, &cidr, 0)) MK_SET (n, MK_IPMATCH) ; } /* * Output selection arguments */ fprintf (stdout, "selection") ; for (i = 0 ; i < argc ; i++) fprintf (stdout, " %s", argv [i]) ; fprintf (stdout, "\n") ; /* * Second pass : identify all routing instances connected to those * L3 nodes we have marked before, and print equipements which are * routing instances. */ for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) { if (n->nodetype == NT_L3 && MK_ISSET (n, MK_IPMATCH)) { struct node *r ; MK_SET (n->eq, MK_IPMATCH) ; r = get_neighbour (n, NT_ROUTER) ; if (r != NULL && ! MK_ISSET (r, MK_ISROUTER)) { MK_SET (n, MK_ISROUTER) ; MK_SET (r, MK_ISROUTER) ; MK_SET (n->eq, MK_ISROUTER) ; if (MK_ISSELECTED (n)) fprintf (stdout, "eq %s:%s router\n", n->eq->name, r->u.router.name) ; } } } /* * Third pass : print equipements which are not routing instances */ for (eq = mobj_head (eqmobj) ; eq != NULL ; eq = eq->next) if (MK_ISSET (eq, MK_IPMATCH) && ! MK_ISSET (eq, MK_ISROUTER)) if (MK_ISSELECTED (eq)) fprintf (stdout, "eq %s host\n", eq->name) ; /* * Fourth pass : identify broadcast domain for each L3 */ for (n = mobj_head (nodemobj) ; n != NULL ; n = n->next) { if (n->nodetype == NT_L3 && MK_ISSET (n, MK_IPMATCH) && ! MK_ISSET (n, MK_PROCESSED)) walkl3 (stdout, n) ; } sel_end () ; exit (0) ; }