Beispiel #1
0
void gnrc_icmpv6_echo_req_handle(gnrc_netif_t *netif, ipv6_hdr_t *ipv6_hdr,
                                 icmpv6_echo_t *echo, uint16_t len)
{
    uint8_t *payload = ((uint8_t *)echo) + sizeof(icmpv6_echo_t);
    gnrc_pktsnip_t *hdr, *pkt;

    if ((echo == NULL) || (len < sizeof(icmpv6_echo_t))) {
        DEBUG("icmpv6_echo: echo was NULL or len (%" PRIu16
              ") was < sizeof(icmpv6_echo_t)\n", len);
        return;
    }

    pkt = gnrc_icmpv6_echo_build(ICMPV6_ECHO_REP, byteorder_ntohs(echo->id),
                                 byteorder_ntohs(echo->seq), payload,
                                 len - sizeof(icmpv6_echo_t));

    if (pkt == NULL) {
        DEBUG("icmpv6_echo: no space left in packet buffer\n");
        return;
    }

    if (ipv6_addr_is_multicast(&ipv6_hdr->dst)) {
        hdr = gnrc_ipv6_hdr_build(pkt, NULL, &ipv6_hdr->src);
    }
    else {
        hdr = gnrc_ipv6_hdr_build(pkt, &ipv6_hdr->dst, &ipv6_hdr->src);
    }

    if (hdr == NULL) {
        DEBUG("icmpv6_echo: no space left in packet buffer\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    pkt = hdr;
    hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

    if (netif != NULL) {
        ((gnrc_netif_hdr_t *)hdr->data)->if_pid = netif->pid;
    }
    else {
        /* ipv6_hdr->dst is loopback address */
        ((gnrc_netif_hdr_t *)hdr->data)->if_pid = KERNEL_PID_UNDEF;
    }

    LL_PREPEND(pkt, hdr);

    if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL,
                                   pkt)) {
        DEBUG("icmpv6_echo: no receivers for IPv6 packets\n");
        gnrc_pktbuf_release(pkt);
    }
}
Beispiel #2
0
gnrc_pktsnip_t *gnrc_netreg_hdr_build(gnrc_nettype_t type, gnrc_pktsnip_t *payload,
                                      uint8_t *src, uint8_t src_len,
                                      uint8_t *dst, uint8_t dst_len)
{
    switch (type) {
#ifdef MODULE_GNRC_IPV6

        case GNRC_NETTYPE_IPV6:
            return gnrc_ipv6_hdr_build(payload, src, src_len, dst, dst_len);
#endif
#ifdef MODULE_GNRC_TCP

        case GNRC_NETTYPE_TCP:
            return gnrc_tcp_hdr_build(payload, src, src_len, dst, dst_len);
#endif
#ifdef MODULE_GNRC_UDP

        case GNRC_NETTYPE_UDP:
            return gnrc_udp_hdr_build(payload, src, src_len, dst, dst_len);
#endif

        default:
            (void)payload;
            (void)src;
            (void)src_len;
            (void)dst;
            (void)dst_len;
            return NULL;
    }
}
Beispiel #3
0
static gnrc_pktsnip_t *_build_ipv6_packet(const ipv6_addr_t *src,
                                          const ipv6_addr_t *dst, uint8_t nh,
                                          void *data, size_t data_len,
                                          uint16_t netif)
{
    gnrc_pktsnip_t *netif_hdr, *ipv6, *payload;
    ipv6_hdr_t *ipv6_hdr;

    if ((netif > INT16_MAX) || (data_len > UINT16_MAX)) {
        return NULL;
    }

    payload = gnrc_pktbuf_add(NULL, data, data_len, GNRC_NETTYPE_UNDEF);
    if (payload == NULL) {
        return NULL;
    }
    ipv6 = gnrc_ipv6_hdr_build(NULL, src, dst);
    if (ipv6 == NULL) {
        return NULL;
    }
    ipv6_hdr = ipv6->data;
    ipv6_hdr->len = byteorder_htons((uint16_t)payload->size);
    ipv6_hdr->nh = nh;
    ipv6_hdr->hl = 64;
    LL_APPEND(payload, ipv6);
    netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
    if (netif_hdr == NULL) {
        return NULL;
    }
    ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = (kernel_pid_t)netif;
    LL_APPEND(payload, netif_hdr);
    return payload;
}
void _gnrc_rpl_send(gnrc_pktsnip_t *pkt, ipv6_addr_t *src, ipv6_addr_t *dst,
        ipv6_addr_t *dodag_id)
{
    gnrc_pktsnip_t *hdr;
    ipv6_addr_t all_RPL_nodes = GNRC_RPL_ALL_NODES_ADDR, ll_addr;
    kernel_pid_t iface = gnrc_ipv6_netif_find_by_addr(NULL, &all_RPL_nodes);
    if (iface == KERNEL_PID_UNDEF) {
        DEBUG("RPL: no suitable interface found for this destination address\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    if (src == NULL) {
        ipv6_addr_t *tmp = NULL;
        if (dodag_id != NULL) {
            tmp = gnrc_ipv6_netif_match_prefix(iface, dodag_id);
        }
        else if (dodag_id == NULL) {
            tmp = gnrc_ipv6_netif_find_best_src_addr(iface, &all_RPL_nodes);
        }

        if (tmp == NULL) {
            DEBUG("RPL: no suitable src address found\n");
            gnrc_pktbuf_release(pkt);
            return;
        }

        memcpy(&ll_addr, tmp, sizeof(ll_addr));
        ipv6_addr_set_link_local_prefix(&ll_addr);
        src = &ll_addr;
    }

    if (dst == NULL) {
        dst = &all_RPL_nodes;
    }

    hdr = gnrc_ipv6_hdr_build(pkt, (uint8_t *)src, sizeof(ipv6_addr_t), (uint8_t *)dst,
                            sizeof(ipv6_addr_t));

    if (hdr == NULL) {
        DEBUG("RPL: Send - no space left in packet buffer\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL,hdr)) {
        DEBUG("RPL: cannot send packet: no subscribers found.\n");
        gnrc_pktbuf_release(hdr);
    }

}
void gnrc_rpl_send(gnrc_pktsnip_t *pkt, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst,
                   ipv6_addr_t *dodag_id)
{
    (void)dodag_id;
    gnrc_pktsnip_t *hdr;
    if (iface == KERNEL_PID_UNDEF) {
        if ((iface = gnrc_ipv6_netif_find_by_addr(NULL, &ipv6_addr_all_rpl_nodes))
            == KERNEL_PID_UNDEF) {
            DEBUG("RPL: no suitable interface found for this destination address\n");
            gnrc_pktbuf_release(pkt);
            return;
        }
    }

    if (src == NULL) {
        src = gnrc_ipv6_netif_match_prefix(iface, &ipv6_addr_link_local_prefix);

        if (src == NULL) {
            DEBUG("RPL: no suitable src address found\n");
            gnrc_pktbuf_release(pkt);
            return;
        }
    }

    if (dst == NULL) {
        dst = (ipv6_addr_t *) &ipv6_addr_all_rpl_nodes;
    }

    hdr = gnrc_ipv6_hdr_build(pkt, src, dst);

    if (hdr == NULL) {
        DEBUG("RPL: Send - no space left in packet buffer\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    pkt = hdr;

    hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
    ((gnrc_netif_hdr_t *)hdr->data)->if_pid = iface;
    LL_PREPEND(pkt, hdr);

    if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
        DEBUG("RPL: cannot send packet: no subscribers found.\n");
        gnrc_pktbuf_release(pkt);
    }
}
Beispiel #6
0
int conn_udp_sendto(const void *data, size_t len, const void *src, size_t src_len,
                    const void *dst, size_t dst_len, int family, uint16_t sport,
                    uint16_t dport)
{
    gnrc_pktsnip_t *pkt, *hdr = NULL;

    pkt = gnrc_pktbuf_add(NULL, (void *)data, len, GNRC_NETTYPE_UNDEF); /* data will only be copied */
    hdr = gnrc_udp_hdr_build(pkt, (uint8_t *)&sport, sizeof(uint16_t), (uint8_t *)&dport,
                             sizeof(uint16_t));
    if (hdr == NULL) {
        gnrc_pktbuf_release(pkt);
        return -ENOMEM;
    }
    pkt = hdr;
    switch (family) {
#ifdef MODULE_GNRC_IPV6
        case AF_INET6:
            if (((src != NULL) && (src_len != sizeof(ipv6_addr_t))) ||
                (dst_len != sizeof(ipv6_addr_t))) {
                gnrc_pktbuf_release(pkt);
                return -EINVAL;
            }
            /* addr will only be copied */
            hdr = gnrc_ipv6_hdr_build(pkt, (uint8_t *)src, src_len, (uint8_t *)dst, dst_len);
            if (hdr == NULL) {
                gnrc_pktbuf_release(pkt);
                return -ENOMEM;
            }
            pkt = hdr;
            break;
#endif /* MODULE_GNRC_IPV6 */
        default:
            (void)hdr;
            (void)src;
            (void)src_len;
            (void)dst;
            (void)dst_len;
            gnrc_pktbuf_release(pkt);
            return -EAFNOSUPPORT;
    }

    gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, pkt);

    return len;
}
Beispiel #7
0
int conn_ip_sendto(const void *data, size_t len, const void *src, size_t src_len,
                   void *dst, size_t dst_len, int family, int proto)
{
    gnrc_pktsnip_t *pkt, *hdr = NULL;
    gnrc_nettype_t l3_type;

    pkt = gnrc_pktbuf_add(NULL, (void *)data, len, GNRC_NETTYPE_UNDEF); /* data will only be copied */

    switch (family) {
#ifdef MODULE_GNRC_IPV6
        case AF_INET6:
            if (((src != NULL) && (src_len != sizeof(ipv6_addr_t))) ||
                (dst_len != sizeof(ipv6_addr_t)) ||
                (((unsigned)proto) > 256U)) {
                gnrc_pktbuf_release(pkt);
                return -EINVAL;
            }
            /* addr will only be copied */
            hdr = gnrc_ipv6_hdr_build(pkt, (uint8_t *)src, src_len, (uint8_t *)dst, dst_len);
            if (hdr == NULL) {
                gnrc_pktbuf_release(pkt);
                return -ENOMEM;
            }
            /* set next header to connection's proto */
            ipv6_hdr_t *ipv6_hdr = hdr->data;
            ipv6_hdr->nh = (uint8_t)proto;
            pkt = hdr;
            l3_type = GNRC_NETTYPE_IPV6;
            break;
#endif /* MODULE_GNRC_IPV6 */
        default:
            (void)src;
            (void)src_len;
            (void)dst;
            (void)dst_len;
            (void)proto;
            (void)hdr;
            gnrc_pktbuf_release(pkt);
            return -EAFNOSUPPORT;
    }

    gnrc_netapi_dispatch_send(l3_type, GNRC_NETREG_DEMUX_CTX_ALL, pkt);

    return len;
}
Beispiel #8
0
static gnrc_pktsnip_t *_build_headers(kernel_pid_t iface, gnrc_pktsnip_t *payload,
                                      ipv6_addr_t *dst, ipv6_addr_t *src)
{
    gnrc_pktsnip_t *l2hdr;
    gnrc_pktsnip_t *iphdr = gnrc_ipv6_hdr_build(payload, (uint8_t *)src, sizeof(ipv6_addr_t),
                                                (uint8_t *)dst, sizeof(ipv6_addr_t));
    if (iphdr == NULL) {
        DEBUG("ndp internal: error allocating IPv6 header.\n");
        return NULL;
    }
    ((ipv6_hdr_t *)iphdr->data)->hl = 255;
    /* add netif header for send interface specification */
    l2hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
    if (l2hdr == NULL) {
        DEBUG("ndp internal: error allocating netif header.\n");
        gnrc_pktbuf_remove_snip(iphdr, iphdr);
        return NULL;
    }
    ((gnrc_netif_hdr_t *)l2hdr->data)->if_pid = iface;
    LL_PREPEND(iphdr, l2hdr);
    return l2hdr;
}
Beispiel #9
0
tftp_state _tftp_send(gnrc_pktsnip_t *buf, tftp_context_t *ctxt, size_t len)
{
    network_uint16_t src_port, dst_port;
    gnrc_pktsnip_t *udp, *ip;

    assert(len <= TFTP_DEFAULT_DATA_SIZE);

    /* down-size the packet to it's used size */
    if (len > TFTP_DEFAULT_DATA_SIZE) {
        DEBUG("tftp: can't reallocate to bigger packet, buffer overflowed\n");
        gnrc_pktbuf_release(buf);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "buffer overflowed");
        }

        return TS_FAILED;
    }
    else if (gnrc_pktbuf_realloc_data(buf, len) != 0) {
        assert(false);

        DEBUG("tftp: failed to reallocate data snippet\n");
        gnrc_pktbuf_release(buf);

        /* inform the user that we can't reallocate */
        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no reallocate");
        }

        return TS_FAILED;
    }

    /* allocate UDP header, set source port := destination port */
    src_port.u16 = ctxt->src_port;
    dst_port.u16 = ctxt->dst_port;
    udp = gnrc_udp_hdr_build(buf, src_port.u16, dst_port.u16);
    if (udp == NULL) {
        DEBUG("tftp: error unable to allocate UDP header\n");
        gnrc_pktbuf_release(buf);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no udp allocate");
        }

        return TS_FAILED;
    }

    /* allocate IPv6 header */
    ip = gnrc_ipv6_hdr_build(udp, NULL, &(ctxt->peer));
    if (ip == NULL) {
        DEBUG("tftp: error unable to allocate IPv6 header\n");
        gnrc_pktbuf_release(udp);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no ip allocate");
        }

        return TS_FAILED;
    }

    /* send packet */
    if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL,
                                  ip) == 0) {
        /* if send failed inform the user */
        DEBUG("tftp: error unable to locate UDP thread\n");
        gnrc_pktbuf_release(ip);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no dispatch send");
        }

        return TS_FAILED;
    }

    /* only set timeout if enabled for this block */
    if (ctxt->block_timeout) {
        ctxt->timer_msg.type = TFTP_TIMEOUT_MSG;
        xtimer_set_msg(&(ctxt->timer), ctxt->block_timeout, &(ctxt->timer_msg), thread_getpid());
        DEBUG("tftp: set timeout %" PRIu32 " ms\n", ctxt->block_timeout / MS_IN_USEC);
    }

    return TS_BUSY;
}
Beispiel #10
0
void gnrc_icmpv6_echo_req_handle(kernel_pid_t iface, ipv6_hdr_t *ipv6_hdr,
                                 icmpv6_echo_t *echo, uint16_t len)
{
    uint8_t *payload = ((uint8_t *)echo) + sizeof(icmpv6_echo_t);
    gnrc_pktsnip_t *hdr, *pkt;
    gnrc_netreg_entry_t *sendto = NULL;

    if ((echo == NULL) || (len < sizeof(icmpv6_echo_t))) {
        DEBUG("icmpv6_echo: echo was NULL or len (%" PRIu16
              ") was < sizeof(icmpv6_echo_t)\n", len);
        return;
    }

    pkt = gnrc_icmpv6_echo_build(ICMPV6_ECHO_REP, byteorder_ntohs(echo->id),
                                 byteorder_ntohs(echo->seq), payload,
                                 len - sizeof(icmpv6_echo_t));

    if (pkt == NULL) {
        DEBUG("icmpv6_echo: no space left in packet buffer\n");
        return;
    }

    if (ipv6_addr_is_multicast(&ipv6_hdr->dst)) {
        hdr = gnrc_ipv6_hdr_build(pkt, NULL, 0, (uint8_t *)&ipv6_hdr->src,
                                  sizeof(ipv6_addr_t));
    }
    else {
        hdr = gnrc_ipv6_hdr_build(pkt, (uint8_t *)&ipv6_hdr->dst,
                                  sizeof(ipv6_addr_t), (uint8_t *)&ipv6_hdr->src,
                                  sizeof(ipv6_addr_t));
    }

    if (hdr == NULL) {
        DEBUG("icmpv6_echo: no space left in packet buffer\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    pkt = hdr;
    hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

    ((gnrc_netif_hdr_t *)hdr->data)->if_pid = iface;

    LL_PREPEND(pkt, hdr);

    sendto = gnrc_netreg_lookup(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL);

    if (sendto == NULL) {
        DEBUG("icmpv6_echo: no receivers for IPv6 packets\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    /* ICMPv6 is not interested anymore so `- 1` */
    gnrc_pktbuf_hold(pkt, gnrc_netreg_num(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL) - 1);

    while (sendto != NULL) {
        if (gnrc_netapi_send(sendto->pid, pkt) < 1) {
            DEBUG("icmpv6_echo: unable to send packet\n");
            gnrc_pktbuf_release(pkt);
        }
        sendto = gnrc_netreg_getnext(sendto);
    }
}