void gnrc_sixlowpan_frag_send(kernel_pid_t pid, gnrc_pktsnip_t *pkt, size_t datagram_size) { gnrc_sixlowpan_netif_t *iface = gnrc_sixlowpan_netif_get(pid); uint16_t offset = 0, res; /* payload_len: actual size of the packet vs * datagram_size: size of the uncompressed IPv6 packet */ size_t payload_len = gnrc_pkt_len(pkt->next); #if defined(DEVELHELP) && defined(ENABLE_DEBUG) if (iface == NULL) { DEBUG("6lo frag: iface == NULL, expect segmentation fault.\n"); gnrc_pktbuf_release(pkt); return; } #endif if ((res = _send_1st_fragment(iface, pkt, payload_len, datagram_size)) == 0) { /* error sending first fragment */ DEBUG("6lo frag: error sending 1st fragment\n"); gnrc_pktbuf_release(pkt); return; } offset += res; thread_yield(); /* (offset + (datagram_size - payload_len) < datagram_size) simplified */ while (offset < payload_len) { if ((res = _send_nth_fragment(iface, pkt, payload_len, datagram_size, offset)) == 0) { /* error sending subsequent fragment */ DEBUG("6lo frag: error sending subsequent fragment (offset = %" PRIu16 ")\n", offset); gnrc_pktbuf_release(pkt); return; } offset += res; thread_yield(); } /* remove original packet from packet buffer */ gnrc_pktbuf_release(pkt); _tag++; }
static int _netif_flag(char *cmd, kernel_pid_t dev, char *flag) { netopt_enable_t set = NETOPT_ENABLE; if (flag[0] == '-') { set = NETOPT_DISABLE; flag++; } if (strcmp(flag, "promisc") == 0) { return _netif_set_flag(dev, NETOPT_PROMISCUOUSMODE, set); } else if (strcmp(flag, "preload") == 0) { return _netif_set_flag(dev, NETOPT_PRELOADING, set); } else if (strcmp(flag, "autoack") == 0) { return _netif_set_flag(dev, NETOPT_AUTOACK, set); } else if (strcmp(flag, "raw") == 0) { return _netif_set_flag(dev, NETOPT_RAWMODE, set); } else if (strcmp(flag, "6lo") == 0) { #ifdef MODULE_GNRC_IPV6_NETIF gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(dev); if (entry == NULL) { puts("error: unable to (un)set 6LoWPAN support"); return 1; } mutex_lock(&entry->mutex); if (set) { entry->flags |= GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN; printf("success: set 6LoWPAN support on interface %" PRIkernel_pid "\n", dev); } else { entry->flags &= ~GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN; printf("success: unset 6LoWPAN support on interface %" PRIkernel_pid "\n", dev); } mutex_unlock(&entry->mutex); return 0; #else puts("error: unable to (un)set 6LoWPAN support"); return 1; #endif } else if (strcmp(flag, "iphc") == 0) { #if defined(MODULE_GNRC_SIXLOWPAN_NETIF) && defined(MODULE_GNRC_SIXLOWPAN_IPHC) gnrc_sixlowpan_netif_t *entry = gnrc_sixlowpan_netif_get(dev); if (entry == NULL) { puts("error: unable to (un)set IPHC"); return 1; } if (set) { entry->iphc_enabled = true; printf("success: enable IPHC on interface %" PRIkernel_pid "\n", dev); } else { entry->iphc_enabled = false; printf("success: disable IPHC on interface %" PRIkernel_pid "\n", dev); } return 0; #else puts("error: unable to (un)set IPHC."); return 1; #endif } _flag_usage(cmd); return 1; }
static void _netif_list(kernel_pid_t dev) { uint8_t hwaddr[MAX_ADDR_LEN]; uint16_t u16; int16_t i16; int res; netopt_state_t state; netopt_enable_t enable; bool linebreak = false; #ifdef MODULE_GNRC_IPV6_NETIF gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(dev); char ipv6_addr[IPV6_ADDR_MAX_STR_LEN]; #endif printf("Iface %2d ", dev); res = gnrc_netapi_get(dev, NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf(" HWaddr: "); printf("%s", gnrc_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); printf(" "); } res = gnrc_netapi_get(dev, NETOPT_CHANNEL, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Channel: %" PRIu16 " ", u16); } res = gnrc_netapi_get(dev, NETOPT_NID, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" NID: 0x%" PRIx16 " ", u16); } res = gnrc_netapi_get(dev, NETOPT_TX_POWER, 0, &i16, sizeof(i16)); if (res >= 0) { printf(" TX-Power: %" PRIi16 "dBm ", i16); } res = gnrc_netapi_get(dev, NETOPT_STATE, 0, &state, sizeof(state)); if (res >= 0) { printf(" State: "); _print_netopt_state(state); } printf("\n "); res = gnrc_netapi_get(dev, NETOPT_ADDRESS_LONG, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf("Long HWaddr: "); printf("%s", gnrc_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); printf("\n "); } res = gnrc_netapi_get(dev, NETOPT_PROMISCUOUSMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("PROMISC "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_AUTOACK, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("AUTOACK "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_PRELOADING, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("PRELOAD "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_RAWMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("RAWMODE "); linebreak = true; } #ifdef MODULE_GNRC_IPV6_NETIF if ((entry != NULL) && (entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) { printf("6LO "); linebreak = true; } #endif #if defined(MODULE_GNRC_SIXLOWPAN_NETIF) && defined(MODULE_GNRC_SIXLOWPAN_IPHC) gnrc_sixlowpan_netif_t *sixlo_entry = gnrc_sixlowpan_netif_get(dev); if ((sixlo_entry != NULL) && (sixlo_entry->iphc_enabled)) { printf("IPHC "); linebreak = true; } #endif if (linebreak) { printf("\n "); } res = gnrc_netapi_get(dev, NETOPT_SRC_LEN, 0, &u16, sizeof(u16)); if (res >= 0) { printf("Source address length: %" PRIu16 "\n ", u16); } #ifdef MODULE_GNRC_IPV6_NETIF for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { if (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) { printf("inet6 addr: "); if (ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr, IPV6_ADDR_MAX_STR_LEN)) { printf("%s/%" PRIu8 " scope: ", ipv6_addr, entry->addrs[i].prefix_len); if ((ipv6_addr_is_link_local(&entry->addrs[i].addr))) { printf("local"); } else { printf("global"); } if (entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST) { if (ipv6_addr_is_multicast(&entry->addrs[i].addr)) { printf(" [multicast]"); } else { printf(" [anycast]"); } } } else { printf("error in conversion"); } printf("\n "); } } #endif puts(""); }
static int _netif_flag(char *cmd, kernel_pid_t dev, char *flag) { netopt_enable_t set = NETOPT_ENABLE; if (flag[0] == '-') { set = NETOPT_DISABLE; flag++; } if (strcmp(flag, "promisc") == 0) { return _netif_set_flag(dev, NETOPT_PROMISCUOUSMODE, set); } else if (strcmp(flag, "preload") == 0) { return _netif_set_flag(dev, NETOPT_PRELOADING, set); } else if (strcmp(flag, "autoack") == 0) { return _netif_set_flag(dev, NETOPT_AUTOACK, set); } else if (strcmp(flag, "raw") == 0) { return _netif_set_flag(dev, NETOPT_RAWMODE, set); } else if (strcmp(flag, "csma") == 0) { return _netif_set_flag(dev, NETOPT_CSMA, set); } else if (strcmp(flag, "autocca") == 0) { return _netif_set_flag(dev, NETOPT_AUTOCCA, set); } else if (strcmp(flag, "iphc") == 0) { #if defined(MODULE_GNRC_SIXLOWPAN_NETIF) && defined(MODULE_GNRC_SIXLOWPAN_IPHC) gnrc_sixlowpan_netif_t *entry = gnrc_sixlowpan_netif_get(dev); if (entry == NULL) { puts("error: unable to (un)set IPHC"); return 1; } if (set) { entry->iphc_enabled = true; printf("success: enable IPHC on interface %" PRIkernel_pid "\n", dev); } else { entry->iphc_enabled = false; printf("success: disable IPHC on interface %" PRIkernel_pid "\n", dev); } return 0; #else puts("error: unable to (un)set IPHC."); return 1; #endif } else if (strcmp(flag, "rtr_adv") == 0) { #if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER) gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(dev); if (entry == NULL) { puts("error: unable to (un)set router advertisement flag."); return 1; } if (set) { gnrc_ipv6_netif_set_rtr_adv(entry, true); printf("success: enable router advertisements on interface %" PRIkernel_pid "\n", dev); } else { gnrc_ipv6_netif_set_rtr_adv(entry, false); printf("success: disable router advertisements on interface %" PRIkernel_pid "\n", dev); } return 0; #else puts("error: unable to (un)set router advertisement flag."); return 1; #endif } _flag_usage(cmd); return 1; }
static void _netif_list(kernel_pid_t dev) { uint8_t hwaddr[MAX_ADDR_LEN]; uint16_t u16; int16_t i16; uint8_t u8; int res; netopt_state_t state; netopt_enable_t enable = NETOPT_DISABLE; bool linebreak = false; #ifdef MODULE_GNRC_IPV6_NETIF gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(dev); char ipv6_addr[IPV6_ADDR_MAX_STR_LEN]; #endif printf("Iface %2d ", dev); res = gnrc_netapi_get(dev, NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf(" HWaddr: "); printf("%s", gnrc_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); printf(" "); } res = gnrc_netapi_get(dev, NETOPT_CHANNEL, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Channel: %" PRIu16 " ", u16); } res = gnrc_netapi_get(dev, NETOPT_CHANNEL_PAGE, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Page: %" PRIu16 " ", u16); } res = gnrc_netapi_get(dev, NETOPT_NID, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" NID: 0x%" PRIx16, u16); } printf("\n "); res = gnrc_netapi_get(dev, NETOPT_ADDRESS_LONG, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf("Long HWaddr: "); printf("%s ", gnrc_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); linebreak = true; } if (linebreak) { printf("\n "); } res = gnrc_netapi_get(dev, NETOPT_TX_POWER, 0, &i16, sizeof(i16)); if (res >= 0) { printf(" TX-Power: %" PRIi16 "dBm ", i16); } res = gnrc_netapi_get(dev, NETOPT_STATE, 0, &state, sizeof(state)); if (res >= 0) { printf(" State: "); _print_netopt_state(state); printf(" "); } res = gnrc_netapi_get(dev, NETOPT_RETRANS, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" max. Retrans.: %u ", (unsigned)u8); } res = gnrc_netapi_get(dev, NETOPT_CSMA_RETRIES, 0, &u8, sizeof(u8)); if (res >= 0) { res = gnrc_netapi_get(dev, NETOPT_CSMA, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf(" CSMA Retries: %u ", (unsigned)u8); } } printf("\n "); res = gnrc_netapi_get(dev, NETOPT_PROMISCUOUSMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("PROMISC "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_AUTOACK, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("AUTOACK "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_ACK_REQ, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("ACK_REQ "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_PRELOADING, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("PRELOAD "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_RAWMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("RAWMODE "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_CSMA, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("CSMA "); linebreak = true; } res = gnrc_netapi_get(dev, NETOPT_AUTOCCA, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf("AUTOCCA "); linebreak = true; } #ifdef MODULE_GNRC_IPV6_NETIF if (entry != NULL) { printf("MTU:%" PRIu16 " ", entry->mtu); printf("HL:%u ", (unsigned)entry->cur_hl); if (entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { printf("6LO "); } if (entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) { printf("RTR "); } if (entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) { printf("RTR_ADV "); } linebreak = true; } #endif #if defined(MODULE_GNRC_SIXLOWPAN_NETIF) && defined(MODULE_GNRC_SIXLOWPAN_IPHC) gnrc_sixlowpan_netif_t *sixlo_entry = gnrc_sixlowpan_netif_get(dev); if ((sixlo_entry != NULL) && (sixlo_entry->iphc_enabled)) { printf("IPHC "); linebreak = true; } #endif if (linebreak) { printf("\n "); } res = gnrc_netapi_get(dev, NETOPT_SRC_LEN, 0, &u16, sizeof(u16)); if (res >= 0) { printf("Source address length: %" PRIu16 "\n ", u16); } #ifdef MODULE_GNRC_IPV6_NETIF if (entry == NULL) { puts(""); return; } printf("Link type: %s", (entry->flags & GNRC_IPV6_NETIF_FLAGS_IS_WIRED) ? "wired" : "wireless"); printf("\n "); for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { if (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) { printf("inet6 addr: "); if (ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr, IPV6_ADDR_MAX_STR_LEN)) { printf("%s/%u scope: ", ipv6_addr, (unsigned)entry->addrs[i].prefix_len); if ((ipv6_addr_is_link_local(&entry->addrs[i].addr))) { printf("local"); } else { printf("global"); } if (entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST) { if (ipv6_addr_is_multicast(&entry->addrs[i].addr)) { printf(" [multicast]"); } else { printf(" [anycast]"); } } } else { printf("error in conversion"); } printf("\n "); } } #endif #ifdef MODULE_L2FILTER l2filter_t *filter = NULL; res = gnrc_netapi_get(dev, NETOPT_L2FILTER, 0, &filter, sizeof(filter)); if (res > 0) { #ifdef MODULE_L2FILTER_WHITELIST puts("\n White-listed link layer addresses:"); #else puts("\n Black-listed link layer addresses:"); #endif int count = 0; for (unsigned i = 0; i < L2FILTER_LISTSIZE; i++) { if (filter[i].addr_len > 0) { char hwaddr_str[filter[i].addr_len * 3]; gnrc_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), filter[i].addr, filter[i].addr_len); printf(" %2i: %s\n", count++, hwaddr_str); } } if (count == 0) { puts(" --- none ---"); } } #endif #ifdef MODULE_NETSTATS_L2 puts(""); _netif_stats(dev, NETSTATS_LAYER2, false); #endif #ifdef MODULE_NETSTATS_IPV6 _netif_stats(dev, NETSTATS_IPV6, false); #endif puts(""); }
void gnrc_sixlowpan_frag_send(gnrc_sixlowpan_msg_frag_t *fragment_msg) { gnrc_sixlowpan_netif_t *iface = gnrc_sixlowpan_netif_get(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; #if defined(DEVELHELP) && defined(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 weater 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; } } }