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; }
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]); }
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]); }
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]); }
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; }
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; }
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; }
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 }
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; }
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; }
/* 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); }
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; }
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; }
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 */ }
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 } }
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; }
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; }
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); }
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; }
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; }
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; }
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 */ }