netutils/netlib: support delete the DNS server address by index or address

- Modify the DHCP-client data structure to support multiple DNS addresses
- Enhance DHCP-option parsing to extract all DNS-server addresses
- Set all received DNS-server addresses
- fix some test case build error

Signed-off-by: nuttxs <zhaoqing.zhang@sony.com>
This commit is contained in:
nuttxs 2025-11-06 11:11:15 +08:00 committed by Xiang Xiao
parent bd10572851
commit 92269be92a
13 changed files with 326 additions and 30 deletions

View file

@ -81,6 +81,7 @@ static int briget_net1_setup(void)
struct dhcpc_state ds;
void *handle;
char inetaddr[INET_ADDRSTRLEN];
int ret;
#endif
printf("NET1: Configuring %s\n", CONFIG_EXAMPLES_BRIDGE_NET1_IFNAME);
@ -162,9 +163,17 @@ static int briget_net1_setup(void)
&ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("NET1 ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);
@ -213,6 +222,7 @@ static int briget_net2_setup(void)
struct dhcpc_state ds;
void *handle;
char inetaddr[INET_ADDRSTRLEN];
int ret;
#endif
printf("NET2: Configuring %s\n", CONFIG_EXAMPLES_BRIDGE_NET2_IFNAME);
@ -288,9 +298,17 @@ static int briget_net2_setup(void)
&ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("NET2 ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);

View file

@ -138,6 +138,7 @@ int main(int argc, FAR char *argv[])
{
struct dhcpc_state ds;
char inetaddr[INET_ADDRSTRLEN];
int ret;
dhcpc_request(handle, &ds);
netlib_set_ipv4addr("eth0", &ds.ipaddr);
@ -152,9 +153,17 @@ int main(int argc, FAR char *argv[])
netlib_set_dripv4addr("eth0", &ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);

View file

@ -91,6 +91,7 @@ static int tcpecho_netsetup(void)
struct dhcpc_state ds;
void *handle;
char inetaddr[INET_ADDRSTRLEN];
int ret;
#endif
/* Many embedded network interfaces must have a software assigned MAC */
@ -166,9 +167,17 @@ static int tcpecho_netsetup(void)
netlib_set_dripv4addr("eth0", &ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);

View file

@ -169,6 +169,7 @@ int main(int argc, FAR char *argv[])
{
struct dhcpc_state ds;
char inetaddr[INET_ADDRSTRLEN];
int ret;
dhcpc_request(handle, &ds);
netlib_set_ipv4addr("eth0", &ds.ipaddr);
@ -183,9 +184,17 @@ int main(int argc, FAR char *argv[])
netlib_set_dripv4addr("eth0", &ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);

View file

@ -41,6 +41,7 @@
* in the article at: http://www.drdobbs.com/web-development/\
* an-embeddable-lightweight-xml-rpc-server/184405364
*/
/* Lightweight Embedded XML-RPC Server main
*
* mtj@cogitollc.com
@ -334,6 +335,7 @@ static int xmlrpc_netinit(void)
{
struct dhcpc_state ds;
char inetaddr[INET_ADDRSTRLEN];
int ret;
dhcpc_request(handle, &ds);
netlib_set_ipv4addr("eth0", &ds.ipaddr);
@ -348,9 +350,17 @@ static int xmlrpc_netinit(void)
netlib_set_dripv4addr("eth0", &ds.default_router);
}
if (ds.dnsaddr.s_addr != 0)
for (int i = 0; i < ds.num_dnsaddr; i++)
{
netlib_set_ipv4dnsaddr(&ds.dnsaddr);
if (ds.dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds.dnsaddr[i]);
if (ret < 0)
{
nerr("ERROR: Set DNS server %d:%s address failed: %d\n",
i, inet_ntoa(ds.dnsaddr[i]), ret);
}
}
}
dhcpc_close(handle);

View file

@ -55,7 +55,8 @@ struct dhcpc_state
struct in_addr serverid;
struct in_addr ipaddr;
struct in_addr netmask;
struct in_addr dnsaddr;
struct in_addr dnsaddr[CONFIG_NETDB_DNSSERVER_NAMESERVERS];
uint8_t num_dnsaddr; /* Number of DNS addresses received */
struct in_addr default_router;
uint32_t lease_time; /* Lease expires in this number of seconds */
uint32_t renewal_time; /* Seconds to transition to RENEW state(T1) */

View file

@ -482,10 +482,14 @@ int netlib_ifdown(FAR const char *ifname);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NETDB_DNSCLIENT)
int netlib_set_ipv4dnsaddr(FAR const struct in_addr *inaddr);
int netlib_del_ipv4dnsaddr(FAR const struct in_addr *inaddr);
int netlib_del_ipv4dnsaddr_by_index(int index);
#endif
#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDB_DNSCLIENT)
int netlib_set_ipv6dnsaddr(FAR const struct in6_addr *inaddr);
int netlib_del_ipv6dnsaddr(FAR const struct in6_addr *inaddr);
int netlib_del_ipv6dnsaddr_by_index(int index);
#endif
int netlib_set_mtu(FAR const char *ifname, int mtu);

View file

@ -378,11 +378,32 @@ static uint8_t dhcpc_parseoptions(FAR struct dhcpc_state *presult,
case DHCP_OPTION_DNS_SERVER:
/* Get the DNS server address in network order */
/* Get the DNS server addresses in network order.
* DHCP option 6 can contain multiple DNS server addresses,
* each 4 bytes long.
*/
if (optptr + 6 <= end)
if (optptr + 2 <= end)
{
memcpy(&presult->dnsaddr.s_addr, optptr + 2, 4);
uint8_t optlen = *(optptr + 1);
uint8_t num_dns = optlen / 4;
uint8_t i;
/* Limit to configured maximum */
if (num_dns > CONFIG_NETDB_DNSSERVER_NAMESERVERS)
{
num_dns = CONFIG_NETDB_DNSSERVER_NAMESERVERS;
}
presult->num_dnsaddr = 0;
for (i = 0; i < num_dns && (optptr + 2 + i * 4 + 4) <= end;
i++)
{
memcpy(&presult->dnsaddr[i].s_addr, optptr + 2 + i * 4,
4);
presult->num_dnsaddr++;
}
}
else
{
@ -946,11 +967,22 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult)
ip4_addr2(presult->netmask.s_addr),
ip4_addr3(presult->netmask.s_addr),
ip4_addr4(presult->netmask.s_addr));
ninfo("Got DNS server %u.%u.%u.%u\n",
ip4_addr1(presult->dnsaddr.s_addr),
ip4_addr2(presult->dnsaddr.s_addr),
ip4_addr3(presult->dnsaddr.s_addr),
ip4_addr4(presult->dnsaddr.s_addr));
/* Print all DNS servers received */
if (presult->num_dnsaddr > 0)
{
uint8_t i;
for (i = 0; i < presult->num_dnsaddr; i++)
{
ninfo("Got DNS server %d: %u.%u.%u.%u\n", i,
ip4_addr1(presult->dnsaddr[i].s_addr),
ip4_addr2(presult->dnsaddr[i].s_addr),
ip4_addr3(presult->dnsaddr[i].s_addr),
ip4_addr4(presult->dnsaddr[i].s_addr));
}
}
ninfo("Got default router %u.%u.%u.%u\n",
ip4_addr1(presult->default_router.s_addr),
ip4_addr2(presult->default_router.s_addr),

View file

@ -47,7 +47,7 @@ if(CONFIG_NETUTILS_NETLIB)
endif()
endif()
if(CONFIG_NETDB_DNSCLIENT)
list(APPEND SRCS netlib_setipv4dnsaddr.c)
list(APPEND SRCS netlib_setipv4dnsaddr.c netlib_delipv4dnsaddr.c)
endif()
if(CONFIG_NET_ROUTE)
list(APPEND SRCS netlib_ipv4route.c netlib_ipv4router.c)
@ -70,7 +70,7 @@ if(CONFIG_NETUTILS_NETLIB)
list(APPEND SRCS netlib_autoconfig.c netlib_obtainipv6addr.c)
endif()
if(CONFIG_NETDB_DNSCLIENT)
list(APPEND SRCS netlib_setipv6dnsaddr.c)
list(APPEND SRCS netlib_setipv6dnsaddr.c netlib_delipv6dnsaddr.c)
endif()
if(CONFIG_NET_ROUTE)
list(APPEND SRCS netlib_ipv6route.c netlib_ipv6router.c)

View file

@ -47,7 +47,7 @@ CSRCS += netlib_getarptab.c
endif
endif
ifeq ($(CONFIG_NETDB_DNSCLIENT),y)
CSRCS += netlib_setipv4dnsaddr.c
CSRCS += netlib_setipv4dnsaddr.c netlib_delipv4dnsaddr.c
endif
ifeq ($(CONFIG_NET_ROUTE),y)
CSRCS += netlib_ipv4route.c netlib_ipv4router.c
@ -71,7 +71,7 @@ CSRCS += netlib_autoconfig.c
CSRCS += netlib_obtainipv6addr.c
endif
ifeq ($(CONFIG_NETDB_DNSCLIENT),y)
CSRCS += netlib_setipv6dnsaddr.c
CSRCS += netlib_setipv6dnsaddr.c netlib_delipv6dnsaddr.c
endif
ifeq ($(CONFIG_NET_ROUTE),y)
CSRCS += netlib_ipv6route.c netlib_ipv6router.c

View file

@ -0,0 +1,97 @@
/****************************************************************************
* apps/netutils/netlib/netlib_delipv4dnsaddr.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/socket.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <nuttx/net/dns.h>
#include "netutils/netlib.h"
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NETDB_DNSCLIENT)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: netlib_del_ipv4dnsaddr
*
* Description:
* Remove a DNS server IPv4 address from the list by address
*
* Parameters:
* inaddr The address to remove
*
* Return:
* Zero (OK) is returned on success; A negated errno value is returned
* on failure.
*
****************************************************************************/
int netlib_del_ipv4dnsaddr(FAR const struct in_addr *inaddr)
{
struct sockaddr_in addr;
int ret = -EINVAL;
if (inaddr)
{
addr.sin_family = AF_INET;
addr.sin_port = 0;
memcpy(&addr.sin_addr, inaddr, sizeof(struct in_addr));
bzero(&addr.sin_zero, sizeof(addr.sin_zero));
ret = dns_del_nameserver((FAR const struct sockaddr *)&addr,
sizeof(struct sockaddr_in));
}
return ret;
}
/****************************************************************************
* Name: netlib_del_ipv4dnsaddr_by_index
*
* Description:
* Remove a DNS server IPv4 address from the list by index (0-based)
*
* Parameters:
* index: The index of the DNS server to remove (0=first, 1=second, etc.)
*
* Return:
* Zero (OK) is returned on success; A negated errno value is returned
* on failure.
*
****************************************************************************/
int netlib_del_ipv4dnsaddr_by_index(int index)
{
return dns_del_nameserver_by_index(index);
}
#endif /* CONFIG_NET_IPv4 && CONFIG_NETDB_DNSCLIENT */

View file

@ -0,0 +1,97 @@
/****************************************************************************
* apps/netutils/netlib/netlib_delipv6dnsaddr.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <nuttx/net/dns.h>
#include "netutils/netlib.h"
#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDB_DNSCLIENT)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: netlib_del_ipv6dnsaddr
*
* Description:
* Remove a DNS server IPv6 address from the list by address
*
* Parameters:
* inaddr The IPv6 address to remove
*
* Return:
* Zero (OK) is returned on success; A negated errno value is returned
* on failure.
*
****************************************************************************/
int netlib_del_ipv6dnsaddr(FAR const struct in6_addr *inaddr)
{
struct sockaddr_in6 addr;
int ret = -EINVAL;
if (inaddr)
{
/* Del the IPv6 DNS server address */
addr.sin6_family = AF_INET6;
addr.sin6_port = 0;
memcpy(&addr.sin6_addr, inaddr, sizeof(struct in6_addr));
ret = dns_del_nameserver((FAR const struct sockaddr *)&addr,
sizeof(struct sockaddr_in6));
}
return ret;
}
/****************************************************************************
* Name: netlib_del_ipv6dnsaddr_by_index
*
* Description:
* Remove a DNS server IPv6 address from the list by index (0-based)
*
* Parameters:
* index:The index of the DNS server to remove (0=first, 1=second, etc.)
*
* Return:
* Zero (OK) is returned on success; A negated errno value is returned
* on failure.
*
****************************************************************************/
int netlib_del_ipv6dnsaddr_by_index(int index)
{
return dns_del_nameserver_by_index(index);
}
#endif /* CONFIG_NET_IPv6 && CONFIG_NETDB_DNSCLIENT */

View file

@ -81,13 +81,23 @@ static int dhcp_setup_result(FAR const char *ifname,
}
#ifdef CONFIG_NETDB_DNSCLIENT
if (ds->dnsaddr.s_addr != 0)
/* Set all received DNS server addresses */
if (ds->num_dnsaddr > 0)
{
ret = netlib_set_ipv4dnsaddr(&ds->dnsaddr);
if (ret < 0)
uint8_t i;
for (i = 0; i < ds->num_dnsaddr; i++)
{
nerr("ERROR: set the DNS server address failed: %d\n", ret);
return ret;
if (ds->dnsaddr[i].s_addr != 0)
{
ret = netlib_set_ipv4dnsaddr(&ds->dnsaddr[i]);
if (ret < 0)
{
nerr("ERROR: set DNS server %d address failed: %d\n",
i, ret);
return ret;
}
}
}
}
#endif