static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr, uint8_t prefix_len, bool anycast) { for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) { if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) { return 0; } if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) { memcpy(&(entry->addrs[i].addr), addr, sizeof(ng_ipv6_addr_t)); DEBUG("Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n", ng_ipv6_addr_to_str(&(entry->addrs[i].addr), addr, sizeof(addr_str)), prefix_len, entry->pid); if (anycast || ng_ipv6_addr_is_multicast(addr)) { if (ng_ipv6_addr_is_multicast(addr)) { entry->addrs[i].prefix_len = NG_IPV6_ADDR_BIT_LEN; } entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST; } else { entry->addrs[i].prefix_len = prefix_len; entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_UNICAST; } return 0; } } return -ENOMEM; }
static void test_ipv6_netif_find_best_src_addr__success(void) { ng_ipv6_addr_t ll_addr1 = NG_IPV6_ADDR_UNSPECIFIED; ng_ipv6_addr_t ll_addr2 = NG_IPV6_ADDR_UNSPECIFIED; ng_ipv6_addr_t mc_addr = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL; ng_ipv6_addr_t *out = NULL; ll_addr1.u8[15] = 1; ng_ipv6_addr_set_link_local_prefix(&ll_addr1); ll_addr2.u8[15] = 2; ng_ipv6_addr_set_link_local_prefix(&ll_addr2); TEST_ASSERT_EQUAL_INT(126, ng_ipv6_addr_match_prefix(&ll_addr2, &ll_addr1)); test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */ TEST_ASSERT_EQUAL_INT(0, ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &mc_addr, DEFAULT_TEST_PREFIX_LEN, false)); TEST_ASSERT_EQUAL_INT(0, ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &ll_addr1, DEFAULT_TEST_PREFIX_LEN, false)); TEST_ASSERT_NOT_NULL((out = ng_ipv6_netif_find_best_src_addr(DEFAULT_TEST_NETIF, &ll_addr2))); TEST_ASSERT(out != &ll_addr1); TEST_ASSERT(out != &ll_addr2); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(out, &ll_addr1)); }
static void test_ipv6_addr_from_str__success4(void) { ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "::")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_addr_from_str__success5(void) { ng_ipv6_addr_t a = NG_IPV6_ADDR_LOOPBACK; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "::1")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static ng_ipv6_addr_t *_add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr, uint8_t prefix_len, uint8_t flags) { ng_ipv6_netif_addr_t *tmp_addr = NULL; for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) { if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) { return &(entry->addrs[i].addr); } if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr)) && !tmp_addr) { tmp_addr = &(entry->addrs[i]); } } if (!tmp_addr) { DEBUG("ipv6 netif: couldn't add %s/%" PRIu8 " to interface %" PRIkernel_pid "\n: No space left.", ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), prefix_len, entry->pid); return NULL; } memcpy(&(tmp_addr->addr), addr, sizeof(ng_ipv6_addr_t)); DEBUG("ipv6 netif: Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n", ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), prefix_len, entry->pid); tmp_addr->prefix_len = prefix_len; tmp_addr->flags = flags; if (ng_ipv6_addr_is_multicast(addr)) { tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST; } else { ng_ipv6_addr_t sol_node; if (!ng_ipv6_addr_is_link_local(addr)) { /* add also corresponding link-local address */ ng_ipv6_addr_t ll_addr; ll_addr.u64[1] = addr->u64[1]; ng_ipv6_addr_set_link_local_prefix(&ll_addr); _add_addr_to_entry(entry, &ll_addr, 64, flags | NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK); } else { tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK; } ng_ipv6_addr_set_solicited_nodes(&sol_node, addr); _add_addr_to_entry(entry, &sol_node, NG_IPV6_ADDR_BIT_LEN, 0); } return &(tmp_addr->addr); }
static void test_ipv6_addr_init_prefix(void) { ng_ipv6_addr_t a, b = { { 0x00, 0x01, 0x02, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ng_ipv6_addr_init_prefix(&a, &b, 31); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); }
static void test_ipv6_addr_from_str__success6(void) { ng_ipv6_addr_t a = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 192, 168, 0, 1 } }; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "::ffff:192.168.0.1")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_addr_from_str__success2(void) { ng_ipv6_addr_t a = { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff } }; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "fe80::f8f9:fafb:fcfd:feff")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_netif_find_addr__success(void) { ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR; ng_ipv6_addr_t *out = NULL; test_ipv6_netif_add_addr__success(); /* adds DEFAULT_TEST_IPV6_ADDR to * DEFAULT_TEST_NETIF */ TEST_ASSERT_NOT_NULL((out = ng_ipv6_netif_find_addr(DEFAULT_TEST_NETIF, &addr))); TEST_ASSERT(out != &addr); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(out, &addr)); }
static void test_ipv6_addr_from_str__success3(void) { ng_ipv6_addr_t a = { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff } }; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "FE80::F8F9:FAFB:FCFD:FEFF")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_addr_from_str__success6(void) { ng_ipv6_addr_t a = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 255, 255, 255, 255 } }; ng_ipv6_addr_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_addr_from_str__success(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_t result; TEST_ASSERT_NOT_NULL(ng_ipv6_addr_from_str(&result, "1:203:405:607:809:a0b:c0d:e0f")); TEST_ASSERT(ng_ipv6_addr_equal(&a, &result)); }
static void test_ipv6_addr_equal_not_equal(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_t b = { { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f } }; TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_equal(&a, &b)); }
static void test_ipv6_addr_equal_equal(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_t b = { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f } }; TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); }
static void test_ipv6_addr_set_all_nodes_multicast_link_local(void) { ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL; ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_LINK_LOCAL; TEST_ASSERT_EQUAL_INT(0xff020000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(b.u64[1])); ng_ipv6_addr_set_all_nodes_multicast(&a, scope); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); }
static void test_ipv6_addr_set_all_routers_multicast_site_local(void) { ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL; ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_SITE_LOCAL; TEST_ASSERT_EQUAL_INT(0xff050000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); TEST_ASSERT_EQUAL_INT(2, byteorder_ntohll(b.u64[1])); ng_ipv6_addr_set_all_routers_multicast(&a, scope); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); }
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); }
static void test_ipv6_addr_set_aiid(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_t b = { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff } }; ng_ipv6_addr_set_aiid(&a, &(b.u8[8])); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); }
static void test_ipv6_addr_init_prefix(void) { ng_ipv6_addr_t a = { { 0x00, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f } }; ng_ipv6_addr_t b = { { 0x00, 0x01, 0x02, 0x03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ng_ipv6_addr_t c = { { 0xff, 0xfe, 0xfd, 0xfe, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f } }; ng_ipv6_addr_init_prefix(&c, &b, 31); TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &c)); }
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); }
ng_ipv6_addr_t *ng_ipv6_netif_find_addr(kernel_pid_t pid, const ng_ipv6_addr_t *addr) { ng_ipv6_netif_t *entry = ng_ipv6_netif_get(pid); if (entry == NULL) { return NULL; } 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)) { mutex_unlock(&entry->mutex); DEBUG("ipv6 netif: Found %s on interface %" PRIkernel_pid "\n", ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), pid); return &(entry->addrs[i].addr); } } mutex_unlock(&entry->mutex); return NULL; }