45 #include "lib/random.h"
48 #include "net/uip-packetqueue.h"
50 #define DEBUG DEBUG_NONE
53 #ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
54 #define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
57 #define NEIGHBOR_STATE_CHANGED(n)
60 struct etimer uip_ds6_timer_periodic;
63 struct stimer uip_ds6_timer_ra;
65 static uint8_t racount;
66 static uint16_t rand_time;
70 static uint8_t rscount;
100 PRINTF(
"Init of IPv6 data structures\n");
101 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",
102 UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
103 UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
104 memset(uip_ds6_nbr_cache, 0,
sizeof(uip_ds6_nbr_cache));
105 memset(uip_ds6_defrt_list, 0,
sizeof(uip_ds6_defrt_list));
106 memset(uip_ds6_prefix_list, 0,
sizeof(uip_ds6_prefix_list));
107 memset(&uip_ds6_if, 0,
sizeof(uip_ds6_if));
108 memset(uip_ds6_routing_table, 0,
sizeof(uip_ds6_routing_table));
112 uip_ds6_if.cur_hop_limit =
UIP_TTL;
113 uip_ds6_if.base_reachable_time = UIP_ND6_REACHABLE_TIME;
115 uip_ds6_if.retrans_timer = UIP_ND6_RETRANS_TIMER;
116 uip_ds6_if.maxdadns = UIP_ND6_DEF_MAXDADNS;
119 uip_create_linklocal_prefix(&loc_fipaddr);
121 uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0);
123 uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0);
126 uip_ds6_addr_add(&loc_fipaddr, 0, ADDR_AUTOCONF);
128 uip_create_linklocal_allnodes_mcast(&loc_fipaddr);
129 uip_ds6_maddr_add(&loc_fipaddr);
131 uip_create_linklocal_allrouters_mcast(&loc_fipaddr);
132 uip_ds6_maddr_add(&loc_fipaddr);
138 random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
152 for(locaddr = uip_ds6_if.addr_list;
153 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
154 if(locaddr->isused) {
155 if((!locaddr->isinfinite) && (
stimer_expired(&locaddr->vlifetime))) {
156 uip_ds6_addr_rm(locaddr);
158 && (locaddr->dadnscount <= uip_ds6_if.maxdadns)
166 for(locdefrt = uip_ds6_defrt_list;
167 locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
168 if((locdefrt->isused) && (!locdefrt->isinfinite) &&
170 uip_ds6_defrt_rm(locdefrt);
176 for(locprefix = uip_ds6_prefix_list;
177 locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
179 if(locprefix->isused && !locprefix->isinfinite
181 uip_ds6_prefix_rm(locprefix);
187 for(locnbr = uip_ds6_nbr_cache;
188 locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB;
191 switch(locnbr->state) {
193 if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
194 uip_ds6_nbr_rm(locnbr);
197 PRINTF(
"NBR_INCOMPLETE: NS %u\n", locnbr->nscount);
199 stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
204 PRINTF(
"REACHABLE: moving to STALE (");
205 PRINT6ADDR(&locnbr->ipaddr);
207 locnbr->state = NBR_STALE;
212 locnbr->state = NBR_PROBE;
214 PRINTF(
"DELAY: moving to PROBE + NS %u\n", locnbr->nscount);
216 stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
220 if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
221 PRINTF(
"PROBE END\n");
222 if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) !=
NULL) {
223 uip_ds6_defrt_rm(locdefrt);
225 uip_ds6_nbr_rm(locnbr);
228 PRINTF(
"PROBE: NS %u\n", locnbr->nscount);
230 stimer_set(&locnbr->sendns, uip_ds6_if.retrans_timer / 1000);
239 #if UIP_CONF_ROUTER & UIP_ND6_SEND_RA
242 uip_ds6_send_ra_periodic();
263 if(element->isused) {
264 if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
265 *out_element = element;
269 *out_element = element;
273 return *out_element !=
NULL ? FREESPACE : NOSPACE;
279 uint8_t isrouter, uint8_t state)
292 memcpy(&locnbr->lladdr, lladdr, UIP_LLADDR_LEN);
294 memset(&locnbr->lladdr, 0, UIP_LLADDR_LEN);
296 locnbr->isrouter = isrouter;
297 locnbr->state = state;
298 #if UIP_CONF_IPV6_QUEUE_PKT
299 uip_packetqueue_new(&locnbr->packethandle);
305 PRINTF(
"Adding neighbor with ip addr ");
307 PRINTF(
"link addr ");
308 PRINTLLADDR((&(locnbr->lladdr)));
309 PRINTF(
"state %u\n", state);
310 NEIGHBOR_STATE_CHANGED(locnbr);
314 }
else if(r == NOSPACE) {
318 clock_time_t oldest_time;
323 for(n = uip_ds6_nbr_cache;
324 n < &uip_ds6_nbr_cache[UIP_DS6_NBR_NB];
327 if(n->last_lookup < oldest_time) {
329 oldest_time = n->last_lookup;
334 uip_ds6_nbr_rm(oldest);
335 return uip_ds6_nbr_add(ipaddr, lladdr, isrouter, state);
338 PRINTF(
"uip_ds6_nbr_add drop\n");
348 #if UIP_CONF_IPV6_QUEUE_PKT
349 uip_packetqueue_free(&nbr->packethandle);
351 NEIGHBOR_STATE_CHANGED(nbr);
371 uip_ds6_defrt_add(
uip_ipaddr_t *ipaddr,
unsigned long interval)
377 locdefrt->isused = 1;
381 locdefrt->isinfinite = 0;
383 locdefrt->isinfinite = 1;
386 PRINTF(
"Adding defrouter with ip addr ");
387 PRINT6ADDR(&locdefrt->ipaddr);
390 ANNOTATE(
"#L %u 1\n", ipaddr->u8[
sizeof(
uip_ipaddr_t) - 1]);
403 ANNOTATE(
"#L %u 0\n", defrt->ipaddr.u8[
sizeof(
uip_ipaddr_t) - 1]);
422 uip_ds6_defrt_choose(
void)
427 for(locdefrt = uip_ds6_defrt_list;
428 locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
429 if(locdefrt->isused) {
430 PRINTF(
"Defrt, IP address ");
431 PRINT6ADDR(&locdefrt->ipaddr);
433 bestnbr = uip_ds6_nbr_lookup(&locdefrt->ipaddr);
435 PRINTF(
"Defrt found, IP address ");
436 PRINT6ADDR(&locdefrt->ipaddr);
438 return &locdefrt->ipaddr;
440 locipaddr = &locdefrt->ipaddr;
441 PRINTF(
"Defrt INCOMPLETE found, IP address ");
442 PRINT6ADDR(&locdefrt->ipaddr);
453 uip_ds6_prefix_add(
uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
454 uint8_t advertise, uint8_t
flags,
unsigned long vtime,
461 locprefix->isused = 1;
463 locprefix->length = ipaddrlen;
464 locprefix->advertise = advertise;
465 locprefix->l_a_reserved =
flags;
466 locprefix->vlifetime = vtime;
467 locprefix->plifetime = ptime;
468 PRINTF(
"Adding prefix ");
469 PRINT6ADDR(&locprefix->ipaddr);
470 PRINTF(
"length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n",
471 ipaddrlen, flags, vtime, ptime);
474 PRINTF(
"No more space in Prefix list\n");
482 uip_ds6_prefix_add(
uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
483 unsigned long interval)
489 locprefix->isused = 1;
491 locprefix->length = ipaddrlen;
493 stimer_set(&(locprefix->vlifetime), interval);
494 locprefix->isinfinite = 0;
496 locprefix->isinfinite = 1;
498 PRINTF(
"Adding prefix ");
499 PRINT6ADDR(&locprefix->ipaddr);
500 PRINTF(
"length %u, vlifetime%lu\n", ipaddrlen, interval);
517 uip_ds6_prefix_lookup(
uip_ipaddr_t *ipaddr, uint8_t ipaddrlen)
532 for(locprefix = uip_ds6_prefix_list;
533 locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
534 if(locprefix->isused &&
535 uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
544 uip_ds6_addr_add(
uip_ipaddr_t *ipaddr,
unsigned long vlifetime, uint8_t type)
553 locaddr->type = type;
555 locaddr->isinfinite = 1;
557 locaddr->isinfinite = 0;
561 random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
563 locaddr->dadnscount = 0;
564 uip_create_solicited_node(ipaddr, &loc_fipaddr);
565 uip_ds6_maddr_add(&loc_fipaddr);
576 uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr);
577 if((locmaddr = uip_ds6_maddr_lookup(&loc_fipaddr)) !=
NULL) {
578 uip_ds6_maddr_rm(locmaddr);
605 uip_ds6_get_link_local(int8_t state)
607 for(locaddr = uip_ds6_if.addr_list;
608 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
609 if(locaddr->isused && (state == -1 || locaddr->state == state)
610 && (uip_is_addr_link_local(&locaddr->ipaddr))) {
624 uip_ds6_get_global(int8_t state)
626 for(locaddr = uip_ds6_if.addr_list;
627 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
628 if(locaddr->isused && (state == -1 || locaddr->state == state)
629 && !(uip_is_addr_link_local(&locaddr->ipaddr))) {
644 locmaddr->isused = 1;
683 locaaddr->isused = 1;
717 uint8_t longestmatch = 0;
719 PRINTF(
"DS6: Looking up route for ");
720 PRINT6ADDR(destipaddr);
723 for(locroute = uip_ds6_routing_table;
724 locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) {
725 if((locroute->isused) && (locroute->length >= longestmatch)
727 (uip_ipaddr_prefixcmp
728 (destipaddr, &locroute->ipaddr, locroute->length))) {
729 longestmatch = locroute->length;
735 PRINTF(
"DS6: Found route:");
736 PRINT6ADDR(destipaddr);
738 PRINT6ADDR(&locrt->nexthop);
741 PRINTF(
"DS6: No route found\n");
756 locroute->isused = 1;
758 locroute->length = length;
760 locroute->metric = metric;
762 PRINTF(
"DS6: adding route: ");
767 ANNOTATE(
"#L %u 1;blue\n", nexthop->u8[
sizeof(
uip_ipaddr_t) - 1]);
778 #if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
781 for(locroute = uip_ds6_routing_table;
782 locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
784 if(locroute->isused &&
uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop)) {
789 ANNOTATE(
"#L %u 0\n",route->nexthop.u8[
sizeof(
uip_ipaddr_t) - 1]);
796 for(locroute = uip_ds6_routing_table;
797 locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
799 if(locroute->isused &&
uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
800 locroute->isused = 0;
803 ANNOTATE(
"#L %u 0\n",nexthop->u8[
sizeof(
uip_ipaddr_t) - 1]);
814 if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) {
816 for(locaddr = uip_ds6_if.addr_list;
817 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
819 if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
820 !uip_is_addr_link_local(&locaddr->ipaddr)) {
829 matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
833 if(matchaddr ==
NULL) {
834 uip_create_unspecified(src);
846 #if (UIP_LLADDR_LEN == 8)
847 memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
848 ipaddr->u8[8] ^= 0x02;
849 #elif (UIP_LLADDR_LEN == 6)
850 memcpy(ipaddr->u8 + 8, lladdr, 3);
851 ipaddr->u8[11] = 0xff;
852 ipaddr->u8[12] = 0xfe;
853 memcpy(ipaddr->u8 + 13, (uint8_t *)lladdr + 3, 3);
854 ipaddr->u8[8] ^= 0x02;
856 #error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
867 for(j = 0; j < 16; j++) {
868 if(src->u8[j] == dst->u8[j]) {
871 x_or = src->u8[j] ^ dst->u8[j];
872 for(k = 0; k < 8; k++) {
873 if((x_or & 0x80) == 0) {
891 if(addr->dadnscount < uip_ds6_if.maxdadns) {
902 PRINTF(
"DAD succeeded, ipaddr:");
903 PRINT6ADDR(&addr->ipaddr);
906 addr->state = ADDR_PREFERRED;
918 if(uip_is_addr_link_local(&addr->ipaddr)) {
919 PRINTF(
"Contiki shutdown, DAD for link local address failed\n");
922 uip_ds6_addr_rm(addr);
930 uip_ds6_send_ra_sollicited(
void)
939 PRINTF(
"Solicited RA, random time %u\n", rand_time);
942 if(
stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) {
955 uip_ds6_send_ra_periodic(
void)
959 uip_nd6_ra_output(
NULL);
960 PRINTF(
"Sending periodic RA\n");
963 rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() %
964 (uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL);
965 PRINTF(
"Random time 1 = %u\n", rand_time);
967 if(racount < UIP_ND6_MAX_INITIAL_RAS) {
968 if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) {
969 rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL;
970 PRINTF(
"Random time 2 = %u\n", rand_time);
974 PRINTF(
"Random time 3 = %u\n", rand_time);
984 if((uip_ds6_defrt_choose() ==
NULL)
985 && (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)) {
986 PRINTF(
"Sending RS %u\n", rscount);
992 PRINTF(
"Router found ? (boolean): %u\n",
993 (uip_ds6_defrt_choose() !=
NULL));
1004 return (uint32_t) (UIP_ND6_MIN_RANDOM_FACTOR
1005 (uip_ds6_if.base_reachable_time)) +
1006 ((uint16_t) (random_rand() << 8) +
1007 (uint16_t) random_rand()) %
1008 (uint32_t) (UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) -
1009 UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));