Пример #1
0
static bool _is_iface(kernel_pid_t dev)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t numof = gnrc_netif_get(ifs);

    for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
        if (ifs[i] == dev) {
            return true;
        }
    }

    return false;
}
Пример #2
0
static void test_gnrc_netif_remove__KERNEL_PID_UNDEF(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t size;

    test_gnrc_netif_add__success();

    gnrc_netif_remove(KERNEL_PID_UNDEF);

    size = gnrc_netif_get(ifs);
    TEST_ASSERT_EQUAL_INT(1, size);
    TEST_ASSERT_EQUAL_INT(TEST_UINT8, ifs[0]);
}
Пример #3
0
static void test_gnrc_netif_remove__not_an_if(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t size;

    test_gnrc_netif_add__success();

    gnrc_netif_remove(TEST_UINT8 + 1);

    size = gnrc_netif_get(ifs);
    TEST_ASSERT_EQUAL_INT(1, size);
    TEST_ASSERT_EQUAL_INT(TEST_UINT8, ifs[0]);
}
Пример #4
0
static void test_gnrc_netif_add__duplicate_entry(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t size;

    for (int i = 0; i < GNRC_NETIF_NUMOF + 4; i++) {
        TEST_ASSERT_EQUAL_INT(0, gnrc_netif_add(TEST_UINT8));
    }

    size = gnrc_netif_get(ifs);
    TEST_ASSERT_EQUAL_INT(1, size);
    TEST_ASSERT_EQUAL_INT(TEST_UINT8, ifs[0]);
}
Пример #5
0
static void *_ipv6_fwd_eventloop(void *arg)
{
    (void)arg;

    msg_t msg, msg_q[8];
    gnrc_netreg_entry_t me_reg;

    msg_init_queue(msg_q, 8);

    me_reg.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    me_reg.pid = thread_getpid();

    gnrc_netreg_register(GNRC_NETTYPE_SIXLOWPAN, &me_reg);

    while(1) {
        msg_receive(&msg);
        gnrc_pktsnip_t *pkt = msg.content.ptr;
        if(msg.type == GNRC_NETAPI_MSG_TYPE_SND) {
            gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
            ipv6 = ipv6->data;

            ipv6_hdr_t *ipv6_hdr =(ipv6_hdr_t *)ipv6;

            /* get the first IPv6 interface and prints its address */
            kernel_pid_t ifs[GNRC_NETIF_NUMOF];
            gnrc_netif_get(ifs);
            gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
            for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
                if ( (!ipv6_addr_is_link_local(&entry->addrs[i].addr)) && (!ipv6_addr_is_link_local(&ipv6_hdr->src)) 
                    && (!ipv6_addr_is_link_local(&ipv6_hdr->dst)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)
                    && (!ipv6_addr_is_unspecified(&entry->addrs[i].addr)) ) {

                    if(!ipv6_addr_equal(&entry->addrs[i].addr, &(ipv6_hdr->src))){

                        char addr_str[IPV6_ADDR_MAX_STR_LEN];
                        printf("IPv6 ROUTER: forward from src = %s ", ipv6_addr_to_str(addr_str, &(ipv6_hdr->src), sizeof(addr_str)) );
                        printf("to dst = %s\n",ipv6_addr_to_str(addr_str, &(ipv6_hdr->dst), sizeof(addr_str)));
                    }
                }
            }
        }
        gnrc_pktbuf_release(pkt);
    }
    /* never reached */
    return NULL;
}
Пример #6
0
int main(void)
{
#ifdef WITH_SHELL
    /* initialize message queue */
    msg_init_queue(_main_msg_q, Q_SZ);
#endif

    eui64_t iid;
    // uint16_t chan = 15;
    netopt_enable_t acks = NETOPT_DISABLE;
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];

    gnrc_netif_get(ifs);
    gnrc_netapi_set(ifs[0], NETOPT_AUTOACK, 0, &acks, sizeof(acks));
    // gnrc_netapi_set(ifs[0], NETOPT_CHANNEL, 0, &chan, sizeof(chan));
    ipv6_addr_from_str(&dst_addr, "2001:affe:1234::1");
    // ipv6_addr_from_str(&dst_addr, "fd38:3734:ad48:0:211d:50ce:a189:7cc4");

    /* initialize senml payload */
    gnrc_netapi_get(ifs[0], NETOPT_IPV6_IID, 0, &iid, sizeof(eui64_t));

    initial_pos  = sprintf(&p_buf[initial_pos], "[{\"bn\":\"urn:dev:mac:");
    initial_pos += sprintf(&p_buf[initial_pos], "%02x%02x%02x%02x%02x%02x%02x%02x",
                           iid.uint8[0], iid.uint8[1], iid.uint8[2], iid.uint8[3],
                           iid.uint8[4], iid.uint8[5], iid.uint8[6], iid.uint8[7]);
    initial_pos += sprintf(&p_buf[initial_pos], "\"},");

    /* initialize sensors */
    hdc1000_init(&th_dev, HDC1000_I2C, HDC1000_ADDR);
    hdc1000_startmeasure(&th_dev);
    mpl3115a2_init(&p_dev, MPL3115A2_I2C, MPL3115A2_ADDR, MPL3115A2_OS_RATIO_DEFAULT);
    mpl3115a2_set_active(&p_dev);
    tcs37727_init(&light_dev, TCS37727_I2C, TCS37727_ADDR, TCS37727_ATIME_DEFAULT);
    tcs37727_set_rgbc_active(&light_dev);

#ifdef WITH_SHELL
    thread_create(beac_stack, sizeof(beac_stack), PRIO, THREAD_CREATE_STACKTEST, beaconing,
                  NULL, "beaconing");
    char line_buf[SHELL_DEFAULT_BUFSIZE];
    shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
#else
    beaconing(NULL);
#endif

    return 0;
}
Пример #7
0
static int comm_init(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    uint16_t pan = COMM_PAN;
    uint16_t chan = COMM_CHAN;

    /* get the PID of the first radio */
    if (gnrc_netif_get(ifs) <= 0) {
        puts("ERROR: comm init, not radio found!\n");
        return (-1);
    }

    /* initialize the radio */
    gnrc_netapi_set(ifs[0], NETOPT_NID, 0, &pan, 2);
    gnrc_netapi_set(ifs[0], NETOPT_CHANNEL, 0, &chan, 2);
    return 0;
}
Пример #8
0
static bool _is_iface(kernel_pid_t iface)
{
#ifdef MODULE_GNRC_NETIF
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t numof = gnrc_netif_get(ifs);

    for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
        if (ifs[i] == iface) {
            return true;
        }
    }

    return false;
#else
    return (thread_get(iface) != NULL);
#endif
}
Пример #9
0
int _ipv6_nc_manage(int argc, char **argv)
{
    if ((argc == 1) || (strcmp("list", argv[1]) == 0)) {
        return _ipv6_nc_list();
    }

    if (argc > 1) {
        if ((argc == 4) && (strcmp("add", argv[1]) == 0)) {
            kernel_pid_t ifs[GNRC_NETIF_NUMOF];
            size_t ifnum = gnrc_netif_get(ifs);
            if (ifnum > 1) {
                puts("error: multiple interfaces exist.");
                return 1;
            }

            return _ipv6_nc_add(ifs[0], argv[2], argv[3]);
        }
        else if ((argc > 4) && (strcmp("add", argv[1]) == 0)) {
            kernel_pid_t iface = (kernel_pid_t)atoi(argv[2]);

            if (!_is_iface(iface)) {
                puts("error: invalid interface given.");
                return 1;
            }

            return _ipv6_nc_add(iface, argv[3], argv[4]);
        }

        if (strcmp("del", argv[1]) == 0) {
            return _ipv6_nc_del(argv[2]);
        }

        if (strcmp("reset", argv[1]) == 0) {
            return _ipv6_nc_reset();
        }
    }

    printf("usage: %s [list]\n"
           "   or: %s add [<iface pid>] <ipv6_addr> <l2_addr>\n"
           "      * <iface pid> is optional if only one interface exists.\n"
           "   or: %s del <ipv6_addr>\n"
           "   or: %s reset\n", argv[0], argv[0], argv[0], argv[0]);
    return 1;
}
Пример #10
0
int main(void)
{
#ifdef WITH_SHELL
    /* initialize message queue */
    msg_init_queue(_main_msg_q, Q_SZ);
#endif

    eui64_t iid;
    // uint16_t chan = 15;
    netopt_enable_t acks = NETOPT_DISABLE;
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];

    gnrc_netif_get(ifs);
    gnrc_netapi_set(ifs[0], NETOPT_AUTOACK, 0, &acks, sizeof(acks));
    ipv6_addr_from_str(&dst_addr, "2001:affe:1234::1");
    // gnrc_netapi_set(ifs[0], NETOPT_CHANNEL, 0, &chan, sizeof(chan));
    // ipv6_addr_from_str(&dst_addr, "fd38:3734:ad48:0:211d:50ce:a189:7cc4");

    /* initialize senml payload */
    gnrc_netapi_get(ifs[0], NETOPT_IPV6_IID, 0, &iid, sizeof(eui64_t));

    initial_pos  = sprintf(&p_buf[initial_pos], "[{\"bn\":\"urn:dev:mac:");
    initial_pos += sprintf(&p_buf[initial_pos], "%02x%02x%02x%02x%02x%02x%02x%02x",
                           iid.uint8[0], iid.uint8[1], iid.uint8[2], iid.uint8[3],
                           iid.uint8[4], iid.uint8[5], iid.uint8[6], iid.uint8[7]);
    initial_pos += sprintf(&p_buf[initial_pos], "\"},");

    thread_create(coap_stack, sizeof(coap_stack), PRIO - 1, THREAD_CREATE_STACKTEST, microcoap_server,
                  NULL, "coap");
#ifdef WITH_SHELL
    thread_create(beac_stack, sizeof(beac_stack), PRIO, THREAD_CREATE_STACKTEST, beaconing,
                  NULL, "beaconing");
    char line_buf[SHELL_DEFAULT_BUFSIZE];
    shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
#else
    beaconing(NULL);
#endif

    return 0;
}
Пример #11
0
/* takes one out of the middle of the netif list and checks if all interfaces
 * are gotten regardless */
static void test_ng_netif_get__success_3_minus_one(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t size;
    int count = 0;

    for (int i = 0; i < 3; i++) {
        TEST_ASSERT_EQUAL_INT(0, gnrc_netif_add(TEST_UINT8 + i));
    }

    gnrc_netif_remove(TEST_UINT8 + 1);

    size = gnrc_netif_get(ifs);
    TEST_ASSERT_EQUAL_INT(2, size);

    for (size_t i = 0; i < size; i++) {
        if ((ifs[i] == TEST_UINT8) || ifs[i] == (TEST_UINT8 + 2)) {
            count++;
        }
    }

    TEST_ASSERT_EQUAL_INT(size, count);
}
Пример #12
0
static int _send(int argc, char **argv)
{
    (void) argc;
    (void) argv;
    gnrc_pktsnip_t *pkt, *hdr;
    gnrc_netif_hdr_t *nethdr;
    uint8_t addr[8];
    size_t addr_len = 0;
    uint8_t flags = 0x00;

    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t numof = gnrc_netif_get(ifs);

    for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {

        flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;

        /* put packet together */
        conn_test_payload_t payload;
        payload.id = conn_test_id;
     //   memcpy(payload.txt, CONN_TEST_PAYLOAD, sizeof(CONN_TEST_PAYLOAD));

        pkt = gnrc_pktbuf_add(NULL, &payload, sizeof(payload), GNRC_NETTYPE_UNDEF);
        hdr = gnrc_netif_hdr_build(NULL, 0, addr, addr_len);
        LL_PREPEND(pkt, hdr);
        nethdr = (gnrc_netif_hdr_t *)hdr->data;
        nethdr->flags = flags;
        /* and send it */
        if (gnrc_netapi_send(ifs[i], pkt) < 1) {
            puts("error: unable to send\n");
            gnrc_pktbuf_release(pkt);
        }
    }

    return 0;
}
Пример #13
0
int _netif_config(int argc, char **argv)
{
    if (argc < 2) {
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t numof = gnrc_netif_get(ifs);

        for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
            _netif_list(ifs[i]);
        }

        return 0;
    }
    else if (_is_number(argv[1])) {
        kernel_pid_t dev = (kernel_pid_t)atoi(argv[1]);

        if (_is_iface(dev)) {
            if (argc < 3) {
                _netif_list(dev);
                return 0;
            }
            else if (strcmp(argv[2], "set") == 0) {
                if (argc < 5) {
                    _set_usage(argv[0]);
                    return 1;
                }

                return _netif_set(argv[0], dev, argv[3], argv[4]);
            }
            else if (strcmp(argv[2], "add") == 0) {
                if (argc < 4) {
                    _add_usage(argv[0]);
                    return 1;
                }

                return _netif_add(argv[0], (kernel_pid_t)dev, argc - 3, argv + 3);
            }
            else if (strcmp(argv[2], "del") == 0) {
                if (argc < 4) {
                    _del_usage(argv[0]);
                    return 1;
                }

                return _netif_del((kernel_pid_t)dev, argv[3]);
            }
            else {
                return _netif_flag(argv[0], dev, argv[2]);
            }
        }
        else {
            puts("error: invalid interface given");
            return 1;
        }
    }

    printf("usage: %s [<if_id>]\n", argv[0]);
    _set_usage(argv[0]);
    _flag_usage(argv[0]);
    _add_usage(argv[0]);
    _del_usage(argv[0]);
    return 1;
}
Пример #14
0
static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                            gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *payload,
                            bool prep_hdr)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t ifnum = 0;

    if (iface == KERNEL_PID_UNDEF) {
        /* get list of interfaces */
        ifnum = gnrc_netif_get(ifs);

        /* throw away packet if no one is interested */
        if (ifnum == 0) {
            DEBUG("ipv6: no interfaces registered, dropping packet\n");
            gnrc_pktbuf_release(pkt);
            return;
        }
    }


#if GNRC_NETIF_NUMOF > 1
    /* netif header not present: send over all interfaces */
    if (iface == KERNEL_PID_UNDEF) {
        assert(pkt == ipv6);
        /* send packet to link layer */
        gnrc_pktbuf_hold(pkt, ifnum - 1);

        for (size_t i = 0; i < ifnum; i++) {
            gnrc_pktsnip_t *netif;
            if (prep_hdr) {
                /* need to get second write access (duplication) to fill IPv6
                 * header interface-local */
                gnrc_pktsnip_t *tmp = gnrc_pktbuf_start_write(pkt);
                gnrc_pktsnip_t *ptr = tmp->next;
                ipv6 = tmp;

                if (ipv6 == NULL) {
                    DEBUG("ipv6: unable to get write access to IPv6 header, "
                          "for interface %" PRIkernel_pid "\n", ifs[i]);
                    gnrc_pktbuf_release(pkt);
                    return;
                }

                /* multiple interfaces => possibly different source addresses
                 * => different checksums => duplication of payload needed */
                while (ptr != payload->next) {
                    /* duplicate everything including payload */
                    tmp->next = gnrc_pktbuf_start_write(ptr);
                    if (tmp->next == NULL) {
                        DEBUG("ipv6: unable to get write access to payload, drop it\n");
                        gnrc_pktbuf_release(ipv6);
                        return;
                    }
                    tmp = tmp->next;
                    ptr = ptr->next;
                }

                if (_fill_ipv6_hdr(ifs[i], ipv6, tmp) < 0) {
                    /* error on filling up header */
                    gnrc_pktbuf_release(ipv6);
                    return;
                }
            }

            /* allocate interface header */
            netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

            if (netif == NULL) {
                DEBUG("ipv6: error on interface header allocation, "
                      "dropping packet\n");
                gnrc_pktbuf_release(ipv6);
                return;
            }

            LL_PREPEND(ipv6, netif);

            _send_multicast_over_iface(ifs[i], ipv6);
        }
    }
    else {
        /* iface != KERNEL_PID_UNDEF implies that netif header is present */
        assert(pkt != ipv6);
        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                gnrc_pktbuf_release(pkt);
                return;
            }
        }

        _send_multicast_over_iface(iface, pkt);
    }
#else   /* GNRC_NETIF_NUMOF */
    (void)ifnum; /* not used in this build branch */
    if (iface == KERNEL_PID_UNDEF) {
        gnrc_pktsnip_t *netif;
        iface = ifs[0];

        /* allocate interface header */
        netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

        if (netif == NULL) {
            DEBUG("ipv6: error on interface header allocation, "
                  "dropping packet\n");
            gnrc_pktbuf_release(pkt);
            return;
        }

        LL_PREPEND(pkt, netif);
    }

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

    _send_multicast_over_iface(iface, pkt);
#endif  /* GNRC_NETIF_NUMOF */
}
Пример #15
0
void gnrc_ipv6_netif_init_by_dev(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t ifnum = gnrc_netif_get(ifs);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
    bool abr_init = false;
#endif

    for (size_t i = 0; i < ifnum; i++) {
        ipv6_addr_t addr;
        eui64_t iid;
        uint16_t tmp;
        gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(ifs[i]);

        if (ipv6_if == NULL) {
            continue;
        }

        mutex_lock(&ipv6_if->mutex);

#ifdef MODULE_GNRC_SIXLOWPAN
        gnrc_nettype_t if_type = GNRC_NETTYPE_UNDEF;

        if ((gnrc_netapi_get(ifs[i], NETOPT_PROTO, 0, &if_type,
                             sizeof(if_type)) != -ENOTSUP) &&
            (if_type == GNRC_NETTYPE_SIXLOWPAN)) {
            uint16_t src_len = 8;
            uint16_t max_frag_size = UINT16_MAX;

            DEBUG("ipv6 netif: Set 6LoWPAN flag\n");
            ipv6_ifs[i].flags |= GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN;

            /* the router flag must be set early here, because otherwise
             * _add_addr_to_entry() wouldn't set the solicited node address.
             * However, addresses have to be configured before calling
             * gnrc_ipv6_netif_set_router().
             */
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
            DEBUG("ipv6 netif: Set router flag\n");
            ipv6_ifs[i].flags |= GNRC_IPV6_NETIF_FLAGS_ROUTER;
#endif
            /* use EUI-64 (8-byte address) for IID generation and for sending
             * packets */
            gnrc_netapi_set(ifs[i], NETOPT_SRC_LEN, 0, &src_len,
                            sizeof(src_len)); /* don't care for result */

            if (gnrc_netapi_get(ifs[i], NETOPT_MAX_PACKET_SIZE,
                                0, &max_frag_size, sizeof(max_frag_size)) < 0) {
                /* if error we assume it works */
                DEBUG("ipv6 netif: Can not get max packet size from interface %"
                      PRIkernel_pid "\n", ifs[i]);
            }

            gnrc_sixlowpan_netif_add(ifs[i], max_frag_size);
        }
#endif

        /* set link-local address */
        if ((gnrc_netapi_get(ifs[i], NETOPT_IPV6_IID, 0, &iid,
                             sizeof(eui64_t)) < 0)) {
            mutex_unlock(&ipv6_if->mutex);
            continue;
        }

        ipv6_addr_set_aiid(&addr, iid.uint8);
        ipv6_addr_set_link_local_prefix(&addr);
        _add_addr_to_entry(ipv6_if, &addr, 64, 0);

        /* set link MTU */
        if ((gnrc_netapi_get(ifs[i], NETOPT_MAX_PACKET_SIZE, 0, &tmp,
                             sizeof(uint16_t)) >= 0)) {
            if (tmp >= IPV6_MIN_MTU) {
                ipv6_if->mtu = tmp;
            }
            /* otherwise leave at GNRC_IPV6_NETIF_DEFAULT_MTU as initialized in
             * gnrc_ipv6_netif_add() */
        }

        if (gnrc_netapi_get(ifs[i], NETOPT_IS_WIRED, 0, &tmp, sizeof(int)) > 0) {
            ipv6_if->flags |= GNRC_IPV6_NETIF_FLAGS_IS_WIRED;
        }
        else {
            ipv6_if->flags &= ~GNRC_IPV6_NETIF_FLAGS_IS_WIRED;
        }

        mutex_unlock(&ipv6_if->mutex);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
        gnrc_ipv6_netif_set_router(ipv6_if, true);
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND
        if (ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
            /* first interface wins */
            if (!abr_init) {
                gnrc_sixlowpan_nd_router_abr_create(&addr, 0);
                gnrc_ipv6_netif_set_rtr_adv(ipv6_if, true);
                abr_init = true;
            }
#endif
            gnrc_sixlowpan_nd_init(ipv6_if);
            continue;   /* skip gnrc_ndp_host_init() */
        }
#endif
#ifdef MODULE_GNRC_NDP_HOST
        /* start periodic router solicitations */
        gnrc_ndp_host_init(ipv6_if);
#endif
    }
}
Пример #16
0
kernel_pid_t gnrc_sixlowpan_nd_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                               kernel_pid_t iface, ipv6_addr_t *dst)
{
    ipv6_addr_t *next_hop = NULL;
    gnrc_ipv6_nc_t *nc_entry = NULL;

#ifdef MODULE_GNRC_IPV6_EXT_RH
    ipv6_hdr_t *hdr;
    gnrc_pktsnip_t *ipv6;
    LL_SEARCH_SCALAR(pkt, ipv6, type, GNRC_NETTYPE_IPV6);
    assert(ipv6);
    hdr = ipv6->data;
    next_hop = ipv6_ext_rh_next_hop(hdr);
#endif
#ifdef MODULE_FIB
    ipv6_addr_t next_hop_actual;    /* FIB copies address into this variable */
    /* don't look-up link local addresses in FIB */
    if ((next_hop == NULL) && !ipv6_addr_is_link_local(dst)) {
        size_t next_hop_size = sizeof(ipv6_addr_t);
        uint32_t next_hop_flags = 0;
        if ((next_hop == NULL) &&
            (fib_get_next_hop(&gnrc_ipv6_fib_table, &iface, next_hop_actual.u8, &next_hop_size,
                              &next_hop_flags, (uint8_t *)dst,
                              sizeof(ipv6_addr_t), 0) >= 0) &&
            (next_hop_size == sizeof(ipv6_addr_t))) {
            next_hop = &next_hop_actual;
        }
    }
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
    /* next hop determination: https://tools.ietf.org/html/rfc6775#section-6.5.4 */
    nc_entry = gnrc_ipv6_nc_get(iface, dst);
    /* if NCE found */
    if (nc_entry != NULL) {
        gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(nc_entry->iface);
        /* and interface is not 6LoWPAN */
        if (!(ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) ||
                /* or entry is registered */
                (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_REGISTERED)) {
        next_hop = dst;
        }
    }
#endif
    /* next hop determination according to: https://tools.ietf.org/html/rfc6775#section-5.6 */
    if ((next_hop == NULL) && ipv6_addr_is_link_local(dst)) {   /* prefix is "on-link" */
        /* multicast is not handled here anyway so we don't need to check that */
        next_hop = dst;
    }
    else if (next_hop == NULL) {                                /* prefix is off-link */
        next_hop = gnrc_ndp_internal_default_router();
    }

    /* address resolution of next_hop: https://tools.ietf.org/html/rfc6775#section-5.7 */
    if ((nc_entry == NULL) || (next_hop != dst)) {
        /* get if not gotten from previous check */
        nc_entry = gnrc_ipv6_nc_get(iface, next_hop);
    }
    /* If a NCE for this destination exist, we can use even for link-local
     * addresses. This should be only the case for 6LBRs. */
    if ((ipv6_addr_is_link_local(next_hop)) && (nc_entry == NULL)) {
/* in case of a border router there is no sensible way for address resolution
 * if the interface is not given */
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
        /* if no interface is specified it is impossible to resolve the
         * link-layer address for a link-local address on a 6LBR */
        if (iface == KERNEL_PID_UNDEF) {
            return KERNEL_PID_UNDEF;
        }
#endif
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t ifnum = gnrc_netif_get(ifs);
        /* we don't need address resolution, the EUI-64 is in next_hop's IID */
        *l2addr_len = sizeof(eui64_t);
        memcpy(l2addr, &next_hop->u8[8], sizeof(eui64_t));
        _revert_iid(l2addr);
        if (iface == KERNEL_PID_UNDEF) {
            for (unsigned i = 0; i < ifnum; i++) {
                gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(ifs[i]);
                if ((ipv6_if != NULL) && (ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
                    /* always take the first 6LoWPAN interface we can find */
                    return ifs[i];
                }
            }
        }
        return iface;
    }
    if ((nc_entry == NULL) || (!gnrc_ipv6_nc_is_reachable(nc_entry)) ||
        (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_TENTATIVE)) {
        return KERNEL_PID_UNDEF;
    }
    else {
        if (nc_entry->l2_addr_len > 0) {
            memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
        }
        *l2addr_len = nc_entry->l2_addr_len;
    }
    return nc_entry->iface;
}
Пример #17
0
int watr_li_network_init (void)
{
    DEBUG("%s()\n", __func__);
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    uint16_t channel = WATR_LI_CHANNEL;
    uint16_t pan_id = WATR_LI_PAN;

    if (0 >= gnrc_netif_get(ifs)) {
        puts ("[watr_li_network_init] ERROR: failed to get ifaces!");
        return -1;
    }
    if (0 > gnrc_netapi_set(ifs[0], NETOPT_CHANNEL, 0, (uint16_t *)&channel, sizeof(uint16_t))) {
        puts ("[watr_li_network_init] ERROR: failed to set channel!");
        return -1;
    }
    if (0 > gnrc_netapi_set(ifs[0], NETOPT_NID, 0, (uint16_t *)&pan_id, sizeof(uint16_t))) {
        puts ("[watr_li_network_init] ERROR: failed to set pan_id!");
        return -1;
    }

    uint8_t iid[8];
    if (0 > gnrc_netapi_get(ifs[0], NETOPT_IPV6_IID, 0, &iid, sizeof(iid))) {
        puts ("[watr_li_network_init] ERROR: failed to get IPv6 IID!");
        return -1;
    }

#ifdef WATR_LI_GLOBAL_IPV6
    ipv6_addr_t myaddr;
    ipv6_addr_set_aiid(&myaddr, iid);
    myaddr.u64[0] = byteorder_htonll(0x2015110700000000);
    if (0 > gnrc_ipv6_netif_add_addr(ifs[0], &myaddr, 64, 0)) {
        puts ("[watr_li_network_init] ERROR: failed to set IPv6 addr!");
        return -1;
    }
#endif

    send_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (send_sock < 0) {
        puts("[watr_li_network_init] ERROR: initializing send socket!");
        return -1;
    }
    /* FIXME stringify my_id. we'll be needing this in a sec. */
    memset(my_id, 0, sizeof(my_id));
    sprintf(my_id,
            "%02X%02X%02X%02X%02X%02X%02X%02X",
            iid[0],iid[1],iid[2],iid[3],iid[4],iid[5],iid[6],iid[7]);

    /* Add my_id to humidity_path */
    register_path = (coap_endpoint_path_t) {1, {"nodes"}}; //FIXME: should be nodes/my_id ?
    humidity_path = (coap_endpoint_path_t) {3, {"nodes", my_id, "humidity"}};

    if (0 > watr_li_set_root_addr(watr_li_root_addr_str)) {
        puts("[watr_li_network_init] ERROR: failed to set root_addr!");
        return -1;
    }
    if (0 > watr_li_register_at_root(my_id)) {
        puts("[watr_li_network_init] ERROR: failed to register at root!");
        return -1;
    }
    return 0;
}
Пример #18
0
static void test_ng_netif_get__empty(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t size = gnrc_netif_get(ifs);
    TEST_ASSERT_EQUAL_INT(0, size);
}
Пример #19
0
int _netif_config(int argc, char **argv)
{
    if (argc < 2) {
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t numof = gnrc_netif_get(ifs);

        for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
            _netif_list(ifs[i]);
        }

        return 0;
    }
    else if (_is_number(argv[1])) {
        kernel_pid_t dev = (kernel_pid_t)atoi(argv[1]);

        if (_is_iface(dev)) {
            if (argc < 3) {
                _netif_list(dev);
                return 0;
            }
            else if (strcmp(argv[2], "set") == 0) {
                if (argc < 5) {
                    _set_usage(argv[0]);
                    return 1;
                }

                return _netif_set(argv[0], dev, argv[3], argv[4]);
            }
            else if (strcmp(argv[2], "add") == 0) {
                if (argc < 4) {
                    _add_usage(argv[0]);
                    return 1;
                }

                return _netif_add(argv[0], (kernel_pid_t)dev, argc - 3, argv + 3);
            }
            else if (strcmp(argv[2], "del") == 0) {
                if (argc < 4) {
                    _del_usage(argv[0]);
                    return 1;
                }

                return _netif_del((kernel_pid_t)dev, argv[3]);
            }
            else if (strcmp(argv[2], "mtu") == 0) {
                if (argc < 4) {
                    _mtu_usage(argv[0]);
                    return 1;
                }

                return _netif_mtu((kernel_pid_t)dev, argv[3]);
            }
#ifdef MODULE_GNRC_IPV6_NETIF
            else if (strcmp(argv[2], "hl") == 0) {
                if (argc < 4) {
                    _hl_usage(argv[0]);
                    return 1;
                }
                int hl;
                gnrc_ipv6_netif_t *entry;
                if (((hl = atoi(argv[3])) < 0) || (hl > UINT8_MAX)) {
                    printf("error: Hop limit must be between %" PRIu16 " and %" PRIu16 "\n",
                            (uint16_t)0, (uint16_t)UINT16_MAX);
                    return 1;
                }
                if ((entry = gnrc_ipv6_netif_get(dev)) == NULL) {
                    puts("error: unable to set hop limit.");
                    return 1;
                }
                entry->cur_hl = hl;
                printf("success: set hop limit %u interface %" PRIkernel_pid "\n", hl, dev);

                return 0;
            }
#endif
            else {
                return _netif_flag(argv[0], dev, argv[2]);
            }
        }
        else {
            puts("error: invalid interface given");
            return 1;
        }
    }

    printf("usage: %s [<if_id>]\n", argv[0]);
    _set_usage(argv[0]);
    _mtu_usage(argv[0]);
    _hl_usage(argv[0]);
    _flag_usage(argv[0]);
    _add_usage(argv[0]);
    _del_usage(argv[0]);
    return 1;
}
Пример #20
0
int _fib_route_handler(int argc, char **argv)
{
    /* e.g. fibroute right now dont care about the adress/protocol family */
    if (argc == 1) {
        fib_print_routes(&gnrc_ipv6_fib_table);
        return 0;
    }

    /* e.g. firoute [add|del] */
    if (argc == 2) {
        if ((strcmp("add", argv[1]) == 0)) {
            _fib_usage(2);
        }
        else if ((strcmp("del", argv[1]) == 0)) {
            _fib_usage(3);
        }
        else if ((strcmp("flush", argv[1]) == 0)) {
            fib_flush(&gnrc_ipv6_fib_table, KERNEL_PID_UNDEF);
            puts("successfully flushed all entries");
        }
        else {
            _fib_usage(0);
        }

        return 1;
    }

    if (argc > 2 && !((strcmp("add", argv[1]) == 0) ||
                      (strcmp("del", argv[1]) == 0) ||
                      (strcmp("flush", argv[1]) == 0))) {
        puts("\nunrecognized parameter2.\nPlease enter fibroute [add|del] for more information.");
        return 1;
    }

    /* e.g. fibroute del <destination> */
    if (argc == 3) {
        if ((strcmp("flush", argv[1]) == 0)) {
            kernel_pid_t iface = atoi(argv[2]);
            if (gnrc_netif_exist(iface)) {
                fib_flush(&gnrc_ipv6_fib_table, iface);
                printf("successfully flushed all entries for interface %" PRIu16"\n", iface);
            }
            else {
                printf("interface %" PRIu16" does not exist\n", iface);
            }
        }
        else if (inet_pton(AF_INET6, argv[2], tmp_ipv6_dst)) {
            fib_remove_entry(&gnrc_ipv6_fib_table, tmp_ipv6_dst, IN6ADDRSZ);
        }
        else if (inet_pton(AF_INET, argv[2], tmp_ipv4_dst)) {
            fib_remove_entry(&gnrc_ipv6_fib_table, tmp_ipv4_dst, INADDRSZ);
        }
        else {
            fib_remove_entry(&gnrc_ipv6_fib_table, (uint8_t *)argv[2],
                             (strlen(argv[2])));
        }

        return 0;
    }

#ifdef MODULE_GNRC_NETIF
    /* e.g. fibroute add <destination> via <next hop> */
    if ((argc == 5) && (strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0)) {
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t ifnum = gnrc_netif_get(ifs);
        if (ifnum == 1) {
            _fib_add(argv[2], argv[4], ifs[0], (uint32_t)FIB_LIFETIME_NO_EXPIRE);
        }
        else {
            _fib_usage(1);
            return 1;
        }

        return 0;
    }

    /* e.g. fibroute add <destination> via <next hop> lifetime <lifetime> */
    if ((argc == 7) && (strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0)
            && (strcmp("lifetime", argv[5]) == 0)) {
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t ifnum = gnrc_netif_get(ifs);
        if (ifnum == 1) {
            _fib_add(argv[2], argv[4], ifs[0], (uint32_t)atoi(argv[6]));
        }
        else {
            _fib_usage(1);
            return 1;
        }

        return 0;
    }
#endif

    /* e.g. fibroute add <destination> via <next hop> dev <device> */
    if (argc == 7) {
        if ((strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0)
            && (strcmp("dev", argv[5]) == 0)) {
            _fib_add(argv[2], argv[4], (kernel_pid_t)atoi(argv[6]), (uint32_t)FIB_LIFETIME_NO_EXPIRE);
        }
        else {
            _fib_usage(1);
            return 1;
        }

        return 0;
    }

    /* e.g. fibroute add <destination> via <next hop> dev <device> lifetime <lifetime> */
    if (argc == 9) {
        if ((strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0)
            && (strcmp("dev", argv[5]) == 0)
            && (strcmp("lifetime", argv[7]) == 0)) {
            _fib_add(argv[2], argv[4], (kernel_pid_t )atoi(argv[6]), (uint32_t)atoi(argv[8]));
        }
        else {
            _fib_usage(2);
            return 1;
        }

        return 0;
    }

    puts("\nunrecognized parameters.\nPlease enter fibroute [add|del] for more information.");
    return 1;
}
Пример #21
0
int _netif_config(int argc, char **argv)
{
    if (argc < 2) {
        kernel_pid_t ifs[GNRC_NETIF_NUMOF];
        size_t numof = gnrc_netif_get(ifs);

        for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
            _netif_list(ifs[i]);
        }

        return 0;
    }
    else if (_is_number(argv[1])) {
        kernel_pid_t dev = atoi(argv[1]);

        if (_is_iface(dev)) {
            if (argc < 3) {
                _netif_list(dev);
                return 0;
            }
            else if (strcmp(argv[2], "set") == 0) {
                if (argc < 5) {
                    _set_usage(argv[0]);
                    return 1;
                }

                return _netif_set(argv[0], dev, argv[3], argv[4]);
            }
            else if (strcmp(argv[2], "add") == 0) {
                if (argc < 4) {
                    _add_usage(argv[0]);
                    return 1;
                }

                return _netif_add(argv[0], (kernel_pid_t)dev, argc - 3, argv + 3);
            }
            else if (strcmp(argv[2], "del") == 0) {
                if (argc < 4) {
                    _del_usage(argv[0]);
                    return 1;
                }

                return _netif_del((kernel_pid_t)dev, argv[3]);
            }
            else if (strcmp(argv[2], "mtu") == 0) {
                if (argc < 4) {
                    _mtu_usage(argv[0]);
                    return 1;
                }

                return _netif_mtu((kernel_pid_t)dev, argv[3]);
            }
#ifdef MODULE_L2FILTER
            else if (strcmp(argv[2], "l2filter") == 0) {
                if (argc < 5) {
                    _l2filter_usage(argv[2]);
                }
                else if (strcmp(argv[3], "add") == 0) {
                    return _netif_addrm_l2filter(dev, argv[4], true);
                }
                else if (strcmp(argv[3], "del") == 0) {
                    return _netif_addrm_l2filter(dev, argv[4], false);
                }
                else {
                    _l2filter_usage(argv[2]);
                }
                return 1;
            }
#endif
#ifdef MODULE_NETSTATS
            else if (strcmp(argv[2], "stats") == 0) {
                uint8_t module;
                bool reset = false;

                /* check for requested module */
                if ((argc == 3) || (strcmp(argv[3], "all") == 0)) {
                    module = NETSTATS_ALL;
                }
                else if (strcmp(argv[3], "l2") == 0) {
                    module = NETSTATS_LAYER2;
                }
                else if (strcmp(argv[3], "ipv6") == 0) {
                    module = NETSTATS_IPV6;
                }
                else {
                    printf("Module %s doesn't exist or does not provide statistics.\n", argv[3]);

                    return 0;
                }

                /* check if reset flag was given */
                if ((argc > 4) && (strncmp(argv[4], "reset", 5) == 0)) {
                    reset = true;
                }
                if (module & NETSTATS_LAYER2) {
                    _netif_stats((kernel_pid_t) dev, NETSTATS_LAYER2, reset);
                }
                if (module & NETSTATS_IPV6) {
                    _netif_stats((kernel_pid_t) dev, NETSTATS_IPV6, reset);
                }

                return 1;
            }
#endif
#ifdef MODULE_GNRC_IPV6_NETIF
            else if (strcmp(argv[2], "hl") == 0) {
                if (argc < 4) {
                    _hl_usage(argv[0]);
                    return 1;
                }
                int hl;
                gnrc_ipv6_netif_t *entry;
                if (((hl = atoi(argv[3])) < 0) || (hl > UINT8_MAX)) {
                    printf("error: Hop limit must be between %" PRIu16 " and %" PRIu16 "\n",
                           (uint16_t)0, (uint16_t)UINT16_MAX);
                    return 1;
                }
                if ((entry = gnrc_ipv6_netif_get(dev)) == NULL) {
                    puts("error: unable to set hop limit.");
                    return 1;
                }
                entry->cur_hl = hl;
                printf("success: set hop limit %u interface %" PRIkernel_pid "\n", hl, dev);

                return 0;
            }
#endif
            else {
                return _netif_flag(argv[0], dev, argv[2]);
            }
        }
        else {
            puts("error: invalid interface given");
            return 1;
        }
    }

    printf("usage: %s [<if_id>]\n", argv[0]);
    _set_usage(argv[0]);
    _mtu_usage(argv[0]);
#ifdef MODULE_GNRC_IPV6_NETIF
    _hl_usage(argv[0]);
#endif
    _flag_usage(argv[0]);
    _add_usage(argv[0]);
    _del_usage(argv[0]);
#ifdef MODULE_L2FILTER
    _l2filter_usage(argv[0]);
#endif
#ifdef MODULE_NETSTATS
    _stats_usage(argv[0]);
#endif
    return 1;
}
Пример #22
0
static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                            gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *payload,
                            bool prep_hdr)
{
    gnrc_pktsnip_t *netif;
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
    size_t ifnum = 0;

    if (iface == KERNEL_PID_UNDEF) {
        /* get list of interfaces */
        ifnum = gnrc_netif_get(ifs);

        /* throw away packet if no one is interested */
        if (ifnum == 0) {
            DEBUG("ipv6: no interfaces registered, dropping packet\n");
            gnrc_pktbuf_release(pkt);
            return;
        }
    }


#if GNRC_NETIF_NUMOF > 1
    /* netif header not present: send over all interfaces */
    if (iface == KERNEL_PID_UNDEF) {
        /* send packet to link layer */
        gnrc_pktbuf_hold(pkt, ifnum - 1);

        for (size_t i = 0; i < ifnum; i++) {
            if (prep_hdr) {
                /* need to get second write access (duplication) to fill IPv6
                 * header interface-local */
                ipv6 = gnrc_pktbuf_start_write(ipv6);

                if (ipv6 == NULL) {
                    DEBUG("ipv6: unable to get write access to IPv6 header, "
                          "for interface %" PRIkernel_pid "\n", ifs[i]);
                    gnrc_pktbuf_release(pkt);
                    return;
                }

                if (_fill_ipv6_hdr(ifs[i], ipv6, payload) < 0) {
                    /* error on filling up header */
                    gnrc_pktbuf_release(pkt);
                    return;
                }
            }

            /* allocate interface header */
            netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

            if (netif == NULL) {
                DEBUG("ipv6: error on interface header allocation, "
                      "dropping packet\n");
                gnrc_pktbuf_release(pkt);
                return;
            }

            LL_PREPEND(pkt, netif);

            _send_multicast_over_iface(ifs[i], pkt, netif);
        }
    }
    else {
        /* iface != KERNEL_PID_UNDEF implies that netif header is present */
        if (prep_hdr) {
            if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) {
                /* error on filling up header */
                gnrc_pktbuf_release(pkt);
                return;
            }
        }

        netif = pkt;

        _send_multicast_over_iface(iface, pkt, netif);
    }
#else   /* GNRC_NETIF_NUMOF */
    (void)ifnum; /* not used in this build branch */
    if (iface == KERNEL_PID_UNDEF) {
        iface = ifs[0];

        /* allocate interface header */
        netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);

        if (netif == NULL) {
            DEBUG("ipv6: error on interface header allocation, "
                  "dropping packet\n");
            gnrc_pktbuf_release(pkt);
            return;
        }

        LL_PREPEND(pkt, netif);
    }
    else {
        netif = pkt;
    }

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

    _send_multicast_over_iface(iface, pkt, netif);
#endif  /* GNRC_NETIF_NUMOF */
}