예제 #1
0
ng_pktsnip_t *ng_ipv6_hdr_build(ng_pktsnip_t *payload,
                                uint8_t *src, uint8_t src_len,
                                uint8_t *dst, uint8_t dst_len)
{
    ng_pktsnip_t *ipv6;
    ng_ipv6_hdr_t *hdr;

    if (((src_len != 0) && (src_len != sizeof(ng_ipv6_addr_t))) ||
        ((dst_len != 0) && (dst_len != sizeof(ng_ipv6_addr_t)))) {
        DEBUG("ipv6_hdr: Address length was not 0 or %zu byte.\n",
              sizeof(ng_ipv6_addr_t));
        return NULL;
    }

    ipv6 = ng_pktbuf_add(payload, NULL, sizeof(ng_ipv6_hdr_t), HDR_NETTYPE);

    if (ipv6 == NULL) {
        DEBUG("ipv6_hdr: no space left in packet buffer\n");
        return NULL;
    }

    hdr = (ng_ipv6_hdr_t *)ipv6->data;

    if ((src != NULL) && (src_len != 0)) {
#ifdef MODULE_NG_IPV6_ADDR
        DEBUG("ipv6_hdr: set packet source to %s\n",
              ng_ipv6_addr_to_str(addr_str, (ng_ipv6_addr_t *)src,
                                  sizeof(addr_str)));
#endif
        memcpy(&hdr->src, src, src_len);
    }
    else {
        DEBUG("ipv6_hdr: set packet source to ::\n");
        ng_ipv6_addr_set_unspecified(&hdr->src);
    }

    memset(&hdr->dst + dst_len, 0, sizeof(ng_ipv6_addr_t) - dst_len);

    if ((dst != NULL) && (dst_len != 0)) {
#ifdef MODULE_NG_IPV6_ADDR
        DEBUG("ipv6_hdr: set packet destination to %s\n",
              ng_ipv6_addr_to_str(addr_str, (ng_ipv6_addr_t *)dst,
                                  sizeof(addr_str)));
#endif
        memcpy(&hdr->dst, dst, dst_len);
    }
    else {
        DEBUG("ipv6_hdr: set packet destination to ::1\n");
        ng_ipv6_addr_set_loopback(&hdr->dst);
    }

    hdr->v_tc_fl = byteorder_htonl(0x60000000); /* set version, tc and fl in one go*/
    hdr->nh = PROTNUM_RESERVED;
    hdr->hl = 0;

    return ipv6;
}
예제 #2
0
static void test_ipv6_addr_set_unspecified(void)
{
    ng_ipv6_addr_t a = { {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
        }
    };

    ng_ipv6_addr_set_unspecified(&a);

    TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_unspecified(&a));
}
예제 #3
0
static void _remove_addr_from_entry(ng_ipv6_netif_t *entry, ng_ipv6_addr_t *addr)
{
    mutex_lock(&entry->mutex);

    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            DEBUG("ipv6 netif: Remove %s to interface %" PRIkernel_pid "\n",
                  ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), entry->pid);
            ng_ipv6_addr_set_unspecified(&(entry->addrs[i].addr));
            entry->addrs[i].flags = 0;

            mutex_unlock(&entry->mutex);
            return;
        }
    }

    mutex_unlock(&entry->mutex);
}
예제 #4
0
void ng_ipv6_netif_remove_addr(kernel_pid_t pid, ng_ipv6_addr_t *addr)
{
    ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid);

    if (entry == NULL) {
        return;
    }

    mutex_lock(&entry->mutex);

    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            DEBUG("Remove %s to interface %" PRIkernel_pid "\n",
                  ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), pid);
            ng_ipv6_addr_set_unspecified(&(entry->addrs[i].addr));
            entry->addrs[i].flags = 0;

            mutex_unlock(&entry->mutex);
            return;
        }
    }

    mutex_unlock(&entry->mutex);
}
예제 #5
0
파일: ng_ndp.c 프로젝트: thiagsaran/RIOT
void ng_ndp_retrans_nbr_sol(ng_ipv6_nc_t *nc_entry)
{
    if ((nc_entry->probes_remaining > 1) &&
        ((ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) ||
         (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_PROBE))) {
        ng_ipv6_addr_t dst;

        DEBUG("ndp: Retransmit neighbor solicitation for %s\n",
              ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));

        /* retransmit neighbor solicatation */
        if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) {
            ng_ipv6_addr_set_solicited_nodes(&dst, &nc_entry->ipv6_addr);
        }
        else {
            dst.u64[0] = nc_entry->ipv6_addr.u64[0];
            dst.u64[1] = nc_entry->ipv6_addr.u64[1];
        }

        nc_entry->probes_remaining--;

        if (nc_entry->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], &nc_entry->ipv6_addr, &dst);
            }

            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(nc_entry->iface);

            _send_nbr_sol(nc_entry->iface, &nc_entry->ipv6_addr, &dst);

            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);
        }
    }
    else if (nc_entry->probes_remaining <= 1) {
        ng_pktqueue_node_t *queue_node;

        /* No need to call ng_ipv6_nc_remove() we know already were the
         * entry is */

        DEBUG("ndp: Remove nc entry %s for interface %" PRIkernel_pid "\n",
              ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)),
              nc_entry->iface);

        while ((queue_node = ng_pktqueue_remove_head(&nc_entry->pkts))) {
            ng_pktbuf_release(queue_node->data);
            queue_node->data = NULL;
        }

        ng_ipv6_addr_set_unspecified(&(nc_entry->ipv6_addr));
        nc_entry->iface = KERNEL_PID_UNDEF;
        nc_entry->flags = 0;
        nc_entry->probes_remaining = 0;
    }
}