/*---------------------------------------------------------------------------*/ void rpl_purge_routes(void) { uip_ds6_route_t *r; uip_ipaddr_t prefix; rpl_dag_t *dag; rpl_instance_t *instance; //changed /* First pass, decrement lifetime */ r = uip_ds6_route_head(); while(r != NULL) { if(r->state.lifetime >= 1) { /* * If a route is at lifetime == 1, set it to 0, scheduling it for * immediate removal below. This achieves the same as the original code, * which would delete lifetime <= 1 */ r->state.lifetime--; } r = uip_ds6_route_next(r); } /* Second pass, remove dead routes */ r = uip_ds6_route_head(); while(r != NULL) { /*Pre-change handle second_instance*/ if(r->state.lifetime < 1) { /* Routes with lifetime == 1 have only just been decremented from 2 to 1, * thus we want to keep them. Hence < and not <= */ uip_ipaddr_copy(&prefix, &r->ipaddr); uip_ds6_route_rm(r); r = uip_ds6_route_head(); PRINTF("No more routes to "); PRINT6ADDR(&prefix); /*Changed*/ instance = rpl_get_instance(r->state.instance_id); dag = instance->current_dag; //dag1 = second_instance->current_dag; /* Propagate this information with a No-Path DAO to preferred parent if we are not a RPL Root */ if(dag->rank != ROOT_RANK(instance)) { PRINTF(" -> generate No-Path DAO\n"); dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME); /* Don't schedule more than 1 No-Path DAO, let next iteration handle that */ return; } PRINTF("\n"); } else { r = uip_ds6_route_next(r); } } }
static void assert_nbr_routes_list_sane(void) { uip_ds6_route_t *r; int count; /* Check if the route list has an infinite loop. */ for(r = uip_ds6_route_head(), count = 0; r != NULL && count < UIP_DS6_ROUTE_NB * 2; r = uip_ds6_route_next(r), count++); if(count > UIP_DS6_ROUTE_NB) { printf("uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n"); } /* Make sure that the route list has as many entries as the num_routes vairable. */ if(count < num_routes) { printf("uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n", num_routes, count, UIP_CONF_MAX_ROUTES); } }
/*---------------------------------------------------------------------------*/ static unsigned short make_routes(void *p) { static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>"; static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>"; uint8_t i,j=0; uint16_t numprinted; uip_ds6_route_t *r; numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { j++; numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length); numprinted += httpd_cgi_sprint_ip6(uip_ds6_route_nexthop(r), uip_appdata + numprinted); if(r->state.lifetime < 3600) { numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime); } else { numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3); } } if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn); numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j); return numprinted; }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *addr) { uip_ds6_route_t *r; uip_ds6_route_t *found_route; uint8_t longestmatch; //ADILA EDIT 10/11/14 //uint8_t found_route_ch; //------------------- PRINTF("uip-ds6-route: Looking up route for "); PRINT6ADDR(addr); PRINTF("\n"); found_route = NULL; longestmatch = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(r->length >= longestmatch && uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { longestmatch = r->length; found_route = r; //ADILA EDIT 10/11/14 //found_route_ch = r->nbrCh; //------------------- } } if(found_route != NULL) { PRINTF("uip-ds6-route: Found route: "); PRINT6ADDR(addr); PRINTF(" via "); PRINT6ADDR(uip_ds6_route_nexthop(found_route)); PRINTF("\n"); //ADILA EDIT 10/11/14 /* printf("uip-ds6-route: Found route: "); uip_debug_ipaddr_print(addr); printf(" via "); uip_debug_ipaddr_print(uip_ds6_route_nexthop(found_route)); printf("\n"); */ //printf("FOUND ROUTE CHANGE TO NEXTHOP CHANNEL %d\n\n", found_route_ch); /*printf("Found route change to nexthop channel %d ", found_route_ch); uip_debug_ipaddr_print(uip_ds6_route_nexthop(found_route)); printf("\n");*/ //PRINTF("FOUND ROUTE CHANGE TO NEXTHOP CHANNEL %d\n\n", found_route_ch); //@ //cc2420_set_channel(found_route_ch); //------------------- } else { PRINTF("uip-ds6-route: No route found\n"); } return found_route; }
/*---------------------------------------------------------------------------*/ void rpl_remove_routes(rpl_dag_t *dag) { uip_ds6_route_t *r; #if RPL_CONF_MULTICAST uip_mcast6_route_t *mcast_route; #endif r = uip_ds6_route_head(); while(r != NULL) { if(r->state.dag == dag) { uip_ds6_route_rm(r); r = uip_ds6_route_head(); } else { r = uip_ds6_route_next(r); } } #if RPL_CONF_MULTICAST mcast_route = uip_mcast6_route_list_head(); while(mcast_route != NULL) { if(mcast_route->dag == dag) { uip_mcast6_route_rm(mcast_route); mcast_route = uip_mcast6_route_list_head(); } else { mcast_route = list_item_next(mcast_route); } } #endif }
/*---------------------------------------------------------------------------*/ void uip_ds6_route_rm(uip_ds6_route_t *route) { #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ if(route != NULL && route->routes != NULL) { PRINTF("uip_ds6_route_rm: removing route: "); PRINT6ADDR(&route->ipaddr); PRINTF("\n"); list_remove(route->routes->route_list, route); if(list_head(route->routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the neibhor from the table */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->routes->route_list); } memb_free(&routememb, route); num_routes--; PRINTF("uip_ds6_route_rm num %d\n", num_routes); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM, &route->ipaddr, uip_ds6_route_nexthop(route)); #endif #if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE /* we need to check if this was the last route towards "nexthop" */ /* if so - remove that link (annotation) */ uip_ds6_route_t *r; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { uip_ipaddr_t *nextr, *nextroute; nextr = uip_ds6_route_nexthop(r); nextroute = uip_ds6_route_nexthop(route); if(nextr != NULL && nextroute != NULL && uip_ipaddr_cmp(nextr, nextroute)) { /* we found another link using the specific nexthop, so keep the #L */ return; } } ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]); #endif } #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return; }
uip_ds6_route_t * uip_ds6_route_lookup_by_nexthop(uip_ipaddr_t *ipaddr) { uip_ds6_route_t *r; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), ipaddr)) { return r; } } return NULL; }
/*develop the handler*/ void routes_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int32_t strpos = 0; uip_ds6_route_t *r; volatile uint8_t i; size_t len = 0; uint8_t index; //>>>>>>>>>>>>>>>>>>index used while experimenting eg. : GET rplinfo/routes?index=1 const char *pstr; uint8_t count; /*Count the number of the routes and return them*/ count=uip_ds6_route_num_routes(); if((len = REST.get_query_variable(request, "index", &pstr))) // Parse for the index variable and compare value { index=(uint8_t)atoi(pstr); if(index >= count) { strpos = snprintf((char *)buffer,preferred_size, "{}"); /* if index is greater or same as count value return empty brackets */ }else { /*seek route entry and return it*/ i = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r), i++) { if (i == index) { break; } } strpos = create_route_msg((char *)buffer, r); } REST.set_header_content_type(response, REST.type.APPLICATION_JSON); // Header will be in JSON format... }else { // index not provided strpos += snprintf((char *)buffer, preferred_size, "%d", count); } //*offset = -1; REST.set_response_payload(response, (char *)buffer, strpos); // Setting the payload of response. }
/*---------------------------------------------------------------------------*/ static PT_THREAD(routes(struct httpd_state *s, char *ptr)) { PSOCK_BEGIN(&s->sout); for(s->u.ptr = uip_ds6_route_head(); s->u.ptr != NULL; s->u.ptr = uip_ds6_route_next(s->u.ptr)) { PSOCK_GENERATOR_SEND(&s->sout, make_route, s); } PSOCK_GENERATOR_SEND(&s->sout, make_routes_roomfor, s); PSOCK_END(&s->sout); }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *addr) { uip_ds6_route_t *r; uip_ds6_route_t *found_route; uint8_t longestmatch; PRINTF("uip-ds6-route: Looking up route for "); PRINT6ADDR(addr); PRINTF("\n"); found_route = NULL; longestmatch = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(r->length >= longestmatch && uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { longestmatch = r->length; found_route = r; /* check if total match - e.g. all 128 bits do match */ if(longestmatch == 128) { break; } } } if(found_route != NULL) { PRINTF("uip-ds6-route: Found route: "); PRINT6ADDR(addr); PRINTF(" via "); PRINT6ADDR(uip_ds6_route_nexthop(found_route)); PRINTF("\n"); } else { PRINTF("uip-ds6-route: No route found\n"); } if(found_route != NULL && found_route != list_head(routelist)) { /* If we found a route, we put it at the start of the routeslist list. The list is ordered by how recently we looked them up: the least recently used route will be at the end of the list - for fast lookups (assuming multiple packets to the same node). */ list_remove(routelist, found_route); list_push(routelist, found_route); } return found_route; }
static uip_ds6_route_t * find_route_entry_by_dao_ack(uint8_t seq) { uip_ds6_route_t *re; re = uip_ds6_route_head(); while(re != NULL) { if(re->state.dao_seqno_out == seq && RPL_ROUTE_IS_DAO_PENDING(re)) { /* found it! */ return re; } re = uip_ds6_route_next(re); } return NULL; }
/*---------------------------------------------------------------------------*/ static uint16_t print_routes(char *msg, int size) { uip_ds6_route_t *r = uip_ds6_route_head(); int len = strlen(msg); while(r != NULL && len < size + 30) { /* output a route entry */ len += sprint_addr6(&msg[len], &r->ipaddr); len += snprintf(&msg[len], size, "->"); len += sprint_addr6(&msg[len], uip_ds6_route_nexthop(r)); len += snprintf(&msg[len], size, "\n"); r = uip_ds6_route_next(r); } return len; }
/*---------------------------------------------------------------------------*/ void rpl_remove_routes(rpl_dag_t *dag) { uip_ds6_route_t *r; r = uip_ds6_route_head(); while(r != NULL) { if(r->state.dag == dag) { uip_ds6_route_rm(r); r = uip_ds6_route_head(); } else { r = uip_ds6_route_next(r); } } }
/*---------------------------------------------------------------------------*/ static PT_THREAD(routesping(struct httpd_state *s, char *ptr)) { PSOCK_BEGIN(&s->sout); for(s->u.ptr = uip_ds6_route_head(); s->u.ptr != NULL; s->u.ptr = uip_ds6_route_next(s->u.ptr)) { uip_ds6_route_t *r = (uip_ds6_route_t*) s->u.ptr; simple_udp_ping_send_ping(&r->ipaddr); PSOCK_GENERATOR_SEND(&s->sout, make_route, s); } PSOCK_GENERATOR_SEND(&s->sout, make_routes_roomfor, s); PSOCK_END(&s->sout); }
/*---------------------------------------------------------------------------*/ void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag) { uip_ds6_route_t *r; r = uip_ds6_route_head(); while(r != NULL) { if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) && r->state.dag == dag) { r->state.lifetime = 0; } r = uip_ds6_route_next(r); } ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); }
/*---------------------------------------------------------------------------*/ static void print_network_status(void) { int i; uint8_t state; uip_ds6_defrt_t *default_route; uip_ds6_route_t *route; PRINTA("--- Network status ---\n"); /* Our IPv6 addresses */ PRINTA("- Server IPv6 addresses:\n"); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { state = uip_ds6_if.addr_list[i].state; if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { PRINTA("-%d- ",i); uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); PRINTA("\n"); } } /* Our default route */ PRINTA("- Default route:\n"); default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); if(default_route != NULL) { PRINTA("-- "); uip_debug_ipaddr_print(&default_route->ipaddr);; PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval); } else { PRINTA("-- None\n"); } /* Our routing entries */ PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes()); route = uip_ds6_route_head(); while(route != NULL) { PRINTA("-- "); uip_debug_ipaddr_print(&route->ipaddr); PRINTA(" via "); uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); route = uip_ds6_route_next(route); } PRINTA("----------------------\n"); }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *addr) { uip_ds6_route_t *r; uip_ds6_route_t *found_route; uint8_t longestmatch; PRINTF("uip-ds6-route: Looking up route for "); PRINT6ADDR(addr); PRINTF("\n"); found_route = NULL; longestmatch = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(r->length >= longestmatch && uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { longestmatch = r->length; found_route = r; } } if(found_route != NULL) { PRINTF("uip-ds6-route: Found route: "); PRINT6ADDR(addr); PRINTF(" via "); PRINT6ADDR(uip_ds6_route_nexthop(found_route)); PRINTF("\n"); } else { PRINTF("uip-ds6-route: No route found\n"); } if(found_route != NULL) { /* If we found a route, we put it at the end of the routeslist list. The list is ordered by how recently we looked them up: the least recently used route will be at the start of the list. */ list_remove(routelist, found_route); list_add(routelist, found_route); } return found_route; }
void routes_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { int32_t strpos = 0; uip_ds6_route_t *r; volatile uint8_t i; size_t len = 0; uint8_t index; const char *pstr; uint8_t count; /* count the number of routes and return the total */ count = uip_ds6_route_num_routes(); if ((len = REST.get_query_variable(request, "index", &pstr))) { index = (uint8_t)atoi(pstr); if (index >= count ) { strpos = snprintf((char *)buffer, preferred_size, "{}"); } else { /* seek to the route entry and return it */ i = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r), i++) { if (i == index) { break; } } strpos = create_route_msg((char *)buffer, r); } REST.set_header_content_type(response, APPLICATION_JSON); } else { /* index not provided */ strpos += snprintf((char *)buffer, preferred_size, "%d", count); } *offset = -1; REST.set_response_payload(response, (char *)buffer, strpos); }
void collect_common_net_print(void) { rpl_dag_t *dag; uip_ds6_route_t *r; /* Let's suppose we have only one instance */ dag = rpl_get_any_dag(); if(dag->preferred_parent != NULL) { PRINTF("Preferred parent: "); PRINT6ADDR(rpl_get_parent_ipaddr(dag->preferred_parent)); PRINTF("\n"); } for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { PRINT6ADDR(&r->ipaddr); } PRINTF("---\n"); }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_lookup(uip_ipaddr_t *addr) { uip_ds6_route_t *r; uip_ds6_route_t *found_route; uint8_t longestmatch; PRINTF("uip-ds6-route: Looking up route for "); PRINT6ADDR(addr); PRINTF("\n"); found_route = NULL; longestmatch = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(r->length >= longestmatch && uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) { longestmatch = r->length; found_route = r; } } if(found_route != NULL) { PRINTF("uip-ds6-route: Found route: "); PRINT6ADDR(addr); PRINTF(" via "); PRINT6ADDR(uip_ds6_route_nexthop(found_route)); PRINTF("\n"); } else { PRINTF("uip-ds6-route: No route found\n"); } return found_route; }
static PT_THREAD(generate_network(struct httpd_state *s)) { static int i; static uip_ds6_route_t *r; static uip_ds6_defrt_t *dr; static uip_ds6_nbr_t *nbr; #if CETIC_6LBR_WITH_MULTICAST static uip_mcast6_route_t *mcast_route; #endif #if RPL_WITH_NON_STORING static rpl_ns_node_t *link; #endif PSOCK_BEGIN(&s->sout); add("<br /><h2>Addresses</h2><pre>"); SEND_STRING(&s->sout, buf); reset_buf(); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); add(" "); add_address_type(uip_ds6_if.addr_list[i].type); add(" "); add_address_state(uip_ds6_if.addr_list[i].state); if(!uip_ds6_if.addr_list[i].isinfinite) { add(" %u s", stimer_remaining(&uip_ds6_if.addr_list[i].vlifetime)); } add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } } add("</pre><h2>Multicast groups</h2><pre>"); for(i = 0; i < UIP_DS6_MADDR_NB; i++) { if(uip_ds6_if.maddr_list[i].isused) { ipaddr_add(&uip_ds6_if.maddr_list[i].ipaddr); add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } } add("</pre><h2>Prefixes</h2><pre>"); for(i = 0; i < UIP_DS6_PREFIX_NB; i++) { if(uip_ds6_prefix_list[i].isused) { ipaddr_add(&uip_ds6_prefix_list[i].ipaddr); #if UIP_CONF_ROUTER if(uip_ds6_prefix_list[i].advertise) { add(" Adv"); } #else if(uip_ds6_prefix_list[i].isinfinite) { add(" Inf"); } #endif add("\n"); } } SEND_STRING(&s->sout, buf); reset_buf(); #if CETIC_6LBR_WITH_IP64 if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0) { add("</pre><h2>IP64</h2><pre>"); if((nvm_data.eth_ip64_flags & CETIC_6LBR_IP64_DHCP) == 0 || ip64_hostaddr_is_configured()) { add("Address : "); ip4addr_add(ip64_get_hostaddr()); add("<br />"); add("Netmask : "); ip4addr_add(ip64_get_netmask()); add("<br />"); add("Gateway : "); ip4addr_add(ip64_get_draddr()); add("<br />"); if((nvm_data.eth_ip64_flags & CETIC_6LBR_IP64_DHCP) != 0) { add("DHCP Server : "); ip4addr_add_u8(cetic_6lbr_ip64_dhcp_state->serverid); add("<br />"); add("DHCP lease time : %d s<br />", uip_ntohs(cetic_6lbr_ip64_dhcp_state->lease_time[0])*65536ul + uip_ntohs(cetic_6lbr_ip64_dhcp_state->lease_time[1])); } } else { add("Waiting configuration<br />"); } SEND_STRING(&s->sout, buf); reset_buf(); } #endif add("</pre><h2>Neighbors</h2><pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"nbr-rm?"); ipaddr_add(&nbr->ipaddr); add("\">del</a>] "); } #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s : ", node_config_get_name(node_config_find_by_lladdr(uip_ds6_nbr_get_ll(nbr)))); } #endif ipaddr_add(&nbr->ipaddr); add(" "); lladdr_add(uip_ds6_nbr_get_ll(nbr)); add(" "); add_network_cases(nbr->state); #if UIP_SWITCH_LOOKUP if(nbr->ifindex != NETWORK_ITF_UNKNOWN) { add(" if:%u", nbr->ifindex); } #endif add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } add("</pre><h2>Routes</h2><pre>"); SEND_STRING(&s->sout, buf); reset_buf(); for(r = uip_ds6_route_head(), i = 0; r != NULL; r = uip_ds6_route_next(r), ++i) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"route-rm?"); ipaddr_add(&r->ipaddr); add("\">del</a>] "); } #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&r->ipaddr))); ipaddr_add(&r->ipaddr); add("/%u) via ", r->length); } else { ipaddr_add(&r->ipaddr); add("/%u via ", r->length); } if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(uip_ds6_route_nexthop(r)))); ipaddr_add(uip_ds6_route_nexthop(r)); add(")"); } else { ipaddr_add(uip_ds6_route_nexthop(r)); } #else ipaddr_add(&r->ipaddr); add("/%u via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); #endif #if CETIC_6LBR_WITH_RPL if(r->state.lifetime != RPL_ROUTE_INFINITE_LIFETIME) { #else if(r->neighbor_routes != NULL) { #endif add(" %lu s\n", r->state.lifetime); } else { add("Inf\n"); } SEND_STRING(&s->sout, buf); reset_buf(); } #if RPL_WITH_NON_STORING add("</pre><h2>Links</h2><pre>"); for(link = rpl_ns_node_head(); link != NULL; link = rpl_ns_node_next(link)) { if(link->parent != NULL) { uip_ipaddr_t child_ipaddr; uip_ipaddr_t parent_ipaddr; rpl_ns_get_node_global_addr(&child_ipaddr, link); rpl_ns_get_node_global_addr(&parent_ipaddr, link->parent); #if CETIC_6LBR_NODE_CONFIG_HAS_NAME if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&child_ipaddr))); ipaddr_add(&child_ipaddr); add(") via "); } else { ipaddr_add(&child_ipaddr); add(" via "); } if ( node_config_loaded ) { add("%s (", node_config_get_name(node_config_find_by_ip(&parent_ipaddr))); ipaddr_add(&parent_ipaddr); add(")"); } else { ipaddr_add(&parent_ipaddr); } #else ipaddr_add(&child_ipaddr); add(" via "); ipaddr_add(&parent_ipaddr); #endif add(" %lu s\n", link->lifetime); SEND_STRING(&s->sout, buf); reset_buf(); } } #endif #if CETIC_6LBR_WITH_MULTICAST add("</pre><h2>Routed multicast groups</h2><pre>"); for(mcast_route = uip_mcast6_route_list_head(), i = 0; mcast_route != NULL; mcast_route = list_item_next(mcast_route), ++i) { if ((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_CONFIG) == 0) { add("[<a href=\"mcast-rm?"); ipaddr_add(&mcast_route->group); add("\">del</a>] "); } ipaddr_add(&mcast_route->group); add(" %lu s\n", mcast_route->lifetime); SEND_STRING(&s->sout, buf); reset_buf(); } #endif add("</pre><h2>Default Routers</h2><pre>"); for(dr = uip_ds6_defrt_head(); dr != NULL; dr = list_item_next(r)) { ipaddr_add(&dr->ipaddr); if(dr->isinfinite) { add(" Inf"); } else { add(" %u s", stimer_remaining(&dr->lifetime)); } add("\n"); SEND_STRING(&s->sout, buf); reset_buf(); } #if UIP_CONF_DS6_ROUTE_INFORMATION add("</pre><h2>Route info</h2><pre>"); for(i = 0; i < UIP_DS6_ROUTE_INFO_NB; i++) { if(uip_ds6_route_info_list[i].isused) { ipaddr_add(&uip_ds6_route_info_list[i].ipaddr); add("/%u (%x) %u s\n", uip_ds6_route_info_list[i].length, uip_ds6_route_info_list[i].flags, uip_ds6_route_info_list[i].lifetime); } } SEND_STRING(&s->sout, buf); reset_buf(); #endif add("</pre><h2>DNS server</h2><pre>"); //Note: Currently we assume only one DNS server uip_ipaddr_t * dns = uip_nameserver_get(0); if(!uip_is_addr_unspecified(dns)) { ipaddr_add(dns); add(" %u s\n", uip_nameserver_next_expiration()); } SEND_STRING(&s->sout, buf); reset_buf(); #if CETIC_6LBR_WITH_IP64 if((nvm_data.global_flags & CETIC_GLOBAL_IP64) != 0) { add("</pre><h2>IP64 connections mapping</h2><pre>"); static struct ip64_addrmap_entry *m; for(m = ip64_addrmap_list(); m != NULL; m = list_item_next(m)) { if(timer_expired(&m->timer)) continue; ipaddr_add(&m->ip6addr); add("%%%d (%d)", m->ip6port, m->protocol); if(m->ip6to4 && m->ip4to6) { add(" <-> "); } else if(m->ip6to4) { add(" -> "); } else { add(" <- "); } ip4addr_add(&m->ip4addr); add("%%%d : %d (%x) %us\n", m->ip4port, m->mapped_port, m->flags, (m->timer.interval - (clock_time() - m->timer.start)) / CLOCK_SECOND); SEND_STRING(&s->sout, buf); reset_buf(); } } #endif #if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0 add("</pre><h2>6LoWPAN Prefix contexts</h2><pre>"); for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { if(addr_contexts[i].used == 1) { add("%d : ", addr_contexts[i].number); ipaddr_add_u8_len(addr_contexts[i].prefix, 8); add("\n"); } } add("</pre><br />"); SEND_STRING(&s->sout, buf); reset_buf(); #endif #if CETIC_6LBR_TRANSPARENTBRIDGE add("<h2>HW Prefixes cache</h2><pre>"); for(i = 0; i < prefixCounter; i++) { add("%02x:%02x:%02x\n", prefixBuffer[i][0], prefixBuffer[i][1], prefixBuffer[i][2]); } SEND_STRING(&s->sout, buf); add("</pre><br />"); reset_buf(); #endif PSOCK_END(&s->sout); } static void add_network_cases(const uint8_t state) { switch (state) { case NBR_INCOMPLETE: add("Incomplete"); break; case NBR_REACHABLE: add("Reachable"); break; case NBR_STALE: add("Stale"); break; case NBR_DELAY: add("Delay"); break; case NBR_PROBE: add("Probe"); break; } } static httpd_cgi_call_t * webserver_network_route_add(struct httpd_state *s) { #if UIP_DS6_STATIC_ROUTES uip_ds6_route_t *route; uip_ipaddr_t ipaddr; uint8_t length; uip_ipaddr_t nexthop; char *p; char *sep; webserver_result_title = "Network"; webserver_result_text = "Add route: Route not created"; do { if(!s->query) break; p = s->query; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "target") != 0) break; p = sep + 1; sep = index(p, '&'); if(sep == NULL) break; *sep = 0; if(uiplib_ipaddrconv(p, &ipaddr) == 0) break; p = sep + 1; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "length") != 0) break; p = sep + 1; sep = index(p, '&'); if(sep == NULL) break; *sep = 0; length = atoi(p); p = sep + 1; sep = index(p, '='); if(sep == NULL) break; *sep = 0; if(strcmp(p, "nexthop") != 0) break; p = sep + 1; if(uiplib_ipaddrconv(p, &nexthop) == 0) break; route = uip_ds6_route_add_static(&ipaddr, length, &nexthop); if(route) { webserver_result_text = "Route created"; } } while (0); #else webserver_result_title = "Network"; webserver_result_text = "Add route: not supported"; #endif return &webserver_result_page; }
/*---------------------------------Main Routine----------------------------*/ int main(void) { /* GCC depends on register r1 set to 0 (?) */ asm volatile ("clr r1"); /* Initialize in a subroutine to maximize stack space */ initialize(); #if DEBUG {struct process *p; for(p = PROCESS_LIST();p != NULL; p = ((struct process *)p->next)) { PRINTA("Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p)); } } #endif while(1) { process_run(); watchdog_periodic(); /* Print rssi of all received packets, useful for range testing */ #ifdef RF230_MIN_RX_POWER uint8_t lastprint; if (rf230_last_rssi != lastprint) { //can be set in halbb.c interrupt routine PRINTA("%u ",rf230_last_rssi); lastprint=rf230_last_rssi; } #endif #if 0 /* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. * This can show when that happens. */ extern uint8_t rf230_calibrated; if (rf230_calibrated) { PRINTA("\nRF230 calibrated!\n"); rf230_calibrated=0; } #endif #if TESTRTIMER /* Timeout can be increased up to 8 seconds maximum. * A one second cycle is convenient for triggering the various debug printouts. * The triggers are staggered to avoid printing everything at once. * My Jackdaw is 4% slow. */ if (rtimerflag) { rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); rtimerflag=0; #if STAMPS if ((rtime%STAMPS)==0) { PRINTA("%us ",rtime); if (rtime%STAMPS*10) PRINTA("\n"); } #endif rtime+=1; #if PINGS && UIP_CONF_IPV6_RPL extern void raven_ping6(void); if ((rtime%PINGS)==1) { PRINTA("**Ping\n"); raven_ping6(); } #endif #if ROUTES && UIP_CONF_IPV6_RPL if ((rtime%ROUTES)==2) { extern uip_ds6_netif_t uip_ds6_if; uint8_t i,j; uip_ds6_nbr_t *nbr; PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); PRINTA("\n"); } } PRINTA("\nNeighbors [%u max]\n",NBR_TABLE_MAX_NEIGHBORS); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { uip_debug_ipaddr_print(&nbr->ipaddr); PRINTA("\n"); j=0; } if (j) PRINTA(" <none>"); PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); uip_ds6_route_t *r; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { if(r->isused) { uip_debug_ipaddr_print(&r->ipaddr); PRINTA("/%u (via ", r->length); uip_debug_ipaddr_print(uip_ds6_route_nexthop(r)); // if(r->state.lifetime < 600) { PRINTA(") %lus\n", r->state.lifetime); // } else { // PRINTA(")\n"); // } j=0; } } if (j) PRINTA(" <none>"); PRINTA("\n---------\n"); } #endif #if STACKMONITOR && CONFIG_STACK_MONITOR if ((rtime%STACKMONITOR)==3) { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { if (*(uint16_t *)p != 0x4242) { PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); break; } p+=100; } while (p<RAMEND-10); } #endif } #endif /* TESTRTIMER */ //Use with RF230BB DEBUGFLOW to show path through driver #if RF230BB&&0 extern uint8_t debugflowsize,debugflow[]; //in rf230bb.c if (debugflowsize) { debugflow[debugflowsize]=0; PRINTA("%s",debugflow); debugflowsize=0; } #endif } return 0; }
/*---------------------------------------------------------------------------*/ static PT_THREAD(generate_routes(struct httpd_state *s)) { static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; #if BUF_USES_STACK char buf[256]; #endif #if WEBSERVER_CONF_LOADTIME static clock_time_t numticks; numticks = clock_time(); #endif PSOCK_BEGIN(&s->sout); SEND_STRING(&s->sout, TOP); #if BUF_USES_STACK bufptr = buf;bufend=bufptr+sizeof(buf); #else blen = 0; #endif ADD("Neighbors<pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { #if WEBSERVER_CONF_NEIGHBOR_STATUS #if BUF_USES_STACK {char* j=bufptr+25; ipaddr_add(&nbr->ipaddr); while (bufptr < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #else {uint8_t j=blen+25; ipaddr_add(&nbr->ipaddr); while (blen < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #endif #else ipaddr_add(&nbr->ipaddr); #endif ADD("\n"); #if BUF_USES_STACK if(bufptr > bufend - 45) { SEND_STRING(&s->sout, buf); bufptr = buf; bufend = bufptr + sizeof(buf); } #else if(blen > sizeof(buf) - 45) { SEND_STRING(&s->sout, buf); blen = 0; } #endif } ADD("</pre>Routes<pre>"); SEND_STRING(&s->sout, buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { #if BUF_USES_STACK #if WEBSERVER_CONF_ROUTE_LINKS ADD("<a href=http://["); ipaddr_add(&r->ipaddr); ADD("]/status.shtml>"); ipaddr_add(&r->ipaddr); ADD("</a>"); #else ipaddr_add(&r->ipaddr); #endif #else #if WEBSERVER_CONF_ROUTE_LINKS ADD("<a href=http://["); ipaddr_add(&r->ipaddr); ADD("]/status.shtml>"); SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not blen = 0; ipaddr_add(&r->ipaddr); ADD("</a>"); #else ipaddr_add(&r->ipaddr); #endif #endif ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(1 || (r->state.lifetime < 600)) { ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } SEND_STRING(&s->sout, buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif } ADD("</pre>"); #if WEBSERVER_CONF_FILESTATS static uint16_t numtimes; ADD("<br><i>This page sent %u times</i>",++numtimes); #endif #if WEBSERVER_CONF_LOADTIME numticks = clock_time() - numticks + 1; ADD(" <i>(%u.%02u sec)</i>",numticks/CLOCK_SECOND,(100*(numticks%CLOCK_SECOND))/CLOCK_SECOND)); #endif SEND_STRING(&s->sout, buf); SEND_STRING(&s->sout, BOTTOM); PSOCK_END(&s->sout); }
static void generate_routes() { static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; #if BUF_USES_STACK char buf[256]; bufptr = buf;bufend=bufptr+sizeof(buf); #else blen = 0; #endif ADD("Neighbors\n"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { #if BUF_USES_STACK {char* j=bufptr+25; ipaddr_add(&nbr->ipaddr); while (bufptr < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #else {uint8_t j=blen+25; ipaddr_add(&nbr->ipaddr); while (blen < j) ADD(" "); switch (nbr->state) { case NBR_INCOMPLETE: ADD(" INCOMPLETE");break; case NBR_REACHABLE: ADD(" REACHABLE");break; case NBR_STALE: ADD(" STALE");break; case NBR_DELAY: ADD(" DELAY");break; case NBR_PROBE: ADD(" NBR_PROBE");break; } } #endif ADD("\n"); #if BUF_USES_STACK if(bufptr > bufend - 45) { PRINTF("%s", buf); bufptr = buf; bufend = bufptr + sizeof(buf); } #else if(blen > sizeof(buf) - 45) { PRINTF("%s", buf); blen = 0; } #endif } ADD("\nRoutes\n"); PRINTF("%s", buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { ipaddr_add(&r->ipaddr); ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(1 || (r->state.lifetime < 600)) { ADD(") %us\n", (unsigned int)r->state.lifetime); // iotlab printf does not have %lu } else { ADD(")\n"); } PRINTF("%s", buf); #if BUF_USES_STACK bufptr = buf; bufend = bufptr + sizeof(buf); #else blen = 0; #endif } }
/*---------------------------------------------------------------------------*/ static PT_THREAD(generate_routes(struct httpd_state *s)) { static int i; static uip_ds6_route_t *r; static uip_ds6_nbr_t *nbr; PSOCK_BEGIN(&s->sout); SEND_STRING(&s->sout, TOP); blen = 0; ADD("Neighbors<pre>"); for(nbr = nbr_table_head(ds6_neighbors); nbr != NULL; nbr = nbr_table_next(ds6_neighbors, nbr)) { ipaddr_add(&nbr->ipaddr); ADD("\n"); if(blen > sizeof(buf) - 45) { SEND_STRING(&s->sout, buf); blen = 0; } } ADD("</pre>Routes<pre>"); SEND_STRING(&s->sout, buf); blen = 0; for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { ipaddr_add(&r->ipaddr); ADD("/%u (via ", r->length); ipaddr_add(uip_ds6_route_nexthop(r)); if(r->state.lifetime < 600) { ADD(") %lus\n", (unsigned long)r->state.lifetime); } else { ADD(")\n"); } SEND_STRING(&s->sout, buf); blen = 0; } ADD("</pre>"); //if(blen > 0) { SEND_STRING(&s->sout, buf); // blen = 0; //} if(sensor_count > 0) { ADD("</pre>Sensors<pre>"); SEND_STRING(&s->sout, buf); blen = 0; for(i = 0; i < sensor_count; i++) { ADD("%s\n", sensors[i]); SEND_STRING(&s->sout, buf); blen = 0; } ADD("</pre>"); SEND_STRING(&s->sout, buf); } SEND_STRING(&s->sout, BOTTOM); PSOCK_END(&s->sout); }