Esempio n. 1
0
static void test_ipv6_nc_add__full(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;

    for (int i = 0; i < NG_IPV6_NC_SIZE; i++) {
        TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr, TEST_STRING4,
                                            sizeof(TEST_STRING4), 0));
        addr.u16[7].u16++;
    }

    TEST_ASSERT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr, TEST_STRING4,
                                    sizeof(TEST_STRING4), 0));
}
Esempio n. 2
0
static void test_ipv6_nc_add__address_registered(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry1, *entry2;

    TEST_ASSERT_NOT_NULL((entry1 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
                                                  TEST_STRING4, sizeof(TEST_STRING4),
                                                  0)));
    TEST_ASSERT_NOT_NULL((entry2 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
                                                  TEST_STRING4, sizeof(TEST_STRING4),
                                                  0)));
    TEST_ASSERT(entry1 == entry2);
}
Esempio n. 3
0
static void test_ipv6_nc_add__l2addr_too_long(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;

    TEST_ASSERT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr, TEST_STRING4,
                                    NG_IPV6_NC_L2_ADDR_MAX + TEST_UINT8, 0));
}
Esempio n. 4
0
static void test_ipv6_nc_add__addr_unspecified(void)
{
    ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED;

    TEST_ASSERT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr, TEST_STRING4,
                                    sizeof(TEST_STRING4), 0));
}
Esempio n. 5
0
static void test_ipv6_nc_add__iface_KERNEL_PID_UNDEF(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;

    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(KERNEL_PID_UNDEF, &addr, TEST_STRING4,
                                        sizeof(TEST_STRING4), 0));
}
Esempio n. 6
0
static int _ipv6_nc_add(kernel_pid_t iface, char *ipv6_addr_str,
                        char *l2_addr_str)
{
    ipv6_addr_t ipv6_addr;
    uint8_t l2_addr[MAX_L2_ADDR_LEN];
    size_t l2_addr_len;

    if (ipv6_addr_from_str(&ipv6_addr, ipv6_addr_str) == NULL) {
        puts("error: unable to parse IPv6 address.");
        return 1;
    }

    if ((l2_addr_len = ng_netif_addr_from_str(l2_addr, sizeof(l2_addr),
                       l2_addr_str)) == 0) {
        puts("error: unable to parse link-layer address.");
        return 1;
    }

    if (ng_ipv6_nc_add(iface, &ipv6_addr, l2_addr, l2_addr_len, 0) == NULL) {
        puts("error: unable to add address to neighbor cache.");
        return 1;
    }

    printf("success: added IPv6 address %s to neighbor cache\n", ipv6_addr_str);
    return 0;
}
Esempio n. 7
0
static bool _handle_sl2a_opt(kernel_pid_t iface, ng_pktsnip_t *pkt,
                             ng_ipv6_hdr_t *ipv6, uint8_t icmpv6_type,
                             ng_ndp_opt_t *sl2a_opt)
{
    ng_ipv6_nc_t *nc_entry = NULL;
    uint8_t sl2a_len = 0;
    uint8_t *sl2a = (uint8_t *)(sl2a_opt + 1);

    if ((sl2a_opt->len == 0) || ng_ipv6_addr_is_unspecified(&ipv6->src)) {
        DEBUG("ndp: invalid source link-layer address option received\n");
        return false;
    }

    while (pkt) {
        if (pkt->type == NG_NETTYPE_NETIF) {
            ng_netif_hdr_t *hdr = pkt->data;
            sl2a_len = hdr->src_l2addr_len;
            break;
        }
        pkt = pkt->next;
    }

    if (sl2a_len == 0) {  /* in case there was no source address in l2 */
        sl2a_len = (sl2a_opt->len / 8) - sizeof(ng_ndp_opt_t);

        /* ignore all zeroes at the end for length */
        for (; sl2a[sl2a_len - 1] == 0x00; sl2a_len--);
    }

    DEBUG("ndp: received SL2A (link-layer address: %s)\n",
          ng_netif_addr_to_str(addr_str, sizeof(addr_str), sl2a, sl2a_len));

    switch (icmpv6_type) {
        case NG_ICMPV6_NBR_SOL:
            nc_entry = ng_ipv6_nc_get(iface, &ipv6->src);

            if (nc_entry != NULL) {
                if ((sl2a_len != nc_entry->l2_addr_len) ||
                    (memcmp(sl2a, nc_entry->l2_addr, sl2a_len) != 0)) {
                    /* if entry exists but l2 address differs: set */
                    nc_entry->l2_addr_len = sl2a_len;
                    memcpy(nc_entry->l2_addr, sl2a, sl2a_len);

                    _set_state(nc_entry, NG_IPV6_NC_STATE_STALE);
                }
            }
            else {
                ng_ipv6_nc_add(iface, &ipv6->src, sl2a, sl2a_len,
                               NG_IPV6_NC_STATE_STALE);
            }

            return true;

        default:    /* wrong encapsulating message: silently discard */
            DEBUG("ndp: silently discard sl2a_opt for ICMPv6 message type %"
                  PRIu8 "\n", icmpv6_type);
            return true;
    }
}
Esempio n. 8
0
static void test_ipv6_nc_add__address_update_despite_free_entry(void)
{
    ipv6_addr_t default_addr = DEFAULT_TEST_IPV6_ADDR;
    ipv6_addr_t other_addr = OTHER_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry1, *entry2;

    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(OTHER_TEST_NETIF, &other_addr,
                                        TEST_STRING4, sizeof(TEST_STRING4),
                                        0));
    TEST_ASSERT_NOT_NULL((entry1 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &default_addr,
                                                  TEST_STRING4, sizeof(TEST_STRING4),
                                                  0)));

    /* create space by removing first entry and see if duplicate is still detected & updated */
    ng_ipv6_nc_remove(OTHER_TEST_NETIF, &other_addr);
    TEST_ASSERT_NOT_NULL((entry2 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &default_addr,
                                                  TEST_STRING4, sizeof(TEST_STRING4),
                                                  0)));
    TEST_ASSERT(entry1 == entry2);
}
Esempio n. 9
0
static void test_ipv6_nc_get_next__2_entries(void)
{
    ipv6_addr_t addr = OTHER_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL;

    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr, TEST_STRING8,
                                        sizeof(TEST_STRING8) - 1, 0));


    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(entry)));
    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(entry));
}
Esempio n. 10
0
static void test_ipv6_nc_get_next__holey(void)
{
    ipv6_addr_t addr1 = OTHER_TEST_IPV6_ADDR;
    ipv6_addr_t addr2 = THIRD_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL, *exp_entry = NULL;

    /* adds DEFAULT_TEST_IPV6_ADDR and OTHER_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
    test_ipv6_nc_get_next__2_entries();
    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr2, TEST_STRING8,
                                        sizeof(TEST_STRING8) - 2, 0));
    TEST_ASSERT_NOT_NULL((exp_entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr2)));
    ng_ipv6_nc_remove(DEFAULT_TEST_NETIF, &addr1);

    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(entry)));
    TEST_ASSERT(exp_entry == entry);
    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(entry));
}
Esempio n. 11
0
kernel_pid_t ng_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                    kernel_pid_t iface, ng_ipv6_addr_t *dst,
                                    ng_pktsnip_t *pkt)
{
    ng_ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL;

#ifdef MODULE_NG_IPV6_EXT_RH
    next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr);
#endif
#ifdef MODULE_FIB
    size_t next_hop_size = sizeof(ng_ipv6_addr_t);
    uint32_t next_hop_flags = 0;
    ng_ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */

    if ((next_hop_ip == NULL) &&
        (fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
                          &next_hop_flags, (uint8_t *)dst,
                          sizeof(ng_ipv6_addr_t), 0) >= 0) &&
        (next_hop_size == sizeof(ng_ipv6_addr_t))) {
        next_hop_ip = &next_hop_actual;
    }

#endif

    if (next_hop_ip == NULL) {            /* no route to host */
        if (iface == KERNEL_PID_UNDEF) {
            /* ng_ipv6_netif_t doubles as prefix list */
            iface = ng_ipv6_netif_find_by_prefix(&prefix, dst);
        }
        else {
            /* ng_ipv6_netif_t doubles as prefix list */
            prefix = ng_ipv6_netif_match_prefix(iface, dst);
        }

        if ((prefix != NULL) &&             /* prefix is on-link */
            (ng_ipv6_netif_addr_get(prefix)->flags &
             NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) {
            next_hop_ip = dst;
#ifdef MODULE_FIB
            /* We don't care if FIB is full, this is just for efficiency
             * for later sends */
            fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0,
                          (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0,
                          FIB_LIFETIME_NO_EXPIRE);
#endif
        }
    }

    if (next_hop_ip == NULL) {
        next_hop_ip = _default_router();
#ifdef MODULE_FIB
        /* We don't care if FIB is full, this is just for efficiency for later
         * sends */
        fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0,
                      (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0,
                      FIB_LIFETIME_NO_EXPIRE);
#endif
    }

    if (next_hop_ip != NULL) {
        ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);

        if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
            DEBUG("ndp: found reachable neighbor (%s => ",
                  ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));
            DEBUG("%s)\n",
                  ng_netif_addr_to_str(addr_str, sizeof(addr_str),
                                       nc_entry->l2_addr, nc_entry->l2_addr_len));

            if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) {
                _set_state(nc_entry, NG_IPV6_NC_STATE_DELAY);
            }

            memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
            *l2addr_len = nc_entry->l2_addr_len;
            /* TODO: unreachability check */
            return nc_entry->iface;
        }
        else if (nc_entry == NULL) {
            ng_pktqueue_t *pkt_node;
            ng_ipv6_addr_t dst_sol;

            nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0,
                                      NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);

            if (nc_entry == NULL) {
                DEBUG("ndp: could not create neighbor cache entry\n");
                return KERNEL_PID_UNDEF;
            }

            pkt_node = _alloc_pkt_node(pkt);

            if (pkt_node == NULL) {
                DEBUG("ndp: could not add packet to packet queue\n");
            }
            else {
                /* prevent packet from being released by IPv6 */
                ng_pktbuf_hold(pkt_node->pkt, 1);
                ng_pktqueue_add(&nc_entry->pkts, pkt_node);
            }

            /* address resolution */
            ng_ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);

            if (iface == KERNEL_PID_UNDEF) {
                timex_t t = { 0, NG_NDP_RETRANS_TIMER };
                kernel_pid_t ifs[NG_NETIF_NUMOF];
                size_t ifnum = ng_netif_get(ifs);

                for (size_t i = 0; i < ifnum; i++) {
                    _send_nbr_sol(ifs[i], next_hop_ip, &dst_sol);
                }

                vtimer_remove(&nc_entry->nbr_sol_timer);
                vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid,
                               NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
            }
            else {
                ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface);

                _send_nbr_sol(iface, next_hop_ip, &dst_sol);

                mutex_lock(&ipv6_iface->mutex);
                vtimer_remove(&nc_entry->nbr_sol_timer);
                vtimer_set_msg(&nc_entry->nbr_sol_timer,
                               ipv6_iface->retrans_timer, ng_ipv6_pid,
                               NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
                mutex_unlock(&ipv6_iface->mutex);
            }
        }
    }

    return KERNEL_PID_UNDEF;
}
Esempio n. 12
0
static void test_ipv6_nc_add__address_NULL(void)
{
    TEST_ASSERT_NULL(ng_ipv6_nc_add(DEFAULT_TEST_NETIF, NULL, TEST_STRING4,
                                    sizeof(TEST_STRING4), 0));
}