Exemplo n.º 1
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);
    found_iface = gnrc_ipv6_nc_get_l2_addr(l2addr, l2addr_len, nc);
#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;
}
Exemplo n.º 2
0
static void test_ipv6_nc_get_l2_addr__NULL_entry(void)
{
    gnrc_ipv6_nc_t *entry = NULL;
    uint8_t l2_addr[GNRC_IPV6_NC_L2_ADDR_MAX];
    uint8_t l2_addr_len = 0;

    TEST_ASSERT_EQUAL_INT(KERNEL_PID_UNDEF,
                          gnrc_ipv6_nc_get_l2_addr(l2_addr, &l2_addr_len, entry));
}
Exemplo n.º 3
0
static void test_ipv6_nc_get_l2_addr__unreachable(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    gnrc_ipv6_nc_t *entry = NULL;
    uint8_t l2_addr[GNRC_IPV6_NC_L2_ADDR_MAX];
    uint8_t l2_addr_len = 0;

    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_EQUAL_INT(KERNEL_PID_UNDEF,
                          gnrc_ipv6_nc_get_l2_addr(l2_addr, &l2_addr_len, entry));
}
Exemplo n.º 4
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_FIB
    kernel_pid_t fib_iface;
    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, &fib_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);
#ifdef MODULE_FIB
    if ((next_hop != NULL) && (nc_entry == NULL)) {
        nc_entry = gnrc_ipv6_nc_get(fib_iface, dst);
    }
#endif
    /* 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 == NULL) ||
                (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();
    }

    /* no routers found */
    if (next_hop == NULL) {
        return KERNEL_PID_UNDEF;
    }

    /* 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 (non-tentative) 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) ||
         (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_TENTATIVE))) {
/* 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 ((gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_TENTATIVE)) {
        return KERNEL_PID_UNDEF;
    }
    else {
        if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_STALE) {
            gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_DELAY);
        }
    }
    return gnrc_ipv6_nc_get_l2_addr(l2addr, l2addr_len, nc_entry);
}