/*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 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"); }
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); }
/*---------------------------------------------------------------------------*/ static unsigned short make_routes_roomfor(void *p) { static const char httpd_cgi_rtesh[] HTTPD_STRING_ATTR = " "; static const char httpd_cgi_rtesf[] HTTPD_STRING_ATTR = "<tr><td colspan=4>(Room for %u more)</td></tr>"; int j = 0; uint16_t numprinted = 0; numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_rtesh); j = uip_ds6_route_num_routes(); numprinted += httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_rtesf, UIP_DS6_ROUTE_NB - j); if(numprinted >= uip_mss()) { return write_mss_error(19); } return numprinted; }
/*---------------------------------------------------------------------------*/ uip_ds6_route_t * uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop) { uip_ds6_route_t *r; struct uip_ds6_route_neighbor_route *nbrr; #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ /* Get link-layer address of next hop, make sure it is in neighbor table */ const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop); if(nexthop_lladdr == NULL) { PRINTF("uip_ds6_route_add: neighbor link-local address unknown for "); PRINT6ADDR(nexthop); PRINTF("\n"); return NULL; } /* First make sure that we don't add a route twice. If we find an existing route for our destination, we'll delete the old one first. */ r = uip_ds6_route_lookup(ipaddr); if(r != NULL) { PRINTF("uip_ds6_route_add: old route for "); PRINT6ADDR(ipaddr); PRINTF(" found, deleting it\n"); uip_ds6_route_rm(r); } { struct uip_ds6_route_neighbor_routes *routes; /* If there is no routing entry, create one. We first need to check if we have room for this route. If not, we remove the least recently used one we have. */ if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) { /* Removing the oldest route entry from the route table. The least recently used route is the first route on the list. */ uip_ds6_route_t *oldest; oldest = list_tail(routelist); /* uip_ds6_route_head(); */ PRINTF("uip_ds6_route_add: dropping route to "); PRINT6ADDR(&oldest->ipaddr); PRINTF("\n"); uip_ds6_route_rm(oldest); } /* Every neighbor on our neighbor table holds a struct uip_ds6_route_neighbor_routes which holds a list of routes that go through the neighbor. We add our route entry to this list. We first check to see if we already have this neighbor in our nbr_route table. If so, the neighbor already has a route entry list. */ routes = nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)nexthop_lladdr); if(routes == NULL) { /* If the neighbor did not have an entry in our neighbor table, we create one. The nbr_table_add_lladdr() function returns a pointer to a pointer that we may use for our own purposes. We initialize this pointer with the list of routing entries that are attached to this neighbor. */ routes = nbr_table_add_lladdr(nbr_routes, (linkaddr_t *)nexthop_lladdr); if(routes == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n"); return NULL; } LIST_STRUCT_INIT(routes, route_list); } /* Allocate a routing entry and populate it. */ r = memb_alloc(&routememb); if(r == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate route\n"); return NULL; } /* add new routes first - assuming that there is a reason to add this and that there is a packet coming soon. */ list_push(routelist, r); nbrr = memb_alloc(&neighborroutememb); if(nbrr == NULL) { /* This should not happen, as we explicitly deallocated one route table entry above. */ PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n"); memb_free(&routememb, r); return NULL; } nbrr->route = r; /* Add the route to this neighbor */ list_add(routes->route_list, nbrr); r->neighbor_routes = routes; num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); r->length = length; #ifdef UIP_DS6_ROUTE_STATE_TYPE memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE)); #endif PRINTF("uip_ds6_route_add: adding route: "); PRINT6ADDR(ipaddr); PRINTF(" via "); PRINT6ADDR(nexthop); PRINTF("\n"); ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]); #if UIP_DS6_NOTIFICATIONS call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop); #endif #if DEBUG != DEBUG_NONE assert_nbr_routes_list_sane(); #endif /* DEBUG != DEBUG_NONE */ return r; }