int get_addr(inet_prefix *dst, char *arg, int family) { if (family == AF_PACKET) { bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "address"); } if (get_addr_1(dst, arg, family)) { bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "address", arg); } return 0; }
int get_addr(inet_prefix *dst, const char *arg, int family) { if (family == AF_PACKET) { fprintf(stderr, "Error: \"%s\" may be inet address, but it is not allowed in this context.\n", arg); exit(1); } if (get_addr_1(dst, arg, family)) { fprintf(stderr, "Error: an inet address is expected rather than \"%s\".\n", arg); exit(1); } return 0; }
__u32 get_addr32(const char *name) { inet_prefix addr; if (get_addr_1(&addr, name, AF_INET)) { fprintf(stderr, "Error: an IP address is expected rather than \"%s\"\n", name); exit(1); } return addr.data[0]; }
int get_prefix_1(inet_prefix *dst, char *arg, int family) { int err; unsigned plen; char *slash; memset(dst, 0, sizeof(*dst)); if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0 || strcmp(arg, "all") == 0) { if (family == AF_DECnet) return -1; dst->family = family; dst->bytelen = 0; dst->bitlen = 0; return 0; } slash = strchr(arg, '/'); if (slash) *slash = 0; err = get_addr_1(dst, arg, family); if (err == 0) { switch(dst->family) { case AF_INET6: dst->bitlen = 128; break; case AF_DECnet: dst->bitlen = 16; break; default: case AF_INET: dst->bitlen = 32; } if (slash) { if (get_netmask(&plen, slash+1, 0) || plen > dst->bitlen) { err = -1; goto done; } dst->flags |= PREFIXLEN_SPECIFIED; dst->bitlen = plen; } } done: if (slash) *slash = '/'; return err; }
static int get_netmask(unsigned *val, const char *arg, int base) { inet_prefix addr; if (!get_unsigned(val, arg, base)) return 0; /* try coverting dotted quad to CIDR */ if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) { int b = mask2bits(addr.data[0]); if (b >= 0) { *val = b; return 0; } } return -1; }
int get_prefix_1(inet_prefix *dst, char *arg, int family) { int err; unsigned plen; char *slash; memset(dst, 0, sizeof(*dst)); if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0 || strcmp(arg, "all") == 0) { if ((family == AF_DECnet) || (family == AF_MPLS)) return -1; dst->family = family; dst->bytelen = 0; dst->bitlen = 0; return 0; } slash = strchr(arg, '/'); if (slash) *slash = 0; err = get_addr_1(dst, arg, family); if (err == 0) { dst->bitlen = af_bit_len(dst->family); if (slash) { if (get_netmask(&plen, slash+1, 0) || plen > dst->bitlen) { err = -1; goto done; } dst->flags |= PREFIXLEN_SPECIFIED; dst->bitlen = plen; } } done: if (slash) *slash = '/'; return err; }
int get_prefix_1(inet_prefix *dst, char *arg, int family) { char *slash; int err, bitlen, flags; slash = strchr(arg, '/'); if (slash) *slash = 0; err = get_addr_1(dst, arg, family); if (slash) *slash = '/'; if (err) return err; bitlen = af_bit_len(dst->family); flags = 0; if (slash) { unsigned int plen; if (dst->bitlen == -2) return -1; if (get_netmask(&plen, slash + 1, 0)) return -1; if (plen > bitlen) return -1; flags |= PREFIXLEN_SPECIFIED; bitlen = plen; } else { if (dst->bitlen == -2) bitlen = 0; } dst->flags |= flags; dst->bitlen = bitlen; return 0; }
int get_prefix_1(inet_prefix * dst, char *arg, int family) { int err; int plen; char *slash; memset(dst, 0, sizeof(*dst)); if (strcmp(arg, bb_INET_default) == 0 || strcmp(arg, "any") == 0) { dst->family = family; dst->bytelen = 0; dst->bitlen = 0; return 0; } slash = strchr(arg, '/'); if (slash) *slash = 0; err = get_addr_1(dst, arg, family); if (err == 0) { switch (dst->family) { case AF_INET6: dst->bitlen = 128; break; default: case AF_INET: dst->bitlen = 32; } if (slash) { if (get_integer(&plen, slash + 1, 0) || plen > dst->bitlen) { err = -1; goto done; } dst->bitlen = plen; } } done: if (slash) *slash = '/'; return err; }
int ll_addr_a2n(unsigned char *lladdr, int len, char *arg) { if (strchr(arg, '.')) { inet_prefix pfx; if (get_addr_1(&pfx, arg, AF_INET)) { bb_error_msg("\"%s\" is invalid lladdr", arg); return -1; } if (len < 4) { return -1; } memcpy(lladdr, pfx.data, 4); return 4; } else { int i; for (i=0; i<len; i++) { int temp; char *cp = strchr(arg, ':'); if (cp) { *cp = 0; cp++; } if (sscanf(arg, "%x", &temp) != 1) { bb_error_msg("\"%s\" is invalid lladdr", arg); return -1; } if (temp < 0 || temp > 255) { bb_error_msg("\"%s\" is invalid lladdr", arg); return -1; } lladdr[i] = temp; if (!cp) { break; } arg = cp; } return i+1; } }
int get_addr_and_pi(int *argc_p, char ***argv_p, inet_prefix * addr, struct tc_rsvp_pinfo *pinfo, int dir, int family) { int argc = *argc_p; char **argv = *argv_p; char *p = strchr(*argv, '/'); struct tc_rsvp_gpi *pi = dir ? &pinfo->dpi : &pinfo->spi; if (p) { __u16 tmp; if (get_u16(&tmp, p+1, 0)) return -1; if (dir == 0) { /* Source port: u16 at offset 0 */ pi->key = htonl(((__u32)tmp)<<16); pi->mask = htonl(0xFFFF0000); } else { /* Destination port: u16 at offset 2 */ pi->key = htonl(((__u32)tmp)); pi->mask = htonl(0x0000FFFF); } pi->offset = 0; *p = 0; } if (get_addr_1(addr, *argv, family)) return -1; if (p) *p = '/'; argc--; argv++; if (pi->mask || argc <= 0) goto done; if (strcmp(*argv, "spi/ah") == 0 || strcmp(*argv, "gpi/ah") == 0) { __u32 gpi; NEXT_ARG(); if (get_u32(&gpi, *argv, 0)) return -1; pi->mask = htonl(0xFFFFFFFF); pi->key = htonl(gpi); pi->offset = 4; if (pinfo->protocol == 0) pinfo->protocol = IPPROTO_AH; argc--; argv++; } else if (strcmp(*argv, "spi/esp") == 0 || strcmp(*argv, "gpi/esp") == 0) { __u32 gpi; NEXT_ARG(); if (get_u32(&gpi, *argv, 0)) return -1; pi->mask = htonl(0xFFFFFFFF); pi->key = htonl(gpi); pi->offset = 0; if (pinfo->protocol == 0) pinfo->protocol = IPPROTO_ESP; argc--; argv++; } else if (strcmp(*argv, "flowlabel") == 0) { __u32 flabel; NEXT_ARG(); if (get_u32(&flabel, *argv, 0)) return -1; if (family != AF_INET6) return -1; pi->mask = htonl(0x000FFFFF); pi->key = htonl(flabel) & pi->mask; pi->offset = -40; argc--; argv++; } else if (strcmp(*argv, "u32") == 0 || strcmp(*argv, "u16") == 0 || strcmp(*argv, "u8") == 0) { int sz = 1; __u32 tmp; __u32 mask = 0xff; if (strcmp(*argv, "u32") == 0) { sz = 4; mask = 0xffff; } else if (strcmp(*argv, "u16") == 0) { mask = 0xffffffff; sz = 2; } NEXT_ARG(); if (get_u32(&tmp, *argv, 0)) return -1; argc--; argv++; if (strcmp(*argv, "mask") == 0) { NEXT_ARG(); if (get_u32(&mask, *argv, 16)) return -1; argc--; argv++; } if (strcmp(*argv, "at") == 0) { NEXT_ARG(); if (get_integer(&pi->offset, *argv, 0)) return -1; argc--; argv++; } if (sz == 1) { if ((pi->offset & 3) == 0) { mask <<= 24; tmp <<= 24; } else if ((pi->offset & 3) == 1) { mask <<= 16; tmp <<= 16; } else if ((pi->offset & 3) == 3) { mask <<= 8; tmp <<= 8; } } else if (sz == 2) { if ((pi->offset & 3) == 0) { mask <<= 16; tmp <<= 16; } } pi->offset &= ~3; pi->mask = htonl(mask); pi->key = htonl(tmp) & pi->mask; } done: *argc_p = argc; *argv_p = argv; return 0; }