Example #1
0
static void test_ipv6_nc_still_reachable__incomplete(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    gnrc_ipv6_nc_t *entry = NULL;

    /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
     * (GNRC_IPV6_NC_STATE_INCOMPLETE << GNRC_IPV6_NC_STATE_POS) */
    test_ipv6_nc_is_reachable__incomplete();

    TEST_ASSERT_NOT_NULL((entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    TEST_ASSERT(!gnrc_ipv6_nc_is_reachable(entry));
    TEST_ASSERT_NOT_NULL(gnrc_ipv6_nc_still_reachable(&addr));
    TEST_ASSERT(!gnrc_ipv6_nc_is_reachable(entry));
}
Example #2
0
static inline kernel_pid_t _next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                            kernel_pid_t iface, ipv6_addr_t *dst,
                                            gnrc_pktsnip_t *pkt)
{
    kernel_pid_t found_iface;
#if defined(MODULE_GNRC_SIXLOWPAN_ND)
    (void)pkt;
    found_iface = gnrc_sixlowpan_nd_next_hop_l2addr(l2addr, l2addr_len, iface, dst);
    if (found_iface > KERNEL_PID_UNDEF) {
        return found_iface;
    }
#endif
#if defined(MODULE_GNRC_NDP_NODE)
    found_iface = gnrc_ndp_node_next_hop_l2addr(l2addr, l2addr_len, iface, dst, pkt);
#elif !defined(MODULE_GNRC_SIXLOWPAN_ND) && defined(MODULE_GNRC_IPV6_NC)
    (void)pkt;
    gnrc_ipv6_nc_t *nc = gnrc_ipv6_nc_get(iface, dst);
    if ((nc == NULL) || !gnrc_ipv6_nc_is_reachable(nc)) {
        return KERNEL_PID_UNDEF;
    }
    found_iface = nc->iface;
    *l2addr_len = nc->l2_addr_len;
    memcpy(l2addr, nc->l2_addr, nc->l2_addr_len);
#elif !defined(MODULE_GNRC_SIXLOWPAN_ND)
    found_iface = KERNEL_PID_UNDEF;
    (void)l2addr;
    (void)l2addr_len;
    (void)iface;
    (void)dst;
    (void)pkt;
    *l2addr_len = 0;
#endif
    return found_iface;
}
Example #3
0
static void test_ipv6_nc_still_reachable__success(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    gnrc_ipv6_nc_t *entry = NULL;

    /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
     * (GNRC_IPV6_NC_STATE_REACHABLE << GNRC_IPV6_NC_STATE_POS) */
    test_ipv6_nc_is_reachable__reachable();

    TEST_ASSERT_NOT_NULL((entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    TEST_ASSERT(gnrc_ipv6_nc_is_reachable(entry));

    entry->flags = (GNRC_IPV6_NC_STATE_STALE << GNRC_IPV6_NC_STATE_POS);

    TEST_ASSERT_NOT_NULL(gnrc_ipv6_nc_still_reachable(&addr));
    TEST_ASSERT(gnrc_ipv6_nc_is_reachable(entry));
}
Example #4
0
static void test_ipv6_nc_is_reachable__unmanaged(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    gnrc_ipv6_nc_t *entry = NULL;

    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */

    TEST_ASSERT_NOT_NULL((entry = gnrc_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr)));
    entry->flags = (GNRC_IPV6_NC_STATE_UNMANAGED << GNRC_IPV6_NC_STATE_POS);
    TEST_ASSERT(gnrc_ipv6_nc_is_reachable(entry));
}
Example #5
0
static void test_ipv6_nc_is_reachable__incomplete(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    gnrc_ipv6_nc_t *entry = NULL;

    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */

    TEST_ASSERT_NOT_NULL((entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    entry->flags = (GNRC_IPV6_NC_STATE_INCOMPLETE << GNRC_IPV6_NC_STATE_POS);
    TEST_ASSERT(!gnrc_ipv6_nc_is_reachable(entry));
}
Example #6
0
kernel_pid_t gnrc_sixlowpan_nd_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                               kernel_pid_t iface, ipv6_addr_t *dst)
{
    ipv6_addr_t *next_hop = NULL;
    gnrc_ipv6_nc_t *nc_entry = NULL;

#ifdef MODULE_GNRC_IPV6_EXT_RH
    ipv6_hdr_t *hdr;
    gnrc_pktsnip_t *ipv6;
    LL_SEARCH_SCALAR(pkt, ipv6, type, GNRC_NETTYPE_IPV6);
    assert(ipv6);
    hdr = ipv6->data;
    next_hop = ipv6_ext_rh_next_hop(hdr);
#endif
#ifdef MODULE_FIB
    ipv6_addr_t next_hop_actual;    /* FIB copies address into this variable */
    /* don't look-up link local addresses in FIB */
    if ((next_hop == NULL) && !ipv6_addr_is_link_local(dst)) {
        size_t next_hop_size = sizeof(ipv6_addr_t);
        uint32_t next_hop_flags = 0;
        if ((next_hop == NULL) &&
            (fib_get_next_hop(&gnrc_ipv6_fib_table, &iface, next_hop_actual.u8, &next_hop_size,
                              &next_hop_flags, (uint8_t *)dst,
                              sizeof(ipv6_addr_t), 0) >= 0) &&
            (next_hop_size == sizeof(ipv6_addr_t))) {
            next_hop = &next_hop_actual;
        }
    }
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
    /* next hop determination: https://tools.ietf.org/html/rfc6775#section-6.5.4 */
    nc_entry = gnrc_ipv6_nc_get(iface, dst);
    /* if NCE found */
    if (nc_entry != NULL) {
        gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(nc_entry->iface);
        /* and interface is not 6LoWPAN */
        if (!(ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) ||
                /* or entry is registered */
                (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_REGISTERED)) {
        next_hop = dst;
        }
    }
#endif
    /* next hop determination according to: https://tools.ietf.org/html/rfc6775#section-5.6 */
    if ((next_hop == NULL) && ipv6_addr_is_link_local(dst)) {   /* prefix is "on-link" */
        /* multicast is not handled here anyway so we don't need to check that */
        next_hop = dst;
    }
    else if (next_hop == NULL) {                                /* prefix is off-link */
        next_hop = gnrc_ndp_internal_default_router();
    }

    /* address resolution of next_hop: https://tools.ietf.org/html/rfc6775#section-5.7 */
    if ((nc_entry == NULL) || (next_hop != dst)) {
        /* get if not gotten from previous check */
        nc_entry = gnrc_ipv6_nc_get(iface, next_hop);
    }
    /* If a NCE for this destination exist, we can use even for link-local
     * addresses. This should be only the case for 6LBRs. */
    if ((ipv6_addr_is_link_local(next_hop)) && (nc_entry == NULL)) {
/* in case of a border router there is no sensible way for address resolution
 * if the interface is not given */
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
        /* if no interface is specified it is impossible to resolve the
         * link-layer address for a link-local address on a 6LBR */
        if (iface == KERNEL_PID_UNDEF) {
            return KERNEL_PID_UNDEF;
        }
#endif
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t ifnum = gnrc_netif_get(ifs);
        /* we don't need address resolution, the EUI-64 is in next_hop's IID */
        *l2addr_len = sizeof(eui64_t);
        memcpy(l2addr, &next_hop->u8[8], sizeof(eui64_t));
        _revert_iid(l2addr);
        if (iface == KERNEL_PID_UNDEF) {
            for (unsigned i = 0; i < ifnum; i++) {
                gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(ifs[i]);
                if ((ipv6_if != NULL) && (ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
                    /* always take the first 6LoWPAN interface we can find */
                    return ifs[i];
                }
            }
        }
        return iface;
    }
    if ((nc_entry == NULL) || (!gnrc_ipv6_nc_is_reachable(nc_entry)) ||
        (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_TENTATIVE)) {
        return KERNEL_PID_UNDEF;
    }
    else {
        if (nc_entry->l2_addr_len > 0) {
            memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
        }
        *l2addr_len = nc_entry->l2_addr_len;
    }
    return nc_entry->iface;
}