Exemple #1
0
static void
test_ipv6_masking(void)
{
    struct in6_addr dest;
    struct in6_addr mask;

    mask = ipv6_create_mask(0);
    dest = ipv6_addr_bitand(&in6addr_exact, &mask);
    assert(ipv6_count_cidr_bits(&dest) == 0);

    mask = ipv6_create_mask(1);
    dest = ipv6_addr_bitand(&in6addr_exact, &mask);
    assert(ipv6_count_cidr_bits(&dest) == 1);

    mask = ipv6_create_mask(13);
    dest = ipv6_addr_bitand(&in6addr_exact, &mask);
    assert(ipv6_count_cidr_bits(&dest) == 13);

    mask = ipv6_create_mask(127);
    dest = ipv6_addr_bitand(&in6addr_exact, &mask);
    assert(ipv6_count_cidr_bits(&dest) == 127);

    mask = ipv6_create_mask(128);
    dest = ipv6_addr_bitand(&in6addr_exact, &mask);
    assert(ipv6_count_cidr_bits(&dest) == 128);
}
Exemple #2
0
static void
test_ipv6_cidr(void)
{
    struct in6_addr dest;

    struct in6_addr src   = {{{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, \
                                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }}};

    dest = ipv6_create_mask(0);
    assert(ipv6_mask_is_any(&dest));
    assert(ipv6_count_cidr_bits(&dest) == 0);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(128);
    assert(ipv6_mask_is_exact(&dest));
    assert(ipv6_count_cidr_bits(&dest) == 128);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(1);
    assert(ipv6_count_cidr_bits(&dest) == 1);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(13);
    assert(ipv6_count_cidr_bits(&dest) == 13);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(64);
    assert(ipv6_count_cidr_bits(&dest) == 64);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(95);
    assert(ipv6_count_cidr_bits(&dest) == 95);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(96);
    assert(ipv6_count_cidr_bits(&dest) == 96);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(97);
    assert(ipv6_count_cidr_bits(&dest) == 97);
    assert(ipv6_is_cidr(&dest));

    dest = ipv6_create_mask(127);
    assert(ipv6_count_cidr_bits(&dest) == 127);
    assert(ipv6_is_cidr(&dest));

    src.s6_addr[8] = 0xf0;
    assert(ipv6_is_cidr(&src));
    assert(ipv6_count_cidr_bits(&src) == 68);

    src.s6_addr[15] = 0x01;
    assert(!ipv6_is_cidr(&src));
    src.s6_addr[15] = 0x00;
    assert(ipv6_is_cidr(&src));

    src.s6_addr[8] = 0x0f;
    assert(!ipv6_is_cidr(&src));
}
Exemple #3
0
static const char *
lex_parse_mask(const char *p, struct lex_token *token)
{
    struct lex_token mask;

    /* Parse just past the '/' as a second integer.  Handle errors. */
    p = lex_parse_integer__(p + 1, &mask);
    if (mask.type == LEX_T_ERROR) {
        lex_token_swap(&mask, token);
        lex_token_destroy(&mask);
        return p;
    }
    ovs_assert(mask.type == LEX_T_INTEGER);

    /* Now convert the value and mask into a masked integer token.
     * We have a few special cases. */
    token->type = LEX_T_MASKED_INTEGER;
    memset(&token->mask, 0, sizeof token->mask);
    uint32_t prefix_bits = ntohll(mask.value.integer);
    if (token->format == mask.format) {
        /* Same format value and mask is always OK. */
        token->mask = mask.value;
    } else if (token->format == LEX_F_IPV4
               && mask.format == LEX_F_DECIMAL
               && prefix_bits <= 32) {
        /* IPv4 address with decimal mask is a CIDR prefix. */
        token->mask.integer = htonll(ntohl(be32_prefix_mask(prefix_bits)));
    } else if (token->format == LEX_F_IPV6
               && mask.format == LEX_F_DECIMAL
               && prefix_bits <= 128) {
        /* IPv6 address with decimal mask is a CIDR prefix. */
        token->mask.ipv6 = ipv6_create_mask(prefix_bits);
    } else if (token->format == LEX_F_DECIMAL
               && mask.format == LEX_F_HEXADECIMAL
               && token->value.integer == 0) {
        /* Special case for e.g. 0/0x1234. */
        token->format = LEX_F_HEXADECIMAL;
        token->mask = mask.value;
    } else {
        lex_error(token, "Value and mask have incompatible formats.");
        return p;
    }

    /* Check invariant that a 1-bit in the value corresponds to a 1-bit in the
     * mask. */
    for (int i = 0; i < ARRAY_SIZE(token->mask.be32); i++) {
        ovs_be32 v = token->value.be32[i];
        ovs_be32 m = token->mask.be32[i];

        if (v & ~m) {
            lex_error(token, "Value contains unmasked 1-bits.");
            break;
        }
    }

    /* Done! */
    lex_token_destroy(&mask);
    return p;
}
Exemple #4
0
int
str_to_ipv6(const char *str_, struct in6_addr *addrp, struct in6_addr *maskp)
{

    char *str = xstrdup(str_);
    char *save_ptr = NULL;
    const char *name, *netmask;
    struct in6_addr addr, mask;
    int retval;

    name = strtok_r(str, "/", &save_ptr);
    retval = name ? lookup_ipv6(name, &addr) : EINVAL;
    if (retval) {
        printf("%s: could not convert to IPv6 address\n", str);
        return -1;
    }
    
    netmask = strtok_r(NULL, "/", &save_ptr);
    if (netmask) {
        int prefix = atoi(netmask);
        if (prefix <= 0 || prefix > 128) {
            printf("%s: network prefix bits not between 1 and 128\n",
                      str);
            return -1;
        } else {
            mask = ipv6_create_mask(prefix);
        }
    } else {
        mask = in6addr_zero ;
        *maskp = mask;
        *addrp = ipv6_addr_bitand(&addr, &in6addr_exact);
        return 1;
    }
    mask = in6addr_exact ;
    *addrp = ipv6_addr_bitand(&addr, &mask);

    if (maskp) {
        *maskp = mask;
    } else {
        if (!ipv6_mask_is_exact(&mask)) {
            printf("%s: netmask not allowed here", str_);
            return -1;
        }
    }

    free(str);
    return 1;
}
Exemple #5
0
static void
add_ipv6_netaddr(struct lport_addresses *laddrs, struct in6_addr addr,
                 unsigned int plen)
{
    laddrs->n_ipv6_addrs++;
    laddrs->ipv6_addrs = xrealloc(laddrs->ipv6_addrs,
        laddrs->n_ipv6_addrs * sizeof *laddrs->ipv6_addrs);

    struct ipv6_netaddr *na = &laddrs->ipv6_addrs[laddrs->n_ipv6_addrs - 1];

    memcpy(&na->addr, &addr, sizeof na->addr);
    na->mask = ipv6_create_mask(plen);
    na->network = ipv6_addr_bitand(&addr, &na->mask);
    na->plen = plen;
    in6_addr_solicited_node(&na->sn_addr, &addr);

    inet_ntop(AF_INET6, &addr, na->addr_s, sizeof na->addr_s);
    inet_ntop(AF_INET6, &na->sn_addr, na->sn_addr_s, sizeof na->sn_addr_s);
    inet_ntop(AF_INET6, &na->network, na->network_s, sizeof na->network_s);
}