mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-08-27 01:29:32 +00:00
Merge pull request #46 from adamdunkels/ipv6-rpl-updates
Thingsquare IPv6/RPL updates
This commit is contained in:
commit
89603f7b78
@ -69,7 +69,7 @@ ifdef UIP_CONF_IPV6
|
|||||||
UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \
|
UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \
|
||||||
resolv.c tcpdump.c uiplib.c simple-udp.c
|
resolv.c tcpdump.c uiplib.c simple-udp.c
|
||||||
NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \
|
NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \
|
||||||
sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c
|
sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c uip-ds6-route.c
|
||||||
ifneq ($(UIP_CONF_RPL),0)
|
ifneq ($(UIP_CONF_RPL),0)
|
||||||
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
CFLAGS += -DUIP_CONF_IPV6_RPL=1
|
||||||
include $(CONTIKI)/core/net/rpl/Makefile.rpl
|
include $(CONTIKI)/core/net/rpl/Makefile.rpl
|
||||||
|
@ -307,25 +307,27 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
|
|||||||
static unsigned short
|
static unsigned short
|
||||||
make_routes(void *p)
|
make_routes(void *p)
|
||||||
{
|
{
|
||||||
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
|
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
|
||||||
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %us<br>";
|
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
|
||||||
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
|
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
|
||||||
uint8_t i,j=0;
|
uint8_t i,j=0;
|
||||||
uint16_t numprinted;
|
uint16_t numprinted;
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
||||||
for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
|
for(r = uip_ds6_route_list_head();
|
||||||
if (uip_ds6_routing_table[i].isused) {
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
j++;
|
j++;
|
||||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
|
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
|
||||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted);
|
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted);
|
||||||
if(uip_ds6_routing_table[i].state.lifetime < 3600*24) {
|
if(r->state.lifetime < 3600) {
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
|
||||||
} else {
|
} else {
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
|
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);
|
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);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
|
||||||
return numprinted;
|
return numprinted;
|
||||||
|
@ -109,7 +109,7 @@ packetbuf_compact(void)
|
|||||||
if(packetbuf_is_reference()) {
|
if(packetbuf_is_reference()) {
|
||||||
memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(),
|
memcpy(&packetbuf[PACKETBUF_HDR_SIZE], packetbuf_reference_ptr(),
|
||||||
packetbuf_datalen());
|
packetbuf_datalen());
|
||||||
} else if (bufptr > 0) {
|
} else if(bufptr > 0) {
|
||||||
len = packetbuf_datalen() + PACKETBUF_HDR_SIZE;
|
len = packetbuf_datalen() + PACKETBUF_HDR_SIZE;
|
||||||
for(i = PACKETBUF_HDR_SIZE; i < len; i++) {
|
for(i = PACKETBUF_HDR_SIZE; i < len; i++) {
|
||||||
packetbuf[i] = packetbuf[bufptr + i];
|
packetbuf[i] = packetbuf[bufptr + i];
|
||||||
|
@ -57,18 +57,18 @@
|
|||||||
|
|
||||||
#include "net/neighbor-info.h"
|
#include "net/neighbor-info.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
extern rpl_of_t RPL_OF;
|
extern rpl_of_t RPL_OF;
|
||||||
static rpl_of_t * const objective_functions[] = {&RPL_OF};
|
static rpl_of_t * const objective_functions[] = {&RPL_OF};
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
#ifndef RPL_CONF_MAX_PARENTS_PER_DAG
|
#ifndef RPL_CONF_MAX_PARENTS_PER_DAG
|
||||||
#define RPL_MAX_PARENTS_PER_DAG 8
|
#define RPL_MAX_PARENTS_PER_DAG 8
|
||||||
#else
|
#else
|
||||||
#define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG
|
#define RPL_MAX_PARENTS_PER_DAG RPL_CONF_MAX_PARENTS_PER_DAG
|
||||||
#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */
|
#endif /* !RPL_CONF_MAX_PARENTS_PER_DAG */
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* RPL definitions. */
|
/* RPL definitions. */
|
||||||
|
|
||||||
#ifndef RPL_CONF_GROUNDED
|
#ifndef RPL_CONF_GROUNDED
|
||||||
@ -77,17 +77,17 @@ static rpl_of_t * const objective_functions[] = {&RPL_OF};
|
|||||||
#define RPL_GROUNDED RPL_CONF_GROUNDED
|
#define RPL_GROUNDED RPL_CONF_GROUNDED
|
||||||
#endif /* !RPL_CONF_GROUNDED */
|
#endif /* !RPL_CONF_GROUNDED */
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
|
/* Allocate parents from the same static MEMB chunk to reduce memory waste. */
|
||||||
MEMB(parent_memb, struct rpl_parent,
|
MEMB(parent_memb, struct rpl_parent,
|
||||||
RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE);
|
RPL_MAX_PARENTS_PER_DAG * RPL_MAX_INSTANCES * RPL_MAX_DAG_PER_INSTANCE);
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Allocate instance table. */
|
/* Allocate instance table. */
|
||||||
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
||||||
rpl_instance_t *default_instance;
|
rpl_instance_t *default_instance;
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Greater-than function for the lollipop counter. */
|
/* Greater-than function for the lollipop counter. */
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
lollipop_greater_than(int a, int b)
|
lollipop_greater_than(int a, int b)
|
||||||
{
|
{
|
||||||
@ -101,7 +101,7 @@ lollipop_greater_than(int a, int b)
|
|||||||
(a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1-
|
(a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1-
|
||||||
RPL_LOLLIPOP_SEQUENCE_WINDOWS));
|
RPL_LOLLIPOP_SEQUENCE_WINDOWS));
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
|
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
|
||||||
static void
|
static void
|
||||||
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||||
@ -118,7 +118,7 @@ remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
||||||
{
|
{
|
||||||
@ -134,7 +134,7 @@ nullify_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
|
remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
|
||||||
{
|
{
|
||||||
@ -155,7 +155,7 @@ remove_worst_parent(rpl_dag_t *dag, rpl_rank_t min_worst_rank)
|
|||||||
rpl_remove_parent(dag, worst);
|
rpl_remove_parent(dag, worst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
|
should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
|
||||||
{
|
{
|
||||||
@ -167,7 +167,7 @@ should_send_dao(rpl_instance_t *instance, rpl_dio_t *dio, rpl_parent_t *p)
|
|||||||
return p == instance->current_dag->preferred_parent &&
|
return p == instance->current_dag->preferred_parent &&
|
||||||
(lollipop_greater_than(dio->dtsn, p->dtsn));
|
(lollipop_greater_than(dio->dtsn, p->dtsn));
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
|
acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
|
||||||
{
|
{
|
||||||
@ -175,7 +175,7 @@ acceptable_rank(rpl_dag_t *dag, rpl_rank_t rank)
|
|||||||
((dag->instance->max_rankinc == 0) ||
|
((dag->instance->max_rankinc == 0) ||
|
||||||
DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance));
|
DAG_RANK(rank, dag->instance) <= DAG_RANK(dag->min_rank + dag->instance->max_rankinc, dag->instance));
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static rpl_dag_t *
|
static rpl_dag_t *
|
||||||
get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||||
{
|
{
|
||||||
@ -197,7 +197,7 @@ get_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_dag_t *
|
rpl_dag_t *
|
||||||
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||||
{
|
{
|
||||||
@ -270,7 +270,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||||||
|
|
||||||
return dag;
|
return dag;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_repair_root(uint8_t instance_id)
|
rpl_repair_root(uint8_t instance_id)
|
||||||
{
|
{
|
||||||
@ -287,7 +287,7 @@ rpl_repair_root(uint8_t instance_id)
|
|||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
|
set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
|
||||||
{
|
{
|
||||||
@ -295,7 +295,7 @@ set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
|
|||||||
memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8);
|
memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8);
|
||||||
uip_ds6_set_addr_iid(ipaddr, &uip_lladdr);
|
uip_ds6_set_addr_iid(ipaddr, &uip_lladdr);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
|
check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
|
||||||
{
|
{
|
||||||
@ -331,7 +331,7 @@ check_prefix(rpl_prefix_t *last_prefix, rpl_prefix_t *new_prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
|
rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
|
||||||
{
|
{
|
||||||
@ -349,17 +349,15 @@ rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len)
|
|||||||
check_prefix(NULL, &dag->prefix_info);
|
check_prefix(NULL, &dag->prefix_info);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
|
rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
|
||||||
{
|
{
|
||||||
if(instance->def_route != NULL) {
|
if(instance->def_route != NULL) {
|
||||||
if(instance->def_route->isused) {
|
|
||||||
PRINTF("RPL: Removing default route through ");
|
PRINTF("RPL: Removing default route through ");
|
||||||
PRINT6ADDR(&instance->def_route->ipaddr);
|
PRINT6ADDR(&instance->def_route->ipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
uip_ds6_defrt_rm(instance->def_route);
|
uip_ds6_defrt_rm(instance->def_route);
|
||||||
}
|
|
||||||
instance->def_route = NULL;
|
instance->def_route = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,16 +371,24 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
|
|||||||
if(instance->def_route == NULL) {
|
if(instance->def_route == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
PRINTF("RPL: Removing default route\n");
|
||||||
|
if(instance->def_route != NULL) {
|
||||||
|
uip_ds6_defrt_rm(instance->def_route);
|
||||||
|
} else {
|
||||||
|
PRINTF("RPL: Not actually removing default route, since instance had no default route\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_instance_t *
|
rpl_instance_t *
|
||||||
rpl_alloc_instance(uint8_t instance_id)
|
rpl_alloc_instance(uint8_t instance_id)
|
||||||
{
|
{
|
||||||
rpl_instance_t *instance, *end;
|
rpl_instance_t *instance, *end;
|
||||||
|
|
||||||
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
|
||||||
|
instance < end; ++instance) {
|
||||||
if(instance->used == 0) {
|
if(instance->used == 0) {
|
||||||
memset(instance, 0, sizeof(*instance));
|
memset(instance, 0, sizeof(*instance));
|
||||||
instance->instance_id = instance_id;
|
instance->instance_id = instance_id;
|
||||||
@ -393,7 +399,7 @@ rpl_alloc_instance(uint8_t instance_id)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_dag_t *
|
rpl_dag_t *
|
||||||
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
||||||
{
|
{
|
||||||
@ -425,13 +431,13 @@ rpl_alloc_dag(uint8_t instance_id, uip_ipaddr_t *dag_id)
|
|||||||
rpl_free_instance(instance);
|
rpl_free_instance(instance);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_set_default_instance(rpl_instance_t *instance)
|
rpl_set_default_instance(rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
default_instance = instance;
|
default_instance = instance;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_free_instance(rpl_instance_t *instance)
|
rpl_free_instance(rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
@ -458,7 +464,7 @@ rpl_free_instance(rpl_instance_t *instance)
|
|||||||
|
|
||||||
instance->used = 0;
|
instance->used = 0;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_free_dag(rpl_dag_t *dag)
|
rpl_free_dag(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
@ -480,7 +486,7 @@ rpl_free_dag(rpl_dag_t *dag)
|
|||||||
}
|
}
|
||||||
dag->used = 0;
|
dag->used = 0;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_parent_t *
|
rpl_parent_t *
|
||||||
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
@ -504,7 +510,7 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
|||||||
list_add(dag->parents, p);
|
list_add(dag->parents, p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_parent_t *
|
rpl_parent_t *
|
||||||
rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
|
rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
@ -518,7 +524,7 @@ rpl_find_parent(rpl_dag_t *dag, uip_ipaddr_t *addr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static rpl_dag_t *
|
static rpl_dag_t *
|
||||||
find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
@ -536,7 +542,7 @@ find_parent_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_parent_t *
|
rpl_parent_t *
|
||||||
rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
@ -554,7 +560,7 @@ rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_dag_t *
|
rpl_dag_t *
|
||||||
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
||||||
{
|
{
|
||||||
@ -645,7 +651,7 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p)
|
|||||||
}
|
}
|
||||||
return best_dag;
|
return best_dag;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_parent_t *
|
rpl_parent_t *
|
||||||
rpl_select_parent(rpl_dag_t *dag)
|
rpl_select_parent(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
@ -668,7 +674,7 @@ rpl_select_parent(rpl_dag_t *dag)
|
|||||||
|
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
||||||
{
|
{
|
||||||
@ -681,7 +687,7 @@ rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
|||||||
list_remove(dag->parents, parent);
|
list_remove(dag->parents, parent);
|
||||||
memb_free(&parent_memb, parent);
|
memb_free(&parent_memb, parent);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
||||||
{
|
{
|
||||||
@ -690,12 +696,10 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
|||||||
dag->rank = INFINITE_RANK;
|
dag->rank = INFINITE_RANK;
|
||||||
if(dag->joined) {
|
if(dag->joined) {
|
||||||
if(dag->instance->def_route != NULL) {
|
if(dag->instance->def_route != NULL) {
|
||||||
if(dag->instance->def_route->isused) {
|
|
||||||
PRINTF("RPL: Removing default route ");
|
PRINTF("RPL: Removing default route ");
|
||||||
PRINT6ADDR(&parent->addr);
|
PRINT6ADDR(&parent->addr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
uip_ds6_defrt_rm(dag->instance->def_route);
|
uip_ds6_defrt_rm(dag->instance->def_route);
|
||||||
}
|
|
||||||
dag->instance->def_route = NULL;
|
dag->instance->def_route = NULL;
|
||||||
}
|
}
|
||||||
dao_output(parent, RPL_ZERO_LIFETIME);
|
dao_output(parent, RPL_ZERO_LIFETIME);
|
||||||
@ -706,7 +710,7 @@ rpl_nullify_parent(rpl_dag_t *dag, rpl_parent_t *parent)
|
|||||||
PRINT6ADDR(&parent->addr);
|
PRINT6ADDR(&parent->addr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
|
rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
|
||||||
{
|
{
|
||||||
@ -714,12 +718,11 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
|
|||||||
dag_src->preferred_parent = NULL;
|
dag_src->preferred_parent = NULL;
|
||||||
dag_src->rank = INFINITE_RANK;
|
dag_src->rank = INFINITE_RANK;
|
||||||
if(dag_src->joined && dag_src->instance->def_route != NULL) {
|
if(dag_src->joined && dag_src->instance->def_route != NULL) {
|
||||||
if(dag_src->instance->def_route->isused) {
|
|
||||||
PRINTF("RPL: Removing default route ");
|
PRINTF("RPL: Removing default route ");
|
||||||
PRINT6ADDR(&parent->addr);
|
PRINT6ADDR(&parent->addr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
PRINTF("rpl_move_parent\n");
|
||||||
uip_ds6_defrt_rm(dag_src->instance->def_route);
|
uip_ds6_defrt_rm(dag_src->instance->def_route);
|
||||||
}
|
|
||||||
dag_src->instance->def_route = NULL;
|
dag_src->instance->def_route = NULL;
|
||||||
}
|
}
|
||||||
} else if(dag_src->joined) {
|
} else if(dag_src->joined) {
|
||||||
@ -735,7 +738,7 @@ rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent)
|
|||||||
parent->dag = dag_dst;
|
parent->dag = dag_dst;
|
||||||
list_add(dag_dst->parents, parent);
|
list_add(dag_dst->parents, parent);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_dag_t *
|
rpl_dag_t *
|
||||||
rpl_get_any_dag(void)
|
rpl_get_any_dag(void)
|
||||||
{
|
{
|
||||||
@ -748,7 +751,7 @@ rpl_get_any_dag(void)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_instance_t *
|
rpl_instance_t *
|
||||||
rpl_get_instance(uint8_t instance_id)
|
rpl_get_instance(uint8_t instance_id)
|
||||||
{
|
{
|
||||||
@ -761,7 +764,7 @@ rpl_get_instance(uint8_t instance_id)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
rpl_of_t *
|
rpl_of_t *
|
||||||
rpl_find_of(rpl_ocp_t ocp)
|
rpl_find_of(rpl_ocp_t ocp)
|
||||||
{
|
{
|
||||||
@ -777,7 +780,7 @@ rpl_find_of(rpl_ocp_t ocp)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
@ -874,7 +877,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
@ -954,7 +957,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||||||
p->dtsn = dio->dtsn;
|
p->dtsn = dio->dtsn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
@ -981,7 +984,7 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
|||||||
|
|
||||||
RPL_STAT(rpl_stats.global_repairs++);
|
RPL_STAT(rpl_stats.global_repairs++);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_local_repair(rpl_instance_t *instance)
|
rpl_local_repair(rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
@ -999,7 +1002,7 @@ rpl_local_repair(rpl_instance_t *instance)
|
|||||||
|
|
||||||
RPL_STAT(rpl_stats.local_repairs++);
|
RPL_STAT(rpl_stats.local_repairs++);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_recalculate_ranks(void)
|
rpl_recalculate_ranks(void)
|
||||||
{
|
{
|
||||||
@ -1035,7 +1038,7 @@ rpl_recalculate_ranks(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
||||||
{
|
{
|
||||||
@ -1082,7 +1085,7 @@ rpl_process_parent_event(rpl_instance_t *instance, rpl_parent_t *p)
|
|||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
@ -1095,27 +1098,10 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dio->rank == INFINITE_RANK) {
|
|
||||||
PRINTF("RPL: Ignoring DIO from node with infinite rank: ");
|
|
||||||
PRINT6ADDR(from);
|
|
||||||
PRINTF("\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = rpl_get_instance(dio->instance_id);
|
|
||||||
if(instance == NULL) {
|
|
||||||
PRINTF("RPL: New instance detected: Joining...\n");
|
|
||||||
rpl_join_instance(from, dio);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dag = get_dag(dio->instance_id, &dio->dag_id);
|
dag = get_dag(dio->instance_id, &dio->dag_id);
|
||||||
if(dag == NULL) {
|
instance = rpl_get_instance(dio->instance_id);
|
||||||
PRINTF("RPL: Adding new DAG to known instance.\n");
|
|
||||||
rpl_add_dag(from, dio);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(dag != NULL && instance != NULL) {
|
||||||
if(lollipop_greater_than(dio->version, dag->version)) {
|
if(lollipop_greater_than(dio->version, dag->version)) {
|
||||||
if(dag->rank == ROOT_RANK(instance)) {
|
if(dag->rank == ROOT_RANK(instance)) {
|
||||||
PRINTF("RPL: Root received inconsistent DIO version number\n");
|
PRINTF("RPL: Root received inconsistent DIO version number\n");
|
||||||
@ -1136,6 +1122,27 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dio->rank == INFINITE_RANK) {
|
||||||
|
PRINTF("RPL: Ignoring DIO from node with infinite rank: ");
|
||||||
|
PRINT6ADDR(from);
|
||||||
|
PRINTF("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instance == NULL) {
|
||||||
|
PRINTF("RPL: New instance detected: Joining...\n");
|
||||||
|
rpl_join_instance(from, dio);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dag == NULL) {
|
||||||
|
PRINTF("RPL: Adding new DAG to known instance.\n");
|
||||||
|
rpl_add_dag(from, dio);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(dio->rank < ROOT_RANK(instance)) {
|
if(dio->rank < ROOT_RANK(instance)) {
|
||||||
PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
|
PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
|
||||||
@ -1219,4 +1226,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
|||||||
}
|
}
|
||||||
p->dtsn = dio->dtsn;
|
p->dtsn = dio->dtsn;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||||
@ -61,7 +61,7 @@
|
|||||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_verify_header(int uip_ext_opt_offset)
|
rpl_verify_header(int uip_ext_opt_offset)
|
||||||
{
|
{
|
||||||
@ -97,9 +97,14 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||||||
down = 1;
|
down = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTF("RPL: Packet going %s\n", down == 1 ? "down" : "up");
|
|
||||||
|
|
||||||
sender_closer = UIP_EXT_HDR_OPT_RPL_BUF->senderrank < instance->current_dag->rank;
|
sender_closer = UIP_EXT_HDR_OPT_RPL_BUF->senderrank < instance->current_dag->rank;
|
||||||
|
|
||||||
|
PRINTF("RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ? "down" : "up",
|
||||||
|
sender_closer,
|
||||||
|
UIP_EXT_HDR_OPT_RPL_BUF->senderrank,
|
||||||
|
instance->current_dag->rank
|
||||||
|
);
|
||||||
|
|
||||||
if((down && !sender_closer) || (!down && sender_closer)) {
|
if((down && !sender_closer) || (!down && sender_closer)) {
|
||||||
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
|
PRINTF("RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank, instance->current_dag->rank,
|
UIP_EXT_HDR_OPT_RPL_BUF->senderrank, instance->current_dag->rank,
|
||||||
@ -118,7 +123,7 @@ rpl_verify_header(int uip_ext_opt_offset)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
set_rpl_opt(unsigned uip_ext_opt_offset)
|
set_rpl_opt(unsigned uip_ext_opt_offset)
|
||||||
{
|
{
|
||||||
@ -141,7 +146,7 @@ set_rpl_opt(unsigned uip_ext_opt_offset)
|
|||||||
UIP_IP_BUF->len[0]++;
|
UIP_IP_BUF->len[0]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_update_header_empty(void)
|
rpl_update_header_empty(void)
|
||||||
{
|
{
|
||||||
@ -183,7 +188,22 @@ rpl_update_header_empty(void)
|
|||||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
||||||
case UIP_EXT_HDR_OPT_RPL:
|
case UIP_EXT_HDR_OPT_RPL:
|
||||||
PRINTF("RPL: Updating RPL option\n");
|
PRINTF("RPL: Updating RPL option\n");
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank=instance->current_dag->rank;
|
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = instance->current_dag->rank;
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the down extension flag correctly as described in Section
|
||||||
|
11.2 of RFC6550. If the packet progresses along a DAO route,
|
||||||
|
the down flag should be set. */
|
||||||
|
|
||||||
|
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||||
|
/* No route was found, so this packet will go towards the RPL
|
||||||
|
root. If so, we should not set the down flag. */
|
||||||
|
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||||
|
} else {
|
||||||
|
/* A DAO route was found so we set the down flag. */
|
||||||
|
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
uip_ext_len = last_uip_ext_len;
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -192,7 +212,7 @@ rpl_update_header_empty(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
rpl_update_header_final(uip_ipaddr_t *addr)
|
rpl_update_header_final(uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
@ -230,7 +250,7 @@ rpl_update_header_final(uip_ipaddr_t *addr)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_remove_header(void)
|
rpl_remove_header(void)
|
||||||
{
|
{
|
||||||
@ -257,7 +277,7 @@ rpl_remove_header(void)
|
|||||||
PRINTF("RPL: No hop-by-hop Option found\n");
|
PRINTF("RPL: No hop-by-hop Option found\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
uint8_t
|
uint8_t
|
||||||
rpl_invert_header(void)
|
rpl_invert_header(void)
|
||||||
{
|
{
|
||||||
@ -292,4 +312,4 @@ rpl_invert_header(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -103,7 +103,11 @@
|
|||||||
/* Default values for RPL constants and variables. */
|
/* Default values for RPL constants and variables. */
|
||||||
|
|
||||||
/* The default value for the DAO timer. */
|
/* The default value for the DAO timer. */
|
||||||
|
#ifdef RPL_CONF_DAO_LATENCY
|
||||||
|
#define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY
|
||||||
|
#else /* RPL_CONF_DAO_LATENCY */
|
||||||
#define RPL_DAO_LATENCY (CLOCK_SECOND * 4)
|
#define RPL_DAO_LATENCY (CLOCK_SECOND * 4)
|
||||||
|
#endif /* RPL_DAO_LATENCY */
|
||||||
|
|
||||||
/* Special value indicating immediate removal. */
|
/* Special value indicating immediate removal. */
|
||||||
#define RPL_ZERO_LIFETIME 0
|
#define RPL_ZERO_LIFETIME 0
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/uip-debug.h"
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static struct ctimer periodic_timer;
|
static struct ctimer periodic_timer;
|
||||||
|
|
||||||
static void handle_periodic_timer(void *ptr);
|
static void handle_periodic_timer(void *ptr);
|
||||||
@ -59,7 +59,7 @@ static uint16_t next_dis;
|
|||||||
/* dio_send_ok is true if the node is ready to send DIOs */
|
/* dio_send_ok is true if the node is ready to send DIOs */
|
||||||
static uint8_t dio_send_ok;
|
static uint8_t dio_send_ok;
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
handle_periodic_timer(void *ptr)
|
handle_periodic_timer(void *ptr)
|
||||||
{
|
{
|
||||||
@ -76,30 +76,29 @@ handle_periodic_timer(void *ptr)
|
|||||||
#endif
|
#endif
|
||||||
ctimer_reset(&periodic_timer);
|
ctimer_reset(&periodic_timer);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
new_dio_interval(rpl_instance_t *instance)
|
new_dio_interval(rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
|
clock_time_t ticks;
|
||||||
|
|
||||||
/* TODO: too small timer intervals for many cases */
|
/* TODO: too small timer intervals for many cases */
|
||||||
time = 1UL << instance->dio_intcurrent;
|
time = 1UL << instance->dio_intcurrent;
|
||||||
|
|
||||||
/* Convert from milliseconds to CLOCK_TICKS. */
|
/* Convert from milliseconds to CLOCK_TICKS. */
|
||||||
time = (time * CLOCK_SECOND) / 1000;
|
ticks = (time * CLOCK_SECOND) / 1000;
|
||||||
|
instance->dio_next_delay = ticks;
|
||||||
instance->dio_next_delay = time;
|
|
||||||
|
|
||||||
/* random number between I/2 and I */
|
/* random number between I/2 and I */
|
||||||
time = time >> 1;
|
ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;
|
||||||
time += (time * random_rand()) / RANDOM_RAND_MAX;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The intervals must be equally long among the nodes for Trickle to
|
* The intervals must be equally long among the nodes for Trickle to
|
||||||
* operate efficiently. Therefore we need to calculate the delay between
|
* operate efficiently. Therefore we need to calculate the delay between
|
||||||
* the randomized time and the start time of the next interval.
|
* the randomized time and the start time of the next interval.
|
||||||
*/
|
*/
|
||||||
instance->dio_next_delay -= time;
|
instance->dio_next_delay -= ticks;
|
||||||
instance->dio_send = 1;
|
instance->dio_send = 1;
|
||||||
|
|
||||||
#if RPL_CONF_STATS
|
#if RPL_CONF_STATS
|
||||||
@ -119,10 +118,10 @@ new_dio_interval(rpl_instance_t *instance)
|
|||||||
instance->dio_counter = 0;
|
instance->dio_counter = 0;
|
||||||
|
|
||||||
/* schedule the timer */
|
/* schedule the timer */
|
||||||
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", time);
|
PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
|
||||||
ctimer_set(&instance->dio_timer, time, &handle_dio_timer, instance);
|
ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
handle_dio_timer(void *ptr)
|
handle_dio_timer(void *ptr)
|
||||||
{
|
{
|
||||||
@ -165,14 +164,16 @@ handle_dio_timer(void *ptr)
|
|||||||
new_dio_interval(instance);
|
new_dio_interval(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_reset_periodic_timer(void)
|
rpl_reset_periodic_timer(void)
|
||||||
{
|
{
|
||||||
next_dis = RPL_DIS_INTERVAL - RPL_DIS_START_DELAY;
|
next_dis = RPL_DIS_INTERVAL / 2 +
|
||||||
|
((uint32_t)RPL_DIS_INTERVAL * (uint32_t)random_rand()) / RANDOM_RAND_MAX -
|
||||||
|
RPL_DIS_START_DELAY;
|
||||||
ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
|
ctimer_set(&periodic_timer, CLOCK_SECOND, handle_periodic_timer, NULL);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Resets the DIO timer in the instance to its minimal interval. */
|
/* Resets the DIO timer in the instance to its minimal interval. */
|
||||||
void
|
void
|
||||||
rpl_reset_dio_timer(rpl_instance_t *instance)
|
rpl_reset_dio_timer(rpl_instance_t *instance)
|
||||||
@ -190,7 +191,7 @@ rpl_reset_dio_timer(rpl_instance_t *instance)
|
|||||||
#endif /* RPL_CONF_STATS */
|
#endif /* RPL_CONF_STATS */
|
||||||
#endif /* RPL_LEAF_ONLY */
|
#endif /* RPL_LEAF_ONLY */
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
handle_dao_timer(void *ptr)
|
handle_dao_timer(void *ptr)
|
||||||
{
|
{
|
||||||
@ -214,7 +215,7 @@ handle_dao_timer(void *ptr)
|
|||||||
}
|
}
|
||||||
ctimer_stop(&instance->dao_timer);
|
ctimer_stop(&instance->dao_timer);
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_schedule_dao(rpl_instance_t *instance)
|
rpl_schedule_dao(rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
@ -233,4 +234,4 @@ rpl_schedule_dao(rpl_instance_t *instance)
|
|||||||
handle_dao_timer, instance);
|
handle_dao_timer, instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -56,40 +56,61 @@
|
|||||||
rpl_stats_t rpl_stats;
|
rpl_stats_t rpl_stats;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
extern uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB];
|
|
||||||
/************************************************************************/
|
|
||||||
void
|
void
|
||||||
rpl_purge_routes(void)
|
rpl_purge_routes(void)
|
||||||
{
|
{
|
||||||
int i;
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
r = uip_ds6_route_list_head();
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
|
||||||
if(uip_ds6_routing_table[i].state.lifetime <= 1) {
|
while(r != NULL) {
|
||||||
uip_ds6_route_rm(&uip_ds6_routing_table[i]);
|
if(r->state.lifetime <= 1) {
|
||||||
|
uip_ds6_route_rm(r);
|
||||||
|
r = uip_ds6_route_list_head();
|
||||||
} else {
|
} else {
|
||||||
uip_ds6_routing_table[i].state.lifetime--;
|
r->state.lifetime--;
|
||||||
}
|
r = list_item_next(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_remove_routes(rpl_dag_t *dag)
|
rpl_remove_routes(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
int i;
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
r = uip_ds6_route_list_head();
|
||||||
if(uip_ds6_routing_table[i].state.dag == dag) {
|
|
||||||
uip_ds6_route_rm(&uip_ds6_routing_table[i]);
|
while(r != NULL) {
|
||||||
|
if(r->state.dag == dag) {
|
||||||
|
uip_ds6_route_rm(r);
|
||||||
|
r = uip_ds6_route_list_head();
|
||||||
|
} else {
|
||||||
|
r = list_item_next(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
|
rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
|
r = uip_ds6_route_list_head();
|
||||||
|
|
||||||
|
while(r != NULL) {
|
||||||
|
if(uip_ipaddr_cmp(&r->nexthop, nexthop) &&
|
||||||
|
r->state.dag == dag) {
|
||||||
|
uip_ds6_route_rm(r);
|
||||||
|
r = uip_ds6_route_list_head();
|
||||||
|
} else {
|
||||||
|
r = list_item_next(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
|
||||||
|
#if 0
|
||||||
uip_ds6_route_t *locroute;
|
uip_ds6_route_t *locroute;
|
||||||
|
|
||||||
for(locroute = uip_ds6_routing_table;
|
for(locroute = uip_ds6_routing_table;
|
||||||
@ -102,8 +123,9 @@ rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
#endif /* 0 */
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_route_t *
|
uip_ds6_route_t *
|
||||||
rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
|
rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
|
||||||
uip_ipaddr_t *next_hop)
|
uip_ipaddr_t *next_hop)
|
||||||
@ -136,7 +158,7 @@ rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len,
|
|||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
||||||
{
|
{
|
||||||
@ -179,7 +201,7 @@ rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
|
|||||||
uip_ds6_route_rm_by_nexthop(&ipaddr);
|
uip_ds6_route_rm_by_nexthop(&ipaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
||||||
{
|
{
|
||||||
@ -203,7 +225,7 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_init(void)
|
rpl_init(void)
|
||||||
{
|
{
|
||||||
@ -222,4 +244,4 @@ rpl_init(void)
|
|||||||
memset(&rpl_stats, 0, sizeof(rpl_stats));
|
memset(&rpl_stats, 0, sizeof(rpl_stats));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/************************************************************************/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -221,7 +221,7 @@ struct rpl_instance {
|
|||||||
uint16_t dio_totsend;
|
uint16_t dio_totsend;
|
||||||
uint16_t dio_totrecv;
|
uint16_t dio_totrecv;
|
||||||
#endif /* RPL_CONF_STATS */
|
#endif /* RPL_CONF_STATS */
|
||||||
uint32_t dio_next_delay; /* delay for completion of dio interval */
|
clock_time_t dio_next_delay; /* delay for completion of dio interval */
|
||||||
struct ctimer dio_timer;
|
struct ctimer dio_timer;
|
||||||
struct ctimer dao_timer;
|
struct ctimer dao_timer;
|
||||||
};
|
};
|
||||||
|
@ -1648,7 +1648,7 @@ input(void)
|
|||||||
if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) {
|
if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) {
|
||||||
sicslowpan_len = frag_size;
|
sicslowpan_len = frag_size;
|
||||||
reass_tag = frag_tag;
|
reass_tag = frag_tag;
|
||||||
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND);
|
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16);
|
||||||
PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n",
|
PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n",
|
||||||
sicslowpan_len, reass_tag);
|
sicslowpan_len, reass_tag);
|
||||||
rimeaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
rimeaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
@ -113,6 +113,34 @@ simple_udp_sendto(struct simple_udp_connection *c,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Send a UDP packet to a specified IP address and UDP port
|
||||||
|
* \param c A pointer to a struct simple_udp_connection
|
||||||
|
* \param data A pointer to the data to be sent
|
||||||
|
* \param datalen The length of the data
|
||||||
|
* \param to The IP address of the receiver
|
||||||
|
* \param port The UDP port of the receiver, in host byte order
|
||||||
|
*
|
||||||
|
* This function sends a UDP packet to a specified IP
|
||||||
|
* address and UDP port. The packet will be sent with the
|
||||||
|
* UDP ports that were specified when the connection wa
|
||||||
|
* registered with simple_udp_register().
|
||||||
|
*
|
||||||
|
* \sa simple_udp_sendto()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
simple_udp_sendto_port(struct simple_udp_connection *c,
|
||||||
|
const void *data, uint16_t datalen,
|
||||||
|
const uip_ipaddr_t *to,
|
||||||
|
uint16_t port)
|
||||||
|
{
|
||||||
|
if(c->udp_conn != NULL) {
|
||||||
|
uip_udp_packet_sendto(c->udp_conn, data, datalen,
|
||||||
|
to, UIP_HTONS(port));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \brief Register a UDP connection
|
* \brief Register a UDP connection
|
||||||
* \param c A pointer to a struct simple_udp_connection
|
* \param c A pointer to a struct simple_udp_connection
|
||||||
|
@ -86,6 +86,10 @@ int simple_udp_sendto(struct simple_udp_connection *c,
|
|||||||
const void *data, uint16_t datalen,
|
const void *data, uint16_t datalen,
|
||||||
const uip_ipaddr_t *to);
|
const uip_ipaddr_t *to);
|
||||||
|
|
||||||
|
int simple_udp_sendto_port(struct simple_udp_connection *c,
|
||||||
|
const void *data, uint16_t datalen,
|
||||||
|
const uip_ipaddr_t *to, uint16_t to_port);
|
||||||
|
|
||||||
void simple_udp_init(void);
|
void simple_udp_init(void);
|
||||||
|
|
||||||
#endif /* SIMPLE_UDP_H */
|
#endif /* SIMPLE_UDP_H */
|
||||||
|
@ -471,13 +471,13 @@ eventhandler(process_event_t ev, process_data_t data)
|
|||||||
}*/
|
}*/
|
||||||
#if !UIP_CONF_ROUTER
|
#if !UIP_CONF_ROUTER
|
||||||
if(data == &uip_ds6_timer_rs &&
|
if(data == &uip_ds6_timer_rs &&
|
||||||
etimer_expired(&uip_ds6_timer_rs)){
|
etimer_expired(&uip_ds6_timer_rs)) {
|
||||||
uip_ds6_send_rs();
|
uip_ds6_send_rs();
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
#endif /* !UIP_CONF_ROUTER */
|
#endif /* !UIP_CONF_ROUTER */
|
||||||
if(data == &uip_ds6_timer_periodic &&
|
if(data == &uip_ds6_timer_periodic &&
|
||||||
etimer_expired(&uip_ds6_timer_periodic)){
|
etimer_expired(&uip_ds6_timer_periodic)) {
|
||||||
uip_ds6_periodic();
|
uip_ds6_periodic();
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
@ -586,6 +586,11 @@ tcpip_ipv6_output(void)
|
|||||||
} else {
|
} else {
|
||||||
nexthop = &locrt->nexthop;
|
nexthop = &locrt->nexthop;
|
||||||
}
|
}
|
||||||
|
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
|
||||||
|
if(nexthop != NULL) {
|
||||||
|
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
}
|
||||||
|
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
|
||||||
}
|
}
|
||||||
/* End of next hop determination */
|
/* End of next hop determination */
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
371
core/net/uip-ds6-route.c
Normal file
371
core/net/uip-ds6-route.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "net/uip-ds6.h"
|
||||||
|
#include "net/uip.h"
|
||||||
|
|
||||||
|
#include "lib/list.h"
|
||||||
|
#include "lib/memb.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
LIST(routelist);
|
||||||
|
MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB);
|
||||||
|
|
||||||
|
LIST(defaultrouterlist);
|
||||||
|
MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB);
|
||||||
|
|
||||||
|
LIST(notificationlist);
|
||||||
|
|
||||||
|
#define DEBUG DEBUG_NONE
|
||||||
|
#include "net/uip-debug.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
call_route_callback(int event, uip_ipaddr_t *route,
|
||||||
|
uip_ipaddr_t *nexthop)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
struct uip_ds6_notification *n;
|
||||||
|
for(n = list_head(notificationlist);
|
||||||
|
n != NULL;
|
||||||
|
n = list_item_next(n)) {
|
||||||
|
if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD ||
|
||||||
|
event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
|
||||||
|
num = list_length(defaultrouterlist);
|
||||||
|
} else {
|
||||||
|
num = list_length(routelist);
|
||||||
|
}
|
||||||
|
n->callback(event, route, nexthop, num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_notification_add(struct uip_ds6_notification *n,
|
||||||
|
uip_ds6_notification_callback c)
|
||||||
|
{
|
||||||
|
if(n != NULL && c != NULL) {
|
||||||
|
n->callback = c;
|
||||||
|
list_add(notificationlist, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_notification_rm(struct uip_ds6_notification *n)
|
||||||
|
{
|
||||||
|
list_remove(notificationlist, n);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_route_init(void)
|
||||||
|
{
|
||||||
|
memb_init(&routememb);
|
||||||
|
list_init(routelist);
|
||||||
|
|
||||||
|
memb_init(&defaultroutermemb);
|
||||||
|
list_init(defaultrouterlist);
|
||||||
|
|
||||||
|
list_init(notificationlist);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_route_t *
|
||||||
|
uip_ds6_route_list_head(void)
|
||||||
|
{
|
||||||
|
return list_head(routelist);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
uip_ds6_route_num_routes(void)
|
||||||
|
{
|
||||||
|
return list_length(routelist);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
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 = list_head(routelist);
|
||||||
|
r != NULL;
|
||||||
|
r = list_item_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(&found_route->nexthop);
|
||||||
|
PRINTF("\n");
|
||||||
|
} else {
|
||||||
|
PRINTF("uip-ds6-route: No route found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return found_route;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_route_t *
|
||||||
|
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
||||||
|
uip_ipaddr_t *nexthop, uint8_t metric)
|
||||||
|
{
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
|
/* First make sure that we don't add a route twice. If we find an
|
||||||
|
existing route for our destination, we'll just update the old
|
||||||
|
one. */
|
||||||
|
r = uip_ds6_route_lookup(ipaddr);
|
||||||
|
if(r != NULL) {
|
||||||
|
PRINTF("uip_ds6_route_add: old route already found, updating this one instead: ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
} else {
|
||||||
|
/* Allocate a routing entry and add the route to the list */
|
||||||
|
r = memb_alloc(&routememb);
|
||||||
|
if(r == NULL) {
|
||||||
|
PRINTF("uip_ds6_route_add: could not allocate memory for new route to ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF(", dropping it\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
list_add(routelist, r);
|
||||||
|
|
||||||
|
PRINTF("uip_ds6_route_add num %d\n", list_length(routelist));
|
||||||
|
}
|
||||||
|
|
||||||
|
uip_ipaddr_copy(&(r->ipaddr), ipaddr);
|
||||||
|
r->length = length;
|
||||||
|
uip_ipaddr_copy(&(r->nexthop), nexthop);
|
||||||
|
r->metric = metric;
|
||||||
|
|
||||||
|
#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]);
|
||||||
|
|
||||||
|
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_route_rm(uip_ds6_route_t *route)
|
||||||
|
{
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
/* Make sure that the route is in the list before removing it. */
|
||||||
|
for(r = list_head(routelist);
|
||||||
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
|
if(r == route) {
|
||||||
|
list_remove(routelist, route);
|
||||||
|
memb_free(&routememb, route);
|
||||||
|
|
||||||
|
PRINTF("uip_ds6_route_rm num %d\n", list_length(routelist));
|
||||||
|
|
||||||
|
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
|
||||||
|
&route->ipaddr, &route->nexthop);
|
||||||
|
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
|
||||||
|
/* we need to check if this was the last route towards "nexthop" */
|
||||||
|
/* if so - remove that link (annotation) */
|
||||||
|
for(r = list_head(routelist);
|
||||||
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
|
if(uip_ipaddr_cmp(&r->nexthop, &route->nexthop)) {
|
||||||
|
/* we found another link using the specific nexthop, so keep the #L */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ANNOTATE("#L %u 0\n", route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
|
||||||
|
{
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
|
r = list_head(routelist);
|
||||||
|
while(r != NULL) {
|
||||||
|
if(uip_ipaddr_cmp(&r->nexthop, nexthop)) {
|
||||||
|
list_remove(routelist, r);
|
||||||
|
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
|
||||||
|
&r->ipaddr, &r->nexthop);
|
||||||
|
r = list_head(routelist);
|
||||||
|
} else {
|
||||||
|
r = list_item_next(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_defrt_t *
|
||||||
|
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
||||||
|
{
|
||||||
|
uip_ds6_defrt_t *d;
|
||||||
|
|
||||||
|
d = uip_ds6_defrt_lookup(ipaddr);
|
||||||
|
if(d == NULL) {
|
||||||
|
d = memb_alloc(&defaultroutermemb);
|
||||||
|
if(d == NULL) {
|
||||||
|
PRINTF("uip_ds6_defrt_add: could not add default route to ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF(", out of memory\n");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
PRINTF("uip_ds6_defrt_add: adding default route to ");
|
||||||
|
PRINT6ADDR(ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
list_push(defaultrouterlist, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
uip_ipaddr_copy(&d->ipaddr, ipaddr);
|
||||||
|
if(interval != 0) {
|
||||||
|
stimer_set(&d->lifetime, interval);
|
||||||
|
d->isinfinite = 0;
|
||||||
|
} else {
|
||||||
|
d->isinfinite = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
|
||||||
|
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
|
||||||
|
{
|
||||||
|
uip_ds6_defrt_t *d;
|
||||||
|
/* Make sure that the defrt is in the list before we remove it. */
|
||||||
|
for(d = list_head(defaultrouterlist);
|
||||||
|
d != NULL;
|
||||||
|
d = list_item_next(d)) {
|
||||||
|
if(d == defrt) {
|
||||||
|
PRINTF("Removing default route\n");
|
||||||
|
list_remove(defaultrouterlist, defrt);
|
||||||
|
memb_free(&defaultroutermemb, defrt);
|
||||||
|
ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
|
||||||
|
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
|
||||||
|
&defrt->ipaddr, &defrt->ipaddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_defrt_t *
|
||||||
|
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
|
||||||
|
{
|
||||||
|
uip_ds6_defrt_t *d;
|
||||||
|
for(d = list_head(defaultrouterlist);
|
||||||
|
d != NULL;
|
||||||
|
d = list_item_next(d)) {
|
||||||
|
if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ipaddr_t *
|
||||||
|
uip_ds6_defrt_choose(void)
|
||||||
|
{
|
||||||
|
uip_ds6_defrt_t *d;
|
||||||
|
uip_ds6_nbr_t *bestnbr;
|
||||||
|
uip_ipaddr_t *addr;
|
||||||
|
|
||||||
|
addr = NULL;
|
||||||
|
for(d = list_head(defaultrouterlist);
|
||||||
|
d != NULL;
|
||||||
|
d = list_item_next(d)) {
|
||||||
|
PRINTF("Defrt, IP address ");
|
||||||
|
PRINT6ADDR(&d->ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
bestnbr = uip_ds6_nbr_lookup(&d->ipaddr);
|
||||||
|
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
|
||||||
|
PRINTF("Defrt found, IP address ");
|
||||||
|
PRINT6ADDR(&d->ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
return &d->ipaddr;
|
||||||
|
} else {
|
||||||
|
addr = &d->ipaddr;
|
||||||
|
PRINTF("Defrt INCOMPLETE found, IP address ");
|
||||||
|
PRINT6ADDR(&d->ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_ds6_defrt_periodic(void)
|
||||||
|
{
|
||||||
|
uip_ds6_defrt_t *d;
|
||||||
|
d = list_head(defaultrouterlist);
|
||||||
|
while(d != NULL) {
|
||||||
|
if(!d->isinfinite &&
|
||||||
|
stimer_expired(&d->lifetime)) {
|
||||||
|
PRINTF("uip_ds6_defrt_periodic: defrt lifetime expired\n");
|
||||||
|
uip_ds6_defrt_rm(d);
|
||||||
|
d = list_head(defaultrouterlist);
|
||||||
|
} else {
|
||||||
|
d = list_item_next(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
132
core/net/uip-ds6-route.h
Normal file
132
core/net/uip-ds6-route.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef UIP_DS6_ROUTE_H
|
||||||
|
#define UIP_DS6_ROUTE_H
|
||||||
|
|
||||||
|
void uip_ds6_route_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Event constants for the uip-ds6 route notification interface. The
|
||||||
|
notification interface allows for a user program to be notified via
|
||||||
|
a callback when a route has been added or removed and when the
|
||||||
|
system has added or removed a default route. */
|
||||||
|
#define UIP_DS6_NOTIFICATION_DEFRT_ADD 0
|
||||||
|
#define UIP_DS6_NOTIFICATION_DEFRT_RM 1
|
||||||
|
#define UIP_DS6_NOTIFICATION_ROUTE_ADD 2
|
||||||
|
#define UIP_DS6_NOTIFICATION_ROUTE_RM 3
|
||||||
|
|
||||||
|
typedef void (* uip_ds6_notification_callback)(int event,
|
||||||
|
uip_ipaddr_t *route,
|
||||||
|
uip_ipaddr_t *nexthop,
|
||||||
|
int num_routes);
|
||||||
|
struct uip_ds6_notification {
|
||||||
|
struct uip_ds6_notification *next;
|
||||||
|
uip_ds6_notification_callback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
void uip_ds6_notification_add(struct uip_ds6_notification *n,
|
||||||
|
uip_ds6_notification_callback c);
|
||||||
|
/*--------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Routing table */
|
||||||
|
#define UIP_DS6_ROUTE_NBS 0
|
||||||
|
#ifndef UIP_CONF_DS6_ROUTE_NBU
|
||||||
|
#define UIP_DS6_ROUTE_NBU 4
|
||||||
|
#else
|
||||||
|
#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU
|
||||||
|
#endif
|
||||||
|
#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU
|
||||||
|
|
||||||
|
/** \brief define some additional RPL related route state and
|
||||||
|
* neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */
|
||||||
|
#ifndef UIP_DS6_ROUTE_STATE_TYPE
|
||||||
|
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
|
||||||
|
/* Needed for the extended route entry state when using ContikiRPL */
|
||||||
|
typedef struct rpl_route_entry {
|
||||||
|
uint32_t lifetime;
|
||||||
|
uint32_t saved_lifetime;
|
||||||
|
void *dag;
|
||||||
|
uint8_t learned_from;
|
||||||
|
} rpl_route_entry_t;
|
||||||
|
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief An entry in the routing table */
|
||||||
|
typedef struct uip_ds6_route {
|
||||||
|
struct uip_ds6_route *next;
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
|
uip_ipaddr_t nexthop;
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t metric;
|
||||||
|
#ifdef UIP_DS6_ROUTE_STATE_TYPE
|
||||||
|
UIP_DS6_ROUTE_STATE_TYPE state;
|
||||||
|
#endif
|
||||||
|
} uip_ds6_route_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief An entry in the default router list */
|
||||||
|
typedef struct uip_ds6_defrt {
|
||||||
|
struct uip_ds6_defrt *next;
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
|
struct stimer lifetime;
|
||||||
|
uint8_t isinfinite;
|
||||||
|
} uip_ds6_defrt_t;
|
||||||
|
|
||||||
|
/** \name Default router list basic routines */
|
||||||
|
/** @{ */
|
||||||
|
uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
|
||||||
|
unsigned long interval);
|
||||||
|
void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt);
|
||||||
|
uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr);
|
||||||
|
uip_ipaddr_t *uip_ds6_defrt_choose(void);
|
||||||
|
|
||||||
|
void uip_ds6_defrt_periodic(void);
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
/** \name Routing Table basic routines */
|
||||||
|
/** @{ */
|
||||||
|
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
|
||||||
|
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
||||||
|
uip_ipaddr_t *next_hop, uint8_t metric);
|
||||||
|
void uip_ds6_route_rm(uip_ds6_route_t *route);
|
||||||
|
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
|
||||||
|
|
||||||
|
int uip_ds6_route_num_routes(void);
|
||||||
|
uip_ds6_route_t *uip_ds6_route_list_head(void);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* UIP_DS6_ROUTE_H */
|
@ -75,9 +75,9 @@ static uint8_t rscount; /** \brief numbe
|
|||||||
/** @{ */
|
/** @{ */
|
||||||
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
|
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
|
||||||
uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */
|
uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */
|
||||||
uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
|
//uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */
|
||||||
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
|
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
|
||||||
uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
|
//uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */
|
||||||
|
|
||||||
/* Used by Cooja to enable extraction of addresses from memory.*/
|
/* Used by Cooja to enable extraction of addresses from memory.*/
|
||||||
uint8_t uip_ds6_addr_size;
|
uint8_t uip_ds6_addr_size;
|
||||||
@ -89,28 +89,29 @@ uint8_t uip_ds6_netif_addr_list_offset;
|
|||||||
static uip_ipaddr_t loc_fipaddr;
|
static uip_ipaddr_t loc_fipaddr;
|
||||||
|
|
||||||
/* Pointers used in this file */
|
/* Pointers used in this file */
|
||||||
static uip_ipaddr_t *locipaddr;
|
|
||||||
static uip_ds6_addr_t *locaddr;
|
static uip_ds6_addr_t *locaddr;
|
||||||
static uip_ds6_maddr_t *locmaddr;
|
static uip_ds6_maddr_t *locmaddr;
|
||||||
static uip_ds6_aaddr_t *locaaddr;
|
static uip_ds6_aaddr_t *locaaddr;
|
||||||
static uip_ds6_prefix_t *locprefix;
|
static uip_ds6_prefix_t *locprefix;
|
||||||
static uip_ds6_nbr_t *locnbr;
|
static uip_ds6_nbr_t *locnbr;
|
||||||
static uip_ds6_defrt_t *locdefrt;
|
static uip_ds6_defrt_t *locdefrt;
|
||||||
static uip_ds6_route_t *locroute;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_init(void)
|
uip_ds6_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
uip_ds6_route_init();
|
||||||
|
|
||||||
PRINTF("Init of IPv6 data structures\n");
|
PRINTF("Init of IPv6 data structures\n");
|
||||||
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
|
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
|
||||||
UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
|
UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
|
||||||
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
|
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
|
||||||
memset(uip_ds6_nbr_cache, 0, sizeof(uip_ds6_nbr_cache));
|
memset(uip_ds6_nbr_cache, 0, sizeof(uip_ds6_nbr_cache));
|
||||||
memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
|
// memset(uip_ds6_defrt_list, 0, sizeof(uip_ds6_defrt_list));
|
||||||
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
|
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
|
||||||
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
|
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
|
||||||
memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
|
// memset(uip_ds6_routing_table, 0, sizeof(uip_ds6_routing_table));
|
||||||
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
|
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
|
||||||
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
|
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
|
||||||
|
|
||||||
@ -174,13 +175,14 @@ uip_ds6_periodic(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Periodic processing on default routers */
|
/* Periodic processing on default routers */
|
||||||
for(locdefrt = uip_ds6_defrt_list;
|
uip_ds6_defrt_periodic();
|
||||||
|
/* for(locdefrt = uip_ds6_defrt_list;
|
||||||
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
|
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
|
||||||
if((locdefrt->isused) && (!locdefrt->isinfinite) &&
|
if((locdefrt->isused) && (!locdefrt->isinfinite) &&
|
||||||
(stimer_expired(&(locdefrt->lifetime)))) {
|
(stimer_expired(&(locdefrt->lifetime)))) {
|
||||||
uip_ds6_defrt_rm(locdefrt);
|
uip_ds6_defrt_rm(locdefrt);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#if !UIP_CONF_ROUTER
|
#if !UIP_CONF_ROUTER
|
||||||
/* Periodic processing on prefixes */
|
/* Periodic processing on prefixes */
|
||||||
@ -398,86 +400,6 @@ uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_defrt_t *
|
|
||||||
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
|
|
||||||
{
|
|
||||||
if(uip_ds6_list_loop
|
|
||||||
((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
|
|
||||||
sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
|
||||||
(uip_ds6_element_t **)&locdefrt) == FREESPACE) {
|
|
||||||
locdefrt->isused = 1;
|
|
||||||
uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
|
|
||||||
if(interval != 0) {
|
|
||||||
stimer_set(&locdefrt->lifetime, interval);
|
|
||||||
locdefrt->isinfinite = 0;
|
|
||||||
} else {
|
|
||||||
locdefrt->isinfinite = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTF("Adding defrouter with ip addr ");
|
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
|
|
||||||
ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
|
|
||||||
return locdefrt;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
|
|
||||||
{
|
|
||||||
if(defrt != NULL) {
|
|
||||||
defrt->isused = 0;
|
|
||||||
ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_defrt_t *
|
|
||||||
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
|
|
||||||
{
|
|
||||||
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_defrt_list,
|
|
||||||
UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt_t), ipaddr, 128,
|
|
||||||
(uip_ds6_element_t **)&locdefrt) == FOUND) {
|
|
||||||
return locdefrt;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ipaddr_t *
|
|
||||||
uip_ds6_defrt_choose(void)
|
|
||||||
{
|
|
||||||
uip_ds6_nbr_t *bestnbr;
|
|
||||||
|
|
||||||
locipaddr = NULL;
|
|
||||||
for(locdefrt = uip_ds6_defrt_list;
|
|
||||||
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
|
|
||||||
if(locdefrt->isused) {
|
|
||||||
PRINTF("Defrt, IP address ");
|
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
|
|
||||||
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
|
|
||||||
PRINTF("Defrt found, IP address ");
|
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
return &locdefrt->ipaddr;
|
|
||||||
} else {
|
|
||||||
locipaddr = &locdefrt->ipaddr;
|
|
||||||
PRINTF("Defrt INCOMPLETE found, IP address ");
|
|
||||||
PRINT6ADDR(&locdefrt->ipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return locipaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
uip_ds6_prefix_t *
|
uip_ds6_prefix_t *
|
||||||
@ -744,104 +666,6 @@ uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_route_t *
|
|
||||||
uip_ds6_route_lookup(uip_ipaddr_t *destipaddr)
|
|
||||||
{
|
|
||||||
uip_ds6_route_t *locrt = NULL;
|
|
||||||
uint8_t longestmatch = 0;
|
|
||||||
|
|
||||||
PRINTF("DS6: Looking up route for ");
|
|
||||||
PRINT6ADDR(destipaddr);
|
|
||||||
PRINTF("\n");
|
|
||||||
|
|
||||||
for(locroute = uip_ds6_routing_table;
|
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
|
|
||||||
if((locroute->isused) && (locroute->length >= longestmatch)
|
|
||||||
&&
|
|
||||||
(uip_ipaddr_prefixcmp
|
|
||||||
(destipaddr, &locroute->ipaddr, locroute->length))) {
|
|
||||||
longestmatch = locroute->length;
|
|
||||||
locrt = locroute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(locrt != NULL) {
|
|
||||||
PRINTF("DS6: Found route:");
|
|
||||||
PRINT6ADDR(destipaddr);
|
|
||||||
PRINTF(" via ");
|
|
||||||
PRINT6ADDR(&locrt->nexthop);
|
|
||||||
PRINTF("\n");
|
|
||||||
} else {
|
|
||||||
PRINTF("DS6: No route found\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return locrt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
uip_ds6_route_t *
|
|
||||||
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
|
|
||||||
uint8_t metric)
|
|
||||||
{
|
|
||||||
if(uip_ds6_list_loop
|
|
||||||
((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
|
|
||||||
sizeof(uip_ds6_route_t), ipaddr, length,
|
|
||||||
(uip_ds6_element_t **)&locroute) == FREESPACE) {
|
|
||||||
locroute->isused = 1;
|
|
||||||
uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
|
|
||||||
locroute->length = length;
|
|
||||||
uip_ipaddr_copy(&(locroute->nexthop), nexthop);
|
|
||||||
locroute->metric = metric;
|
|
||||||
|
|
||||||
#ifdef UIP_DS6_ROUTE_STATE_TYPE
|
|
||||||
memset(&locroute->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PRINTF("DS6: adding route: ");
|
|
||||||
PRINT6ADDR(ipaddr);
|
|
||||||
PRINTF(" via ");
|
|
||||||
PRINT6ADDR(nexthop);
|
|
||||||
PRINTF("\n");
|
|
||||||
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return locroute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_ds6_route_rm(uip_ds6_route_t *route)
|
|
||||||
{
|
|
||||||
route->isused = 0;
|
|
||||||
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
|
|
||||||
/* we need to check if this was the last route towards "nexthop" */
|
|
||||||
/* if so - remove that link (annotation) */
|
|
||||||
for(locroute = uip_ds6_routing_table;
|
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
|
||||||
locroute++) {
|
|
||||||
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
|
|
||||||
/* we found another link using the specific nexthop, so keep the #L */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ANNOTATE("#L %u 0\n",route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
|
|
||||||
{
|
|
||||||
for(locroute = uip_ds6_routing_table;
|
|
||||||
locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
|
|
||||||
locroute++) {
|
|
||||||
if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
|
|
||||||
locroute->isused = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "sys/stimer.h"
|
#include "sys/stimer.h"
|
||||||
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
|
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
|
||||||
#include "net/uip-nd6.h"
|
#include "net/uip-nd6.h"
|
||||||
|
#include "net/uip-ds6-route.h"
|
||||||
|
|
||||||
/*--------------------------------------------------*/
|
/*--------------------------------------------------*/
|
||||||
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
|
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
|
||||||
@ -82,15 +83,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU
|
#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU
|
||||||
|
|
||||||
/* Routing table */
|
|
||||||
#define UIP_DS6_ROUTE_NBS 0
|
|
||||||
#ifndef UIP_CONF_DS6_ROUTE_NBU
|
|
||||||
#define UIP_DS6_ROUTE_NBU 4
|
|
||||||
#else
|
|
||||||
#define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU
|
|
||||||
#endif
|
|
||||||
#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU
|
|
||||||
|
|
||||||
/* Unicast address list*/
|
/* Unicast address list*/
|
||||||
#define UIP_DS6_ADDR_NBS 1
|
#define UIP_DS6_ADDR_NBS 1
|
||||||
#ifndef UIP_CONF_DS6_ADDR_NBU
|
#ifndef UIP_CONF_DS6_ADDR_NBU
|
||||||
@ -158,9 +150,8 @@
|
|||||||
#define FOUND 0
|
#define FOUND 0
|
||||||
#define FREESPACE 1
|
#define FREESPACE 1
|
||||||
#define NOSPACE 2
|
#define NOSPACE 2
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------*/
|
/*--------------------------------------------------*/
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
#include "net/uip-packetqueue.h"
|
#include "net/uip-packetqueue.h"
|
||||||
#endif /*UIP_CONF_QUEUE_PKT */
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
@ -181,14 +172,6 @@ typedef struct uip_ds6_nbr {
|
|||||||
#endif /*UIP_CONF_QUEUE_PKT */
|
#endif /*UIP_CONF_QUEUE_PKT */
|
||||||
} uip_ds6_nbr_t;
|
} uip_ds6_nbr_t;
|
||||||
|
|
||||||
/** \brief An entry in the default router list */
|
|
||||||
typedef struct uip_ds6_defrt {
|
|
||||||
uint8_t isused;
|
|
||||||
uip_ipaddr_t ipaddr;
|
|
||||||
struct stimer lifetime;
|
|
||||||
uint8_t isinfinite;
|
|
||||||
} uip_ds6_defrt_t;
|
|
||||||
|
|
||||||
/** \brief A prefix list entry */
|
/** \brief A prefix list entry */
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
typedef struct uip_ds6_prefix {
|
typedef struct uip_ds6_prefix {
|
||||||
@ -236,19 +219,6 @@ typedef struct uip_ds6_maddr {
|
|||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
} uip_ds6_maddr_t;
|
} uip_ds6_maddr_t;
|
||||||
|
|
||||||
/** \brief define some additional RPL related route state and
|
|
||||||
* neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */
|
|
||||||
#ifndef UIP_DS6_ROUTE_STATE_TYPE
|
|
||||||
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
|
|
||||||
/* Needed for the extended route entry state when using ContikiRPL */
|
|
||||||
typedef struct rpl_route_entry {
|
|
||||||
uint32_t lifetime;
|
|
||||||
uint32_t saved_lifetime;
|
|
||||||
void *dag;
|
|
||||||
uint8_t learned_from;
|
|
||||||
} rpl_route_entry_t;
|
|
||||||
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
|
|
||||||
|
|
||||||
/* only define the callback if RPL is active */
|
/* only define the callback if RPL is active */
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
#ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
|
#ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
|
||||||
@ -258,18 +228,6 @@ typedef struct rpl_route_entry {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief An entry in the routing table */
|
|
||||||
typedef struct uip_ds6_route {
|
|
||||||
uint8_t isused;
|
|
||||||
uip_ipaddr_t ipaddr;
|
|
||||||
uint8_t length;
|
|
||||||
uint8_t metric;
|
|
||||||
uip_ipaddr_t nexthop;
|
|
||||||
#ifdef UIP_DS6_ROUTE_STATE_TYPE
|
|
||||||
UIP_DS6_ROUTE_STATE_TYPE state;
|
|
||||||
#endif
|
|
||||||
} uip_ds6_route_t;
|
|
||||||
|
|
||||||
/** \brief Interface structure (contains all the interface variables) */
|
/** \brief Interface structure (contains all the interface variables) */
|
||||||
typedef struct uip_ds6_netif {
|
typedef struct uip_ds6_netif {
|
||||||
uint32_t link_mtu;
|
uint32_t link_mtu;
|
||||||
@ -325,15 +283,6 @@ uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(uip_lladdr_t *lladdr);
|
|||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** \name Default router list basic routines */
|
|
||||||
/** @{ */
|
|
||||||
uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
|
|
||||||
unsigned long interval);
|
|
||||||
void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt);
|
|
||||||
uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr);
|
|
||||||
uip_ipaddr_t *uip_ds6_defrt_choose(void);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** \name Prefix list basic routines */
|
/** \name Prefix list basic routines */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
@ -381,16 +330,6 @@ uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
|
|||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
/** \name Routing Table basic routines */
|
|
||||||
/** @{ */
|
|
||||||
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
|
|
||||||
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
|
||||||
uip_ipaddr_t *next_hop, uint8_t metric);
|
|
||||||
void uip_ds6_route_rm(uip_ds6_route_t *route);
|
|
||||||
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** \brief set the last 64 bits of an IP address based on the MAC address */
|
/** \brief set the last 64 bits of an IP address based on the MAC address */
|
||||||
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);
|
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ uip_icmp6_echo_request_input(void)
|
|||||||
|
|
||||||
if(uip_ext_len > 0) {
|
if(uip_ext_len > 0) {
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
if ((temp_ext_len=rpl_invert_header())) {
|
if((temp_ext_len = rpl_invert_header())) {
|
||||||
/* If there were other extension headers*/
|
/* If there were other extension headers*/
|
||||||
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
|
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
|
||||||
if (uip_ext_len != temp_ext_len) {
|
if (uip_ext_len != temp_ext_len) {
|
||||||
@ -118,7 +118,7 @@ uip_icmp6_echo_request_input(void)
|
|||||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||||
(uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
|
(uip_len - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
|
||||||
}
|
}
|
||||||
uip_ext_len=temp_ext_len;
|
uip_ext_len = temp_ext_len;
|
||||||
} else {
|
} else {
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
/* If there were extension headers*/
|
/* If there were extension headers*/
|
||||||
|
@ -98,17 +98,25 @@
|
|||||||
|
|
||||||
/** \name RFC 4861 Node constant */
|
/** \name RFC 4861 Node constant */
|
||||||
#define UIP_ND6_MAX_MULTICAST_SOLICIT 3
|
#define UIP_ND6_MAX_MULTICAST_SOLICIT 3
|
||||||
|
|
||||||
|
#ifdef UIP_CONF_ND6_MAX_UNICAST_SOLICIT
|
||||||
|
#define UIP_ND6_MAX_UNICAST_SOLICIT UIP_CONF_ND6_MAX_UNICAST_SOLICIT
|
||||||
|
#else /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
|
||||||
#define UIP_ND6_MAX_UNICAST_SOLICIT 3
|
#define UIP_ND6_MAX_UNICAST_SOLICIT 3
|
||||||
|
#endif /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
|
||||||
|
|
||||||
#ifdef UIP_CONF_ND6_REACHABLE_TIME
|
#ifdef UIP_CONF_ND6_REACHABLE_TIME
|
||||||
#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME
|
#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME
|
||||||
#else
|
#else
|
||||||
#define UIP_ND6_REACHABLE_TIME 30000
|
#define UIP_ND6_REACHABLE_TIME 30000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UIP_CONF_ND6_RETRANS_TIMER
|
#ifdef UIP_CONF_ND6_RETRANS_TIMER
|
||||||
#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER
|
#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER
|
||||||
#else
|
#else
|
||||||
#define UIP_ND6_RETRANS_TIMER 1000
|
#define UIP_ND6_RETRANS_TIMER 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5
|
#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5
|
||||||
#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2)
|
#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2)
|
||||||
#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2)
|
#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2)
|
||||||
|
@ -43,6 +43,12 @@
|
|||||||
|
|
||||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
|
#ifdef UIP_SPLIT_CONF_SIZE
|
||||||
|
#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
|
||||||
|
#else /* UIP_SPLIT_CONF_SIZE */
|
||||||
|
#define UIP_SPLIT_SIZE UIP_TCP_MSS
|
||||||
|
#endif /* UIP_SPLIT_CONF_SIZE */
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_split_output(void)
|
uip_split_output(void)
|
||||||
@ -50,9 +56,11 @@ uip_split_output(void)
|
|||||||
#if UIP_TCP
|
#if UIP_TCP
|
||||||
uint16_t tcplen, len1, len2;
|
uint16_t tcplen, len1, len2;
|
||||||
|
|
||||||
/* We only try to split maximum sized TCP segments. */
|
/* We only split TCP segments that are larger than or equal to
|
||||||
|
UIP_SPLIT_SIZE, which is configurable through
|
||||||
|
UIP_SPLIT_CONF_SIZE. */
|
||||||
if(BUF->proto == UIP_PROTO_TCP &&
|
if(BUF->proto == UIP_PROTO_TCP &&
|
||||||
uip_len == UIP_TCP_MSS + UIP_TCPIP_HLEN) {
|
uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
|
||||||
|
|
||||||
tcplen = uip_len - UIP_TCPIP_HLEN;
|
tcplen = uip_len - UIP_TCPIP_HLEN;
|
||||||
/* Split the segment in two. If the original packet length was
|
/* Split the segment in two. If the original packet length was
|
||||||
|
@ -59,21 +59,19 @@
|
|||||||
* Representation of an IP address.
|
* Representation of an IP address.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if UIP_CONF_IPV6
|
typedef union uip_ip4addr_t {
|
||||||
|
uint8_t u8[4]; /* Initializer, must come first. */
|
||||||
|
uint16_t u16[2];
|
||||||
|
} uip_ip4addr_t;
|
||||||
|
|
||||||
typedef union uip_ip6addr_t {
|
typedef union uip_ip6addr_t {
|
||||||
uint8_t u8[16]; /* Initializer, must come first!!! */
|
uint8_t u8[16]; /* Initializer, must come first. */
|
||||||
uint16_t u16[8];
|
uint16_t u16[8];
|
||||||
} uip_ip6addr_t;
|
} uip_ip6addr_t;
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
typedef uip_ip6addr_t uip_ipaddr_t;
|
typedef uip_ip6addr_t uip_ipaddr_t;
|
||||||
#else /* UIP_CONF_IPV6 */
|
#else /* UIP_CONF_IPV6 */
|
||||||
typedef union uip_ip4addr_t {
|
|
||||||
uint8_t u8[4]; /* Initializer, must come first!!! */
|
|
||||||
uint16_t u16[2];
|
|
||||||
#if 0
|
|
||||||
uint32_t u32;
|
|
||||||
#endif
|
|
||||||
} uip_ip4addr_t;
|
|
||||||
typedef uip_ip4addr_t uip_ipaddr_t;
|
typedef uip_ip4addr_t uip_ipaddr_t;
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
||||||
@ -988,6 +986,12 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
|||||||
#ifndef uip_ipaddr_copy
|
#ifndef uip_ipaddr_copy
|
||||||
#define uip_ipaddr_copy(dest, src) (*(dest) = *(src))
|
#define uip_ipaddr_copy(dest, src) (*(dest) = *(src))
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef uip_ip4addr_copy
|
||||||
|
#define uip_ip4addr_copy(dest, src) (*(dest) = *(src))
|
||||||
|
#endif
|
||||||
|
#ifndef uip_ip6addr_copy
|
||||||
|
#define uip_ip6addr_copy(dest, src) (*(dest) = *(src))
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two IP addresses
|
* Compare two IP addresses
|
||||||
@ -1009,11 +1013,14 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
|||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#if !UIP_CONF_IPV6
|
#define uip_ip4addr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
|
||||||
#define uip_ipaddr_cmp(addr1, addr2) ((addr1)->u16[0] == (addr2)->u16[0] && \
|
|
||||||
(addr1)->u16[1] == (addr2)->u16[1])
|
(addr1)->u16[1] == (addr2)->u16[1])
|
||||||
|
#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
|
||||||
|
|
||||||
|
#if !UIP_CONF_IPV6
|
||||||
|
#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2)
|
||||||
#else /* !UIP_CONF_IPV6 */
|
#else /* !UIP_CONF_IPV6 */
|
||||||
#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
|
#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2)
|
||||||
#endif /* !UIP_CONF_IPV6 */
|
#endif /* !UIP_CONF_IPV6 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1040,15 +1047,15 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
|||||||
*
|
*
|
||||||
* \hideinitializer
|
* \hideinitializer
|
||||||
*/
|
*/
|
||||||
#if !UIP_CONF_IPV6
|
|
||||||
#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
|
#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
|
||||||
(((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \
|
(((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) == \
|
||||||
(((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \
|
(((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) && \
|
||||||
((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \
|
((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) == \
|
||||||
(((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1])))
|
(((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1])))
|
||||||
#else
|
|
||||||
#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0)
|
#define uip_ipaddr_prefixcmp(addr1, addr2, length) (memcmp(addr1, addr2, length>>3) == 0)
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -855,7 +855,7 @@ ext_hdr_options_process(void)
|
|||||||
case UIP_EXT_HDR_OPT_RPL:
|
case UIP_EXT_HDR_OPT_RPL:
|
||||||
PRINTF("Processing RPL option\n");
|
PRINTF("Processing RPL option\n");
|
||||||
if(rpl_verify_header(uip_ext_opt_offset)) {
|
if(rpl_verify_header(uip_ext_opt_offset)) {
|
||||||
PRINTF("RPL Option Error : Dropping Packet");
|
PRINTF("RPL Option Error: Dropping Packet\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2;
|
uip_ext_opt_offset += (UIP_EXT_HDR_OPT_RPL_BUF->opt_len) + 2;
|
||||||
@ -1123,17 +1123,19 @@ uip_process(uint8_t flag)
|
|||||||
if(*uip_next_hdr == UIP_PROTO_HBHO) {
|
if(*uip_next_hdr == UIP_PROTO_HBHO) {
|
||||||
#if UIP_CONF_IPV6_CHECKS
|
#if UIP_CONF_IPV6_CHECKS
|
||||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
||||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
#endif /* UIP_CONF_IPV6_CHECKS */
|
||||||
switch(ext_hdr_options_process()) {
|
switch(ext_hdr_options_process()) {
|
||||||
case 0:
|
case 0:
|
||||||
/*continue*/
|
/* continue */
|
||||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/*silently discard*/
|
PRINTF("Dropping packet after extension header processing\n");
|
||||||
|
/* silently discard */
|
||||||
goto drop;
|
goto drop;
|
||||||
case 2:
|
case 2:
|
||||||
|
PRINTF("Sending error message after extension header processing\n");
|
||||||
/* send icmp error message (created in ext_hdr_options_process)
|
/* send icmp error message (created in ext_hdr_options_process)
|
||||||
* and discard*/
|
* and discard*/
|
||||||
goto send;
|
goto send;
|
||||||
@ -1448,6 +1450,11 @@ uip_process(uint8_t flag)
|
|||||||
#if UIP_UDP_CHECKSUMS
|
#if UIP_UDP_CHECKSUMS
|
||||||
uip_len = uip_len - UIP_IPUDPH_LEN;
|
uip_len = uip_len - UIP_IPUDPH_LEN;
|
||||||
uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||||
|
/* XXX hack: UDP/IPv6 receivers should drop packets with UDP
|
||||||
|
checksum 0. Here, we explicitly receive UDP packets with checksum
|
||||||
|
0. This is to be able to debug code that for one reason or
|
||||||
|
another miscomputes UDP checksums. The reception of zero UDP
|
||||||
|
checksums should be turned into a configration option. */
|
||||||
if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
|
if(UIP_UDP_BUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
|
||||||
UIP_STAT(++uip_stat.udp.drop);
|
UIP_STAT(++uip_stat.udp.drop);
|
||||||
UIP_STAT(++uip_stat.udp.chkerr);
|
UIP_STAT(++uip_stat.udp.chkerr);
|
||||||
@ -2215,12 +2222,11 @@ uip_process(uint8_t flag)
|
|||||||
UIP_TCP_BUF->srcport = uip_connr->lport;
|
UIP_TCP_BUF->srcport = uip_connr->lport;
|
||||||
UIP_TCP_BUF->destport = uip_connr->rport;
|
UIP_TCP_BUF->destport = uip_connr->rport;
|
||||||
|
|
||||||
|
|
||||||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
|
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr);
|
||||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr);
|
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||||
PRINTF("Sending TCP packet to");
|
PRINTF("Sending TCP packet to ");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||||
PRINTF("from");
|
PRINTF(" from ");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
|
@ -42,9 +42,8 @@
|
|||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
|
||||||
{
|
{
|
||||||
#if UIP_CONF_IPV6
|
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
int tmp, zero;
|
int tmp, zero;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -54,7 +53,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||||||
zero = -1;
|
zero = -1;
|
||||||
if(*addrstr == '[') addrstr++;
|
if(*addrstr == '[') addrstr++;
|
||||||
|
|
||||||
for(len = 0; len < sizeof(uip_ipaddr_t) - 1; addrstr++) {
|
for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) {
|
||||||
c = *addrstr;
|
c = *addrstr;
|
||||||
if(c == ':' || c == '\0' || c == ']' || c == '/') {
|
if(c == ':' || c == '\0' || c == ']' || c == '/') {
|
||||||
ipaddr->u8[len] = (value >> 8) & 0xff;
|
ipaddr->u8[len] = (value >> 8) & 0xff;
|
||||||
@ -91,21 +90,28 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||||||
PRINTF("uiplib: too large address\n");
|
PRINTF("uiplib: too large address\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(len < sizeof(uip_ipaddr_t)) {
|
if(len < sizeof(uip_ip6addr_t)) {
|
||||||
if(zero < 0) {
|
if(zero < 0) {
|
||||||
PRINTF("uiplib: too short address\n");
|
PRINTF("uiplib: too short address\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memmove(&ipaddr->u8[zero + sizeof(uip_ipaddr_t) - len],
|
memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len],
|
||||||
&ipaddr->u8[zero], len - zero);
|
&ipaddr->u8[zero], len - zero);
|
||||||
memset(&ipaddr->u8[zero], 0, sizeof(uip_ipaddr_t) - len);
|
memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* UIP_CONF_IPV6 */
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Parse a IPv4-address from a string. Returns the number of characters read
|
||||||
|
* for the address. */
|
||||||
|
int
|
||||||
|
uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
|
||||||
|
{
|
||||||
unsigned char tmp;
|
unsigned char tmp;
|
||||||
char c;
|
char c;
|
||||||
unsigned char i, j;
|
unsigned char i, j;
|
||||||
|
uint8_t charsread = 0;
|
||||||
|
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
|
|
||||||
@ -117,7 +123,7 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||||||
if(j > 4) {
|
if(j > 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(c == '.' || c == 0) {
|
if(c == '.' || c == 0 || c == ' ') {
|
||||||
ipaddr->u8[i] = tmp;
|
ipaddr->u8[i] = tmp;
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
} else if(c >= '0' && c <= '9') {
|
} else if(c >= '0' && c <= '9') {
|
||||||
@ -126,10 +132,21 @@ uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
++addrstr;
|
++addrstr;
|
||||||
} while(c != '.' && c != 0);
|
++charsread;
|
||||||
|
} while(c != '.' && c != 0 && c != ' ');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return charsread-1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *ipaddr)
|
||||||
|
{
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
|
return uiplib_ip6addrconv(addrstr, ipaddr);
|
||||||
|
#else /* UIP_CONF_IPV6 */
|
||||||
|
return uiplib_ip4addrconv(addrstr, ipaddr);
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
* \param addrstr A pointer to a string containing the IP address in
|
* \param addrstr A pointer to a string containing the IP address in
|
||||||
* textual form.
|
* textual form.
|
||||||
*
|
*
|
||||||
* \param addr A pointer to a uip_ipaddr_t that will be filled in with
|
* \param addr A pointer to a uip_ip4addr_t that will be filled in with
|
||||||
* the numerical representation of the address.
|
* the numerical representation of the address.
|
||||||
*
|
*
|
||||||
* \retval 0 If the IP address could not be parsed.
|
* \retval 0 If the IP address could not be parsed.
|
||||||
@ -68,6 +68,8 @@
|
|||||||
*/
|
*/
|
||||||
CCIF int uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *addr);
|
CCIF int uiplib_ipaddrconv(const char *addrstr, uip_ipaddr_t *addr);
|
||||||
|
|
||||||
|
CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
|
||||||
|
CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* __UIPLIB_H__ */
|
#endif /* __UIPLIB_H__ */
|
||||||
|
@ -149,6 +149,7 @@ static
|
|||||||
PT_THREAD(generate_routes(struct httpd_state *s))
|
PT_THREAD(generate_routes(struct httpd_state *s))
|
||||||
{
|
{
|
||||||
static int i;
|
static int i;
|
||||||
|
static uip_ds6_route_t *r;
|
||||||
PSOCK_BEGIN(&s->sout);
|
PSOCK_BEGIN(&s->sout);
|
||||||
|
|
||||||
SEND_STRING(&s->sout, TOP);
|
SEND_STRING(&s->sout, TOP);
|
||||||
@ -169,20 +170,20 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||||||
ADD("</pre>Routes<pre>");
|
ADD("</pre>Routes<pre>");
|
||||||
SEND_STRING(&s->sout, buf);
|
SEND_STRING(&s->sout, buf);
|
||||||
blen = 0;
|
blen = 0;
|
||||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
for(r = uip_ds6_route_list_head();
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
r != NULL;
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
r = list_item_next(r)) {
|
||||||
ADD("/%u (via ", uip_ds6_routing_table[i].length);
|
ipaddr_add(&r->ipaddr);
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
|
ADD("/%u (via ", r->length);
|
||||||
if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
ipaddr_add(&r->nexthop);
|
||||||
ADD(") %lus\n", (unsigned long)uip_ds6_routing_table[i].state.lifetime);
|
if(r->state.lifetime < 600) {
|
||||||
|
ADD(") %lus\n", (unsigned long)r->state.lifetime);
|
||||||
} else {
|
} else {
|
||||||
ADD(")\n");
|
ADD(")\n");
|
||||||
}
|
}
|
||||||
SEND_STRING(&s->sout, buf);
|
SEND_STRING(&s->sout, buf);
|
||||||
blen = 0;
|
blen = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ADD("</pre>");
|
ADD("</pre>");
|
||||||
//if(blen > 0) {
|
//if(blen > 0) {
|
||||||
SEND_STRING(&s->sout, buf);
|
SEND_STRING(&s->sout, buf);
|
||||||
|
@ -57,7 +57,6 @@
|
|||||||
uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
|
uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011};
|
||||||
|
|
||||||
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
|
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
|
||||||
extern uip_ds6_route_t uip_ds6_routing_table[];
|
|
||||||
|
|
||||||
static uip_ipaddr_t prefix;
|
static uip_ipaddr_t prefix;
|
||||||
static uint8_t prefix_set;
|
static uint8_t prefix_set;
|
||||||
@ -149,6 +148,7 @@ static
|
|||||||
PT_THREAD(generate_routes(struct httpd_state *s))
|
PT_THREAD(generate_routes(struct httpd_state *s))
|
||||||
{
|
{
|
||||||
static int i;
|
static int i;
|
||||||
|
static uip_ds6_route_t *r;
|
||||||
#if BUF_USES_STACK
|
#if BUF_USES_STACK
|
||||||
char buf[256];
|
char buf[256];
|
||||||
#endif
|
#endif
|
||||||
@ -220,35 +220,36 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||||||
#else
|
#else
|
||||||
blen = 0;
|
blen = 0;
|
||||||
#endif
|
#endif
|
||||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
for(r = uip_ds6_route_list_head(); r != NULL; r = list_item_next(r)) {
|
||||||
|
|
||||||
#if BUF_USES_STACK
|
#if BUF_USES_STACK
|
||||||
#if WEBSERVER_CONF_ROUTE_LINKS
|
#if WEBSERVER_CONF_ROUTE_LINKS
|
||||||
ADD("<a href=http://[");
|
ADD("<a href=http://[");
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
ADD("]/status.shtml>");
|
ADD("]/status.shtml>");
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
ADD("</a>");
|
ADD("</a>");
|
||||||
#else
|
#else
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if WEBSERVER_CONF_ROUTE_LINKS
|
#if WEBSERVER_CONF_ROUTE_LINKS
|
||||||
ADD("<a href=http://[");
|
ADD("<a href=http://[");
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
ADD("]/status.shtml>");
|
ADD("]/status.shtml>");
|
||||||
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
|
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
|
||||||
blen = 0;
|
blen = 0;
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
ADD("</a>");
|
ADD("</a>");
|
||||||
#else
|
#else
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
ipaddr_add(&r->ipaddr);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
ADD("/%u (via ", uip_ds6_routing_table[i].length);
|
ADD("/%u (via ", r->length);
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
|
ipaddr_add(&r->nexthop);
|
||||||
if(1 || (uip_ds6_routing_table[i].state.lifetime < 600)) {
|
if(1 || (r->state.lifetime < 600)) {
|
||||||
ADD(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
|
ADD(") %lus\n", r->state.lifetime);
|
||||||
} else {
|
} else {
|
||||||
ADD(")\n");
|
ADD(")\n");
|
||||||
}
|
}
|
||||||
@ -259,7 +260,6 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||||||
blen = 0;
|
blen = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ADD("</pre>");
|
ADD("</pre>");
|
||||||
|
|
||||||
#if WEBSERVER_CONF_FILESTATS
|
#if WEBSERVER_CONF_FILESTATS
|
||||||
|
@ -70,7 +70,8 @@ void
|
|||||||
collect_common_net_print(void)
|
collect_common_net_print(void)
|
||||||
{
|
{
|
||||||
rpl_dag_t *dag;
|
rpl_dag_t *dag;
|
||||||
int i;
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
/* Let's suppose we have only one instance */
|
/* Let's suppose we have only one instance */
|
||||||
dag = rpl_get_any_dag();
|
dag = rpl_get_any_dag();
|
||||||
if(dag->preferred_parent != NULL) {
|
if(dag->preferred_parent != NULL) {
|
||||||
@ -78,12 +79,10 @@ collect_common_net_print(void)
|
|||||||
PRINT6ADDR(&dag->preferred_parent->addr);
|
PRINT6ADDR(&dag->preferred_parent->addr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
}
|
}
|
||||||
PRINTF("Route entries:\n");
|
for(r = uip_ds6_route_list_head();
|
||||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
r != NULL;
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
r = list_item_next(r)) {
|
||||||
PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr);
|
PRINT6ADDR(&r->ipaddr);
|
||||||
PRINTF("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PRINTF("---\n");
|
PRINTF("---\n");
|
||||||
}
|
}
|
||||||
|
@ -536,17 +536,22 @@ extern uip_ds6_netif_t uip_ds6_if;
|
|||||||
}
|
}
|
||||||
if (j) PRINTF(" <none>");
|
if (j) PRINTF(" <none>");
|
||||||
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
||||||
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
|
{
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
uip_ds6_route_t *r;
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
||||||
PRINTF("/%u (via ", uip_ds6_routing_table[i].length);
|
j = 1;
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
|
for(r = uip_ds6_route_list_head();
|
||||||
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
|
ipaddr_add(&r->ipaddr);
|
||||||
|
PRINTF("/%u (via ", r->length);
|
||||||
|
ipaddr_add(&r->nexthop);
|
||||||
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
||||||
PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
|
PRINTF(") %lus\n", r->state.lifetime);
|
||||||
// } else {
|
// } else {
|
||||||
// PRINTF(")\n");
|
// PRINTF(")\n");
|
||||||
// }
|
// }
|
||||||
j=0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j) PRINTF(" <none>");
|
if (j) PRINTF(" <none>");
|
||||||
|
@ -354,25 +354,27 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
|
|||||||
static unsigned short
|
static unsigned short
|
||||||
make_routes(void *p)
|
make_routes(void *p)
|
||||||
{
|
{
|
||||||
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
|
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_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
|
||||||
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
|
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
|
||||||
uint8_t i,j=0;
|
uint8_t i,j=0;
|
||||||
uint16_t numprinted;
|
uint16_t numprinted;
|
||||||
|
uip_ds6_route_t *r;
|
||||||
|
|
||||||
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
||||||
for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
|
for(r = uip_ds6_route_list_head();
|
||||||
if (uip_ds6_routing_table[i].isused) {
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
j++;
|
j++;
|
||||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
|
numprinted += httpd_cgi_sprint_ip6(r->ipaddr, uip_appdata + numprinted);
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, r->length);
|
||||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted);
|
numprinted += httpd_cgi_sprint_ip6(r->nexthop, uip_appdata + numprinted);
|
||||||
if(uip_ds6_routing_table[i].state.lifetime < 3600) {
|
if(r->state.lifetime < 3600) {
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, uip_ds6_routing_table[i].state.lifetime);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, r->state.lifetime);
|
||||||
} else {
|
} else {
|
||||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
|
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);
|
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);
|
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
|
||||||
return numprinted;
|
return numprinted;
|
||||||
|
@ -531,18 +531,22 @@ extern uip_ds6_netif_t uip_ds6_if;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j) PRINTF(" <none>");
|
if (j) PRINTF(" <none>");
|
||||||
|
{
|
||||||
|
uip_ds6_route_t *r;
|
||||||
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
||||||
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
|
j = 1;
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
for(r = uip_ds6_route_list_head();
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
r != NULL;
|
||||||
PRINTF("/%u (via ", uip_ds6_routing_table[i].length);
|
r = list_item_next(r)) {
|
||||||
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
|
ipaddr_add(&r->ipaddr);
|
||||||
|
PRINTF("/%u (via ", r->length);
|
||||||
|
ipaddr_add(&r->nexthop);
|
||||||
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
||||||
PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
|
PRINTF(") %lus\n", r->state.lifetime);
|
||||||
// } else {
|
// } else {
|
||||||
// PRINTF(")\n");
|
// PRINTF(")\n");
|
||||||
// }
|
// }
|
||||||
j=0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j) PRINTF(" <none>");
|
if (j) PRINTF(" <none>");
|
||||||
|
@ -614,18 +614,23 @@ extern uip_ds6_netif_t uip_ds6_if;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j) printf(" <none>");
|
if (j) printf(" <none>");
|
||||||
printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
||||||
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
|
{
|
||||||
if(uip_ds6_routing_table[i].isused) {
|
uip_ds6_route_t *r;
|
||||||
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
|
PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
|
||||||
printf("/%u (via ", uip_ds6_routing_table[i].length);
|
j = 1;
|
||||||
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
|
for(r = uip_ds6_route_list_head();
|
||||||
|
r != NULL;
|
||||||
|
r = list_item_next(r)) {
|
||||||
|
ipaddr_add(&r->ipaddr);
|
||||||
|
PRINTF("/%u (via ", r->length);
|
||||||
|
ipaddr_add(&r->nexthop);
|
||||||
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
||||||
printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
|
PRINTF(") %lus\n", r->state.lifetime);
|
||||||
// } else {
|
// } else {
|
||||||
// printf(")\n");
|
// PRINTF(")\n");
|
||||||
// }
|
// }
|
||||||
j=0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j) printf(" <none>");
|
if (j) printf(" <none>");
|
||||||
|
Loading…
Reference in New Issue
Block a user