Exemple #1
0
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)));
}
Exemple #2
0
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;
}
Exemple #3
0
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)));
}
Exemple #4
0
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;
    }
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
0
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;
}
Exemple #9
0
/* 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;
}
Exemple #10
0
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;
}
Exemple #11
0
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("");
}
Exemple #12
0
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("");
}