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); }
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()); }
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()); }
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()); }
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()); }
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()); }
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); }
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; }
/** * @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; }
/* 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; }
/* 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); } }
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()); }
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()); }
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); } }
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); }
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()); }
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; } } } }
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; }
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; } } } }
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; }
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); } }
/** * @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); } } }
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; }
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()); }
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; }
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; }
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; }
/** * @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); }
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; }
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); }