46 #include "lib/random.h"
47 #include "net/ipv6/uip-nd6.h"
48 #include "net/ipv6/uip-ds6.h"
49 #include "net/ip/uip-packetqueue.h"
53 #define DEBUG DEBUG_PRINT
56 struct etimer uip_ds6_timer_periodic;
59 struct stimer uip_ds6_timer_ra;
61 static uint8_t racount;
62 static uint16_t rand_time;
66 static uint8_t rscount;
76 uint8_t uip_ds6_netif_addr_list_offset;
81 static uip_ipaddr_t loc_fipaddr;
97 PRINTF(
"Init of IPv6 data structures\n");
98 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",
99 NBR_TABLE_MAX_NEIGHBORS, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
100 UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
101 memset(uip_ds6_prefix_list, 0,
sizeof(uip_ds6_prefix_list));
102 memset(&uip_ds6_if, 0,
sizeof(uip_ds6_if));
103 printf(
"***uip_ds6_if: %d\n",
sizeof(uip_ds6_if));
105 uip_ds6_netif_addr_list_offset = offsetof(
struct uip_ds6_netif, addr_list);
109 uip_ds6_if.cur_hop_limit =
UIP_TTL;
110 uip_ds6_if.base_reachable_time = UIP_ND6_REACHABLE_TIME;
112 uip_ds6_if.retrans_timer = UIP_ND6_RETRANS_TIMER;
116 uip_create_linklocal_prefix(&loc_fipaddr);
118 uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0);
120 uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0);
123 uip_ds6_addr_add(&loc_fipaddr, 0, ADDR_AUTOCONF);
126 uip_ds6_maddr_add(&loc_fipaddr);
129 uip_ds6_maddr_add(&loc_fipaddr);
135 random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
138 etimer_set(&uip_ds6_timer_periodic, UIP_DS6_PERIOD);
150 for(locaddr = uip_ds6_if.addr_list;
151 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
152 if(locaddr->isused) {
153 if((!locaddr->isinfinite) && (
stimer_expired(&locaddr->vlifetime))) {
154 uip_ds6_addr_rm(locaddr);
155 #if UIP_ND6_DEF_MAXDADNS > 0
156 }
else if((locaddr->state == ADDR_TENTATIVE)
157 && (locaddr->dadnscount <= uip_ds6_if.maxdadns)
160 uip_ds6_dad(locaddr);
178 for(locprefix = uip_ds6_prefix_list;
179 locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
181 if(locprefix->isused && !locprefix->isinfinite
183 uip_ds6_prefix_rm(locprefix);
190 #if UIP_CONF_ROUTER & UIP_ND6_SEND_RA
193 uip_ds6_send_ra_periodic();
203 uint16_t elementsize, uip_ipaddr_t *ipaddr,
214 if(element->isused) {
215 if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
216 *out_element = element;
220 *out_element = element;
224 return *out_element !=
NULL ? FREESPACE : NOSPACE;
231 uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
232 uint8_t advertise, uint8_t flags,
unsigned long vtime,
239 locprefix->isused = 1;
241 locprefix->length = ipaddrlen;
242 locprefix->advertise = advertise;
243 locprefix->l_a_reserved = flags;
244 locprefix->vlifetime = vtime;
245 locprefix->plifetime = ptime;
246 PRINTF(
"Adding prefix ");
247 PRINT6ADDR(&locprefix->ipaddr);
248 PRINTF(
" length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n",
249 ipaddrlen, flags, vtime, ptime);
252 PRINTF(
"No more space in Prefix list\n");
260 uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
261 unsigned long interval)
267 locprefix->isused = 1;
269 locprefix->length = ipaddrlen;
271 stimer_set(&(locprefix->vlifetime), interval);
272 locprefix->isinfinite = 0;
274 locprefix->isinfinite = 1;
276 PRINTF(
"Adding prefix ");
277 PRINT6ADDR(&locprefix->ipaddr);
278 PRINTF(
"length %u, vlifetime%lu\n", ipaddrlen, interval);
295 uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen)
308 uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
310 for(locprefix = uip_ds6_prefix_list;
311 locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
312 if(locprefix->isused &&
313 uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
322 uip_ds6_addr_add(uip_ipaddr_t *ipaddr,
unsigned long vlifetime, uint8_t type)
330 locaddr->type = type;
332 locaddr->isinfinite = 1;
334 locaddr->isinfinite = 0;
337 #if UIP_ND6_DEF_MAXDADNS > 0
338 locaddr->state = ADDR_TENTATIVE;
340 random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
342 locaddr->dadnscount = 0;
344 locaddr->state = ADDR_PREFERRED;
347 uip_ds6_maddr_add(&loc_fipaddr);
359 if((locmaddr = uip_ds6_maddr_lookup(&loc_fipaddr)) !=
NULL) {
360 uip_ds6_maddr_rm(locmaddr);
369 uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr)
387 uip_ds6_get_link_local(int8_t state)
389 for(locaddr = uip_ds6_if.addr_list;
390 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
391 if(locaddr->isused && (state == -1 || locaddr->state == state)
406 uip_ds6_get_global(int8_t state)
408 for(locaddr = uip_ds6_if.addr_list;
409 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
410 if(locaddr->isused && (state == -1 || locaddr->state == state)
420 uip_ds6_maddr_add(
const uip_ipaddr_t *ipaddr)
426 locmaddr->isused = 1;
445 uip_ds6_maddr_lookup(
const uip_ipaddr_t *ipaddr)
459 uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
465 locaaddr->isused = 1;
484 uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
504 for(locaddr = uip_ds6_if.addr_list;
505 locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
507 if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
516 #if UIP_IPV6_MULTICAST
518 matchaddr = uip_ds6_get_global(ADDR_PREFERRED);
521 matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
525 if(matchaddr ==
NULL) {
538 #if (UIP_LLADDR_LEN == 8)
539 memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
540 ipaddr->u8[8] ^= 0x02;
541 #elif (UIP_LLADDR_LEN == 6)
542 memcpy(ipaddr->u8 + 8, lladdr, 3);
543 ipaddr->u8[11] = 0xff;
544 ipaddr->u8[12] = 0xfe;
545 memcpy(ipaddr->u8 + 13, (uint8_t *)lladdr + 3, 3);
546 ipaddr->u8[8] ^= 0x02;
548 #error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
559 for(j = 0; j < 16; j++) {
560 if(src->u8[j] == dst->u8[j]) {
563 x_or = src->u8[j] ^ dst->u8[j];
564 for(k = 0; k < 8; k++) {
565 if((x_or & 0x80) == 0) {
579 #if UIP_ND6_DEF_MAXDADNS > 0
584 if(addr->dadnscount < uip_ds6_if.maxdadns) {
595 PRINTF(
"DAD succeeded, ipaddr:");
596 PRINT6ADDR(&addr->ipaddr);
599 addr->state = ADDR_PREFERRED;
612 PRINTF(
"Contiki shutdown, DAD for link local address failed\n");
615 uip_ds6_addr_rm(addr);
624 uip_ds6_send_ra_sollicited(
void)
633 PRINTF(
"Solicited RA, random time %u\n", rand_time);
636 if(
stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) {
649 uip_ds6_send_ra_periodic(
void)
653 uip_nd6_ra_output(
NULL);
654 PRINTF(
"Sending periodic RA\n");
657 rand_time = UIP_ND6_MIN_RA_INTERVAL +
random_rand() %
658 (uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL);
659 PRINTF(
"Random time 1 = %u\n", rand_time);
661 if(racount < UIP_ND6_MAX_INITIAL_RAS) {
662 if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) {
663 rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL;
664 PRINTF(
"Random time 2 = %u\n", rand_time);
668 PRINTF(
"Random time 3 = %u\n", rand_time);
679 && (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)) {
680 PRINTF(
"Sending RS %u\n", rscount);
686 PRINTF(
"Router found ? (boolean): %u\n",
698 return (uint32_t) (UIP_ND6_MIN_RANDOM_FACTOR
699 (uip_ds6_if.base_reachable_time)) +
702 (uint32_t) (UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) -
703 UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));