diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 273b45134..af545a0d3 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -72,6 +72,7 @@ #include "net/ipv6/uip-icmp6.h" #include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-ds6.h" +#include "net/ip/uip-nameserver.h" #include "lib/random.h" /*------------------------------------------------------------------*/ @@ -112,6 +113,7 @@ void uip_log(char *msg); #define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) #define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +#define UIP_ND6_OPT_RDNSS_BUF ((uip_nd6_opt_dns *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) /** @} */ static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/ @@ -715,6 +717,29 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) uip_len += UIP_ND6_OPT_MTU_LEN; nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; + +#if UIP_ND6_RA_RDNSS + if(uip_nameserver_count() > 0) { + uint8_t i = 0; + uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip; + uip_ipaddr_t *dns = NULL; + UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS; + UIP_ND6_OPT_RDNSS_BUF->reserved = 0; + UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration(); + if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) { + UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds(); + } + while((dns = uip_nameserver_get(i)) != NULL) { + uip_ipaddr_copy(ip++, dns); + i++; + } + UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1); + PRINTF("%d nameservers reported\n", i); + uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3; + nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3; + } +#endif /* UIP_ND6_RA_RDNSS */ + UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); @@ -938,6 +963,23 @@ ra_input(void) /* End of autonomous flag related processing */ } break; +#if UIP_ND6_RA_RDNSS + case UIP_ND6_OPT_RDNSS: + if(UIP_ND6_RA_BUF->flags_reserved & (UIP_ND6_O_FLAG << 6)){ + PRINTF("Processing RDNSS option\n"); + uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2; + uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip); + PRINTF("got %d nameservers\n", naddr); + while(naddr-- > 0) { + PRINTF(" nameserver: "); + PRINT6ADDR(ip); + PRINTF(" lifetime: %lx\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); + uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime)); + ip++; + } + } + break; +#endif /* UIP_ND6_RA_RDNSS */ default: PRINTF("ND option not supported in RA"); break; diff --git a/core/net/ipv6/uip-nd6.h b/core/net/ipv6/uip-nd6.h index 0ece86522..f0711356a 100644 --- a/core/net/ipv6/uip-nd6.h +++ b/core/net/ipv6/uip-nd6.h @@ -87,7 +87,7 @@ #define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL #endif #define UIP_ND6_M_FLAG 0 -#define UIP_ND6_O_FLAG 0 +#define UIP_ND6_O_FLAG (UIP_ND6_RA_RDNSS || UIP_ND6_RA_DNSSL) #define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL #define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/ @@ -139,6 +139,30 @@ /** @} */ +/** \name RFC 6106 RA DNS Options Constants */ +/** @{ */ +#ifndef UIP_CONF_ND6_RA_RDNSS +#define UIP_ND6_RA_RDNSS 0 +#else +#define UIP_ND6_RA_RDNSS UIP_CONF_ND6_RA_RDNSS +#endif + +/** \brief Number of DNS to hold on the node */ +#if UIP_ND6_RA_RDNSS +#define UIP_ND6_RDNSS_POOL_SIZE 2 +#else +#define UIP_ND6_RDNSS_POOL_SIZE 0 +#endif + +#ifndef UIP_CONF_ND6_RA_DNSSL +#define UIP_ND6_RA_DNSSL 0 +#else +#error Not implemented +#define UIP_ND6_RA_DNSSL UIP_CONF_ND6_RA_DNSSL +#endif +/** @} */ + + /** \name ND6 option types */ /** @{ */ #define UIP_ND6_OPT_SLLAO 1 @@ -146,6 +170,8 @@ #define UIP_ND6_OPT_PREFIX_INFO 3 #define UIP_ND6_OPT_REDIRECTED_HDR 4 #define UIP_ND6_OPT_MTU 5 +#define UIP_ND6_OPT_RDNSS 25 +#define UIP_ND6_OPT_DNSSL 31 /** @} */ /** \name ND6 option types */ @@ -168,6 +194,8 @@ #define UIP_ND6_OPT_HDR_LEN 2 #define UIP_ND6_OPT_PREFIX_INFO_LEN 32 #define UIP_ND6_OPT_MTU_LEN 8 +#define UIP_ND6_OPT_RDNSS_LEN 1 +#define UIP_ND6_OPT_DNSSL_LEN 1 /* Length of TLLAO and SLLAO options, it is L2 dependant */ @@ -290,6 +318,15 @@ typedef struct uip_nd6_opt_mtu { uint32_t mtu; } uip_nd6_opt_mtu; +/** \brief ND option RDNSS */ +typedef struct uip_nd6_opt_dns { + uint8_t type; + uint8_t len; + uint16_t reserved; + uint32_t lifetime; + uip_ipaddr_t ip; +} uip_nd6_opt_dns; + /** \struct Redirected header option */ typedef struct uip_nd6_opt_redirected_hdr { uint8_t type;