Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
    }
}