73 #include "net/ipv6/uip-nd6.h"
74 #include "net/ipv6/uip-ds6.h"
75 #include "lib/random.h"
79 #define DEBUG DEBUG_NONE
86 #define UIP_LOG(m) uip_log(m)
104 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
105 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
107 #define UIP_ND6_RS_BUF ((uip_nd6_rs *)&uip_buf[uip_l2_l3_icmp_hdr_len])
108 #define UIP_ND6_RA_BUF ((uip_nd6_ra *)&uip_buf[uip_l2_l3_icmp_hdr_len])
109 #define UIP_ND6_NS_BUF ((uip_nd6_ns *)&uip_buf[uip_l2_l3_icmp_hdr_len])
110 #define UIP_ND6_NA_BUF ((uip_nd6_na *)&uip_buf[uip_l2_l3_icmp_hdr_len])
113 #define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
114 #define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
115 #define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
118 static uint8_t nd6_opt_offset;
119 static uint8_t *nd6_opt_llao;
121 #if !UIP_CONF_ROUTER // TBD see if we move it to ra_input
123 static uip_ipaddr_t ipaddr;
134 create_llao(uint8_t *llao, uint8_t type) {
135 llao[UIP_ND6_OPT_TYPE_OFFSET] = type;
137 memcpy(&llao[UIP_ND6_OPT_DATA_OFFSET], &
uip_lladdr, UIP_LLADDR_LEN);
139 memset(&llao[UIP_ND6_OPT_DATA_OFFSET + UIP_LLADDR_LEN], 0,
150 PRINTF(
"Received NS from ");
154 PRINTF(
" with target address ");
155 PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NS_BUF->tgtipaddr));
159 #if UIP_CONF_IPV6_CHECKS
163 PRINTF(
"NS received is bad\n");
170 nd6_opt_offset = UIP_ND6_NS_LEN;
171 while(uip_l3_icmp_hdr_len + nd6_opt_offset <
uip_len) {
172 #if UIP_CONF_IPV6_CHECKS
174 PRINTF(
"NS received is bad\n");
180 nd6_opt_llao = &uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset];
181 #if UIP_CONF_IPV6_CHECKS
184 PRINTF(
"NS received is bad\n");
195 if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
196 lladdr, UIP_LLADDR_LEN) != 0) {
197 memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
199 nbr->state = NBR_STALE;
201 if(nbr->state == NBR_INCOMPLETE) {
202 nbr->state = NBR_STALE;
206 #if UIP_CONF_IPV6_CHECKS
211 PRINTF(
"ND option not supported in NS");
217 addr = uip_ds6_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr);
219 #if UIP_ND6_DEF_MAXDADNS > 0
222 #if UIP_CONF_IPV6_CHECKS
224 PRINTF(
"NS received is bad\n");
228 if(addr->state != ADDR_TENTATIVE) {
231 flags = UIP_ND6_NA_FLAG_OVERRIDE;
235 uip_ds6_dad_failed(addr);
244 #if UIP_CONF_IPV6_CHECKS
252 PRINTF(
"NS received is bad\n");
261 flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE;
266 if(uip_ds6_addr_lookup(&
UIP_IP_BUF->destipaddr) == addr) {
269 flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE;
272 #if UIP_CONF_IPV6_CHECKS
273 PRINTF(
"NS received is bad\n");
285 flags = flags | UIP_ND6_NA_FLAG_ROUTER;
299 UIP_ND6_NA_BUF->flagsreserved = flags;
300 memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr,
sizeof(uip_ipaddr_t));
302 create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
312 PRINTF(
"Sending NA to ");
316 PRINTF(
" with target address ");
317 PRINT6ADDR(&UIP_ND6_NA_BUF->tgtipaddr);
346 UIP_ND6_NS_BUF->reserved = 0;
360 PRINTF(
"Dropping NS due to no suitable source address\n");
367 create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
374 UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN;
375 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN;
382 PRINTF(
"Sending NS to ");
386 PRINTF(
" with target address ");
400 uint8_t is_solicited;
403 PRINTF(
"Received NA from ");
407 PRINTF(
" with target address ");
408 PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NA_BUF->tgtipaddr));
417 is_router = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_ROUTER));
419 ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_SOLICITED));
421 ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_OVERRIDE));
423 #if UIP_CONF_IPV6_CHECKS
428 PRINTF(
"NA received is bad\n");
434 nd6_opt_offset = UIP_ND6_NA_LEN;
436 while(uip_l3_icmp_hdr_len + nd6_opt_offset <
uip_len) {
437 #if UIP_CONF_IPV6_CHECKS
439 PRINTF(
"NA received is bad\n");
448 PRINTF(
"ND option not supported in NA\n");
453 addr = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
456 #if UIP_ND6_DEF_MAXDADNS > 0
457 if(addr->state == ADDR_TENTATIVE) {
458 uip_ds6_dad_failed(addr);
461 PRINTF(
"NA received is bad\n");
470 if(nd6_opt_llao != 0) {
472 memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], (
void *)lladdr,
475 if(nbr->state == NBR_INCOMPLETE) {
476 if(nd6_opt_llao ==
NULL) {
479 memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
482 nbr->state = NBR_REACHABLE;
486 stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000);
489 nbr->state = NBR_STALE;
491 nbr->isrouter = is_router;
493 if(!is_override && is_llchange) {
494 if(nbr->state == NBR_REACHABLE) {
495 nbr->state = NBR_STALE;
499 if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange)
500 || nd6_opt_llao == 0) {
501 if(nd6_opt_llao != 0) {
502 memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
506 nbr->state = NBR_REACHABLE;
508 stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000);
510 if(nd6_opt_llao != 0 && is_llchange) {
511 nbr->state = NBR_STALE;
516 if(nbr->isrouter && !is_router) {
522 nbr->isrouter = is_router;
525 #if UIP_CONF_IPV6_QUEUE_PKT
533 if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
534 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
536 uip_packetqueue_free(&nbr->packethandle);
552 uip_nd6_rs_input(
void)
555 PRINTF(
"Received RS from ");
563 #if UIP_CONF_IPV6_CHECKS
570 PRINTF(
"RS received is bad\n");
577 nd6_opt_offset = UIP_ND6_RS_LEN;
580 while(uip_l3_icmp_hdr_len + nd6_opt_offset <
uip_len) {
581 #if UIP_CONF_IPV6_CHECKS
583 PRINTF(
"RS received is bad\n");
592 PRINTF(
"ND option not supported in RS\n");
598 if(nd6_opt_llao !=
NULL) {
599 #if UIP_CONF_IPV6_CHECKS
601 PRINTF(
"RS received is bad\n");
608 (
uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
611 if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
616 (
uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
617 nbr->reachable = nbr_data.reachable;
618 nbr->sendns = nbr_data.sendns;
619 nbr->nscount = nbr_data.nscount;
623 #if UIP_CONF_IPV6_CHECKS
629 uip_ds6_send_ra_sollicited();
638 uip_nd6_ra_output(uip_ipaddr_t * dest)
658 UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit;
660 UIP_ND6_RA_BUF->flags_reserved =
661 (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6);
663 UIP_ND6_RA_BUF->router_lifetime =
uip_htons(UIP_ND6_ROUTER_LIFETIME);
666 UIP_ND6_RA_BUF->reachable_time = 0;
667 UIP_ND6_RA_BUF->retrans_timer = 0;
669 uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN;
670 nd6_opt_offset = UIP_ND6_RA_LEN;
677 if((prefix->isused) && (prefix->advertise)) {
678 UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO;
679 UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
680 UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length;
681 UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved;
682 UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime);
683 UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime);
684 UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0;
686 nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN;
687 uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
699 UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU;
700 UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3;
701 UIP_ND6_OPT_MTU_BUF->reserved = 0;
703 UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500);
705 uip_len += UIP_ND6_OPT_MTU_LEN;
706 nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
715 PRINTF(
"Sending RA to ");
742 UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN;
743 uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN;
749 create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
757 PRINTF(
"Sending RS to ");
770 PRINTF(
"Received RA from ");
777 #if UIP_CONF_IPV6_CHECKS
781 PRINTF(
"RA received is bad");
786 if(UIP_ND6_RA_BUF->cur_ttl != 0) {
787 uip_ds6_if.cur_hop_limit = UIP_ND6_RA_BUF->cur_ttl;
788 PRINTF(
"uip_ds6_if.cur_hop_limit %u\n", uip_ds6_if.cur_hop_limit);
791 if(UIP_ND6_RA_BUF->reachable_time != 0) {
792 if(uip_ds6_if.base_reachable_time !=
793 uip_ntohl(UIP_ND6_RA_BUF->reachable_time)) {
794 uip_ds6_if.base_reachable_time = uip_ntohl(UIP_ND6_RA_BUF->reachable_time);
798 if(UIP_ND6_RA_BUF->retrans_timer != 0) {
799 uip_ds6_if.retrans_timer = uip_ntohl(UIP_ND6_RA_BUF->retrans_timer);
803 nd6_opt_offset = UIP_ND6_RA_LEN;
804 while(uip_l3_icmp_hdr_len + nd6_opt_offset <
uip_len) {
806 PRINTF(
"RA received is bad");
811 PRINTF(
"Processing SLLAO option in RA\n");
819 if(nbr->state == NBR_INCOMPLETE) {
820 nbr->state = NBR_STALE;
823 if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
824 lladdr, UIP_LLADDR_LEN) != 0) {
825 memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
827 nbr->state = NBR_STALE;
832 case UIP_ND6_OPT_MTU:
833 PRINTF(
"Processing MTU option in RA\n");
834 uip_ds6_if.link_mtu =
837 case UIP_ND6_OPT_PREFIX_INFO:
838 PRINTF(
"Processing PREFIX option in RA\n");
840 if((uip_ntohl(nd6_opt_prefix_info->validlt) >=
841 uip_ntohl(nd6_opt_prefix_info->preferredlt))
844 if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) {
846 uip_ds6_prefix_lookup(&nd6_opt_prefix_info->prefix,
847 nd6_opt_prefix_info->preflen);
849 if(nd6_opt_prefix_info->validlt != 0) {
851 prefix = uip_ds6_prefix_add(&nd6_opt_prefix_info->prefix,
852 nd6_opt_prefix_info->preflen,
853 uip_ntohl(nd6_opt_prefix_info->
856 prefix = uip_ds6_prefix_add(&nd6_opt_prefix_info->prefix,
857 nd6_opt_prefix_info->preflen, 0);
861 switch (nd6_opt_prefix_info->validlt) {
863 uip_ds6_prefix_rm(prefix);
866 prefix->isinfinite = 1;
869 PRINTF(
"Updating timer of prefix");
870 PRINT6ADDR(&prefix->ipaddr);
871 PRINTF(
"new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt));
873 uip_ntohl(nd6_opt_prefix_info->validlt));
874 prefix->isinfinite = 0;
881 if((nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_AUTONOMOUS)
882 && (nd6_opt_prefix_info->validlt != 0)
883 && (nd6_opt_prefix_info->preflen == UIP_DEFAULT_PREFIX_LEN)) {
887 addr = uip_ds6_addr_lookup(&ipaddr);
888 if((addr !=
NULL) && (addr->type == ADDR_AUTOCONF)) {
891 if((uip_ntohl(nd6_opt_prefix_info->validlt) > 2 * 60 * 60) ||
892 (uip_ntohl(nd6_opt_prefix_info->validlt) >
894 PRINTF(
"Updating timer of address");
895 PRINT6ADDR(&addr->ipaddr);
896 PRINTF(
"new value %lu\n",
897 uip_ntohl(nd6_opt_prefix_info->validlt));
899 uip_ntohl(nd6_opt_prefix_info->validlt));
902 PRINTF(
"Updating timer of address ");
903 PRINT6ADDR(&addr->ipaddr);
904 PRINTF(
"new value %lu\n", (
unsigned long)(2 * 60 * 60));
906 addr->isinfinite = 0;
908 addr->isinfinite = 1;
911 if(uip_ntohl(nd6_opt_prefix_info->validlt) ==
913 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
915 uip_ds6_addr_add(&ipaddr, uip_ntohl(nd6_opt_prefix_info->validlt),
924 PRINTF(
"ND option not supported in RA");
931 if(UIP_ND6_RA_BUF->router_lifetime != 0) {
938 long)(uip_ntohs(UIP_ND6_RA_BUF->router_lifetime)));
941 (
unsigned long)(uip_ntohs(UIP_ND6_RA_BUF->router_lifetime)));
949 #if UIP_CONF_IPV6_QUEUE_PKT
958 if(nbr !=
NULL && uip_packetqueue_buflen(&nbr->packethandle) != 0) {
959 uip_len = uip_packetqueue_buflen(&nbr->packethandle);
961 uip_packetqueue_free(&nbr->packethandle);