This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new 92269be92 netutils/netlib: support delete the DNS server address by
index or address
92269be92 is described below
commit 92269be92af9107bb6e62c100270c592214bb53d
Author: nuttxs <[email protected]>
AuthorDate: Thu Nov 6 11:11:15 2025 +0800
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 <[email protected]>
---
examples/bridge/bridge_main.c | 26 +++++++--
examples/discover/discover_main.c | 13 ++++-
examples/tcpecho/tcpecho_main.c | 13 ++++-
examples/webserver/webserver_main.c | 13 ++++-
examples/xmlrpc/xmlrpc_main.c | 14 ++++-
include/netutils/dhcpc.h | 3 +-
include/netutils/netlib.h | 4 ++
netutils/dhcpc/dhcpc.c | 48 +++++++++++++---
netutils/netlib/CMakeLists.txt | 4 +-
netutils/netlib/Makefile | 4 +-
netutils/netlib/netlib_delipv4dnsaddr.c | 97 +++++++++++++++++++++++++++++++++
netutils/netlib/netlib_delipv6dnsaddr.c | 97 +++++++++++++++++++++++++++++++++
netutils/netlib/netlib_obtainipv4addr.c | 20 +++++--
13 files changed, 326 insertions(+), 30 deletions(-)
diff --git a/examples/bridge/bridge_main.c b/examples/bridge/bridge_main.c
index 2893c01c4..8d2165514 100644
--- a/examples/bridge/bridge_main.c
+++ b/examples/bridge/bridge_main.c
@@ -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);
diff --git a/examples/discover/discover_main.c
b/examples/discover/discover_main.c
index ba81dbcb0..cd14720ed 100644
--- a/examples/discover/discover_main.c
+++ b/examples/discover/discover_main.c
@@ -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);
diff --git a/examples/tcpecho/tcpecho_main.c b/examples/tcpecho/tcpecho_main.c
index fac12f898..96aba8096 100644
--- a/examples/tcpecho/tcpecho_main.c
+++ b/examples/tcpecho/tcpecho_main.c
@@ -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);
diff --git a/examples/webserver/webserver_main.c
b/examples/webserver/webserver_main.c
index d13b332eb..7a16c8c45 100644
--- a/examples/webserver/webserver_main.c
+++ b/examples/webserver/webserver_main.c
@@ -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);
diff --git a/examples/xmlrpc/xmlrpc_main.c b/examples/xmlrpc/xmlrpc_main.c
index 2147e095f..feeb0bf4e 100644
--- a/examples/xmlrpc/xmlrpc_main.c
+++ b/examples/xmlrpc/xmlrpc_main.c
@@ -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
*
* [email protected]
@@ -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);
diff --git a/include/netutils/dhcpc.h b/include/netutils/dhcpc.h
index 3529e554f..d55fca170 100644
--- a/include/netutils/dhcpc.h
+++ b/include/netutils/dhcpc.h
@@ -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)
*/
diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h
index 2e816441f..469bd0461 100644
--- a/include/netutils/netlib.h
+++ b/include/netutils/netlib.h
@@ -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);
diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c
index 3b0c2e191..dc6b46230 100644
--- a/netutils/dhcpc/dhcpc.c
+++ b/netutils/dhcpc/dhcpc.c
@@ -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),
diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt
index d97307e6d..66bc927a0 100644
--- a/netutils/netlib/CMakeLists.txt
+++ b/netutils/netlib/CMakeLists.txt
@@ -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)
diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile
index 93508ef85..c590970e5 100644
--- a/netutils/netlib/Makefile
+++ b/netutils/netlib/Makefile
@@ -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
diff --git a/netutils/netlib/netlib_delipv4dnsaddr.c
b/netutils/netlib/netlib_delipv4dnsaddr.c
new file mode 100644
index 000000000..45995d863
--- /dev/null
+++ b/netutils/netlib/netlib_delipv4dnsaddr.c
@@ -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 */
diff --git a/netutils/netlib/netlib_delipv6dnsaddr.c
b/netutils/netlib/netlib_delipv6dnsaddr.c
new file mode 100644
index 000000000..26abe6028
--- /dev/null
+++ b/netutils/netlib/netlib_delipv6dnsaddr.c
@@ -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 */
diff --git a/netutils/netlib/netlib_obtainipv4addr.c
b/netutils/netlib/netlib_obtainipv4addr.c
index 6156445f6..5390466fe 100644
--- a/netutils/netlib/netlib_obtainipv4addr.c
+++ b/netutils/netlib/netlib_obtainipv4addr.c
@@ -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