icmpv6: add route advertise RDNSS field handle when icmpv6_input

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2023-03-15 13:52:18 +08:00 committed by Alan Carvalho de Assis
parent baa10ee047
commit d9e009cb46
3 changed files with 70 additions and 5 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -33,6 +33,7 @@
#include <nuttx/net/netdev.h>
#include <nuttx/net/netstats.h>
#include <nuttx/net/icmpv6.h>
#include <nuttx/net/dns.h>
#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;
}