static void test_ipv6_addr_is_solicited_node_multicast_but_no_solicited_node(void) { ng_ipv6_addr_t a = { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f } }; TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_solicited_node(&a)); }
static void test_ipv6_addr_is_solicited_node_solicited_node_multicast(void) { ng_ipv6_addr_t a = { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x0d, 0x0e, 0x0f } }; TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_solicited_node(&a)); }
void ng_ndp_nbr_sol_handle(kernel_pid_t iface, ng_pktsnip_t *pkt, ng_ipv6_hdr_t *ipv6, ng_ndp_nbr_sol_t *nbr_sol, size_t icmpv6_size) { uint16_t opt_offset = 0; uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ng_ndp_nbr_sol_t); ng_ipv6_addr_t *tgt; int sicmpv6_size = (int)icmpv6_size; /* check validity */ if ((ipv6->hl != 255) || (nbr_sol->code != 0) || (icmpv6_size < sizeof(ng_ndp_nbr_sol_t)) || ng_ipv6_addr_is_multicast(&nbr_sol->tgt) || (ng_ipv6_addr_is_unspecified(&ipv6->src) && ng_ipv6_addr_is_solicited_node(&ipv6->dst))) { DEBUG("ndp: neighbor solicitation was invalid.\n"); /* ipv6 releases */ return; } if ((tgt = ng_ipv6_netif_find_addr(iface, &nbr_sol->tgt)) == NULL) { DEBUG("ndp: Target address is not to interface %" PRIkernel_pid "\n", iface); /* ipv6 releases */ return; } sicmpv6_size -= sizeof(ng_ndp_nbr_sol_t); while (sicmpv6_size > 0) { ng_ndp_opt_t *opt = (ng_ndp_opt_t *)(buf + opt_offset); switch (opt->type) { case NG_NDP_OPT_SL2A: if (!_handle_sl2a_opt(iface, pkt, ipv6, nbr_sol->type, opt)) { /* invalid source link-layer address option */ return; } break; default: /* silently discard all other options */ break; } opt_offset += (opt->len * 8); sicmpv6_size -= (opt->len * 8); } _send_nbr_adv(iface, tgt, &ipv6->src, ng_ipv6_addr_is_multicast(&ipv6->dst)); return; }