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); }
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; }
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 }
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; } } }
static inline bool _is_iface(kernel_pid_t iface) { return (gnrc_netif_get_by_pid(iface) != NULL); }