Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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];
}
Пример #4
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;
}
Пример #5
0
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;
}
Пример #6
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) || (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;
}
Пример #7
0
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;
}
Пример #8
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;
}
Пример #9
0
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;
	}
}
Пример #10
0
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;
}