gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr) { gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, ipv6_addr); if (entry == NULL) { DEBUG("ipv6_nc: No entry found for %s\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); return NULL; } if ((gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_INCOMPLETE) && (gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_UNMANAGED)) { #if defined(MODULE_GNRC_IPV6_NETIF) && defined(MODULE_VTIMER) && defined(MODULE_GNRC_IPV6) gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(entry->iface); timex_t t = iface->reach_time; vtimer_remove(&entry->nbr_sol_timer); vtimer_set_msg(&entry->nbr_sol_timer, t, gnrc_ipv6_pid, GNRC_NDP_MSG_NC_STATE_TIMEOUT, entry); #endif DEBUG("ipv6_nc: Marking entry %s as reachable\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); entry->flags &= ~(GNRC_IPV6_NC_STATE_MASK >> GNRC_IPV6_NC_STATE_POS); entry->flags |= (GNRC_IPV6_NC_STATE_REACHABLE >> GNRC_IPV6_NC_STATE_POS); }
void print_tcp_status(int in_or_out, ipv6_hdr_t *ipv6_header, tcp_hdr_t *tcp_header, socket_t *tcp_socket) { char addr_str[IPV6_MAX_ADDR_STR_LEN]; printf("--- %s TCP packet: ---\n", (in_or_out == INC_PACKET ? "Incoming" : "Outgoing")); printf("IPv6 Source: %s\n", ipv6_addr_to_str(addr_str, &ipv6_header->srcaddr)); printf("IPv6 Dest: %s\n", ipv6_addr_to_str(addr_str, &ipv6_header->destaddr)); printf("TCP Length: %x\n", ipv6_header->length - TCP_HDR_LEN); printf("Source Port: %x, Dest. Port: %x\n", NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); printf("Source Port: %u, Dest. Port: %u\n", NTOHS(tcp_header->src_port), NTOHS(tcp_header->dst_port)); printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %x\n", tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); printf("ACK: %" PRIu32 ", SEQ: %" PRIu32 ", Window: %u\n", tcp_header->ack_nr, tcp_header->seq_nr, tcp_header->window); print_tcp_flags(tcp_header); print_tcp_cb(&tcp_socket->tcp_control); #ifdef TCP_HC printf_tcp_context(&tcp_socket->tcp_control.tcp_context); #endif }
void rpl_udp_dodag(int argc, char **argv) { (void) argc; (void) argv; printf("---------------------------\n"); rpl_dodag_t *mydodag = rpl_get_my_dodag(); if (mydodag == NULL) { printf("Not part of a dodag\n"); printf("---------------------------\n"); return; } printf("Part of Dodag:\n"); printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (&mydodag->dodag_id))); printf("my rank: %d\n", mydodag->my_rank); if (!is_root) { printf("my preferred parent:\n"); printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (&mydodag->my_preferred_parent->addr))); } printf("---------------------------\n"); }
/** * @brief Check if the given IPv6 address is assigned to any configured * interface * * @param[in] addr The IPv6 address to check * * @return 1 If *addr* is assigned to at least one interface * @return 0 If *addr* is not assigned to any interface * @return -1 If no IPv6 address is configured to any interface */ static int is_our_address(ipv6_addr_t *addr) { int if_id = -1; int if_counter = -1; DEBUGF("Is this my addres: %s?\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, addr)); while ((if_id = net_if_iter_interfaces(if_id)) >= 0) { ipv6_net_if_ext_t *net_if_ext = ipv6_net_if_get_ext(if_id); ipv6_net_if_addr_t *myaddr = NULL; uint8_t prefix = net_if_ext->prefix / 8; uint8_t suffix = IPV6_ADDR_LEN - prefix; while ((myaddr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id, (net_if_addr_t **) &myaddr)) != NULL) { if_counter++; DEBUGF("\tCompare with: %s?\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (ipv6_addr_t*) myaddr->addr_data)); if ((ipv6_get_addr_match(myaddr->addr_data, addr) >= net_if_ext->prefix) && (memcmp(&addr->uint8[prefix], &myaddr->addr_data->uint8[prefix], suffix) == 0)) { return 1; } } } /* return negative value if no address is configured so far */ if (if_counter >= 0) { return 0; } return -1; }
gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_lookup_addr(const ipv6_addr_t *addr) { uint8_t best = 0; gnrc_sixlowpan_ctx_t *res = NULL; mutex_lock(&_ctx_mutex); for (unsigned int id = 0; id < GNRC_SIXLOWPAN_CTX_SIZE; id++) { if (_valid(id)) { uint8_t match = ipv6_addr_match_prefix(&_ctxs[id].prefix, addr); if ((_ctxs[id].prefix_len <= match) && (match > best)) { best = match; res = &(_ctxs[id]); } } } mutex_unlock(&_ctx_mutex); #if ENABLE_DEBUG if (res != NULL) { DEBUG("6lo ctx: found context (%u, %s/%" PRIu8 ") ", (res->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK), ipv6_addr_to_str(ipv6str, &res->prefix, sizeof(ipv6str)), res->prefix_len); DEBUG("for address %s\n", ipv6_addr_to_str(ipv6str, addr, sizeof(ipv6str))); } #endif return res; }
int is_our_address(ipv6_addr_t *addr) { ipv6_net_if_ext_t *net_if_ext; ipv6_net_if_addr_t *myaddr; uint8_t prefix, suffix; int if_id = -1; DEBUGF("Is this my addres: %s?\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, addr)); while ((if_id = net_if_iter_interfaces(if_id)) >= 0) { net_if_ext = ipv6_net_if_get_ext(if_id); myaddr = NULL; prefix = net_if_ext->prefix / 8; suffix = IPV6_ADDR_LEN - prefix; while ((myaddr = (ipv6_net_if_addr_t *)net_if_iter_addresses(if_id, (net_if_addr_t **) &myaddr)) != NULL) { DEBUGF("\tCompare with: %s?\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (ipv6_addr_t*) myaddr->addr_data)); if ((ipv6_get_addr_match(myaddr->addr_data, addr) >= net_if_ext->prefix) && (memcmp(&addr->uint8[prefix], &myaddr->addr_data->uint8[prefix], suffix) == 0)) { return 1; } } } return 0; }
/* UDP send command */ void sixlowapp_udp_send(ipv6_addr_t *dest, uint16_t port, char *payload, size_t len) { int sock; sockaddr6_t sa; int bytes_sent; sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (-1 == sock) { printf("Error Creating Socket!"); return; } memset(&sa, 0, sizeof(sa)); sa.sin6_family = AF_INET; memcpy(&sa.sin6_addr, dest, 16); sa.sin6_port = HTONS(port); printf("Trying to send %i bytes to %s:%" PRIu16 "\n", len, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest), port); bytes_sent = socket_base_sendto(sock, payload, len, 0, &sa, sizeof(sa)); if (bytes_sent < 0) { printf("Error sending packet!\n"); } else { printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest)); } socket_base_close(sock); }
void _rpl_route_handler(int argc, char **argv) { (void) argc; (void) argv; rpl_routing_entry_t *rtable; rtable = rpl_get_routing_table(); unsigned c = 0; puts("--------------------------------------------------------------------"); puts("Routing table"); printf(" %-3s %-18s %-18s %s\n", "#", "target", "next hop", "lifetime"); puts("--------------------------------------------------------------------"); for (int i = 0; i < rpl_max_routing_entries; i++) { if (rtable[i].used) { c++; printf(" %03d: %-18s ", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (&rtable[i].address))); printf("%-18s ", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, (&rtable[i].next_hop))); printf("%d\n", rtable[i].lifetime); } } puts("--------------------------------------------------------------------"); printf(" %u routing table entries\n", c); puts("$"); }
ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t *addr) { DEBUGF("Looking up the next hop to %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, addr)); for (uint8_t i = 0; i < rpl_max_routing_entries; i++) { if (rpl_routing_table[i].used) { DEBUGF("checking %d: %s\n", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_routing_table[i].address)); } if ((RPL_DEFAULT_MOP == RPL_NON_STORING_MODE) && rpl_is_root()) { if (rpl_routing_table[i].used && rpl_equal_id(&rpl_routing_table[i].address, addr)) { DEBUGF("found %d: %s\n", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_routing_table[i].address)); return &rpl_routing_table[i].address; } } else { if (rpl_routing_table[i].used && rpl_equal_id(&rpl_routing_table[i].address, addr)) { DEBUGF("found %d: %s\n", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_routing_table[i].next_hop)); return &rpl_routing_table[i].next_hop; } } } return (rpl_get_my_preferred_parent()); }
/* obligatory for each mode. normally not modified */ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header) { uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); DEBUGF("Trying to send to destination: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, destination)); ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; ipv6_send_buf->flowlabel = 0; ipv6_send_buf->nextheader = next_header; ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT; ipv6_send_buf->length = HTONS(p_len); memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_net_if_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->checksum = icmpv6_csum(ipv6_send_buf, icmp_send_buf); /* The packet was "assembled" in rpl_%mode%.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the * right memory location already. */ if (p_ptr != payload) { memcpy(p_ptr, payload, p_len); } if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) { ipv6_send_packet(ipv6_send_buf, NULL); } else { /* find appropriate next hop before sending */ ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); DEBUGF("Trying to send to destination: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, next_hop)); if (next_hop == NULL) { if (i_am_root) { DEBUGF("[Error] destination unknown: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, &ipv6_send_buf->destaddr)); return; } else { next_hop = rpl_get_my_preferred_parent(); if (next_hop == NULL) { DEBUGF("[Error] no preferred parent, dropping package\n"); return; } } } DEBUGF("Sending done (for RPL)\n"); ipv6_send_packet(ipv6_send_buf, NULL); } }
void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol, size_t icmpv6_size) { uint16_t opt_offset = 0; uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX]; uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ndp_nbr_sol_t); ipv6_addr_t *tgt; int sicmpv6_size = (int)icmpv6_size, l2src_len = 0; DEBUG("ndp: received neighbor solicitation (src: %s, ", ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str))); DEBUG("dst: %s, ", ipv6_addr_to_str(addr_str, &ipv6->dst, sizeof(addr_str))); DEBUG("tgt: %s)\n", ipv6_addr_to_str(addr_str, &nbr_sol->tgt, sizeof(addr_str))); /* check validity */ if ((ipv6->hl != 255) || (nbr_sol->code != 0) || (icmpv6_size < sizeof(ndp_nbr_sol_t)) || ipv6_addr_is_multicast(&nbr_sol->tgt) || (ipv6_addr_is_unspecified(&ipv6->src) && ipv6_addr_is_solicited_node(&ipv6->dst))) { DEBUG("ndp: neighbor solicitation was invalid.\n"); /* ipv6 releases */ return; } if ((tgt = gnrc_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(ndp_nbr_sol_t); while (sicmpv6_size > 0) { ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); switch (opt->type) { case NDP_OPT_SL2A: if ((l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, nbr_sol->type, opt, l2src)) < 0) { /* -ENOTSUP can not happen, since the function only returns this for invalid * message types containing the SL2A. Neighbor solicitations are not an * invalid message type for SL2A. According to that, we don't need to watch * out for that here, but regardless, the source link-layer address option * is invalid. */ return; } break; default: /* silently discard all other options */ break; } opt_offset += (opt->len * 8); sicmpv6_size -= (opt->len * 8); } _stale_nc(iface, &ipv6->src, l2src, l2src_len); gnrc_ndp_internal_send_nbr_adv(iface, tgt, &ipv6->src, ipv6_addr_is_multicast(&ipv6->dst), NULL); }
static ipv6_addr_t *_add_addr_to_entry(gnrc_ipv6_netif_t *entry, const ipv6_addr_t *addr, uint8_t prefix_len, uint8_t flags) { gnrc_ipv6_netif_addr_t *tmp_addr = NULL; for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { if (ipv6_addr_equal(&(entry->addrs[i].addr), addr)) { return &(entry->addrs[i].addr); } if (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.", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), prefix_len, entry->pid); return NULL; } memcpy(&(tmp_addr->addr), addr, sizeof(ipv6_addr_t)); DEBUG("ipv6 netif: Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n", 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 (ipv6_addr_is_multicast(addr)) { tmp_addr->flags |= GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST; } else { ipv6_addr_t sol_node; if (!ipv6_addr_is_link_local(addr)) { /* add also corresponding link-local address */ ipv6_addr_t ll_addr; ll_addr.u64[1] = addr->u64[1]; ipv6_addr_set_link_local_prefix(&ll_addr); _add_addr_to_entry(entry, &ll_addr, 64, flags | GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK); } else { tmp_addr->flags |= GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK; } ipv6_addr_set_solicited_nodes(&sol_node, addr); _add_addr_to_entry(entry, &sol_node, IPV6_ADDR_BIT_LEN, 0); } return &(tmp_addr->addr); }
void ng_ndp_retrans_nbr_sol(ng_ipv6_nc_t *nc_entry) { if ((ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) || (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_PROBE)) { if (nc_entry->probes_remaining > 1) { ipv6_addr_t dst; DEBUG("ndp: Retransmit neighbor solicitation for %s\n", ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); /* retransmit neighbor solicatation */ if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) { ipv6_addr_set_solicited_nodes(&dst, &nc_entry->ipv6_addr); } else { dst.u64[0] = nc_entry->ipv6_addr.u64[0]; dst.u64[1] = nc_entry->ipv6_addr.u64[1]; } nc_entry->probes_remaining--; if (nc_entry->iface == KERNEL_PID_UNDEF) { timex_t t = { 0, NG_NDP_RETRANS_TIMER }; kernel_pid_t ifs[NG_NETIF_NUMOF]; size_t ifnum = ng_netif_get(ifs); for (size_t i = 0; i < ifnum; i++) { ng_ndp_internal_send_nbr_sol(ifs[i], &nc_entry->ipv6_addr, &dst); } vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); } else { ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); ng_ndp_internal_send_nbr_sol(nc_entry->iface, &nc_entry->ipv6_addr, &dst); mutex_lock(&ipv6_iface->mutex); vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, ipv6_iface->retrans_timer, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); mutex_unlock(&ipv6_iface->mutex); } } else if (nc_entry->probes_remaining <= 1) { DEBUG("ndp: Remove nc entry %s for interface %" PRIkernel_pid "\n", ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)), nc_entry->iface); ng_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr); } } }
static uint8_t _find_by_prefix_unsafe(ipv6_addr_t **res, gnrc_ipv6_netif_t *iface, const ipv6_addr_t *addr, uint8_t *only) { uint8_t best_match = 0; for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { uint8_t match; if ((only != NULL) && !(bf_isset(only, i))) { continue; } if (((only != NULL) && gnrc_ipv6_netif_addr_is_non_unicast(&(iface->addrs[i].addr))) || ipv6_addr_is_unspecified(&(iface->addrs[i].addr))) { continue; } match = ipv6_addr_match_prefix(&(iface->addrs[i].addr), addr); if ((only == NULL) && !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 ", ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)), iface->pid); DEBUG("%s by %" PRIu8 " bits (used as source address = %s)\n", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), best_match, (only != NULL) ? "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, ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), (only != NULL) ? "true" : "false"); } #endif return best_match; }
static gnrc_rpl_dodag_t *_root_dodag_init(uint8_t instance_id, ipv6_addr_t *dodag_id, uint8_t mop) { if (gnrc_rpl_pid == KERNEL_PID_UNDEF) { DEBUG("RPL: RPL thread not started\n"); return NULL; } ipv6_addr_t *configured_addr; gnrc_ipv6_netif_addr_t *netif_addr = NULL; gnrc_rpl_instance_t *inst = NULL; gnrc_rpl_dodag_t *dodag = NULL; if (instance_id == 0) { DEBUG("RPL: instance id (%d) must be a positive number greater than zero\n", instance_id); return NULL; } if (gnrc_ipv6_netif_find_by_addr(&configured_addr, dodag_id) == KERNEL_PID_UNDEF) { DEBUG("RPL: no IPv6 address configured to match the given dodag id: %s\n", ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); return NULL; } if ((netif_addr = gnrc_ipv6_netif_addr_get(configured_addr)) == NULL) { DEBUG("RPL: no netif address found for %s\n", ipv6_addr_to_str(addr_str, configured_addr, sizeof(addr_str))); return NULL; } if (gnrc_rpl_instance_add(instance_id, &inst)) { inst->of = (gnrc_rpl_of_t *) gnrc_rpl_get_of_for_ocp(GNRC_RPL_DEFAULT_OCP); inst->mop = mop; inst->min_hop_rank_inc = GNRC_RPL_DEFAULT_MIN_HOP_RANK_INCREASE; inst->max_rank_inc = GNRC_RPL_DEFAULT_MAX_RANK_INCREASE; } else if (inst == NULL) { DEBUG("RPL: could not allocate memory for a new instance with id %d", instance_id); return NULL; } else if (inst->mop != mop) { DEBUG("RPL: instance (%d) exists with another MOP", instance_id); return NULL; } if (!gnrc_rpl_dodag_add(inst, dodag_id, &dodag)) { DEBUG("RPL: DODAG with id %s exists or no memory left for a new DODAG", ipv6_addr_to_str(addr_str, dodag_id, sizeof(addr_str))); return NULL; } dodag->prefix_len = netif_addr->prefix_len; dodag->addr_preferred = netif_addr->preferred; dodag->addr_valid = netif_addr->valid; return dodag; }
void *_udp_server(void *args) { uint16_t port = (uint16_t) atoi(args); ipv6_addr_t server_addr = IPV6_ADDR_UNSPECIFIED; msg_init_queue(server_msg_queue, SERVER_MSG_QUEUE_SIZE); if(conn_udp_create(&conn, &server_addr, sizeof(server_addr), AF_INET6, port) < 0) { return NULL; } server_running = true; printf("Success: started UDP server on port %" PRIu16 "\n", port); char *arg[4]; char *cmd = "udp_send"; char *port_str = "8888"; arg[0] = cmd; arg[2] = port_str; char src_str[IPV6_ADDR_MAX_STR_LEN]; while (1) { int res; ipv6_addr_t src; size_t src_len = sizeof(ipv6_addr_t); if ((res = conn_udp_recvfrom(&conn, server_buffer, sizeof(server_buffer), &src, &src_len, &port)) < 0) { puts("Error while receiving"); } else if (res == 0) { puts("No data received"); } else { server_buffer[res] = '\0'; if (gnrc_rpl_instances[0].state && gnrc_rpl_instances[0].dodag.node_status == GNRC_RPL_ROOT_NODE) { printf("%s;%s\n", ipv6_addr_to_str(src_str, &src, sizeof(src_str)), server_buffer); ipv6_addr_to_str(addr_str, &ipv6_addr_all_nodes_link_local, sizeof(addr_str)); arg[1] = addr_str; arg[3] = src_str; udp_send(4, arg); } else { ipv6_addr_t payload; ipv6_addr_from_str(&payload, server_buffer); if ((gnrc_ipv6_netif_find_by_addr(NULL, &payload) != KERNEL_PID_UNDEF) && (!acked)) { acked = true; printf("diff: %llu\n", xtimer_now64() - time); } } } } return NULL; }
uint16_t ipv6_csum(ipv6_hdr_t *ipv6_header, uint8_t *buf, uint16_t len, uint8_t proto) { uint16_t sum = 0; DEBUG("Calculate checksum over src: %s, dst: %s, len: %04X, buf: %p, proto: %u\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &ipv6_header->srcaddr), ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &ipv6_header->destaddr), len, buf, proto); sum = len + proto; sum = csum(sum, (uint8_t *)&ipv6_header->srcaddr, 2 * sizeof(ipv6_addr_t)); sum = csum(sum, buf, len); return (sum == 0) ? 0xffff : HTONS(sum); }
ipv6_addr_t *rpl_get_next_hop(ipv6_addr_t *addr) { DEBUGF("looking up the next hop to %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, addr)); for (uint8_t i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { if (rpl_routing_table[i].used) { DEBUGF("checking %d: %s\n", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_routing_table[i].address)); } if (rpl_routing_table[i].used && rpl_equal_id(&rpl_routing_table[i].address, addr)) { DEBUGF("found %d: %s\n", i, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_routing_table[i].next_hop)); return &rpl_routing_table[i].next_hop; } } return (rpl_get_my_preferred_parent()); }
void table(char *unused) { (void) unused; rpl_routing_entry_t *rtable; rtable = rpl_get_routing_table(); printf("---------------------------\n"); printf("OUTPUT\n"); printf("---------------------------\n"); for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) { if (rtable[i].used) { printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address))); printf("entry %d lifetime %d\n", i, rtable[i].lifetime); if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) { puts("multi-hop"); } printf("--------------\n"); } } printf("$\n"); }
static void _remove_addr_from_entry(gnrc_ipv6_netif_t *entry, ipv6_addr_t *addr) { mutex_lock(&entry->mutex); for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { if (ipv6_addr_equal(&(entry->addrs[i].addr), addr)) { DEBUG("ipv6 netif: Remove %s to interface %" PRIkernel_pid "\n", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), entry->pid); ipv6_addr_set_unspecified(&(entry->addrs[i].addr)); entry->addrs[i].flags = 0; #ifdef MODULE_GNRC_NDP_ROUTER /* Removal of prefixes MAY allow the router to retransmit up to * GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF unsolicited RA * (see https://tools.ietf.org/html/rfc4861#section-6.2.4) */ if ((entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) && (entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) && (!ipv6_addr_is_multicast(addr) && !ipv6_addr_is_link_local(addr))) { entry->rtr_adv_count = GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF; mutex_unlock(&entry->mutex); /* function below relocks the mutex */ gnrc_ndp_router_retrans_rtr_adv(entry); return; } #endif mutex_unlock(&entry->mutex); return; } } mutex_unlock(&entry->mutex); }
void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr) { gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(iface, ipv6_addr); if (entry != NULL) { DEBUG("ipv6_nc: Remove %s for interface %" PRIkernel_pid "\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), iface); #ifdef MODULE_GNRC_NDP_NODE while (entry->pkts != NULL) { gnrc_pktbuf_release(entry->pkts->pkt); entry->pkts->pkt = NULL; gnrc_pktqueue_remove_head(&entry->pkts); } #endif #ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER xtimer_remove(&entry->type_timeout); #endif #if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) xtimer_remove(&entry->rtr_adv_timer); #endif ipv6_addr_set_unspecified(&(entry->ipv6_addr)); entry->iface = KERNEL_PID_UNDEF; entry->flags = 0; } }
void send_DAO_ACK(ipv6_addr_t *destination) { char addr_str[IPV6_MAX_ADDR_STR_LEN]; printf("%s\n", ipv6_addr_to_str(addr_str, destination)); rpl_dodag_t *my_dodag; my_dodag = rpl_get_my_dodag(); if (my_dodag == NULL) { return; } mutex_lock(&rpl_send_mutex); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DAO_ACK; icmp_send_buf->checksum = ~icmpv6_csum(IPV6_PROTO_NUM_ICMPV6); rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf(); rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id; rpl_send_dao_ack_buf->d_reserved = 0; rpl_send_dao_ack_buf->dao_sequence = my_dodag->dao_seq; rpl_send_dao_ack_buf->status = 0; uint16_t plen = ICMPV6_HDR_LEN + DIS_BASE_LEN; rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6, NULL); mutex_unlock(&rpl_send_mutex); }
int _ipv6_nc_routers(int argc, char **argv) { kernel_pid_t iface = KERNEL_PID_UNDEF; char ipv6_str[IPV6_ADDR_MAX_STR_LEN]; if (argc > 1) { iface = atoi(argv[1]); if (!_is_iface(iface)) { printf("usage: %s [<iface pid>]\n", argv[0]); return 1; } } puts("if Router state type"); puts("---------------------------------------------------"); for (ng_ipv6_nc_t *entry = ng_ipv6_nc_get_next_router(NULL); entry != NULL; entry = ng_ipv6_nc_get_next_router(entry)) { if ((iface != KERNEL_PID_UNDEF) && (iface != entry->iface)) { continue; } printf("%2" PRIkernel_pid " %-30s ", entry->iface, ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str))); _print_nc_state(entry); _print_nc_type(entry); puts(""); } return 0; }
kernel_pid_t gnrc_ipv6_netif_find_by_addr(ipv6_addr_t **out, const ipv6_addr_t *addr) { for (int i = 0; i < GNRC_NETIF_NUMOF; i++) { if (out != NULL) { *out = gnrc_ipv6_netif_find_addr(ipv6_ifs[i].pid, addr); if (*out != NULL) { DEBUG("ipv6 netif: Found %s on interface %" PRIkernel_pid "\n", ipv6_addr_to_str(addr_str, *out, sizeof(addr_str)), ipv6_ifs[i].pid); return ipv6_ifs[i].pid; } } else { if (gnrc_ipv6_netif_find_addr(ipv6_ifs[i].pid, addr) != NULL) { DEBUG("ipv6 netif: Found :: on interface %" PRIkernel_pid "\n", ipv6_ifs[i].pid); return ipv6_ifs[i].pid; } } } if (out != NULL) { *out = NULL; } return KERNEL_PID_UNDEF; }
static void fib_print_address(universal_address_container_t *entry) { uint8_t address[UNIVERSAL_ADDRESS_SIZE]; size_t addr_size = UNIVERSAL_ADDRESS_SIZE; uint8_t *ret = universal_address_get_address(entry, address, &addr_size); if (ret == address) { #ifdef MODULE_IPV6_ADDR if (addr_size == sizeof(ipv6_addr_t)) { printf("%-" NG_FIB_ADDR_PRINT_LENS "s", ipv6_addr_to_str(addr_str, (ipv6_addr_t *) address, sizeof(addr_str))); return; } #endif for (size_t i = 0; i < UNIVERSAL_ADDRESS_SIZE; ++i) { if (i <= addr_size) { printf("%02x", address[i]); } else { printf(" "); } } #ifdef MODULE_IPV6_ADDR /* print trailing whitespaces */ for (size_t i = 0; i < NG_FIB_ADDR_PRINT_LEN - (UNIVERSAL_ADDRESS_SIZE * 2); ++i) { printf(" "); } #endif } }
bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, gnrc_netif_t *netif, gnrc_ipv6_nib_nc_t *nce) { bool res = (netif != NULL) && gnrc_netif_is_6ln(netif) && ipv6_addr_is_link_local(dst); if (res) { uint8_t l2addr_len; if ((l2addr_len = _reverse_iid(dst, netif, nce->l2addr)) > 0) { DEBUG("nib: resolve address %s%%%u by reverse translating to ", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), (unsigned)netif->pid); nce->l2addr_len = l2addr_len; DEBUG("%s\n", gnrc_netif_addr_to_str(nce->l2addr, nce->l2addr_len, addr_str)); memcpy(&nce->ipv6, dst, sizeof(nce->ipv6)); nce->info = 0; nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) & GNRC_IPV6_NIB_NC_INFO_IFACE_MASK; nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE; nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED; } else { res = false; } } return res; }
static void _print_addr(ipv6_addr_t *addr, uint8_t flags) { char addr_str[IPV6_ADDR_MAX_STR_LEN]; printf(" inet6 addr: "); ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)); printf("%s scope: ", addr_str); if ((ipv6_addr_is_link_local(addr))) { printf("local"); } else { printf("global"); } if (flags & GNRC_NETIF_IPV6_ADDRS_FLAGS_ANYCAST) { printf(" [anycast]"); } if (flags & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE) { printf(" TNT[%u]", flags & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE); } else { switch (flags & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_MASK) { case GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_DEPRECATED: printf(" DPR"); break; case GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID: printf(" VAL"); break; default: printf(" UNK"); break; } } printf("\n"); }
void rpl_send_DAO_ACK(rpl_dodag_t *my_dodag, ipv6_addr_t *destination) { #if ENABLE_DEBUG if (destination) { DEBUGF("Send DAO ACK to %s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, destination)); } #endif if (my_dodag == NULL) { return; } icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->type = ICMPV6_TYPE_RPL_CONTROL; icmp_send_buf->code = ICMP_CODE_DAO_ACK; rpl_send_dao_ack_buf = get_rpl_send_dao_ack_buf(); rpl_send_dao_ack_buf->rpl_instanceid = my_dodag->instance->id; rpl_send_dao_ack_buf->d_reserved = 0; rpl_send_dao_ack_buf->dao_sequence = my_dodag->dao_seq; rpl_send_dao_ack_buf->status = 0; uint16_t plen = ICMPV6_HDR_LEN + DAO_ACK_LEN; rpl_send(destination, (uint8_t *)icmp_send_buf, plen, IPV6_PROTO_NUM_ICMPV6); }
void _handle_rereg_address(const ipv6_addr_t *addr) { gnrc_netif_t *netif = gnrc_netif_get_by_ipv6_addr(addr); _nib_dr_entry_t *router = _nib_drl_get_dr(); const bool router_reachable = (router != NULL) && _is_reachable(router->next_hop); if (router_reachable && (netif != NULL)) { assert((unsigned)netif->pid == _nib_onl_get_if(router->next_hop)); DEBUG("nib: Re-registering %s", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); DEBUG(" with upstream router %s\n", ipv6_addr_to_str(addr_str, &router->next_hop->ipv6, sizeof(addr_str))); _snd_ns(&router->next_hop->ipv6, netif, addr, &router->next_hop->ipv6); } else { DEBUG("nib: Couldn't re-register %s, no current router found or address " "wasn't assigned to any interface anymore.\n", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); } if (netif != NULL) { int idx = gnrc_netif_ipv6_addr_idx(netif, addr); if (router_reachable && (_is_valid(netif, idx) || (_is_tentative(netif, idx) && (gnrc_netif_ipv6_addr_dad_trans(netif, idx) < SIXLOWPAN_ND_REG_TRANSMIT_NUMOF)))) { uint32_t retrans_time; if (_is_valid(netif, idx)) { retrans_time = SIXLOWPAN_ND_MAX_RS_SEC_INTERVAL * MS_PER_SEC; } else { retrans_time = netif->ipv6.retrans_time; /* increment encoded retransmission count */ netif->ipv6.addrs_flags[idx]++; } _evtimer_add(&netif->ipv6.addrs[idx], GNRC_IPV6_NIB_REREG_ADDRESS, &netif->ipv6.addrs_timers[idx], retrans_time); } else { netif->ipv6.rs_sent = 0; _handle_search_rtr(netif); } } }
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; }