From d9e009cb46315c0467e73d3b4a79410fde079b40 Mon Sep 17 00:00:00 2001 From: zhanghongyu Date: Wed, 15 Mar 2023 13:52:18 +0800 Subject: [PATCH] icmpv6: add route advertise RDNSS field handle when icmpv6_input Signed-off-by: zhanghongyu --- include/nuttx/net/icmpv6.h | 20 ++++++++++++---- net/icmpv6/Kconfig | 7 ++++++ net/icmpv6/icmpv6_input.c | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/include/nuttx/net/icmpv6.h b/include/nuttx/net/icmpv6.h index cae937a3ab..d9872a3fbd 100644 --- a/include/nuttx/net/icmpv6.h +++ b/include/nuttx/net/icmpv6.h @@ -102,11 +102,12 @@ /* Option types */ -#define ICMPv6_OPT_SRCLLADDR 1 /* Source Link-Layer Address */ -#define ICMPv6_OPT_TGTLLADDR 2 /* Target Link-Layer Address */ -#define ICMPv6_OPT_PREFIX 3 /* Prefix Information */ -#define ICMPv6_OPT_REDIRECT 4 /* Redirected Header */ -#define ICMPv6_OPT_MTU 5 /* MTU */ +#define ICMPv6_OPT_SRCLLADDR 1 /* Source Link-Layer Address */ +#define ICMPv6_OPT_TGTLLADDR 2 /* Target Link-Layer Address */ +#define ICMPv6_OPT_PREFIX 3 /* Prefix Information */ +#define ICMPv6_OPT_REDIRECT 4 /* Redirected Header */ +#define ICMPv6_OPT_MTU 5 /* MTU */ +#define ICMPv6_OPT_RDNSS 25 /* DNS */ /* ICMPv6 Neighbor Advertisement message flags */ @@ -351,6 +352,15 @@ struct icmpv6_mtu_s uint16_t mtu[2]; /* " " ": MTU */ }; +struct icmpv6_rdnss_s +{ + uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_RNDSS */ + uint8_t optlen; /* " " ": Option length: 1 octet */ + uint16_t reserved; /* " " ": Reserved */ + uint16_t lifetime[2]; /* " " ": lifetime */ + uint8_t servers[1]; /* Octets 2-: Beginning of the DNS Servers */ +}; + /* The structure holding the ICMP statistics that are gathered if * CONFIG_NET_STATISTICS is defined. */ diff --git a/net/icmpv6/Kconfig b/net/icmpv6/Kconfig index d7090e35b0..f83918a5ab 100644 --- a/net/icmpv6/Kconfig +++ b/net/icmpv6/Kconfig @@ -88,6 +88,13 @@ config ICMPv6_AUTOCONF_DELAYMSEC when an Router Solicitation is sent until the Router Advertisement is received. +config ICMPv6_AUTOCONF_RDNSS + bool "ICMPv6 handle RDNSS field in router advertise" + default n + ---help--- + Handle the RDNSS field in the Router Advertisement and add it to + netdb DNS Server. + endif # NET_ICMPv6_AUTOCONF config NET_ICMPv6_ROUTER diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index 2a1ed92d4e..9216f5ac27 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "devif/devif.h" #include "neighbor/neighbor.h" @@ -357,6 +358,53 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen) } break; +#ifdef CONFIG_ICMPv6_AUTOCONF_RDNSS + case ICMPv6_OPT_RDNSS: + { + FAR struct icmpv6_rdnss_s *rdnss = + (FAR struct icmpv6_rdnss_s *)opt; + FAR struct in6_addr *servers; + struct sockaddr_in6 addr; + int nservers; + int ret; + int i; + + if (rdnss->optlen < 3) + { + nerr("rdnss error length %d\n", rdnss->optlen); + break; + } + + /* optlen is in units of 8 bytes. The header is 1 unit + * (8 bytes) and each address is another 2 units + * (16 bytes). So the number of addresses is equal to + * (optlen - 1) / 2. + */ + + servers = (FAR struct in6_addr *)rdnss->servers; + nservers = (rdnss->optlen - 1) / 2; + + /* Set the IPv6 DNS server address */ + + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + + for (i = 0; i < CONFIG_NETDB_DNSSERVER_NAMESERVERS && + i < nservers; i++) + { + net_ipv6addr_copy(&addr.sin6_addr, servers + i); + ret = dns_add_nameserver( + (FAR const struct sockaddr *)&addr, + sizeof(struct sockaddr_in6)); + if (ret < 0 && ret != -EEXIST) + { + nerr("dns add nameserver failed %d", ret); + } + } + } + break; +#endif + default: break; }