int ipv6_net_if_add_addr(int if_id, const ipv6_addr_t *addr, ndp_addr_state_t state, uint32_t val_ltime, uint32_t pref_ltime, uint8_t is_anycast) { ipv6_net_if_addr_t *addr_entry; ipv6_net_if_hit_t hit; if (ipv6_addr_is_unspecified(addr) == 128) { DEBUG("ERROR: unspecified address (::) can't be assigned to interface.\n"); return 0; } if (ipv6_addr_is_multicast(addr) && is_anycast) { DEBUG("ERROR: anycast addresses must not be multicast addresses " "(i.e. start with ff::/2)\n"); return 0; } if (ipv6_net_if_addr_match(&hit, addr)) { return 1; } if (ipv6_net_if_addr_buffer_count < IPV6_NET_IF_ADDR_BUFFER_LEN) { timex_t valtime = {val_ltime, 0}; timex_t preftime = {pref_ltime, 0}; timex_t now; vtimer_now(&now); ipv6_addr_t *addr_data = &ipv6_addr_buffer[ipv6_net_if_addr_buffer_count]; memcpy(addr_data, addr, sizeof(ipv6_addr_t)); addr_entry = &ipv6_net_if_addr_buffer[ipv6_net_if_addr_buffer_count]; addr_entry->addr_data = addr_data; addr_entry->addr_len = 128; if (is_anycast) { addr_entry->addr_protocol = NET_IF_L3P_IPV6_ANYCAST; } else if (ipv6_addr_is_multicast(addr_data)) { addr_entry->addr_protocol = NET_IF_L3P_IPV6_MULTICAST; } else { addr_entry->addr_protocol = NET_IF_L3P_IPV6_UNICAST; } addr_entry->ndp_state = state; addr_entry->valid_lifetime = timex_add(now, valtime); addr_entry->preferred_lifetime = timex_add(now, preftime); addr_entry->is_anycast = is_anycast; ipv6_net_if_addr_buffer_count++; net_if_add_address(if_id, (net_if_addr_t *)addr_entry); /* Register to Solicited-Node multicast address according to RFC 4291 */ if (is_anycast || !ipv6_addr_is_multicast(addr)) { ipv6_addr_t sol_node_mcast_addr; ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr); if (ipv6_net_if_addr_match(&hit, &sol_node_mcast_addr) == NULL) { ipv6_net_if_add_addr(if_id, &sol_node_mcast_addr, state, val_ltime, pref_ltime, 0); } } return 1; } return 0; }
int test_net_if_add_address(int iface, net_if_addr_t *addr1, net_if_addr_t *addr2) { int count = 0; net_if_addr_t *addr_ptr = NULL; if (net_if_add_address(iface + 1, addr1)) { printf("FAILED: expected net_if_add_address(%d, %p) to fail.\n", iface + 1, (void *)addr1); return 0; } if (net_if_add_address(iface, NULL)) { printf("FAILED: expected net_if_add_address(%d, NULL) to fail.\n", iface); return 0; } if (!net_if_add_address(iface, addr1)) { printf("FAILED: Address addition failed\n"); return 0; } if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_MULTICAST)) { printf("FAILED: L3 type IPv6 multicast expected on interface %d.\n", iface); return 0; } if (net_if_get_l3p_types(iface) & ~NET_IF_L3P_IPV6_MULTICAST) { printf("FAILED: L3 type other than IPv6 multicast not expected on interface %d.\n", iface); return 0; } if (!net_if_add_address(iface, addr2)) { printf("FAILED: Address addition failed\n"); return 0; } if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_MULTICAST)) { printf("FAILED: L3 type IPv6 multcast expected on interface %d.\n", iface); return 0; } if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_PREFIX)) { printf("FAILED: L3 type IPv6 prefix expected on interface %d.\n", iface); return 0; } if (net_if_get_l3p_types(iface) & ~(NET_IF_L3P_IPV6_MULTICAST | NET_IF_L3P_IPV6_PREFIX)) { printf("FAILED: L3 type other than IPv6 multicast and IPv6 prefix not expected on interface %d.\n", iface); return 0; } while (net_if_iter_addresses(iface, &addr_ptr)) { if (addr_ptr == addr1 || addr_ptr == addr2) { count++; } } if (count != 2) { printf("FAILED: expected 2 addresses in iface's address list once respectively\n"); printf(" missing '%d'\n", 2 - count); return 0; } return 1; }