Beispiel #1
0
static void test_pkt_len__2_elem__overflow(void)
{
    ng_pktsnip_t snip1 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, NULL);
    ng_pktsnip_t snip2 = _INIT_ELEM(SIZE_MAX, NULL, &snip1);

    TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8) - 1, ng_pkt_len(&snip2));
    /* size should overflow */
    TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8), ng_pkt_len(&snip1));
}
Beispiel #2
0
static void test_pkt_len__2_elem(void)
{
    ng_pktsnip_t snip1 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, NULL);
    ng_pktsnip_t snip2 = _INIT_ELEM_STATIC_DATA(TEST_STRING12, &snip1);

    TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8) + sizeof(TEST_STRING12),
                          ng_pkt_len(&snip2));
    TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8), ng_pkt_len(&snip1));
}
Beispiel #3
0
static void _send(ng_pktsnip_t *pkt)
{
    ng_udp_hdr_t *hdr;
    ng_pktsnip_t *udp_snip;
    ng_netreg_entry_t *sendto;

    /* get udp snip and hdr */
    LL_SEARCH_SCALAR(pkt, udp_snip, type, NG_NETTYPE_UDP);
    udp_snip = ng_pktbuf_start_write(udp_snip);
    if (udp_snip == NULL) {
        DEBUG("udp: cannot send packet: unable to allocate packet\n");
        ng_pktbuf_release(pkt);
        return;
    }
    hdr = (ng_udp_hdr_t *)udp_snip->data;
    /* fill in size field */
    hdr->length = byteorder_htons(ng_pkt_len(udp_snip));

    /* and forward packet to the network layer */
    sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL);
    /* throw away packet if no one is interested */
    if (sendto == NULL) {
        DEBUG("udp: cannot send packet: network layer not found\n");
        ng_pktbuf_release(pkt);
        return;
    }
    /* send packet to network layer */
    ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1);
    while (sendto != NULL) {
        ng_netapi_send(sendto->pid, pkt);
        sendto = ng_netreg_getnext(sendto);
    }
}
Beispiel #4
0
/**
 * @brief   Make a raw dump of the given packet contents
 */
void dump_pkt(ng_pktsnip_t *pkt)
{
    ng_pktsnip_t *snip = pkt;

    printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n",
           ng_pkt_len(pkt), 0, hwtimer_now());

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

    ng_pktbuf_release(pkt);
}
Beispiel #5
0
static int _fill_ipv6_hdr(kernel_pid_t iface, ng_pktsnip_t *ipv6,
                          ng_pktsnip_t *payload)
{
    int res;
    ng_ipv6_hdr_t *hdr = ipv6->data;

    hdr->len = byteorder_htons(ng_pkt_len(payload));
    DEBUG("ipv6: set payload length to %zu (network byteorder %04" PRIx16 ")\n",
          ng_pkt_len(payload), hdr->len.u16);

    /* check if e.g. extension header was not already marked */
    if (hdr->nh == NG_PROTNUM_RESERVED) {
        hdr->nh = ng_nettype_to_protnum(payload->type);

        /* if still reserved: mark no next header */
        if (hdr->nh == NG_PROTNUM_RESERVED) {
            hdr->nh = NG_PROTNUM_IPV6_NONXT;
        }
    }

    DEBUG("ipv6: set next header to %" PRIu8 "\n", hdr->nh);

    if (hdr->hl == 0) {
        hdr->hl = ng_ipv6_netif_get(iface)->cur_hl;
    }

    if (ng_ipv6_addr_is_unspecified(&hdr->src)) {
        ng_ipv6_addr_t *src = ng_ipv6_netif_find_best_src_addr(iface, &hdr->dst);

        if (src != NULL) {
            DEBUG("ipv6: set packet source to %s\n",
                  ng_ipv6_addr_to_str(addr_str, src, sizeof(addr_str)));
            memcpy(&hdr->src, src, sizeof(ng_ipv6_addr_t));
        }

        /* Otherwise leave unspecified */
    }

    DEBUG("ipv6: calculate checksum for upper header.\n");

#if NG_NETIF_NUMOF > 1
    if (payload->users > 1) {
        ng_pktsnip_t *ptr = ipv6;

        /* We deal with multiple interfaces here (multicast) => possible
         * different source addresses => duplication of payload needed */
        while (ptr != payload->next) {
            ng_pktsnip_t *old = ptr->next;
            /* duplicate everything including payload */
            ptr->next = ng_pktbuf_start_write(ptr->next);

            if (ptr->next == NULL) {
                DEBUG("ipv6: unable to get write access to payload, drop it\n");
                return -ENOBUFS;
            }

            ptr = old;
        }
    }
#endif /* NG_NETIF_NUMOF */

    if ((res = ng_netreg_calc_csum(payload, ipv6)) < 0) {
        if (res != -ENOENT) {   /* if there is no checksum we are okay */
            DEBUG("ipv6: checksum calculation failed.\n");
            return res;
        }
    }

    return 0;
}
Beispiel #6
0
static void test_pkt_len__1_elem__size_data(void)
{
    ng_pktsnip_t snip = _INIT_ELEM_STATIC_DATA(TEST_STRING8, NULL);

    TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8), ng_pkt_len(&snip));
}
Beispiel #7
0
static void test_pkt_len__1_elem__size_0(void)
{
    ng_pktsnip_t snip = _INIT_ELEM(0, NULL, NULL);

    TEST_ASSERT_EQUAL_INT(0, ng_pkt_len(&snip));
}
Beispiel #8
0
static void test_pkt_len__NULL(void)
{
    TEST_ASSERT_EQUAL_INT(0, ng_pkt_len(NULL));
}
Beispiel #9
0
static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
{
    kernel_pid_t iface = KERNEL_PID_UNDEF;
    ng_pktsnip_t *ipv6, *payload;
    ng_ipv6_addr_t *tmp;
    ng_ipv6_hdr_t *hdr;
    /* get IPv6 snip and (if present) generic interface header */
    if (pkt->type == NG_NETTYPE_NETIF) {
        /* If there is already a netif header (routing protocols and
         * neighbor discovery might add them to preset sending interface) */
        iface = ((ng_netif_hdr_t *)pkt->data)->if_pid;
        /* seize payload as temporary variable */
        ipv6 = ng_pktbuf_start_write(pkt);   /* write protect for later removal
                                              * in _send_unicast() */
        if (ipv6 == NULL) {
            DEBUG("ipv6: unable to get write access to netif header, dropping packet\n");
            ng_pktbuf_release(pkt);
            return;
        }
        pkt = ipv6;  /* Reset pkt from temporary variable */

        ipv6 = pkt->next;
    }
    else {
        ipv6 = pkt;
    }
    /* seize payload as temporary variable */
    payload = ng_pktbuf_start_write(ipv6);
    if (payload == NULL) {
        DEBUG("ipv6: unable to get write access to IPv6 header, dropping packet\n");
        ng_pktbuf_release(pkt);
        return;
    }
    if (ipv6 != pkt) {      /* in case packet has netif header */
        pkt->next = payload;/* pkt is already write-protected so we can do that */
    }
    ipv6 = payload;  /* Reset ipv6 from temporary variable */

    hdr = ipv6->data;
    payload = ipv6->next;

    if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
        _send_multicast(iface, pkt, ipv6, payload, prep_hdr);
    }
    else if ((ng_ipv6_addr_is_loopback(&hdr->dst)) ||   /* dst is loopback address */
             ((iface == KERNEL_PID_UNDEF) && /* or dst registered to any local interface */
              ((iface = ng_ipv6_netif_find_by_addr(&tmp, &hdr->dst)) != KERNEL_PID_UNDEF)) ||
             ((iface != KERNEL_PID_UNDEF) && /* or dst registered to given interface */
              (ng_ipv6_netif_find_addr(iface, &hdr->dst) != NULL))) {
        uint8_t *rcv_data;
        ng_pktsnip_t *ptr = ipv6, *rcv_pkt;

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        rcv_pkt = ng_pktbuf_add(NULL, NULL, ng_pkt_len(ipv6), NG_NETTYPE_IPV6);

        if (rcv_pkt == NULL) {
            DEBUG("ipv6: error on generating loopback packet\n");
            ng_pktbuf_release(pkt);
            return;
        }

        rcv_data = rcv_pkt->data;

        /* "reverse" packet (by making it one snip as if received from NIC) */
        while (ptr != NULL) {
            memcpy(rcv_data, ptr->data, ptr->size);
            rcv_data += ptr->size;
            ptr = ptr->next;
        }

        ng_pktbuf_release(pkt);

        DEBUG("ipv6: packet is addressed to myself => loopback\n");

        ng_netapi_receive(ng_ipv6_pid, rcv_pkt);
    }
    else {
        uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
        uint8_t l2addr[l2addr_len];

        iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst, pkt);

        if (iface == KERNEL_PID_UNDEF) {
            DEBUG("ipv6: error determining next hop's link layer address\n");
            ng_pktbuf_release(pkt);
            return;
        }

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        _send_unicast(iface, l2addr, l2addr_len, pkt);
    }
}
Beispiel #10
0
static void _send(ng_pktsnip_t *pkt)
{
    ng_netif_hdr_t *hdr;
    ng_pktsnip_t *ipv6, *sixlowpan;
    ng_sixlowpan_netif_t *iface;
    /* cppcheck: datagram_size will be read by frag */
    /* cppcheck-suppress unreadVariable */
    size_t payload_len, datagram_size;
    uint16_t max_frag_size;
    /* cppcheck: disp is needed in other build paths on this level already */
    /* cppcheck-suppress variableScope */
    uint8_t *disp;

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

    hdr = pkt->data;
    ipv6 = pkt->next;

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

    /* payload length and datagram size are different in that the payload
     * length is the length of the IPv6 datagram + 6LoWPAN dispatches,
     * while the datagram size is the size of only the IPv6 datagram */
    payload_len = ng_pkt_len(ipv6);
    /* cppcheck: datagram_size will be read by ng_sixlowpan_frag implementation */
    /* cppcheck-suppress unreadVariable */
    datagram_size = (uint16_t)payload_len;

    /* use sixlowpan packet snip as temporary one */
    sixlowpan = ng_pktbuf_start_write(pkt);

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

    pkt = sixlowpan;
    iface = ng_sixlowpan_netif_get(hdr->if_pid);

    if (iface == NULL) {
        if (ng_netapi_get(hdr->if_pid, NETCONF_OPT_MAX_PACKET_SIZE,
                          0, &max_frag_size, sizeof(max_frag_size)) < 0) {
            /* if error we assume it works */
            DEBUG("6lo: can not get max packet size from interface %"
                  PRIkernel_pid "\n", hdr->if_pid);
            max_frag_size = UINT16_MAX;
        }

        ng_sixlowpan_netif_add(hdr->if_pid, max_frag_size);
        iface = ng_sixlowpan_netif_get(hdr->if_pid);
    }
    else {
        max_frag_size = iface->max_frag_size;
    }

#ifdef MODULE_NG_SIXLOWPAN_IPHC
    if (iface->iphc_enabled) {
        if (!ng_sixlowpan_iphc_encode(pkt)) {
            DEBUG("6lo: error on IPHC encoding\n");
            ng_pktbuf_release(pkt);
            return;
        }
    }
    else {
        DEBUG("6lo: Send uncompressed\n");

        sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t),
                                  NG_NETTYPE_SIXLOWPAN);

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

        sixlowpan->next = ipv6;
        pkt->next = sixlowpan;
        disp = sixlowpan->data;
        disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
        payload_len++;
    }
#else
    DEBUG("6lo: Send uncompressed\n");

    sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN);

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

    sixlowpan->next = ipv6;
    pkt->next = sixlowpan;
    disp = sixlowpan->data;
    disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
    payload_len++;
#endif

    DEBUG("6lo: max_frag_size = %" PRIu16 " for interface %"
          PRIkernel_pid "\n", 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 */
    if (payload_len <= max_frag_size) {
        DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
              (void *)pkt, hdr->if_pid);
        ng_netapi_send(hdr->if_pid, pkt);

        return;
    }
#ifdef MODULE_NG_SIXLOWPAN_FRAG
    else {
        DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
              (unsigned int)payload_len, max_frag_size);
        ng_sixlowpan_frag_send(hdr->if_pid, pkt, payload_len, datagram_size);
    }
#else
    (void)datagram_size;
    DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
          (unsigned int)payload_len, max_frag_size);
#endif
}
Beispiel #11
0
static void _send(ng_pktsnip_t *pkt)
{
    ng_netif_hdr_t *hdr;
    ng_pktsnip_t *pkt2;
    ng_sixlowpan_netif_t *iface;
    /* datagram_size: pure IPv6 packet without 6LoWPAN dispatches or compression */
    size_t datagram_size;

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

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

    pkt2 = ng_pktbuf_start_write(pkt);

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

    hdr = pkt2->data;
    iface = ng_sixlowpan_netif_get(hdr->if_pid);
    datagram_size = ng_pkt_len(pkt2->next);

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

#ifdef MODULE_NG_SIXLOWPAN_IPHC
    if (iface->iphc_enabled) {
        if (!ng_sixlowpan_iphc_encode(pkt2)) {
            DEBUG("6lo: error on IPHC encoding\n");
            ng_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");
            ng_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");
        ng_pktbuf_release(pkt2);
        return;
    }
#endif
    DEBUG("6lo: iface->max_frag_size = %" PRIu16 " for interface %"
          PRIkernel_pid "\n", iface->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 */
    if (datagram_size <= iface->max_frag_size) {
        DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
              (void *)pkt2, hdr->if_pid);
        ng_netapi_send(hdr->if_pid, pkt2);

        return;
    }
#ifdef MODULE_NG_SIXLOWPAN_FRAG
    else {
        DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
              (unsigned int)datagram_size, iface->max_frag_size);
        ng_sixlowpan_frag_send(hdr->if_pid, pkt2, datagram_size);
    }
#else
    (void)datagram_size;
    DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
          (unsigned int)datagram_size, iface->max_frag_size);
#endif
}
Beispiel #12
0
int _send(ng_netdev_t *dev, ng_pktsnip_t *pkt)
{
    (void)dev;
    size_t size;
    size_t pos = 0;
    uint8_t *dst_addr;
    ng_netif_hdr_t *hdr;
    ng_pktsnip_t *payload;

    /* check packet */
    if (pkt == NULL || pkt->next == NULL) {
        DEBUG("nrfmin: Error sending packet: packet incomplete\n");
        return -ENOMSG;
    }

    /* check if payload is withing length bounds */
    size = ng_pkt_len(pkt->next);
    if (size > CONF_PAYLOAD_LEN) {
        ng_pktbuf_release(pkt);
        DEBUG("nrfmin: Error sending packet: payload to large\n");
        return -EOVERFLOW;
    }
    /* get netif header and check address length */
    hdr = (ng_netif_hdr_t *)pkt->data;
    if (hdr->dst_l2addr_len != 2) {
        DEBUG("nrfmin: Error sending packet: dest address has invalid size\n");
        ng_pktbuf_release(pkt);
        return -ENOMSG;
    }
    dst_addr = ng_netif_hdr_get_dst_addr(hdr);

    DEBUG("nrfmin: Sending packet to %02x:%02x - size %u\n",
           dst_addr[0], dst_addr[1], size);

    /* wait for any ongoing transmission to finish */
    while (_state == STATE_TX);
    /* write data into TX buffer */
    payload = pkt->next;
    _tx_buf.length = 6 + size;
    _tx_buf.src_addr[0] = (uint8_t)(_addr >> 8);
    _tx_buf.src_addr[1] = (uint8_t)(_addr);
    _tx_buf.dst_addr[0] = dst_addr[0];
    _tx_buf.dst_addr[1] = dst_addr[1];
    _tx_buf.proto = _nettype_to_nrftype(payload->type);
    while (payload) {
        memcpy(&(_tx_buf.payload[pos]), payload->data, payload->size);
        pos += payload->size;
        payload = payload->next;
    }

    /* save old state and switch to idle if applicable */
    _tx_prestate = _state;
    if (_tx_prestate == STATE_RX) {
        _switch_to_idle();
    }
    /* set packet pointer to TX buffer and write destination address */
    NRF_RADIO->PACKETPTR = (uint32_t)(&_tx_buf);
    NRF_RADIO->BASE0 &= ~(0xffff);
    NRF_RADIO->BASE0 |= ((((uint16_t)dst_addr[0]) << 8) | dst_addr[1]);
    /* start transmission */
    _state = STATE_TX;
    NRF_RADIO->TASKS_TXEN = 1;

    /* release packet */
    ng_pktbuf_release(pkt);
    return (int)size;
}