Esempio n. 1
0
void _handle_reply_rs(_nib_onl_entry_t *host)
{
    gnrc_netif_t *netif = gnrc_netif_get_by_pid(_nib_onl_get_if(host));

    assert(netif != NULL);
    gnrc_netif_acquire(netif);
    if (gnrc_netif_is_rtr_adv(netif)) {
        _snd_rtr_advs(netif, &host->ipv6, false);
    }
    gnrc_netif_release(netif);
}
Esempio n. 2
0
File: main.c Progetto: A-Paul/RIOT
static void _set_test_mode(int argc, char **argv, uint8_t mode)
{
    (void) argc;
    if (_is_number(argv[1])) {
        kernel_pid_t dev = atoi(argv[1]);

        if (gnrc_netif_get_by_pid(dev)) {
            gnrc_netapi_set(dev, NETOPT_RF_TESTMODE, 0, (void *)&mode, sizeof(mode));
            return;
        }
    }
    printf("usage: %s <if_id>\n", argv[0]);
    return;
}
Esempio n. 3
0
static void _send(gnrc_pktsnip_t *pkt)
{
    gnrc_netif_hdr_t *hdr;
    gnrc_pktsnip_t *pkt2;
    gnrc_netif_t *iface;
    /* datagram_size: pure IPv6 packet without 6LoWPAN dispatches or compression */
    size_t datagram_size;

    if ((pkt == NULL) || (pkt->size < sizeof(gnrc_netif_hdr_t))) {
        DEBUG("6lo: Sending packet has no netif header\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    if ((pkt->next == NULL) || (pkt->next->type != GNRC_NETTYPE_IPV6)) {
        DEBUG("6lo: Sending packet has no IPv6 header\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    pkt2 = gnrc_pktbuf_start_write(pkt);

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

    hdr = pkt2->data;
    iface = gnrc_netif_get_by_pid(hdr->if_pid);
    datagram_size = gnrc_pkt_len(pkt2->next);

    if (iface == NULL) {
        DEBUG("6lo: Can not get 6LoWPAN specific interface information.\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
    if (iface->flags & GNRC_NETIF_FLAGS_6LO_HC) {
        if (!gnrc_sixlowpan_iphc_encode(pkt2)) {
            DEBUG("6lo: error on IPHC encoding\n");
            gnrc_pktbuf_release(pkt2);
            return;
        }
        /* IPHC dispatch does not count on dispatch length since it _shortens_
         * the datagram */
    }
    else {
        if (!_add_uncompr_disp(pkt2)) {
            /* adding uncompressed dispatch failed */
            DEBUG("6lo: no space left in packet buffer\n");
            gnrc_pktbuf_release(pkt2);
            return;
        }
    }
#else
    /* suppress clang-analyzer report about iface being not read */
    (void) iface;
    if (!_add_uncompr_disp(pkt2)) {
        /* adding uncompressed dispatch failed */
        DEBUG("6lo: no space left in packet buffer\n");
        gnrc_pktbuf_release(pkt2);
        return;
    }
#endif
    DEBUG("6lo: iface->sixlo.max_frag_size = %" PRIu16 " for interface %"
          PRIkernel_pid "\n", iface->sixlo.max_frag_size, hdr->if_pid);

    /* IP should not send anything here if it is not a 6LoWPAN interface,
     * so we don't need to check for NULL pointers.
     * Note, that datagram_size cannot be used here, because the header size
     * might be changed by IPHC. */
    if (gnrc_pkt_len(pkt2->next) <= iface->sixlo.max_frag_size) {
        DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
              (void *)pkt2, hdr->if_pid);
        if (gnrc_netapi_send(hdr->if_pid, pkt2) < 1) {
            DEBUG("6lo: unable to send %p over %" PRIu16 "\n", (void *)pkt, hdr->if_pid);
            gnrc_pktbuf_release(pkt2);
        }

        return;
    }
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
    else if (fragment_msg.pkt != NULL) {
        DEBUG("6lo: Fragmentation already ongoing. Dropping packet\n");
        gnrc_pktbuf_release(pkt2);
        return;
    }
    else if (datagram_size <= SIXLOWPAN_FRAG_MAX_LEN) {
        DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
              (unsigned int)datagram_size, iface->max_frag_size);
        msg_t msg;

        fragment_msg.pid = hdr->if_pid;
        fragment_msg.pkt = pkt2;
        fragment_msg.datagram_size = datagram_size;
        /* Sending the first fragment has an offset==0 */
        fragment_msg.offset = 0;

        /* set the outgoing message's fields */
        msg.type = GNRC_SIXLOWPAN_MSG_FRAG_SND;
        msg.content.ptr = &fragment_msg;
        /* send message to self */
        msg_send_to_self(&msg);
    }
    else {
        DEBUG("6lo: packet too big (%u > %" PRIu16 ")\n",
              (unsigned int)datagram_size, (uint16_t)SIXLOWPAN_FRAG_MAX_LEN);
        gnrc_pktbuf_release(pkt2);
    }
#else
    (void) datagram_size;
    DEBUG("6lo: packet too big (%u > %" PRIu16 ")\n",
          (unsigned int)datagram_size, iface->max_frag_size);
    gnrc_pktbuf_release(pkt2);
#endif
}
Esempio n. 4
0
void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
{
    assert(ctx != NULL);
    gnrc_sixlowpan_msg_frag_t *fragment_msg = ctx;
    gnrc_netif_t *iface = gnrc_netif_get_by_pid(fragment_msg->pid);
    uint16_t res;
    /* payload_len: actual size of the packet vs
     * datagram_size: size of the uncompressed IPv6 packet */
    size_t payload_len = gnrc_pkt_len(fragment_msg->pkt->next);
    msg_t msg;

    assert((fragment_msg->pkt == pkt) || (pkt == NULL));
    (void)page;
    (void)pkt;
#if defined(DEVELHELP) && ENABLE_DEBUG
    if (iface == NULL) {
        DEBUG("6lo frag: iface == NULL, expect segmentation fault.\n");
        /* remove original packet from packet buffer */
        gnrc_pktbuf_release(fragment_msg->pkt);
        /* 6LoWPAN free for next fragmentation */
        fragment_msg->pkt = NULL;
        return;
    }
#endif

    /* Check whether to send the first or an Nth fragment */
    if (fragment_msg->offset == 0) {
        /* increment tag for successive, fragmented datagrams */
        _tag++;
        if ((res = _send_1st_fragment(iface, fragment_msg->pkt, payload_len, fragment_msg->datagram_size)) == 0) {
            /* error sending first fragment */
            DEBUG("6lo frag: error sending 1st fragment\n");
            gnrc_pktbuf_release(fragment_msg->pkt);
            fragment_msg->pkt = NULL;
            return;
        }
        fragment_msg->offset += res;

        /* send message to self*/
        msg.type = GNRC_SIXLOWPAN_MSG_FRAG_SND;
        msg.content.ptr = (void *)fragment_msg;
        msg_send_to_self(&msg);
        thread_yield();
    }
    else {
        /* (offset + (datagram_size - payload_len) < datagram_size) simplified */
        if (fragment_msg->offset < payload_len) {
            if ((res = _send_nth_fragment(iface, fragment_msg->pkt, payload_len, fragment_msg->datagram_size,
                                          fragment_msg->offset)) == 0) {
                /* error sending subsequent fragment */
                DEBUG("6lo frag: error sending subsequent fragment (offset = %" PRIu16
                      ")\n", fragment_msg->offset);
                gnrc_pktbuf_release(fragment_msg->pkt);
                fragment_msg->pkt = NULL;
                return;
                }
            fragment_msg->offset += res;

            /* send message to self*/
            msg.type = GNRC_SIXLOWPAN_MSG_FRAG_SND;
            msg.content.ptr = (void *)fragment_msg;
            msg_send_to_self(&msg);
            thread_yield();
        }
        else {
            gnrc_pktbuf_release(fragment_msg->pkt);
            fragment_msg->pkt = NULL;
        }
    }
}
Esempio n. 5
0
static inline bool _is_iface(kernel_pid_t iface)
{
    return (gnrc_netif_get_by_pid(iface) != NULL);
}