Example #1
0
static int _add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr,
                              uint8_t prefix_len, bool anycast)
{
    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            return 0;
        }

        if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) {
            memcpy(&(entry->addrs[i].addr), addr, sizeof(ng_ipv6_addr_t));
            DEBUG("Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n",
                  ng_ipv6_addr_to_str(&(entry->addrs[i].addr), addr,
                                      sizeof(addr_str)),
                  prefix_len, entry->pid);

            if (anycast || ng_ipv6_addr_is_multicast(addr)) {
                if (ng_ipv6_addr_is_multicast(addr)) {
                    entry->addrs[i].prefix_len = NG_IPV6_ADDR_BIT_LEN;
                }

                entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST;
            }
            else {
                entry->addrs[i].prefix_len = prefix_len;

                entry->addrs[i].flags = NG_IPV6_NETIF_ADDR_FLAGS_UNICAST;
            }

            return 0;
        }
    }

    return -ENOMEM;
}
Example #2
0
void ng_ndp_nbr_sol_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
                           ng_ipv6_hdr_t *ipv6, ng_ndp_nbr_sol_t *nbr_sol,
                           size_t icmpv6_size)
{
    uint16_t opt_offset = 0;
    uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ng_ndp_nbr_sol_t);
    ng_ipv6_addr_t *tgt;
    int sicmpv6_size = (int)icmpv6_size;

    /* check validity */
    if ((ipv6->hl != 255) || (nbr_sol->code != 0) ||
        (icmpv6_size < sizeof(ng_ndp_nbr_sol_t)) ||
        ng_ipv6_addr_is_multicast(&nbr_sol->tgt) ||
        (ng_ipv6_addr_is_unspecified(&ipv6->src) &&
         ng_ipv6_addr_is_solicited_node(&ipv6->dst))) {
        DEBUG("ndp: neighbor solicitation was invalid.\n");
        /* ipv6 releases */
        return;
    }

    if ((tgt = ng_ipv6_netif_find_addr(iface, &nbr_sol->tgt)) == NULL) {
        DEBUG("ndp: Target address is not to interface %" PRIkernel_pid "\n",
              iface);
        /* ipv6 releases */
        return;
    }

    sicmpv6_size -= sizeof(ng_ndp_nbr_sol_t);

    while (sicmpv6_size > 0) {
        ng_ndp_opt_t *opt = (ng_ndp_opt_t *)(buf + opt_offset);

        switch (opt->type) {
            case NG_NDP_OPT_SL2A:
                if (!_handle_sl2a_opt(iface, pkt, ipv6, nbr_sol->type, opt)) {
                    /* invalid source link-layer address option */
                    return;
                }

                break;

            default:
                /* silently discard all other options */
                break;
        }

        opt_offset += (opt->len * 8);
        sicmpv6_size -= (opt->len * 8);
    }

    _send_nbr_adv(iface, tgt, &ipv6->src,
                  ng_ipv6_addr_is_multicast(&ipv6->dst));

    return;
}
Example #3
0
ng_pktsnip_t *ng_ndp_nbr_adv_build(uint8_t flags, ng_ipv6_addr_t *tgt,
                                   ng_pktsnip_t *options)
{
    ng_pktsnip_t *pkt;
    ng_ndp_nbr_adv_t *nbr_adv;

    DEBUG("ndp: building neighbor advertisement message\n");

    if (ng_ipv6_addr_is_multicast(tgt)) {
        DEBUG("ndp: tgt must not be multicast\n");
        return NULL;
    }

    pkt = ng_icmpv6_build(options, NG_ICMPV6_NBR_ADV, 0, sizeof(ng_ndp_nbr_adv_t));

    if (pkt == NULL) {
        return NULL;
    }

    nbr_adv = pkt->data;
    nbr_adv->flags = (flags & NG_NDP_NBR_ADV_FLAGS_MASK);
    nbr_adv->resv[0] = nbr_adv->resv[1] = nbr_adv->resv[2] = 0;
    memcpy(&nbr_adv->tgt, tgt, sizeof(ng_ipv6_addr_t));

    return pkt;
}
Example #4
0
static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
{
    kernel_pid_t iface = KERNEL_PID_UNDEF;
    ng_pktsnip_t *ipv6, *payload;
    ng_ipv6_hdr_t *hdr;
    /* seize payload as temporary variable */
    payload = ng_pktbuf_start_write(pkt);

    if (payload == NULL) {
        DEBUG("ipv6: unable to get write access to packet, dropping packet\n");
        ng_pktbuf_release(pkt);
        return;
    }

    pkt = payload;  /* Reset pkt from temporary variable */

    /* get IPv6 snip and (if present) generic interface header */
    if (pkt->type == NG_NETTYPE_NETIF) {
        /* If there is already a netif header (routing protocols and
         * neighbor discovery might add them to preset sending interface) */
        iface = ((ng_netif_hdr_t *)pkt->data)->if_pid;
        ipv6 = pkt->next;
    }
    else {
        ipv6 = pkt;
    }

    hdr = ipv6->data;
    payload = ipv6->next;       /* TODO: parse extension headers */

    if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
        _send_multicast(iface, pkt, ipv6, payload, prep_hdr);
    }
    else {
        uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
        uint8_t l2addr[l2addr_len];

        iface = ng_ndp_next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst,
                                       pkt);

        if (iface == KERNEL_PID_UNDEF) {
            DEBUG("ipv6: error determining next hop's link layer address\n");
            ng_pktbuf_release(pkt);
            return;
        }

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        _send_unicast(iface, l2addr, l2addr_len, pkt);
    }
}
Example #5
0
static void test_ipv6_addr_is_multicast_multicast(void)
{
    ng_ipv6_addr_t a = { {
            0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
        }
    };
    TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_multicast(&a));
}
Example #6
0
static ng_ipv6_addr_t *_add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr,
                                          uint8_t prefix_len, uint8_t flags)
{
    ng_ipv6_netif_addr_t *tmp_addr = NULL;

    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
            return &(entry->addrs[i].addr);
        }

        if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr)) && !tmp_addr) {
            tmp_addr = &(entry->addrs[i]);
        }
    }

    if (!tmp_addr) {
        DEBUG("ipv6 netif: couldn't add %s/%" PRIu8 " to interface %" PRIkernel_pid "\n: No space left.",
              ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              prefix_len, entry->pid);
        return NULL;
    }

    memcpy(&(tmp_addr->addr), addr, sizeof(ng_ipv6_addr_t));
    DEBUG("ipv6 netif: Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n",
          ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
          prefix_len, entry->pid);

    tmp_addr->prefix_len = prefix_len;
    tmp_addr->flags = flags;

    if (ng_ipv6_addr_is_multicast(addr)) {
        tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST;
    }
    else {
        ng_ipv6_addr_t sol_node;

        if (!ng_ipv6_addr_is_link_local(addr)) {
            /* add also corresponding link-local address */
            ng_ipv6_addr_t ll_addr;

            ll_addr.u64[1] = addr->u64[1];
            ng_ipv6_addr_set_link_local_prefix(&ll_addr);

            _add_addr_to_entry(entry, &ll_addr, 64,
                               flags | NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK);
        }
        else {
            tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK;
        }

        ng_ipv6_addr_set_solicited_nodes(&sol_node, addr);
        _add_addr_to_entry(entry, &sol_node, NG_IPV6_ADDR_BIT_LEN, 0);
    }

    return &(tmp_addr->addr);
}
Example #7
0
static uint8_t _find_by_prefix_unsafe(ng_ipv6_addr_t **res, ng_ipv6_netif_t *iface,
                                      const ng_ipv6_addr_t *addr, bool only_unicast)
{
    uint8_t best_match = 0;

    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        uint8_t match;

        if ((only_unicast &&
             ng_ipv6_netif_addr_is_non_unicast(&(iface->addrs[i].addr))) ||
            ng_ipv6_addr_is_unspecified(&(iface->addrs[i].addr))) {
            continue;
        }

        match = ng_ipv6_addr_match_prefix(&(iface->addrs[i].addr), addr);

        if (only_unicast && !ng_ipv6_addr_is_multicast(addr) &&
            (match < iface->addrs[i].prefix_len)) {
            /* match but not of same subnet */
            continue;
        }

        if (match > best_match) {
            if (res != NULL) {
                *res = &(iface->addrs[i].addr);
            }

            best_match = match;
        }
    }

#if ENABLE_DEBUG
    if (*res != NULL) {
        DEBUG("ipv6 netif: Found %s on interface %" PRIkernel_pid " matching ",
              ng_ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)),
              iface->pid);
        DEBUG("%s by %" PRIu8 " bits (used as source address = %s)\n",
              ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              best_match,
              (only_unicast) ? "true" : "false");
    }
    else {
        DEBUG("ipv6 netif: Did not found any address on interface %" PRIkernel_pid
              " matching %s (used as source address = %s)\n",
              iface->pid,
              ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              (only_unicast) ? "true" : "false");
    }
#endif

    return best_match;
}
Example #8
0
ng_pktsnip_t *ng_ndp_nbr_sol_build(ng_ipv6_addr_t *tgt, ng_pktsnip_t *options)
{
    ng_pktsnip_t *pkt;

    DEBUG("ndp: building neighbor solicitation message\n");

    if (ng_ipv6_addr_is_multicast(tgt)) {
        DEBUG("ndp: tgt must not be multicast\n");
        return NULL;
    }

    pkt = ng_icmpv6_build(options, NG_ICMPV6_NBR_SOL, 0, sizeof(ng_ndp_nbr_sol_t));

    if (pkt != NULL) {
        ng_ndp_nbr_sol_t *nbr_sol = pkt->data;
        nbr_sol->resv.u32 = 0;
        nbr_sol->tgt.u64[0].u64 = tgt->u64[0].u64;
        nbr_sol->tgt.u64[1].u64 = tgt->u64[1].u64;
    }

    return pkt;
}
Example #9
0
void ng_ndp_nbr_adv_handle(kernel_pid_t iface, ng_pktsnip_t *pkt,
                           ng_ipv6_hdr_t *ipv6, ng_ndp_nbr_adv_t *nbr_adv,
                           size_t icmpv6_size)
{
    uint16_t opt_offset = 0;
    uint8_t *buf = ((uint8_t *)nbr_adv) + sizeof(ng_ndp_nbr_adv_t);
    int l2tgt_len = 0;
    uint8_t l2tgt[NG_IPV6_NC_L2_ADDR_MAX];
    int sicmpv6_size = (int)icmpv6_size;
    ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, &nbr_adv->tgt);
    ng_pktsnip_t *netif;
    ng_netif_hdr_t *netif_hdr = NULL;

    DEBUG("ndp: received neighbor advertisement (src: %s, ",
          ng_ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)));
    DEBUG("dst: %s, ",
          ng_ipv6_addr_to_str(addr_str, &ipv6->dst, sizeof(addr_str)));
    DEBUG("tgt: %s)\n",
          ng_ipv6_addr_to_str(addr_str, &nbr_adv->tgt, sizeof(addr_str)));

    /* check validity */
    if ((ipv6->hl != 255) || (nbr_adv->code != 0) ||
        (icmpv6_size < sizeof(ng_ndp_nbr_adv_t)) ||
        ng_ipv6_addr_is_multicast(&nbr_adv->tgt)) {
        DEBUG("ndp: neighbor advertisement was invalid.\n");
        /* ipv6 releases */
        return;
    }

    if (nc_entry == NULL) {
        /* see https://tools.ietf.org/html/rfc4861#section-7.2.5 */
        DEBUG("ndp: no neighbor cache entry found for advertisement's target\n");
        /* ipv6 releases */
        return;
    }

    sicmpv6_size -= sizeof(ng_ndp_nbr_adv_t);

    while (sicmpv6_size > 0) {
        ng_ndp_opt_t *opt = (ng_ndp_opt_t *)(buf + opt_offset);

        switch (opt->type) {
            case NG_NDP_OPT_TL2A:
                if ((l2tgt_len = _handle_tl2a_opt(pkt, ipv6, nbr_adv->type, opt,
                                                  l2tgt)) < 0) {
                    /* invalid target link-layer address option */
                    return;
                }

                break;

            default:
                /* silently discard all other options */
                break;
        }

        opt_offset += (opt->len * 8);
        sicmpv6_size -= (opt->len * 8);
    }

    LL_SEARCH_SCALAR(pkt, netif, type, NG_NETTYPE_NETIF);

    if (netif != NULL) {
        netif_hdr = netif->data;
    }

    if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) {
        ng_pktqueue_t *queued_pkt;

        if (_pkt_has_l2addr(netif_hdr) && (l2tgt_len == 0)) {
            /* link-layer has addresses, but no TLLAO supplied: discard silently
             * (see https://tools.ietf.org/html/rfc4861#section-7.2.5) */
            return;
        }

        nc_entry->iface = iface;
        nc_entry->l2_addr_len = l2tgt_len;
        memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len);

        if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_S) {
            _set_state(nc_entry, NG_IPV6_NC_STATE_REACHABLE);
        }
        else {
            _set_state(nc_entry, NG_IPV6_NC_STATE_STALE);
        }

        if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_R) {
            nc_entry->flags |= NG_IPV6_NC_IS_ROUTER;
        }
        else {
            nc_entry->flags &= ~NG_IPV6_NC_IS_ROUTER;
            /* TODO: update FIB */
        }

        while ((queued_pkt = ng_pktqueue_remove_head(&nc_entry->pkts)) != NULL) {
            ng_netapi_send(ng_ipv6_pid, queued_pkt->pkt);
            queued_pkt->pkt = NULL;
        }
    }
    else {
        /* first or-term: no link-layer, but nc_entry has l2addr,
         * second or-term: different l2addr cached */
        bool l2tgt_changed = false;

        if ((!_pkt_has_l2addr(netif_hdr)) && (l2tgt_len == 0)) {
            /* there was previously a L2 address registered */
            l2tgt_changed = (nc_entry->l2_addr_len != 0);
        }
        /* link-layer has addresses and TLLAO with different address */
        else if (_pkt_has_l2addr(netif_hdr) && (l2tgt_len != 0)) {
            l2tgt_changed = (!(l2tgt_len == nc_entry->l2_addr_len)) &&
                            (memcmp(nc_entry->l2_addr, l2tgt, l2tgt_len) == 0);
        }

        if ((nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_O) || !l2tgt_changed ||
            (l2tgt_len == 0)) {
            if (l2tgt_len != 0) {
                nc_entry->iface = iface;
                nc_entry->l2_addr_len = l2tgt_len;
                memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len);
            }

            if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_S) {
                _set_state(nc_entry, NG_IPV6_NC_STATE_REACHABLE);
            }
            else if (l2tgt_changed && (l2tgt_len != 0)) {
                _set_state(nc_entry, NG_IPV6_NC_STATE_STALE);
            }

            if (nbr_adv->flags & NG_NDP_NBR_ADV_FLAGS_R) {
                nc_entry->flags |= NG_IPV6_NC_IS_ROUTER;
            }
            else {
                nc_entry->flags &= ~NG_IPV6_NC_IS_ROUTER;
                /* TODO: update FIB */
            }
        }
        else if (l2tgt_changed) {
            if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_REACHABLE) {
                _set_state(nc_entry, NG_IPV6_NC_STATE_STALE);

            }
        }
    }

    return;
}
Example #10
0
static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
{
    kernel_pid_t iface = KERNEL_PID_UNDEF;
    ng_pktsnip_t *ipv6, *payload;
    ng_ipv6_addr_t *tmp;
    ng_ipv6_hdr_t *hdr;
    /* get IPv6 snip and (if present) generic interface header */
    if (pkt->type == NG_NETTYPE_NETIF) {
        /* If there is already a netif header (routing protocols and
         * neighbor discovery might add them to preset sending interface) */
        iface = ((ng_netif_hdr_t *)pkt->data)->if_pid;
        /* seize payload as temporary variable */
        ipv6 = ng_pktbuf_start_write(pkt);   /* write protect for later removal
                                              * in _send_unicast() */
        if (ipv6 == NULL) {
            DEBUG("ipv6: unable to get write access to netif header, dropping packet\n");
            ng_pktbuf_release(pkt);
            return;
        }
        pkt = ipv6;  /* Reset pkt from temporary variable */

        ipv6 = pkt->next;
    }
    else {
        ipv6 = pkt;
    }
    /* seize payload as temporary variable */
    payload = ng_pktbuf_start_write(ipv6);
    if (payload == NULL) {
        DEBUG("ipv6: unable to get write access to IPv6 header, dropping packet\n");
        ng_pktbuf_release(pkt);
        return;
    }
    if (ipv6 != pkt) {      /* in case packet has netif header */
        pkt->next = payload;/* pkt is already write-protected so we can do that */
    }
    ipv6 = payload;  /* Reset ipv6 from temporary variable */

    hdr = ipv6->data;
    payload = ipv6->next;

    if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
        _send_multicast(iface, pkt, ipv6, payload, prep_hdr);
    }
    else if ((ng_ipv6_addr_is_loopback(&hdr->dst)) ||   /* dst is loopback address */
             ((iface == KERNEL_PID_UNDEF) && /* or dst registered to any local interface */
              ((iface = ng_ipv6_netif_find_by_addr(&tmp, &hdr->dst)) != KERNEL_PID_UNDEF)) ||
             ((iface != KERNEL_PID_UNDEF) && /* or dst registered to given interface */
              (ng_ipv6_netif_find_addr(iface, &hdr->dst) != NULL))) {
        uint8_t *rcv_data;
        ng_pktsnip_t *ptr = ipv6, *rcv_pkt;

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        rcv_pkt = ng_pktbuf_add(NULL, NULL, ng_pkt_len(ipv6), NG_NETTYPE_IPV6);

        if (rcv_pkt == NULL) {
            DEBUG("ipv6: error on generating loopback packet\n");
            ng_pktbuf_release(pkt);
            return;
        }

        rcv_data = rcv_pkt->data;

        /* "reverse" packet (by making it one snip as if received from NIC) */
        while (ptr != NULL) {
            memcpy(rcv_data, ptr->data, ptr->size);
            rcv_data += ptr->size;
            ptr = ptr->next;
        }

        ng_pktbuf_release(pkt);

        DEBUG("ipv6: packet is addressed to myself => loopback\n");

        ng_netapi_receive(ng_ipv6_pid, rcv_pkt);
    }
    else {
        uint8_t l2addr_len = NG_IPV6_NC_L2_ADDR_MAX;
        uint8_t l2addr[l2addr_len];

        iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst, pkt);

        if (iface == KERNEL_PID_UNDEF) {
            DEBUG("ipv6: error determining next hop's link layer address\n");
            ng_pktbuf_release(pkt);
            return;
        }

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        _send_unicast(iface, l2addr, l2addr_len, pkt);
    }
}
Example #11
0
static int _netif_add(char *cmd_name, kernel_pid_t dev, int argc, char **argv)
{
#ifdef MODULE_NG_IPV6_NETIF
    enum {
        _UNICAST = 0,
        _MULTICAST,     /* multicast value just to check if given addr is mc */
        _ANYCAST
    } type = _UNICAST;
    char *addr_str = argv[0];
    ng_ipv6_addr_t addr;
    uint8_t prefix_len;

    if (argc > 1) {
        if (strcmp(argv[0], "anycast") == 0) {
            type = _ANYCAST;
            addr_str = argv[1];
        }
        else if (strcmp(argv[0], "multicast") == 0) {
            type = _MULTICAST;
            addr_str = argv[1];
        }
        else if (strcmp(argv[0], "unicast") == 0) {
            /* type already set to unicast */
            addr_str = argv[1];
        }
        else {
            _add_usage(cmd_name);
            return 1;
        }
    }

    prefix_len = _get_prefix_len(addr_str);

    if (ng_ipv6_addr_from_str(&addr, addr_str) == NULL) {
        puts("error: unable to parse IPv6 address.");
        return 1;
    }

    if ((argc > 1) && (ng_ipv6_addr_is_multicast(&addr)) && (type != _MULTICAST)) {
        puts("error: address was not a multicast address.");
        return 1;
    }

    if (ng_ipv6_netif_add_addr(dev, &addr, prefix_len,
                               (type == _ANYCAST) ?
                               NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST :
                               NG_IPV6_NETIF_ADDR_FLAGS_UNICAST) == NULL) {
        printf("error: unable to add IPv6 address\n");
        return 1;
    }

    printf("success: added %s/%d to interface %" PRIkernel_pid "\n", addr_str,
           prefix_len, dev);

    return 0;
#else
    (void)cmd_name;
    (void)dev;
    (void)argc;
    (void)argv;
    puts("error: unable to add IPv6 address.");

    return 1;
#endif
}
Example #12
0
static void _netif_list(kernel_pid_t dev)
{
    uint8_t hwaddr[MAX_ADDR_LEN];
    uint16_t u16;
    int16_t i16;
    int res;
    ng_netconf_state_t state;
    ng_netconf_enable_t enable;
    bool linebreak = false;
#ifdef MODULE_NG_IPV6_NETIF
    ng_ipv6_netif_t *entry = ng_ipv6_netif_get(dev);
    char ipv6_addr[NG_IPV6_ADDR_MAX_STR_LEN];
#endif


    printf("Iface %2d  ", dev);

    res = ng_netapi_get(dev, NETCONF_OPT_ADDRESS, 0, hwaddr, sizeof(hwaddr));

    if (res >= 0) {
        char hwaddr_str[res * 3];
        printf(" HWaddr: ");
        printf("%s", ng_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str),
                                          hwaddr, res));
        printf(" ");
    }

    res = ng_netapi_get(dev, NETCONF_OPT_CHANNEL, 0, &u16, sizeof(u16));

    if (res >= 0) {
        printf(" Channel: %" PRIu16 " ", u16);
    }

    res = ng_netapi_get(dev, NETCONF_OPT_NID, 0, &u16, sizeof(u16));

    if (res >= 0) {
        printf(" NID: 0x%" PRIx16 " ", u16);
    }

    res = ng_netapi_get(dev, NETCONF_OPT_TX_POWER, 0, &i16, sizeof(i16));

    if (res >= 0) {
        printf(" TX-Power: %" PRIi16 "dBm ", i16);
    }

    res = ng_netapi_get(dev, NETCONF_OPT_STATE, 0, &state, sizeof(state));

    if (res >= 0) {
        printf(" State: ");
        _print_netconf_state(state);
    }

    printf("\n           ");

    res = ng_netapi_get(dev, NETCONF_OPT_ADDRESS_LONG, 0, hwaddr, sizeof(hwaddr));

    if (res >= 0) {
        char hwaddr_str[res * 3];
        printf("Long HWaddr: ");
        printf("%s", ng_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str),
                                          hwaddr, res));
        printf("\n           ");
    }

    res = ng_netapi_get(dev, NETCONF_OPT_PROMISCUOUSMODE, 0, &enable, sizeof(enable));

    if ((res >= 0) && (enable == NETCONF_ENABLE)) {
        printf("PROMISC  ");
        linebreak = true;
    }

    res = ng_netapi_get(dev, NETCONF_OPT_AUTOACK, 0, &enable, sizeof(enable));

    if ((res >= 0) && (enable == NETCONF_ENABLE)) {
        printf("AUTOACK  ");
        linebreak = true;
    }

    res = ng_netapi_get(dev, NETCONF_OPT_PRELOADING, 0, &enable, sizeof(enable));

    if ((res >= 0) && (enable == NETCONF_ENABLE)) {
        printf("PRELOAD  ");
        linebreak = true;
    }

    res = ng_netapi_get(dev, NETCONF_OPT_RAWMODE, 0, &enable, sizeof(enable));

    if ((res >= 0) && (enable == NETCONF_ENABLE)) {
        printf("RAWMODE  ");
        linebreak = true;
    }

#ifdef MODULE_NG_IPV6_NETIF
    if ((entry != NULL) && (entry->flags & NG_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
        printf("6LO ");
        linebreak = true;
    }
#endif

    if (linebreak) {
        printf("\n           ");
    }

    res = ng_netapi_get(dev, NETCONF_OPT_SRC_LEN, 0, &u16, sizeof(u16));

    if (res >= 0) {
        printf("Source address length: %" PRIu16 "\n           ", u16);
    }

#ifdef MODULE_NG_IPV6_NETIF
    for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
        if (!ng_ipv6_addr_is_unspecified(&entry->addrs[i].addr)) {
            printf("inet6 addr: ");

            if (ng_ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr,
                                    NG_IPV6_ADDR_MAX_STR_LEN)) {
                printf("%s/%" PRIu8 "  scope: ", ipv6_addr,
                       entry->addrs[i].prefix_len);

                if ((ng_ipv6_addr_is_link_local(&entry->addrs[i].addr))) {
                    printf("local");
                }
                else {
                    printf("global");
                }

                if (entry->addrs[i].flags & NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST) {
                    if (ng_ipv6_addr_is_multicast(&entry->addrs[i].addr)) {
                        printf(" [multicast]");
                    }
                    else {
                        printf(" [anycast]");
                    }
                }
            }
            else {
                printf("error in conversion");
            }

            printf("\n           ");
        }
    }
#endif

    puts("");
}
Example #13
0
static void _send(ng_pktsnip_t *pkt, bool prep_hdr)
{
    kernel_pid_t iface = KERNEL_PID_UNDEF;
    ng_pktsnip_t *ipv6, *payload;
    ng_ipv6_hdr_t *hdr;
    ng_ipv6_nc_t *nc_entry;

    /* seize payload as temporary variable */
    payload = ng_pktbuf_start_write(pkt);

    if (payload == NULL) {
        DEBUG("ipv6: unable to get write access to packet, dropping packet\n");
        ng_pktbuf_release(pkt);
        return;
    }

    pkt = payload;  /* Reset pkt from temporary variable */

    /* get IPv6 snip and (if present) generic interface header */
    if (pkt->type == NG_NETTYPE_NETIF) {
        /* If there is already a netif header (routing protocols and
         * neighbor discovery might add them to preset sending interface) */
        iface = ((ng_netif_hdr_t *)pkt->data)->if_pid;
        ipv6 = pkt->next;
    }
    else {
        ipv6 = pkt;
    }

    hdr = ipv6->data;
    payload = ipv6->next;       /* TODO: parse extension headers */

    if (ng_ipv6_addr_is_multicast(&hdr->dst)) {
        _send_multicast(iface, pkt, ipv6, payload, prep_hdr);
    }
    else {
        ng_ipv6_addr_t *next_hop = NULL;

        next_hop = &hdr->dst;   /* TODO: next hop determination */

        if ((nc_entry = ng_ipv6_nc_get_reachable(iface, next_hop)) == NULL) {
            DEBUG("ipv6: No link layer address for next_hop %s found.\n",
                  ng_ipv6_addr_to_str(addr_str, next_hop, sizeof(addr_str)));
            ng_pktbuf_release(pkt);
            return;
        }
        else {
            iface = nc_entry->iface;
        }

        if (iface == KERNEL_PID_UNDEF) {
            DEBUG("ipv6: no interface for %s registered, dropping packet\n",
                  ng_ipv6_addr_to_str(addr_str, next_hop, sizeof(addr_str)));
            ng_pktbuf_release(pkt);
            return;
        }

        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                ng_pktbuf_release(pkt);
                return;
            }
        }

        _send_unicast(iface, nc_entry->l2_addr, nc_entry->l2_addr_len, pkt);
    }
}