static void test_ng_netif_addr_to_str__out_too_short(void) { static const uint8_t addr[] = {0x05, 0xcd}; char out[2]; TEST_ASSERT_NULL(gnrc_netif_addr_to_str(out, sizeof(out), addr, sizeof(addr))); }
bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, gnrc_netif_t *netif, gnrc_ipv6_nib_nc_t *nce) { bool res = (netif != NULL) && gnrc_netif_is_6ln(netif) && ipv6_addr_is_link_local(dst); if (res) { uint8_t l2addr_len; if ((l2addr_len = _reverse_iid(dst, netif, nce->l2addr)) > 0) { DEBUG("nib: resolve address %s%%%u by reverse translating to ", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), (unsigned)netif->pid); nce->l2addr_len = l2addr_len; DEBUG("%s\n", gnrc_netif_addr_to_str(nce->l2addr, nce->l2addr_len, addr_str)); memcpy(&nce->ipv6, dst, sizeof(nce->ipv6)); nce->info = 0; nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) & GNRC_IPV6_NIB_NC_INFO_IFACE_MASK; nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE; nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED; } else { res = false; } } return res; }
static void test_ng_netif_addr_to_str__success(void) { static const uint8_t addr[] = {0x05, 0xcd}; char out[3 * sizeof(addr)]; TEST_ASSERT_EQUAL_STRING("05:cd", gnrc_netif_addr_to_str(out, sizeof(out), addr, sizeof(addr))); }
int gnrc_ndp_internal_tl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, uint8_t icmpv6_type, ndp_opt_t *tl2a_opt, uint8_t *l2addr) { uint8_t tl2a_len = 0; uint8_t *tl2a = (uint8_t *)(tl2a_opt + 1); if ((tl2a_opt->len == 0) || ipv6_addr_is_unspecified(&ipv6->src)) { DEBUG("ndp: invalid target link-layer address option received\n"); return -EINVAL; } switch (icmpv6_type) { case ICMPV6_NBR_ADV: while (pkt) { if (pkt->type == GNRC_NETTYPE_NETIF) { gnrc_netif_hdr_t *hdr = pkt->data; tl2a_len = hdr->src_l2addr_len; break; } pkt = pkt->next; } if (tl2a_len == 0) { /* in case there was no source address in l2 */ tl2a_len = (tl2a_opt->len / 8) - sizeof(ndp_opt_t); /* ignore all zeroes at the end for length */ for (; tl2a[tl2a_len - 1] == 0x00; tl2a_len--); } DEBUG("ndp: received TL2A (link-layer address: %s)\n", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), tl2a, tl2a_len)); memcpy(l2addr, tl2a, tl2a_len); return (int)tl2a_len; default: /* wrong encapsulating message: silently discard */ DEBUG("ndp: silently discard tl2a_opt for ICMPv6 message type %" PRIu8 "\n", icmpv6_type); return 0; } }
static int _ipv6_nc_list(void) { char ipv6_str[IPV6_ADDR_MAX_STR_LEN]; char l2addr_str[3 * MAX_L2_ADDR_LEN]; puts("IPv6 address if L2 address state type"); puts("------------------------------------------------------------------------------"); for (gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get_next(NULL); entry != NULL; entry = gnrc_ipv6_nc_get_next(entry)) { printf("%-30s %2" PRIkernel_pid " %-24s ", ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str)), entry->iface, gnrc_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), entry->l2_addr, entry->l2_addr_len)); _print_nc_state(entry); _print_nc_type(entry); puts(""); } return 0; }
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) { netdev_t *dev = netif->dev; netdev_ieee802154_rx_info_t rx_info; gnrc_pktsnip_t *pkt = NULL; int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL); if (bytes_expected >= (int)IEEE802154_MIN_FRAME_LEN) { int nread; pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF); if (pkt == NULL) { DEBUG("_recv_ieee802154: cannot allocate pktsnip.\n"); /* Discard packet on netdev device */ dev->driver->recv(dev, NULL, bytes_expected, NULL); return NULL; } nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info); if (nread <= 0) { gnrc_pktbuf_release(pkt); return NULL; } #ifdef MODULE_NETSTATS_L2 netif->stats.rx_count++; netif->stats.rx_bytes += nread; #endif if (netif->flags & GNRC_NETIF_FLAGS_RAWMODE) { /* Raw mode, skip packet processing, but provide rx_info via * GNRC_NETTYPE_NETIF */ gnrc_pktsnip_t *netif_snip = gnrc_netif_hdr_build(NULL, 0, NULL, 0); if (netif_snip == NULL) { DEBUG("_recv_ieee802154: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } gnrc_netif_hdr_t *hdr = netif_snip->data; hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; hdr->if_pid = netif->pid; LL_APPEND(pkt, netif_snip); } else { /* Normal mode, try to parse the frame according to IEEE 802.15.4 */ gnrc_pktsnip_t *ieee802154_hdr, *netif_hdr; gnrc_netif_hdr_t *hdr; #if ENABLE_DEBUG char src_str[GNRC_NETIF_HDR_L2ADDR_PRINT_LEN]; #endif size_t mhr_len = ieee802154_get_frame_hdr_len(pkt->data); /* nread was checked for <= 0 before so we can safely cast it to * unsigned */ if ((mhr_len == 0) || ((size_t)nread < mhr_len)) { DEBUG("_recv_ieee802154: illegally formatted frame received\n"); gnrc_pktbuf_release(pkt); return NULL; } nread -= mhr_len; /* mark IEEE 802.15.4 header */ ieee802154_hdr = gnrc_pktbuf_mark(pkt, mhr_len, GNRC_NETTYPE_UNDEF); if (ieee802154_hdr == NULL) { DEBUG("_recv_ieee802154: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } netif_hdr = _make_netif_hdr(ieee802154_hdr->data); if (netif_hdr == NULL) { DEBUG("_recv_ieee802154: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } hdr = netif_hdr->data; #ifdef MODULE_L2FILTER if (!l2filter_pass(dev->filter, gnrc_netif_hdr_get_src_addr(hdr), hdr->src_l2addr_len)) { gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(netif_hdr); DEBUG("_recv_ieee802154: packet dropped by l2filter\n"); return NULL; } #endif #ifdef MODULE_GNRC_NETIF_DEDUP if (_already_received(netif, hdr, ieee802154_hdr->data)) { gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(netif_hdr); DEBUG("_recv_ieee802154: packet dropped by deduplication\n"); return NULL; } memcpy(netif->last_pkt.src, gnrc_netif_hdr_get_src_addr(hdr), hdr->src_l2addr_len); netif->last_pkt.src_len = hdr->src_l2addr_len; netif->last_pkt.seq = ieee802154_get_seq(ieee802154_hdr->data); #endif /* MODULE_GNRC_NETIF_DEDUP */ hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; hdr->if_pid = thread_getpid(); dev->driver->get(dev, NETOPT_PROTO, &pkt->type, sizeof(pkt->type)); #if ENABLE_DEBUG DEBUG("_recv_ieee802154: received packet from %s of length %u\n", gnrc_netif_addr_to_str(gnrc_netif_hdr_get_src_addr(hdr), hdr->src_l2addr_len, src_str), nread); #if defined(MODULE_OD) od_hex_dump(pkt->data, nread, OD_WIDTH_DEFAULT); #endif #endif gnrc_pktbuf_remove_snip(pkt, ieee802154_hdr); LL_APPEND(pkt, netif_hdr); } DEBUG("_recv_ieee802154: reallocating.\n"); gnrc_pktbuf_realloc_data(pkt, nread); } else if (bytes_expected > 0) { DEBUG("_recv_ieee802154: received frame is too short\n"); dev->driver->recv(dev, NULL, bytes_expected, NULL); } return pkt; }
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 gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) { netdev2_t *netdev = gnrc_netdev2->dev; netdev2_ieee802154_rx_info_t rx_info; netdev2_ieee802154_t *state = (netdev2_ieee802154_t *)gnrc_netdev2->dev; gnrc_pktsnip_t *pkt = NULL; int bytes_expected = netdev->driver->recv(netdev, NULL, 0, NULL); if (bytes_expected > 0) { int nread; pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF); if (pkt == NULL) { DEBUG("_recv_ieee802154: cannot allocate pktsnip.\n"); return NULL; } nread = netdev->driver->recv(netdev, pkt->data, bytes_expected, &rx_info); if (nread <= 0) { gnrc_pktbuf_release(pkt); return NULL; } if (!(state->flags & NETDEV2_IEEE802154_RAW)) { gnrc_pktsnip_t *ieee802154_hdr, *netif_hdr; gnrc_netif_hdr_t *hdr; #if ENABLE_DEBUG char src_str[GNRC_NETIF_HDR_L2ADDR_MAX_LEN]; #endif size_t mhr_len = ieee802154_get_frame_hdr_len(pkt->data); if (mhr_len == 0) { DEBUG("_recv_ieee802154: illegally formatted frame received\n"); gnrc_pktbuf_release(pkt); return NULL; } nread -= mhr_len; /* mark IEEE 802.15.4 header */ ieee802154_hdr = gnrc_pktbuf_mark(pkt, mhr_len, GNRC_NETTYPE_UNDEF); if (ieee802154_hdr == NULL) { DEBUG("_recv_ieee802154: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } netif_hdr = _make_netif_hdr(ieee802154_hdr->data); if (netif_hdr == NULL) { DEBUG("_recv_ieee802154: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } hdr = netif_hdr->data; hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; hdr->if_pid = thread_getpid(); pkt->type = state->proto; #if ENABLE_DEBUG DEBUG("_recv_ieee802154: received packet from %s of length %u\n", gnrc_netif_addr_to_str(src_str, sizeof(src_str), gnrc_netif_hdr_get_src_addr(hdr), hdr->src_l2addr_len), nread); #if defined(MODULE_OD) od_hex_dump(pkt->data, nread, OD_WIDTH_DEFAULT); #endif #endif gnrc_pktbuf_remove_snip(pkt, ieee802154_hdr); LL_APPEND(pkt, netif_hdr); } DEBUG("_recv_ieee802154: reallocating.\n"); gnrc_pktbuf_realloc_data(pkt, nread); } return pkt; }
/* tests receiving */ static int test_receive(void) { ethernet_hdr_t *rcv_mac = (ethernet_hdr_t *)_tmp; uint8_t *rcv_payload = _tmp + sizeof(ethernet_hdr_t); gnrc_pktsnip_t *pkt, *hdr; gnrc_netreg_entry_t me = { NULL, GNRC_NETREG_DEMUX_CTX_ALL, thread_getpid() }; msg_t msg; if (_dev.netdev.event_callback == NULL) { puts("Device's event_callback not set"); return 0; } /* prepare receive buffer */ memcpy(rcv_mac->dst, _dev_addr, sizeof(_dev_addr)); memcpy(rcv_mac->src, _test_src, sizeof(_test_src)); /* no gnrc_ipv6 in compile unit => ETHERTYPE_IPV6 translates to * GNRC_NETTYPE_UNDEF */ rcv_mac->type = byteorder_htons(ETHERTYPE_IPV6); memcpy(rcv_payload, _TEST_PAYLOAD2, sizeof(_TEST_PAYLOAD2) - 1); _tmp_len = sizeof(_TEST_PAYLOAD2) + sizeof(ethernet_hdr_t) - 1; /* register for GNRC_NETTYPE_UNDEF */ gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &me); /* fire ISR event */ _dev.netdev.event_callback((netdev2_t *)&_dev.netdev, NETDEV2_EVENT_ISR); /* wait for packet from MAC layer*/ msg_receive(&msg); /* check message */ if (msg.sender_pid != _mac_pid) { puts("Unexpected sender of netapi receive message"); return 0; } if (msg.type != GNRC_NETAPI_MSG_TYPE_RCV) { puts("Expected netapi receive message"); return 0; } pkt = msg.content.ptr; /* check payload */ if (pkt->size != _tmp_len - sizeof(ethernet_hdr_t)) { puts("Payload of unexpected size"); } if ((pkt->type != GNRC_NETTYPE_UNDEF) || (memcmp(pkt->data, _TEST_PAYLOAD2, pkt->size) != 0)) { puts("Unexpected payload"); puts("==========================================================="); puts("expected"); puts("==========================================================="); od_hex_dump(_TEST_PAYLOAD2, pkt->size, OD_WIDTH_DEFAULT); puts("==========================================================="); puts("send data"); puts("==========================================================="); od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT); return 0; } hdr = pkt->next; /* check netif header */ if ((hdr->type != GNRC_NETTYPE_NETIF) || (hdr->next != NULL) || (hdr->size) != (sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN))) { puts("Malformed header received"); return 0; } if (memcmp(gnrc_netif_hdr_get_src_addr(hdr->data), _test_src, ETHERNET_ADDR_LEN) != 0) { char addr_str[ETHERNET_ADDR_LEN * 3]; puts("Unexpected source received"); puts("================="); puts("expected"); puts("================="); puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), _test_src, ETHERNET_ADDR_LEN)); puts("================="); puts("received source"); puts("================="); puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), gnrc_netif_hdr_get_src_addr(hdr->data), ETHERNET_ADDR_LEN)); return 0; } if (memcmp(gnrc_netif_hdr_get_dst_addr(hdr->data), _dev_addr, ETHERNET_ADDR_LEN) != 0) { char addr_str[ETHERNET_ADDR_LEN * 3]; puts("Unexpected destination received"); puts("================="); puts("expected"); puts("================="); puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), _dev_addr, ETHERNET_ADDR_LEN)); puts("===================="); puts("received destination"); puts("===================="); puts(gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), gnrc_netif_hdr_get_dst_addr(hdr->data), ETHERNET_ADDR_LEN)); return 0; } gnrc_pktbuf_release(pkt); gnrc_netreg_unregister(GNRC_NETTYPE_UNDEF, &me); return 1; }
gnrc_ipv6_nc_t *gnrc_ipv6_nc_add(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr, const void *l2_addr, size_t l2_addr_len, uint8_t flags) { gnrc_ipv6_nc_t *free_entry = NULL; if (ipv6_addr == NULL) { DEBUG("ipv6_nc: address was NULL\n"); return NULL; } if ((l2_addr_len > GNRC_IPV6_NC_L2_ADDR_MAX) || ipv6_addr_is_unspecified(ipv6_addr)) { DEBUG("ipv6_nc: invalid parameters\n"); return NULL; } for (int i = 0; i < GNRC_IPV6_NC_SIZE; i++) { if (ipv6_addr_equal(&(ncache[i].ipv6_addr), ipv6_addr)) { DEBUG("ipv6_nc: Address %s already registered.\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); if ((l2_addr != NULL) && (l2_addr_len > 0)) { DEBUG("ipv6_nc: Update to L2 address %s", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2_addr, l2_addr_len)); memcpy(&(ncache[i].l2_addr), l2_addr, l2_addr_len); ncache[i].l2_addr_len = l2_addr_len; ncache[i].flags = flags; DEBUG(" with flags = 0x%0x\n", flags); } return &ncache[i]; } if (ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr)) && !free_entry) { /* found the first free entry */ free_entry = &ncache[i]; } } if (!free_entry) { /* reached end of NC without finding updateable or free entry */ DEBUG("ipv6_nc: neighbor cache full.\n"); return NULL; } /* Otherwise, fill free entry with your fresh information */ free_entry->iface = iface; #ifdef MODULE_GNRC_NDP_NODE free_entry->pkts = NULL; #endif memcpy(&(free_entry->ipv6_addr), ipv6_addr, sizeof(ipv6_addr_t)); DEBUG("ipv6_nc: Register %s for interface %" PRIkernel_pid, ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), iface); if ((l2_addr != NULL) && (l2_addr_len > 0)) { DEBUG(" to L2 address %s", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2_addr, l2_addr_len)); memcpy(&(free_entry->l2_addr), l2_addr, l2_addr_len); free_entry->l2_addr_len = l2_addr_len; } free_entry->flags = flags; DEBUG(" with flags = 0x%0x\n", flags); if (gnrc_ipv6_nc_get_state(free_entry) == GNRC_IPV6_NC_STATE_INCOMPLETE) { DEBUG("ipv6_nc: Set remaining probes to %" PRIu8 "\n", (uint8_t) GNRC_NDP_MAX_MC_NBR_SOL_NUMOF); free_entry->probes_remaining = GNRC_NDP_MAX_MC_NBR_SOL_NUMOF; } #ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER free_entry->type_timeout_msg.type = GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT; free_entry->type_timeout_msg.content.ptr = (char *) free_entry; #endif free_entry->rtr_timeout_msg.type = GNRC_NDP_MSG_RTR_TIMEOUT; free_entry->rtr_timeout_msg.content.ptr = (char *) free_entry; #if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) free_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_DELAY; free_entry->rtr_adv_msg.content.ptr = (char *) free_entry; #endif free_entry->nbr_sol_msg.content.ptr = (char *) free_entry; return free_entry; }
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(""); }
static void _netif_list(kernel_pid_t iface) { #ifdef MODULE_GNRC_IPV6 ipv6_addr_t ipv6_addrs[GNRC_NETIF_IPV6_ADDRS_NUMOF]; ipv6_addr_t ipv6_groups[GNRC_NETIF_IPV6_GROUPS_NUMOF]; #endif uint8_t hwaddr[GNRC_NETIF_L2ADDR_MAXLEN]; uint32_t u32; uint16_t u16; int16_t i16; uint8_t u8; int res; netopt_state_t state; unsigned line_thresh = 1; printf("Iface %2d ", iface); res = gnrc_netapi_get(iface, NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf(" HWaddr: %s ", gnrc_netif_addr_to_str(hwaddr, res, hwaddr_str)); } res = gnrc_netapi_get(iface, NETOPT_CHANNEL, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Channel: %" PRIu16 " ", u16); } res = gnrc_netapi_get(iface, NETOPT_CHANNEL_FREQUENCY, 0, &u32, sizeof(u32)); if (res >= 0) { printf(" Frequency: %" PRIu32 "Hz ", u32); } res = gnrc_netapi_get(iface, NETOPT_CHANNEL_PAGE, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Page: %" PRIu16 " ", u16); } res = gnrc_netapi_get(iface, NETOPT_NID, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" NID: 0x%" PRIx16, u16); } res = gnrc_netapi_get(iface, NETOPT_BANDWIDTH, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" BW: %skHz ", _netopt_bandwidth_str[u8]); } res = gnrc_netapi_get(iface, NETOPT_SPREADING_FACTOR, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" SF: %u ", u8); } res = gnrc_netapi_get(iface, NETOPT_CODING_RATE, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" CR: %s ", _netopt_coding_rate_str[u8]); } res = gnrc_netapi_get(iface, NETOPT_LINK_CONNECTED, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" Link: %s ", (netopt_enable_t)u8 ? "up" : "down" ); } line_thresh = _newline(0U, line_thresh); res = gnrc_netapi_get(iface, 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, res, hwaddr_str)); line_thresh++; } line_thresh = _newline(0U, line_thresh); res = gnrc_netapi_get(iface, NETOPT_TX_POWER, 0, &i16, sizeof(i16)); if (res >= 0) { printf(" TX-Power: %" PRIi16 "dBm ", i16); } res = gnrc_netapi_get(iface, NETOPT_STATE, 0, &state, sizeof(state)); if (res >= 0) { printf(" State: %s ", _netopt_state_str[state]); line_thresh++; } res = gnrc_netapi_get(iface, NETOPT_RETRANS, 0, &u8, sizeof(u8)); if (res >= 0) { printf(" max. Retrans.: %u ", (unsigned)u8); line_thresh++; } res = gnrc_netapi_get(iface, NETOPT_CSMA_RETRIES, 0, &u8, sizeof(u8)); if (res >= 0) { netopt_enable_t enable = NETOPT_DISABLE; res = gnrc_netapi_get(iface, NETOPT_CSMA, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETOPT_ENABLE)) { printf(" CSMA Retries: %u ", (unsigned)u8); } line_thresh++; } line_thresh = _newline(0U, line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_PROMISCUOUSMODE, "PROMISC ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_AUTOACK, "AUTOACK ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_ACK_REQ, "ACK_REQ ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_PRELOADING, "PRELOAD ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_RAWMODE, "RAWMODE ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_MAC_NO_SLEEP, "MAC_NO_SLEEP ", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_CSMA, "CSMA ", line_thresh); line_thresh += _LINE_THRESHOLD + 1; /* enforce linebreak after this option */ line_thresh = _netif_list_flag(iface, NETOPT_AUTOCCA, "AUTOCCA", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_IQ_INVERT, "IQ_INVERT", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_SINGLE_RECEIVE, "RX_SINGLE", line_thresh); line_thresh = _netif_list_flag(iface, NETOPT_CHANNEL_HOP, "CHAN_HOP", line_thresh); res = gnrc_netapi_get(iface, NETOPT_MAX_PDU_SIZE, 0, &u16, sizeof(u16)); if (res > 0) { printf("L2-PDU:%" PRIu16 " ", u16); line_thresh++; } #ifdef MODULE_GNRC_IPV6 res = gnrc_netapi_get(iface, NETOPT_MAX_PDU_SIZE, GNRC_NETTYPE_IPV6, &u16, sizeof(u16)); if (res > 0) { printf("MTU:%" PRIu16 " ", u16); line_thresh++; } res = gnrc_netapi_get(iface, NETOPT_HOP_LIMIT, 0, &u8, sizeof(u8)); if (res > 0) { printf("HL:%u ", u8); line_thresh++; } line_thresh = _netif_list_flag(iface, NETOPT_IPV6_FORWARDING, "RTR ", line_thresh); #ifndef MODULE_GNRC_SIXLOWPAN_IPHC line_thresh += _LINE_THRESHOLD + 1; /* enforce linebreak after this option */ #endif line_thresh = _netif_list_flag(iface, NETOPT_IPV6_SND_RTR_ADV, "RTR_ADV ", line_thresh); #ifdef MODULE_GNRC_SIXLOWPAN line_thresh = _netif_list_flag(iface, NETOPT_6LO, "6LO ", line_thresh); #endif #ifdef MODULE_GNRC_SIXLOWPAN_IPHC line_thresh += _LINE_THRESHOLD + 1; /* enforce linebreak after this option */ line_thresh = _netif_list_flag(iface, NETOPT_6LO_IPHC, "IPHC ", line_thresh); #endif #endif res = gnrc_netapi_get(iface, NETOPT_SRC_LEN, 0, &u16, sizeof(u16)); if (res >= 0) { printf("Source address length: %" PRIu16 , u16); line_thresh++; } line_thresh = _newline(0U, line_thresh); #ifdef MODULE_GNRC_IPV6 printf("Link type: %s", (gnrc_netapi_get(iface, NETOPT_IS_WIRED, 0, &u16, sizeof(u16)) > 0) ? "wired" : "wireless"); line_thresh = _newline(0U, ++line_thresh); res = gnrc_netapi_get(iface, NETOPT_IPV6_ADDR, 0, ipv6_addrs, sizeof(ipv6_addrs)); if (res >= 0) { uint8_t ipv6_addrs_flags[GNRC_NETIF_IPV6_ADDRS_NUMOF]; memset(ipv6_addrs_flags, 0, sizeof(ipv6_addrs_flags)); /* assume it to succeed (otherwise array will stay 0) */ gnrc_netapi_get(iface, NETOPT_IPV6_ADDR_FLAGS, 0, ipv6_addrs_flags, sizeof(ipv6_addrs_flags)); /* yes, the res of NETOPT_IPV6_ADDR is meant to be here ;-) */ for (unsigned i = 0; i < (res / sizeof(ipv6_addr_t)); i++) { _netif_list_ipv6(&ipv6_addrs[i], ipv6_addrs_flags[i]); } } res = gnrc_netapi_get(iface, NETOPT_IPV6_GROUP, 0, ipv6_groups, sizeof(ipv6_groups)); if (res >= 0) { for (unsigned i = 0; i < (res / sizeof(ipv6_addr_t)); i++) { _netif_list_groups(&ipv6_groups[i]); } } #endif #ifdef MODULE_L2FILTER l2filter_t *filter = NULL; res = gnrc_netapi_get(iface, 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(filter[i].addr, filter[i].addr_len, hwaddr_str); printf(" %2i: %s\n", count++, hwaddr_str); } } if (count == 0) { puts(" --- none ---"); } } #endif #ifdef MODULE_NETSTATS_L2 puts(""); _netif_stats(iface, NETSTATS_LAYER2, false); #endif #ifdef MODULE_NETSTATS_IPV6 _netif_stats(iface, NETSTATS_IPV6, false); #endif puts(""); }