Ejemplo n.º 1
0
void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt, uint8_t nh)
{
    int receiver_num;

    pkt->type = gnrc_nettype_from_protnum(nh);

    switch (nh) {
#ifdef MODULE_GNRC_ICMPV6
        case PROTNUM_ICMPV6:
            DEBUG("ipv6: handle ICMPv6 packet (nh = %u)\n", nh);
            gnrc_icmpv6_demux(iface, pkt);
            break;
#endif
#ifdef MODULE_GNRC_IPV6_EXT
        case PROTNUM_IPV6_EXT_HOPOPT:
        case PROTNUM_IPV6_EXT_DST:
        case PROTNUM_IPV6_EXT_RH:
        case PROTNUM_IPV6_EXT_FRAG:
        case PROTNUM_IPV6_EXT_AH:
        case PROTNUM_IPV6_EXT_ESP:
        case PROTNUM_IPV6_EXT_MOB:
            DEBUG("ipv6: handle extension header (nh = %u)\n", nh);
            if (!gnrc_ipv6_ext_demux(iface, pkt, nh)) {
                DEBUG("ipv6: stop packet processing.\n");
                return;
            }
#endif
        case PROTNUM_IPV6:
            DEBUG("ipv6: handle encapsulated IPv6 packet (nh = %u)\n", nh);
            _decapsulate(pkt);
            break;
        default:
            (void)iface;
            break;
    }

    DEBUG("ipv6: forward nh = %u to other threads\n", nh);
    receiver_num = gnrc_netreg_num(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL) +
                   gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh);

    if (receiver_num == 0) {
        DEBUG("ipv6: unable to forward packet as no one is interested in it\n");
        gnrc_pktbuf_release(pkt);
        return;
    }

    gnrc_pktbuf_hold(pkt, receiver_num - 1);    /* IPv6 is not interested anymore so `- 1` */

    /* XXX can't use gnrc_netapi_dispatch_receive() twice here since a call to that function
     *     implicitly hands all rights to the packet to one of the receiving threads. As a result,
     *     the second call to gnrc_netapi_dispatch_receive() would be invalid */
    _dispatch_rcv_pkt(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt);
    _dispatch_rcv_pkt(GNRC_NETTYPE_IPV6, nh, pkt);
}
Ejemplo n.º 2
0
static void test_pktbuf_merge_data__success1(void)
{
    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, 0, GNRC_NETTYPE_TEST);

    TEST_ASSERT_NOT_NULL(pkt);
    TEST_ASSERT_NULL(pkt->data);

    TEST_ASSERT_EQUAL_INT(0, gnrc_pktbuf_merge(pkt));
    gnrc_pktbuf_release(pkt);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 3
0
static void test_pktbuf_realloc_data__alignment(void)
{
    gnrc_pktsnip_t *pkt1, *pkt2, *pkt3;

    /* see: https://github.com/RIOT-OS/RIOT/pull/4602 */
    pkt1 = gnrc_pktbuf_add(NULL, TEST_STRING8, sizeof(TEST_STRING8), GNRC_NETTYPE_TEST);
    pkt2 = gnrc_pktbuf_add(NULL, NULL, 23, GNRC_NETTYPE_TEST);
    pkt3 = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16), GNRC_NETTYPE_UNDEF);

    TEST_ASSERT_NOT_NULL(pkt1);
    TEST_ASSERT_NOT_NULL(pkt2);
    TEST_ASSERT_NOT_NULL(pkt3);

    TEST_ASSERT_EQUAL_INT(0, gnrc_pktbuf_realloc_data(pkt2, 21));

    gnrc_pktbuf_release(pkt1);
    gnrc_pktbuf_release(pkt2);
    gnrc_pktbuf_release(pkt3);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 4
0
static void test_pktbuf_merge_data__memfull(void)
{
    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, (GNRC_PKTBUF_SIZE / 4),
                                          GNRC_NETTYPE_TEST);

    pkt = gnrc_pktbuf_add(pkt, NULL, (GNRC_PKTBUF_SIZE / 4) + 1,
                          GNRC_NETTYPE_TEST);
    TEST_ASSERT_EQUAL_INT(ENOMEM, gnrc_pktbuf_merge(pkt));
    gnrc_pktbuf_release(pkt);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 5
0
static void test_pktbuf_realloc_data__size_0(void)
{
    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, sizeof(TEST_STRING8), GNRC_NETTYPE_TEST);

    TEST_ASSERT_EQUAL_INT(0, gnrc_pktbuf_realloc_data(pkt, 0));
    TEST_ASSERT(gnrc_pktbuf_is_sane());
    TEST_ASSERT_NULL(pkt->data);
    TEST_ASSERT_EQUAL_INT(0, pkt->size);
    TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_TEST, pkt->type);
    gnrc_pktbuf_release(pkt);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 6
0
static void test_pktbuf_reverse_snips__too_full(void)
{
    gnrc_pktsnip_t *pkt, *pkt_next, *pkt_huge;
    const size_t pkt_huge_size = GNRC_PKTBUF_SIZE - (3 * 8) -
                                 (3 * sizeof(gnrc_pktsnip_t)) - 4;

    pkt_next = gnrc_pktbuf_add(NULL, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
    TEST_ASSERT_NOT_NULL(pkt_next);
    /* hold to enforce duplication */
    gnrc_pktbuf_hold(pkt_next, 1);
    pkt = gnrc_pktbuf_add(pkt_next, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
    TEST_ASSERT_NOT_NULL(pkt);
    /* filling up rest of packet buffer */
    pkt_huge = gnrc_pktbuf_add(NULL, NULL, pkt_huge_size, GNRC_NETTYPE_UNDEF);
    TEST_ASSERT_NOT_NULL(pkt_huge);
    TEST_ASSERT_NULL(gnrc_pktbuf_reverse_snips(pkt));
    gnrc_pktbuf_release(pkt_huge);
    /* release because of hold above */
    gnrc_pktbuf_release(pkt_next);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 7
0
void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst)
{
    gnrc_pktsnip_t *hdr, *pkt = NULL;
    ipv6_addr_t *src = NULL, all_routers = IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL;
    DEBUG("ndp internal: send router solicitation (iface: %" PRIkernel_pid ", dst: ff02::2)\n",
          iface);
    if (dst == NULL) {
        dst = &all_routers;
    }
    /* check if there is a fitting source address to target */
    if ((src = gnrc_ipv6_netif_find_best_src_addr(iface, dst)) != 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_rtr_sol_build(pkt);
    if (hdr == NULL) {
        DEBUG("ndp internal: error allocating router 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.º 8
0
static bool _assemble_beacon(gnrc_netif_t *netif, uint8_t total_tdma_slot_num,
                             uint8_t total_tdma_node_num, uint8_t *slots_list,
                             gnrc_gomach_l2_id_t *id_list, gnrc_pktsnip_t **pkt,
                             gnrc_pktsnip_t **gomach_pkt,
                             gnrc_gomach_frame_beacon_t *gomach_beaocn_hdr)
{
    /* If there are slots to allocate, add the slots list and the ID list to
     * the beacon! */
    netif->mac.rx.vtdma_manag.total_slots_num = total_tdma_slot_num;

    /* Add the slots list to the beacon. */
    *pkt = gnrc_pktbuf_add(NULL, slots_list, total_tdma_node_num * sizeof(uint8_t),
                           GNRC_NETTYPE_GOMACH);
    if (*pkt == NULL) {
        LOG_ERROR("ERROR: [GOMACH]: pktbuf add failed in gnrc_gomach_send_beacon().\n");
        return false;
    }
    *gomach_pkt = *pkt;

    /* Add the ID list to the beacon. */
    *pkt = gnrc_pktbuf_add(*pkt, id_list, total_tdma_node_num * sizeof(gnrc_gomach_l2_id_t),
                           GNRC_NETTYPE_GOMACH);
    if (*pkt == NULL) {
        LOG_ERROR("ERROR: [GOMACH]: pktbuf add failed in gnrc_gomach_send_beacon().\n");
        gnrc_pktbuf_release(*gomach_pkt);
        return false;
    }
    *gomach_pkt = *pkt;

    /* Add the GoMacH header to the beacon. */
    *pkt = gnrc_pktbuf_add(*pkt, gomach_beaocn_hdr, sizeof(gnrc_gomach_frame_beacon_t),
                           GNRC_NETTYPE_GOMACH);
    if (*pkt == NULL) {
        LOG_ERROR("ERROR: [GOMACH]: pktbuf add failed in gnrc_gomach_send_beacon().\n");
        gnrc_pktbuf_release(*gomach_pkt);
        return false;
    }

    return true;
}
Ejemplo n.º 9
0
/**
 * @brief marks IPv6 extension header if needed.
 *   updates pkt and returns next header.
 * @param[in] current  The current header
 * @param[in,out] pkt  The whole packet
 * @return The next header
 * @return NULL on error
 */
static gnrc_pktsnip_t *_mark_extension_header(gnrc_pktsnip_t *current,
                                              gnrc_pktsnip_t **pkt)
{
    gnrc_pktsnip_t *ext_snip, *tmp, *next;
    ipv6_ext_t *ext = (ipv6_ext_t *) current->data;
    size_t offset = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT);

    if (current == *pkt) {
        if ((tmp = gnrc_pktbuf_start_write(*pkt)) == NULL) {
            DEBUG("ipv6: could not get a copy of pkt\n");
            gnrc_pktbuf_release(*pkt);
            return NULL;
        }
        *pkt = tmp;

        ext_snip = gnrc_pktbuf_mark(*pkt, offset, GNRC_NETTYPE_IPV6_EXT);
        next = *pkt;

        if (ext_snip == NULL) {
            gnrc_pktbuf_release(*pkt);
            return NULL;
        }
    }
    else {
        /* the header is already marked */

        next = NULL;

        for (tmp = *pkt; tmp != NULL; tmp = tmp->next) {
            if (tmp->next == current) {
                next = tmp;
                break;
            }
        }

        assert(next != NULL);
    }

    return next;
}
Ejemplo n.º 10
0
/* shell commands */
int _netif_send(int argc, char **argv)
{
    kernel_pid_t dev;
    uint8_t addr[MAX_ADDR_LEN];
    size_t addr_len;
    gnrc_pktsnip_t *pkt;
    gnrc_netif_hdr_t *nethdr;
    uint8_t flags = 0x00;

    if (argc < 4) {
        printf("usage: %s <if> [<addr>|bcast] <data>\n", argv[0]);
        return 1;
    }

    /* parse interface */
    dev = (kernel_pid_t)atoi(argv[1]);

    if (!_is_iface(dev)) {
        puts("error: invalid interface given");
        return 1;
    }

    /* parse address */
    addr_len = gnrc_netif_addr_from_str(addr, sizeof(addr), argv[2]);

    if (addr_len == 0) {
        if (strcmp(argv[2], "bcast") == 0) {
            flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
        }
        else {
            puts("error: invalid address given");
            return 1;
        }
    }

    /* put packet together */
    pkt = gnrc_pktbuf_add(NULL, argv[3], strlen(argv[3]), GNRC_NETTYPE_UNDEF);
    pkt = gnrc_pktbuf_add(pkt, NULL, sizeof(gnrc_netif_hdr_t) + addr_len,
                          GNRC_NETTYPE_NETIF);
    nethdr = (gnrc_netif_hdr_t *)pkt->data;
    gnrc_netif_hdr_init(nethdr, 0, addr_len);
    gnrc_netif_hdr_set_dst_addr(nethdr, addr, addr_len);
    nethdr->flags = flags;
    /* and send it */
    if (gnrc_netapi_send(dev, pkt) < 1) {
        puts("error: unable to send\n");
        gnrc_pktbuf_release(pkt);
        return 1;
    }

    return 0;
}
Ejemplo n.º 11
0
/* internal functions */
static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt,
                                  uint8_t nh, bool interested)
{
#ifdef MODULE_GNRC_IPV6_EXT
    const bool should_dispatch_current_type = ((current->type != GNRC_NETTYPE_IPV6_EXT) ||
                                               (current->next->type == GNRC_NETTYPE_IPV6));
#else
    const bool should_dispatch_current_type = (current->next->type == GNRC_NETTYPE_IPV6);
#endif

    DEBUG("ipv6: forward nh = %u to other threads\n", nh);

    /* dispatch IPv6 extension header only once */
    if (should_dispatch_current_type) {
        bool should_release = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) == 0) &&
                              (!interested);

        if (!should_release) {
            gnrc_pktbuf_hold(pkt, 1);   /* don't remove from packet buffer in
                                         * next dispatch */
        }
        if (gnrc_netapi_dispatch_receive(current->type,
                                         GNRC_NETREG_DEMUX_CTX_ALL,
                                         pkt) == 0) {
            gnrc_pktbuf_release(pkt);
        }

        if (should_release) {
            return;
        }
    }
    if (interested) {
        gnrc_pktbuf_hold(pkt, 1);   /* don't remove from packet buffer in
                                     * next dispatch */
    }
    if (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, nh, pkt) == 0) {
        gnrc_pktbuf_release(pkt);
    }
}
Ejemplo n.º 12
0
static void test_pktbuf_release__success(void)
{
    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16),
                                          GNRC_NETTYPE_TEST);

    for (uint8_t i = 0; i < TEST_UINT8; i++) {
        uint8_t prev_users = pkt->users;
        gnrc_pktbuf_hold(pkt, 1);
        TEST_ASSERT_EQUAL_INT(prev_users + 1, pkt->users);
    }

    TEST_ASSERT(!gnrc_pktbuf_is_empty());

    for (uint8_t i = 0; i < TEST_UINT8; i++) {
        uint8_t prev_users = pkt->users;
        gnrc_pktbuf_release(pkt);
        TEST_ASSERT_EQUAL_INT(prev_users - 1, pkt->users);
    }

    TEST_ASSERT(!gnrc_pktbuf_is_empty());
    gnrc_pktbuf_release(pkt);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 13
0
static void test_pktbuf_reverse_snips__success(void)
{
    gnrc_pktsnip_t *pkt, *pkt_next, *pkt_reversed;

    pkt_next = gnrc_pktbuf_add(NULL, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
    TEST_ASSERT_NOT_NULL(pkt_next);
    pkt = gnrc_pktbuf_add(pkt_next, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
    TEST_ASSERT_NOT_NULL(pkt);
    pkt_reversed = gnrc_pktbuf_reverse_snips(pkt);
    TEST_ASSERT(pkt_reversed == pkt_next);
    TEST_ASSERT(pkt_reversed->next == pkt);
    gnrc_pktbuf_release(pkt_reversed);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 14
0
void gnrc_priority_pktqueue_flush(gnrc_priority_pktqueue_t* queue)
{
    assert(queue != NULL);

    if(gnrc_priority_pktqueue_length(queue) == 0){
        return;
    }
    gnrc_priority_pktqueue_node_t* node;
    while( (node = (gnrc_priority_pktqueue_node_t *)priority_queue_remove_head(queue)) )
    {
        gnrc_pktbuf_release(node->pkt);
        _free_node(node);
    }
}
Ejemplo n.º 15
0
static void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
{
    ((gnrc_netif_hdr_t *)pkt->data)->if_pid = iface;
    gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface);

    assert(if_entry != NULL);
    if (gnrc_pkt_len(pkt->next) > if_entry->mtu) {
        DEBUG("ipv6: packet too big\n");
        gnrc_pktbuf_release(pkt);
        return;
    }
#ifdef MODULE_GNRC_SIXLOWPAN
    if ((if_entry != NULL) && (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
        DEBUG("ipv6: send to 6LoWPAN instead\n");
        if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_SIXLOWPAN, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
            DEBUG("ipv6: no 6LoWPAN thread found");
            gnrc_pktbuf_release(pkt);
        }
        return;
    }
#endif
    gnrc_netapi_send(iface, pkt);
}
Ejemplo n.º 16
0
static void test_pktbuf_release__short_pktsnips(void)
{
    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, TEST_STRING8, sizeof(TEST_STRING8),
                                          GNRC_NETTYPE_UNDEF);
    gnrc_pktsnip_t *hdr = gnrc_pktbuf_mark(pkt, sizeof(TEST_STRING8) - 1, GNRC_NETTYPE_TEST);
    TEST_ASSERT(pkt);
    TEST_ASSERT(hdr);
    TEST_ASSERT(pkt->next == hdr);
    TEST_ASSERT(hdr->next == NULL);
    TEST_ASSERT_EQUAL_INT(hdr->size, sizeof(TEST_STRING8) - 1);
    TEST_ASSERT_EQUAL_INT(pkt->size, 1);
    gnrc_pktbuf_release(pkt);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 17
0
void gnrc_gomach_cp_packet_process(gnrc_netif_t *netif)
{
    assert(netif != NULL);

    gnrc_pktsnip_t *pkt;
    gnrc_gomach_packet_info_t receive_packet_info;

    while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
        /* Parse the received packet, fetch key MAC informations. */
        int res = _parse_packet(netif, pkt, &receive_packet_info);
        if (res != 0) {
            LOG_DEBUG("[GOMACH] CP: Packet could not be parsed: %i\n", res);
            gnrc_pktbuf_release(pkt);
            continue;
        }

        switch (receive_packet_info.header->type) {
            case GNRC_GOMACH_FRAME_PREAMBLE: {
                _cp_packet_process_preamble(netif, &receive_packet_info, pkt);
                break;
            }

            case GNRC_GOMACH_FRAME_DATA: {
                _cp_packet_process_data(netif, &receive_packet_info, pkt);
                break;
            }
            case GNRC_GOMACH_FRAME_BROADCAST: {
                _cp_packet_process_bcast(netif, pkt);
                break;
            }
            default: {
                gnrc_pktbuf_release(pkt);
                break;
            }
        }
    }
}
Ejemplo n.º 18
0
ssize_t sock_ip_recv(sock_ip_t *sock, void *data, size_t max_len,
                     uint32_t timeout, sock_ip_ep_t *remote)
{
    gnrc_pktsnip_t *pkt;
    sock_ip_ep_t tmp;
    int res;

    assert((sock != NULL) && (data != NULL) && (max_len > 0));
    if (sock->local.family == 0) {
        return -EADDRNOTAVAIL;
    }
    tmp.family = sock->local.family;
    res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp);
    if (res < 0) {
        return res;
    }
    if (pkt->size > max_len) {
        gnrc_pktbuf_release(pkt);
        return -ENOBUFS;
    }
    if (remote != NULL) {
        /* return remote to possibly block if wrong remote */
        memcpy(remote, &tmp, sizeof(tmp));
    }
    if ((sock->remote.family != AF_UNSPEC) &&   /* check remote end-point if set */
        /* We only have IPv6 for now, so just comparing the whole end point
         * should suffice */
        ((memcmp(&sock->remote.addr, &ipv6_addr_unspecified,
                 sizeof(ipv6_addr_t)) != 0) &&
         (memcmp(&sock->remote.addr, &tmp.addr, sizeof(ipv6_addr_t)) != 0))) {
        gnrc_pktbuf_release(pkt);
        return -EPROTO;
    }
    memcpy(data, pkt->data, pkt->size);
    gnrc_pktbuf_release(pkt);
    return (int)pkt->size;
}
Ejemplo n.º 19
0
void gnrc_gomach_packet_process_in_vtdma(gnrc_netif_t *netif)
{
    assert(netif != NULL);

    gnrc_pktsnip_t *pkt;
    gnrc_gomach_packet_info_t receive_packet_info;

    while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
        /* Parse the received packet. */
        int res = _parse_packet(netif, pkt, &receive_packet_info);
        if (res != 0) {
            LOG_DEBUG("[GOMACH] vtdma: Packet could not be parsed: %i\n", res);
            gnrc_pktbuf_release(pkt);
            continue;
        }

        switch (receive_packet_info.header->type) {
            case GNRC_GOMACH_FRAME_DATA: {
                gnrc_gomach_indicator_update(netif, pkt, &receive_packet_info);

                if ((gnrc_gomach_check_duplicate(netif, &receive_packet_info))) {
                    gnrc_pktbuf_release(pkt);
                    LOG_DEBUG("[GOMACH] vtdma: received a duplicate packet.\n");
                    return;
                }

                gnrc_gomach_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
                gnrc_mac_dispatch(&netif->mac.rx);
                break;
            }
            default: {
                gnrc_pktbuf_release(pkt);
                break;
            }
        }
    }
}
Ejemplo n.º 20
0
static bool _wait_preamble_ack_preambleack(gnrc_netif_t *netif,
                                           gnrc_gomach_packet_info_t *info,
                                           gnrc_pktsnip_t *pkt)
{
    if ((memcmp(&netif->l2addr, &info->dst_addr.addr,
                netif->l2addr_len) == 0) &&
        (memcmp(&netif->mac.tx.current_neighbor->l2_addr,
                &info->src_addr.addr,
                netif->mac.tx.current_neighbor->l2_addr_len) == 0)) {
        /* Got preamble-ACK from targeted device. */
        gnrc_gomach_set_got_preamble_ack(netif, true);

        /* Analyze the preamble-ACK to get phase-locked with the neighbor device. */
        gnrc_gomach_process_preamble_ack(netif, pkt);

        gnrc_pktbuf_release(pkt);
        gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
        return false;
    }

    /* Preamble-ACK is not from targeted device. release it. */
    gnrc_pktbuf_release(pkt);
    return true;
}
Ejemplo n.º 21
0
static void _dispatch_rcv_pkt(gnrc_nettype_t type, uint32_t demux_ctx,
                              gnrc_pktsnip_t *pkt)
{
    gnrc_netreg_entry_t *entry = gnrc_netreg_lookup(type, demux_ctx);

    while (entry) {
        DEBUG("ipv6: Send receive command for %p to %" PRIu16 "\n", (void *)pkt,
              entry->pid);
        if (gnrc_netapi_receive(entry->pid, pkt) < 1) {
            DEBUG("ipv6: unable to deliver packet\n");
            gnrc_pktbuf_release(pkt);
        }
        entry = gnrc_netreg_getnext(entry);
    }
}
Ejemplo n.º 22
0
/**
 * @brief   Function called by the device driver on device events
 *
 * @param[in] event         type of event
 * @param[in] data          optional parameter
 */
static void _event_cb(gnrc_netdev_event_t event, void *data)
{
    DEBUG("nomac: event triggered -> %i\n", event);
    /* NOMAC only understands the RX_COMPLETE event... */
    if (event == NETDEV_EVENT_RX_COMPLETE) {
        gnrc_pktsnip_t *pkt;

        /* get pointer to the received packet */
        pkt = (gnrc_pktsnip_t *)data;
        /* send the packet to everyone interested in it's type */
        if (!gnrc_netapi_dispatch_receive(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
            DEBUG("nomac: unable to forward packet of type %i\n", pkt->type);
            gnrc_pktbuf_release(pkt);
        }
    }
}
Ejemplo n.º 23
0
int gnrc_conn_recvfrom(conn_t *conn, void *data, size_t max_len, void *addr, size_t *addr_len,
                       uint16_t *port)
{
    msg_t msg;
    int timeout = 3;
    while ((timeout--) > 0) {
        gnrc_pktsnip_t *pkt, *l3hdr;
        size_t size = 0;
        msg_receive(&msg);
        switch (msg.type) {
            case GNRC_NETAPI_MSG_TYPE_RCV:
                pkt = (gnrc_pktsnip_t *)msg.content.ptr;
                if (pkt->size > max_len) {
                    return -ENOMEM;
                }
                LL_SEARCH_SCALAR(pkt, l3hdr, type, conn->l3_type);
                if (l3hdr == NULL) {
                    msg_send_to_self(&msg); /* requeue invalid messages */
                    continue;
                }
#if defined(MODULE_CONN_UDP) || defined(MODULE_CONN_TCP)
                if ((conn->l4_type != GNRC_NETTYPE_UNDEF) && (port != NULL)) {
                    gnrc_pktsnip_t *l4hdr;
                    LL_SEARCH_SCALAR(pkt, l4hdr, type, conn->l4_type);
                    if (l4hdr == NULL) {
                        msg_send_to_self(&msg); /* requeue invalid messages */
                        continue;
                    }
                    *port = byteorder_ntohs(((udp_hdr_t *)l4hdr->data)->src_port);
                }
#endif  /* defined(MODULE_CONN_UDP) */
                if (addr != NULL) {
                    memcpy(addr, &((ipv6_hdr_t *)l3hdr->data)->src, sizeof(ipv6_addr_t));
                    *addr_len = sizeof(ipv6_addr_t);
                }
                memcpy(data, pkt->data, pkt->size);
                size = pkt->size;
                gnrc_pktbuf_release(pkt);
                return (int)size;
            default:
                (void)port;
                msg_send_to_self(&msg); /* requeue invalid messages */
                break;
        }
    }
    return -ETIMEDOUT;
}
Ejemplo n.º 24
0
static void test_pktbuf_get_iovec__1_elem(void)
{
    struct iovec *vec;
    size_t len;
    gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16),
                                           GNRC_NETTYPE_UNDEF);
    snip = gnrc_pktbuf_get_iovec(snip, &len);
    vec = (struct iovec *)snip->data;

    TEST_ASSERT_EQUAL_INT(sizeof(struct iovec), snip->size);
    TEST_ASSERT_EQUAL_INT(1, len);
    TEST_ASSERT(snip->next->data == vec[0].iov_base);
    TEST_ASSERT_EQUAL_INT(snip->next->size, vec[0].iov_len);

    gnrc_pktbuf_release(snip);
    TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Ejemplo n.º 25
0
static void *_ipv6_fwd_eventloop(void *arg)
{
    (void)arg;

    msg_t msg, msg_q[8];
    gnrc_netreg_entry_t me_reg;

    msg_init_queue(msg_q, 8);

    me_reg.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    me_reg.pid = thread_getpid();

    gnrc_netreg_register(GNRC_NETTYPE_SIXLOWPAN, &me_reg);

    while(1) {
        msg_receive(&msg);
        gnrc_pktsnip_t *pkt = msg.content.ptr;
        if(msg.type == GNRC_NETAPI_MSG_TYPE_SND) {
            gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
            ipv6 = ipv6->data;

            ipv6_hdr_t *ipv6_hdr =(ipv6_hdr_t *)ipv6;

            /* get the first IPv6 interface and prints its address */
            kernel_pid_t ifs[GNRC_NETIF_NUMOF];
            gnrc_netif_get(ifs);
            gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
            for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
                if ( (!ipv6_addr_is_link_local(&entry->addrs[i].addr)) && (!ipv6_addr_is_link_local(&ipv6_hdr->src)) 
                    && (!ipv6_addr_is_link_local(&ipv6_hdr->dst)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)
                    && (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) ) {

                    if(!ipv6_addr_equal(&entry->addrs[i].addr, &(ipv6_hdr->src))){

                        char addr_str[IPV6_ADDR_MAX_STR_LEN];
                        printf("IPv6 ROUTER: forward from src = %s ", ipv6_addr_to_str(addr_str, &(ipv6_hdr->src), sizeof(addr_str)) );
                        printf("to dst = %s\n",ipv6_addr_to_str(addr_str, &(ipv6_hdr->dst), sizeof(addr_str)));
                    }
                }
            }
        }
        gnrc_pktbuf_release(pkt);
    }
    /* never reached */
    return NULL;
}
Ejemplo n.º 26
0
static gnrc_pktsnip_t *_add_pios(gnrc_ipv6_netif_t *ipv6_iface, gnrc_pktsnip_t *pkt)
{
    gnrc_pktsnip_t *tmp;
    for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (_pio_from_iface_addr(&tmp, &ipv6_iface->addrs[i], pkt)) {
            if (tmp != NULL) {
                pkt = tmp;
            }
            else {
                DEBUG("ndp rtr: error allocating PIO\n");
                gnrc_pktbuf_release(pkt);
                return NULL;
            }
        }
    }
    return pkt;
}
Ejemplo n.º 27
0
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
    if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, pkt)) {
        gnrc_pktbuf_release(pkt);
        LOG_WARNING("WARNING: [LWMAC] TX queue full, drop packet\n");
        return -ENOBUFS;
    }

    lwmac_schedule_update(netif);

    /* Execute main state machine because something just happend*/
    while (gnrc_lwmac_get_reschedule(netif)) {
        lwmac_update(netif);
    }

    return 0;
}
Ejemplo n.º 28
0
/**
 * @brief   Make a raw dump of the given packet contents
 */
void dump_pkt(gnrc_pktsnip_t *pkt)
{
    gnrc_pktsnip_t *snip = pkt;

    printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08" PRIx64 "\n\n",
           gnrc_pkt_len(pkt), 0, xtimer_now64());

    while (snip) {
        for (size_t i = 0; i < snip->size; i++) {
            printf("0x%02x ", ((uint8_t *)(snip->data))[i]);
        }
        snip = snip->next;
    }
    puts("\n");

    gnrc_pktbuf_release(pkt);
}
Ejemplo n.º 29
0
int gnrc_gomach_dispatch_defer(gnrc_pktsnip_t *buffer[], gnrc_pktsnip_t *pkt)
{
    assert(buffer != NULL);
    assert(pkt != NULL);

    for (unsigned i = 0; i < GNRC_MAC_DISPATCH_BUFFER_SIZE; i++) {
        /* Buffer will be filled bottom-up and emptied completely so no holes */
        if (buffer[i] == NULL) {
            buffer[i] = pkt;
            return 0;
        }
    }

    gnrc_pktbuf_release(pkt);
    LOG_ERROR("ERROR: [GOMACH]: dispatch buffer full, drop pkt.\n");

    return -ENOBUFS;
}
Ejemplo n.º 30
0
static void _dump(gnrc_pktsnip_t *pkt)
{
    int snips = 0;
    int size = 0;
    gnrc_pktsnip_t *snip = pkt;

    while (snip != NULL) {
        printf("~~ SNIP %2i - size: %3u byte, type: ", snips,
               (unsigned int)snip->size);
        _dump_snip(snip);
        ++snips;
        size += snip->size;
        snip = snip->next;
    }

    printf("~~ PKT    - %2i snips, total size: %3i byte\n", snips, size);
    gnrc_pktbuf_release(pkt);
}