void ng_netif_hdr_print(ng_netif_hdr_t *hdr) { char addr_str[NG_NETIF_HDR_L2ADDR_MAX_LEN * 3]; printf("if_pid: %" PRIkernel_pid " ", hdr->if_pid); printf("rssi: %" PRIu8 " ", hdr->rssi); printf("lqi: %" PRIu8 "\n", hdr->lqi); if (hdr->src_l2addr_len > 0) { printf("src_l2addr: %s\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), ng_netif_hdr_get_src_addr(hdr), (size_t)hdr->src_l2addr_len)); } else { puts("src_l2addr: (nil)"); } if (hdr->dst_l2addr_len > 0) { printf("dst_l2addr: %s\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), ng_netif_hdr_get_dst_addr(hdr), (size_t)hdr->dst_l2addr_len)); } else { puts("dst_l2addr: (nil)"); } }
static void _dump_netif_hdr(ng_netif_hdr_t *hdr) { char addr_str[ADDR_STR_MAX]; printf("if_pid: %" PRIkernel_pid " ", hdr->if_pid); printf("rssi: %" PRIu8 " ", hdr->rssi); printf("lqi: %" PRIu8 "\n", hdr->lqi); printf("src_l2addr: %s\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), ng_netif_hdr_get_src_addr(hdr), (size_t)hdr->src_l2addr_len)); printf("dst_l2addr: %s\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), ng_netif_hdr_get_dst_addr(hdr), (size_t)hdr->dst_l2addr_len)); }
static void test_ng_netif_addr_to_str__out_too_short(void) { static const uint8_t addr[] = {0x05, 0xcd}; char out[2]; TEST_ASSERT_NULL(ng_netif_addr_to_str(out, sizeof(out), addr, sizeof(addr))); }
static bool _handle_sl2a_opt(kernel_pid_t iface, ng_pktsnip_t *pkt, ng_ipv6_hdr_t *ipv6, uint8_t icmpv6_type, ng_ndp_opt_t *sl2a_opt) { ng_ipv6_nc_t *nc_entry = NULL; uint8_t sl2a_len = 0; uint8_t *sl2a = (uint8_t *)(sl2a_opt + 1); if ((sl2a_opt->len == 0) || ng_ipv6_addr_is_unspecified(&ipv6->src)) { DEBUG("ndp: invalid source link-layer address option received\n"); return false; } while (pkt) { if (pkt->type == NG_NETTYPE_NETIF) { ng_netif_hdr_t *hdr = pkt->data; sl2a_len = hdr->src_l2addr_len; break; } pkt = pkt->next; } if (sl2a_len == 0) { /* in case there was no source address in l2 */ sl2a_len = (sl2a_opt->len / 8) - sizeof(ng_ndp_opt_t); /* ignore all zeroes at the end for length */ for (; sl2a[sl2a_len - 1] == 0x00; sl2a_len--); } DEBUG("ndp: received SL2A (link-layer address: %s)\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), sl2a, sl2a_len)); switch (icmpv6_type) { case NG_ICMPV6_NBR_SOL: nc_entry = ng_ipv6_nc_get(iface, &ipv6->src); if (nc_entry != NULL) { if ((sl2a_len != nc_entry->l2_addr_len) || (memcmp(sl2a, nc_entry->l2_addr, sl2a_len) != 0)) { /* if entry exists but l2 address differs: set */ nc_entry->l2_addr_len = sl2a_len; memcpy(nc_entry->l2_addr, sl2a, sl2a_len); _set_state(nc_entry, NG_IPV6_NC_STATE_STALE); } } else { ng_ipv6_nc_add(iface, &ipv6->src, sl2a, sl2a_len, NG_IPV6_NC_STATE_STALE); } return true; default: /* wrong encapsulating message: silently discard */ DEBUG("ndp: silently discard sl2a_opt for ICMPv6 message type %" PRIu8 "\n", icmpv6_type); return true; } }
ng_pktsnip_t *ng_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, ng_pktsnip_t *next) { DEBUG("ndp: building target link-layer address option (l2addr: %s)\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, l2addr_len)); return _opt_l2a_build(NG_NDP_OPT_TL2A, l2addr, l2addr_len, next); }
static void test_ng_netif_addr_to_str__success(void) { static const uint8_t addr[] = {0x05, 0xcd}; char out[3 * sizeof(addr)]; TEST_ASSERT_EQUAL_STRING("05:cd", ng_netif_addr_to_str(out, sizeof(out), addr, sizeof(addr))); }
void icn_initInterest(uint16_t seq) { if (WANT_CONTENT) { uint32_t tmp1; uint16_t tmp2; tmp1 = _getSmallestMissing(); LOG_DEBUG("Smallest missing is %lu\n", tmp1); tmp2 = seq; if ((tmp1 < NUMBER_OF_CHUNKS) && (tmp1 >= 0)) { LOG_INFO("Scheduling retransmission for %lu\n", tmp1); vtimer_remove(&retry_vt); vtimer_set_msg(&retry_vt, retry_interval, thread_getpid(), ICN_RESEND_INTEREST, &tmp1); } if (bf_isset(received_chunks, seq)) { LOG_INFO("Already received a chunk for %u, not sending again\n", seq); return; } #if FLOW_CONTROL if (seq > (receive_counter + FLOW_THR)) { LOG_INFO("Flow control, seq is %u, receive counter is %u\n", seq, receive_counter); return; } #endif /* create packet */ ng_pktsnip_t *pkt; icn_pkt_t icn_pkt; icn_pkt.type = ICN_INTEREST; icn_pkt.seq = seq; memcpy(icn_pkt.payload, interest, strlen(interest) + 1); pkt = ng_pktbuf_add(NULL, &icn_pkt, sizeof(icn_pkt_t), NG_NETTYPE_UNDEF); // send interest packet if (tmp2 < NUMBER_OF_CHUNKS) { LOG_INFO("Sending Interest for %u to %s\n", seq, ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), CONTENT_STORE->uint8, ADDR_LEN_64B)); icn_send(CONTENT_STORE, pkt); } if (tmp2 < NUMBER_OF_CHUNKS) { tmp2++; #if TIMED_SENDING vtimer_remove(&periodic_vt); vtimer_set_msg(&periodic_vt, interval, thread_getpid(), ICN_SEND_INTEREST, &tmp2); #else icn_initInterest(tmp2); #endif } } else { LOG_DEBUG("nothing to do\n"); } }
void icn_send(eui64_t *dst, ng_pktsnip_t *pkt) { ng_netif_hdr_t *nethdr; uint8_t flags = 0x00; if (!_linkIsScheduled(dst)) { LOG_DEBUG("No direct neighbor, look for a route\n"); eui64_t *tmp; tmp = _routeLookup(dst); if (tmp == NULL) { LOG_ERROR("Not route for %s found\n", ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), dst->uint8, ADDR_LEN_64B)); ng_pktbuf_release(pkt); return; } dst = tmp; } LOG_DEBUG("Sending to %s\n", ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), dst->uint8, ADDR_LEN_64B)); /* put packet together */ if (pkt->type == NG_NETTYPE_NETIF) { LOG_DEBUG("packet has already a netif header\n"); } else { LOG_DEBUG("creating netif header\n"); pkt = ng_pktbuf_add(pkt, NULL, sizeof(ng_netif_hdr_t) + ADDR_LEN_64B, NG_NETTYPE_NETIF); } nethdr = (ng_netif_hdr_t *)pkt->data; ng_netif_hdr_init(nethdr, 0, ADDR_LEN_64B); ng_netif_hdr_set_dst_addr(nethdr, dst->uint8, ADDR_LEN_64B); nethdr->flags = flags; /* and send it */ send_counter++; ng_netapi_send(*if_id, pkt); }
static int _handle_tl2a_opt(ng_pktsnip_t *pkt, ng_ipv6_hdr_t *ipv6, uint8_t icmpv6_type, ng_ndp_opt_t *tl2a_opt, uint8_t *l2addr) { uint8_t tl2a_len = 0; uint8_t *tl2a = (uint8_t *)(tl2a_opt + 1); if ((tl2a_opt->len == 0) || ng_ipv6_addr_is_unspecified(&ipv6->src)) { DEBUG("ndp: invalid target link-layer address option received\n"); return -EINVAL; } switch (icmpv6_type) { case NG_ICMPV6_NBR_ADV: while (pkt) { if (pkt->type == NG_NETTYPE_NETIF) { ng_netif_hdr_t *hdr = pkt->data; tl2a_len = hdr->src_l2addr_len; break; } pkt = pkt->next; } if (tl2a_len == 0) { /* in case there was no source address in l2 */ tl2a_len = (tl2a_opt->len / 8) - sizeof(ng_ndp_opt_t); /* ignore all zeroes at the end for length */ for (; tl2a[tl2a_len - 1] == 0x00; tl2a_len--); } DEBUG("ndp: received TL2A (link-layer address: %s)\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), tl2a, tl2a_len)); memcpy(l2addr, tl2a, tl2a_len); return (int)tl2a_len; default: /* wrong encapsulating message: silently discard */ DEBUG("ndp: silently discard tl2a_opt for ICMPv6 message type %" PRIu8 "\n", icmpv6_type); return 0; } }
static int _ipv6_nc_list(void) { char ipv6_str[IPV6_ADDR_MAX_STR_LEN]; char l2addr_str[3 * MAX_L2_ADDR_LEN]; puts("IPv6 address if L2 address state type"); puts("------------------------------------------------------------------------------"); for (ng_ipv6_nc_t *entry = ng_ipv6_nc_get_next(NULL); entry != NULL; entry = ng_ipv6_nc_get_next(entry)) { printf("%-30s %2" PRIkernel_pid " %-24s ", ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str)), entry->iface, ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), entry->l2_addr, entry->l2_addr_len)); _print_nc_state(entry); _print_nc_type(entry); puts(""); } return 0; }
kernel_pid_t ng_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, kernel_pid_t iface, ng_ipv6_addr_t *dst, ng_pktsnip_t *pkt) { ng_ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL; #ifdef MODULE_NG_IPV6_EXT_RH next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr); #endif #ifdef MODULE_FIB size_t next_hop_size = sizeof(ng_ipv6_addr_t); uint32_t next_hop_flags = 0; ng_ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */ if ((next_hop_ip == NULL) && (fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size, &next_hop_flags, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0) >= 0) && (next_hop_size == sizeof(ng_ipv6_addr_t))) { next_hop_ip = &next_hop_actual; } #endif if (next_hop_ip == NULL) { /* no route to host */ if (iface == KERNEL_PID_UNDEF) { /* ng_ipv6_netif_t doubles as prefix list */ iface = ng_ipv6_netif_find_by_prefix(&prefix, dst); } else { /* ng_ipv6_netif_t doubles as prefix list */ prefix = ng_ipv6_netif_match_prefix(iface, dst); } if ((prefix != NULL) && /* prefix is on-link */ (ng_ipv6_netif_addr_get(prefix)->flags & NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) { next_hop_ip = dst; #ifdef MODULE_FIB /* We don't care if FIB is full, this is just for efficiency * for later sends */ fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0, (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0, FIB_LIFETIME_NO_EXPIRE); #endif } } if (next_hop_ip == NULL) { next_hop_ip = _default_router(); #ifdef MODULE_FIB /* We don't care if FIB is full, this is just for efficiency for later * sends */ fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0, (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0, FIB_LIFETIME_NO_EXPIRE); #endif } if (next_hop_ip != NULL) { ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, next_hop_ip); if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) { DEBUG("ndp: found reachable neighbor (%s => ", ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); DEBUG("%s)\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), nc_entry->l2_addr, nc_entry->l2_addr_len)); if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) { _set_state(nc_entry, NG_IPV6_NC_STATE_DELAY); } memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len); *l2addr_len = nc_entry->l2_addr_len; /* TODO: unreachability check */ return nc_entry->iface; } else if (nc_entry == NULL) { ng_pktqueue_t *pkt_node; ng_ipv6_addr_t dst_sol; nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0, NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS); if (nc_entry == NULL) { DEBUG("ndp: could not create neighbor cache entry\n"); return KERNEL_PID_UNDEF; } pkt_node = _alloc_pkt_node(pkt); if (pkt_node == NULL) { DEBUG("ndp: could not add packet to packet queue\n"); } else { /* prevent packet from being released by IPv6 */ ng_pktbuf_hold(pkt_node->pkt, 1); ng_pktqueue_add(&nc_entry->pkts, pkt_node); } /* address resolution */ ng_ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip); if (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++) { _send_nbr_sol(ifs[i], next_hop_ip, &dst_sol); } 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(iface); _send_nbr_sol(iface, next_hop_ip, &dst_sol); 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); } } } return KERNEL_PID_UNDEF; }
static void _netif_list(kernel_pid_t dev) { uint8_t hwaddr[MAX_ADDR_LEN]; uint16_t u16; int16_t i16; int res; ng_netconf_state_t state; ng_netconf_enable_t enable; bool linebreak = false; #ifdef MODULE_NG_IPV6_NETIF ng_ipv6_netif_t *entry = ng_ipv6_netif_get(dev); char ipv6_addr[NG_IPV6_ADDR_MAX_STR_LEN]; #endif printf("Iface %2d ", dev); res = ng_netapi_get(dev, NETCONF_OPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf(" HWaddr: "); printf("%s", ng_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); printf(" "); } res = ng_netapi_get(dev, NETCONF_OPT_CHANNEL, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" Channel: %" PRIu16 " ", u16); } res = ng_netapi_get(dev, NETCONF_OPT_NID, 0, &u16, sizeof(u16)); if (res >= 0) { printf(" NID: 0x%" PRIx16 " ", u16); } res = ng_netapi_get(dev, NETCONF_OPT_TX_POWER, 0, &i16, sizeof(i16)); if (res >= 0) { printf(" TX-Power: %" PRIi16 "dBm ", i16); } res = ng_netapi_get(dev, NETCONF_OPT_STATE, 0, &state, sizeof(state)); if (res >= 0) { printf(" State: "); _print_netconf_state(state); } printf("\n "); res = ng_netapi_get(dev, NETCONF_OPT_ADDRESS_LONG, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { char hwaddr_str[res * 3]; printf("Long HWaddr: "); printf("%s", ng_netif_addr_to_str(hwaddr_str, sizeof(hwaddr_str), hwaddr, res)); printf("\n "); } res = ng_netapi_get(dev, NETCONF_OPT_PROMISCUOUSMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETCONF_ENABLE)) { printf("PROMISC "); linebreak = true; } res = ng_netapi_get(dev, NETCONF_OPT_AUTOACK, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETCONF_ENABLE)) { printf("AUTOACK "); linebreak = true; } res = ng_netapi_get(dev, NETCONF_OPT_PRELOADING, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETCONF_ENABLE)) { printf("PRELOAD "); linebreak = true; } res = ng_netapi_get(dev, NETCONF_OPT_RAWMODE, 0, &enable, sizeof(enable)); if ((res >= 0) && (enable == NETCONF_ENABLE)) { printf("RAWMODE "); linebreak = true; } #ifdef MODULE_NG_IPV6_NETIF if ((entry != NULL) && (entry->flags & NG_IPV6_NETIF_FLAGS_SIXLOWPAN)) { printf("6LO "); linebreak = true; } #endif if (linebreak) { printf("\n "); } res = ng_netapi_get(dev, NETCONF_OPT_SRC_LEN, 0, &u16, sizeof(u16)); if (res >= 0) { printf("Source address length: %" PRIu16 "\n ", u16); } #ifdef MODULE_NG_IPV6_NETIF for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) { if (!ng_ipv6_addr_is_unspecified(&entry->addrs[i].addr)) { printf("inet6 addr: "); if (ng_ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr, NG_IPV6_ADDR_MAX_STR_LEN)) { printf("%s/%" PRIu8 " scope: ", ipv6_addr, entry->addrs[i].prefix_len); if ((ng_ipv6_addr_is_link_local(&entry->addrs[i].addr))) { printf("local"); } else { printf("global"); } if (entry->addrs[i].flags & NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST) { if (ng_ipv6_addr_is_multicast(&entry->addrs[i].addr)) { printf(" [multicast]"); } else { printf(" [anycast]"); } } } else { printf("error in conversion"); } printf("\n "); } } #endif puts(""); }
static void rcv(ng_pktsnip_t *pkt) { ng_pktsnip_t *netif_pkt = pkt; ng_netif_hdr_t *netif_hdr; netif_pkt = pkt->next; if (netif_pkt->type == NG_NETTYPE_NETIF) { netif_hdr = netif_pkt->data; LOG_DEBUG("Received packet from %s\n", ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), ng_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len)); icn_pkt_t *icn_pkt = (icn_pkt_t*) pkt->data; //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT); switch (icn_pkt->type) { case ICN_INTEREST: if (HAS_CONTENT) { LOG_INFO("received interest, have content, sequence number is %u\n", icn_pkt->seq); icn_initContent((eui64_t*)ng_netif_hdr_get_src_addr(netif_hdr), icn_pkt->seq); ng_pktbuf_release(pkt); } else { memcpy(&pit_entry, ng_netif_hdr_get_src_addr(netif_hdr), ADDR_LEN_64B); pit_ctr++; /* forward to CS node */ pkt->next = NULL; ng_pktbuf_release(netif_pkt); icn_send(CONTENT_STORE, pkt); } break; case ICN_CONTENT: if (pit_ctr) { LOG_DEBUG("Forwarding chunk to PIT entry: %s\n", ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), pit_entry.uint8, ADDR_LEN_64B)); pkt->next = NULL; ng_pktbuf_release(netif_pkt); icn_send(&pit_entry, pkt); if (--pit_ctr <= 0) { pit_ctr = 0; } } else if (WANT_CONTENT) { uint16_t tmp; tmp = icn_pkt->seq; if (bf_isset(received_chunks, tmp)) { LOG_ERROR("Duplicate chunk number %u\n", tmp); } else { LOG_INFO("received content that I was waiting for with sequence number %u\n", tmp); LOG_INFO("Current send counter is %u\n", send_counter); bf_set(received_chunks, tmp); } receive_counter = (receive_counter < tmp) ? tmp : receive_counter; ng_pktbuf_release(pkt); } else { LOG_ERROR("Received content, but no PIT entry is available\n"); ng_pktbuf_release(pkt); } break; case ICN_BACKGROUND: ng_pktbuf_release(pkt); break; default: LOG_ERROR("unexpected packet received\n"); ng_pktbuf_release(pkt); } } else { LOG_ERROR("unknown snippet\n"); } }