void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_addr_t *dst) { gnrc_pktsnip_t *hdr, *pkt = NULL; ipv6_addr_t *src = NULL; DEBUG("ndp internal: send neighbor solicitation (iface: %" PRIkernel_pid ", tgt: %s, ", iface, ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); /* check if there is a fitting source address to target */ if ((src = gnrc_ipv6_netif_find_best_src_addr(iface, tgt)) != NULL) { uint8_t l2src[8]; size_t l2src_len; l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); if (l2src_len > 0) { /* add source address link-layer address option */ pkt = gnrc_ndp_opt_sl2a_build(l2src, l2src_len, NULL); if (pkt == NULL) { DEBUG("ndp internal: error allocating Source Link-layer address option.\n"); gnrc_pktbuf_release(pkt); return; } } } hdr = gnrc_ndp_nbr_sol_build(tgt, pkt); if (hdr == NULL) { DEBUG("ndp internal: error allocating Neighbor solicitation.\n"); gnrc_pktbuf_release(pkt); return; } pkt = hdr; hdr = _build_headers(iface, pkt, dst, src); if (hdr == NULL) { DEBUG("ndp internal: error adding lower-layer headers.\n"); gnrc_pktbuf_release(pkt); return; } gnrc_netapi_send(gnrc_ipv6_pid, hdr); }
void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *tgt, ipv6_addr_t *dst) { #ifdef MODULE_GNRC_SIXLOWPAN_ND gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); assert(ipv6_iface != NULL); #endif gnrc_pktsnip_t *hdr, *pkt = NULL; /* both suppressions, since they are needed in the MODULE_GNRC_SIXLOWPAN_ND branch */ /* cppcheck-suppress variableScope */ uint8_t l2src[8]; /* cppcheck-suppress variableScope */ size_t l2src_len = 0; DEBUG("ndp internal: send neighbor solicitation (iface: %" PRIkernel_pid ", src: %s, ", iface, ipv6_addr_to_str(addr_str, src, sizeof(addr_str))); DEBUG(" tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); /* check if there is a fitting source address to target */ if (src == NULL) { src = gnrc_ipv6_netif_find_best_src_addr(iface, tgt); } if (src != NULL) { l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); if (l2src_len > 0) { /* add source address link-layer address option */ pkt = gnrc_ndp_opt_sl2a_build(l2src, l2src_len, NULL); if (pkt == NULL) { DEBUG("ndp internal: error allocating Source Link-layer address option.\n"); gnrc_pktbuf_release(pkt); return; } } } #ifdef MODULE_GNRC_SIXLOWPAN_ND if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { if (l2src_len != sizeof(eui64_t)) { l2src_len = (uint16_t)gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0, l2src, sizeof(l2src)); if (l2src_len != sizeof(eui64_t)) { DEBUG("ndp internal: can't get EUI-64 of the interface\n"); gnrc_pktbuf_release(pkt); return; } } hdr = gnrc_sixlowpan_nd_opt_ar_build(0, GNRC_SIXLOWPAN_ND_AR_LTIME, (eui64_t *)l2src, pkt); if (hdr == NULL) { DEBUG("ndp internal: error allocatin Address Registration option.\n"); gnrc_pktbuf_release(pkt); return; } pkt = hdr; } #endif hdr = gnrc_ndp_nbr_sol_build(tgt, pkt); if (hdr == NULL) { DEBUG("ndp internal: error allocating Neighbor solicitation.\n"); gnrc_pktbuf_release(pkt); return; } pkt = hdr; hdr = _build_headers(iface, pkt, dst, src); if (hdr == NULL) { DEBUG("ndp internal: error adding lower-layer headers.\n"); gnrc_pktbuf_release(pkt); return; } else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { DEBUG("ndp internal: unable to send neighbor solicitation\n"); gnrc_pktbuf_release(hdr); } }