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; }
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)); }
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); }
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); }
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; } }