Skip to content

Commit 04133e0

Browse files
committed
Merge branch 'contrib/github_pr_15057' into 'master'
feat(dhcps): Support for multiple DNS servers (GitHub PR) Closes IDFGH-14266 See merge request espressif/esp-idf!36256
2 parents 5d63f25 + b3523a6 commit 04133e0

File tree

4 files changed

+204
-53
lines changed

4 files changed

+204
-53
lines changed

components/esp_netif/lwip/esp_netif_lwip.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,11 +1990,11 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
19901990
if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
19911991
#if ESP_DHCPS
19921992
// if DHCP server configured to set DNS in dhcps API
1993-
if (type != ESP_NETIF_DNS_MAIN) {
1993+
if (type >= ESP_NETIF_DNS_FALLBACK) {
19941994
ESP_LOGD(TAG, "set dns invalid type");
19951995
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
19961996
} else {
1997-
dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip);
1997+
dhcps_dns_setserver_by_type(esp_netif->dhcps, &lwip_ip, (dns_type_t)type);
19981998
}
19991999
#else
20002000
LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
@@ -2053,7 +2053,7 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg)
20532053
if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
20542054
#if ESP_DHCPS
20552055
ip4_addr_t dns_ip;
2056-
dhcps_dns_getserver(esp_netif->dhcps, &dns_ip);
2056+
dhcps_dns_getserver_by_type(esp_netif->dhcps, &dns_ip, (dns_type_t)type);
20572057
memcpy(&dns->ip.u_addr.ip4, &dns_ip, sizeof(ip4_addr_t));
20582058
dns->ip.type = ESP_IPADDR_TYPE_V4;
20592059
#else

components/lwip/apps/dhcpserver/dhcpserver.c

Lines changed: 87 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ struct dhcps_t {
126126
struct netif *dhcps_netif;
127127
ip4_addr_t broadcast_dhcps;
128128
ip4_addr_t server_address;
129-
ip4_addr_t dns_server;
129+
ip4_addr_t dns_server[DNS_TYPE_MAX];
130130
ip4_addr_t client_address;
131131
ip4_addr_t client_address_plus;
132132
ip4_addr_t dhcps_mask;
@@ -155,7 +155,10 @@ dhcps_t *dhcps_new(void)
155155
return NULL;
156156
}
157157
dhcps->dhcps_netif = NULL;
158-
dhcps->dns_server.addr = 0;
158+
159+
for (int i = 0; i < DNS_TYPE_MAX; i++) {
160+
dhcps->dns_server[i].addr = 0;
161+
}
159162
#ifdef USE_CLASS_B_NET
160163
dhcps->dhcps_mask.addr = PP_HTONL(LWIP_MAKEU32(255, 240, 0, 0));
161164
#else
@@ -194,6 +197,18 @@ static void get_ip_info(struct netif * netif, ip_info_t *ip_info)
194197
}
195198
}
196199

200+
static inline u8_t* dhcps_option_ip(u8_t *optptr, const ip4_addr_t *ip)
201+
{
202+
LWIP_ASSERT("dhcps_option_ip: optptr must not be NULL", (optptr != NULL));
203+
LWIP_ASSERT("dhcps_option_ip: ip must not be NULL", (ip != NULL));
204+
205+
*optptr++ = ip4_addr1(ip);
206+
*optptr++ = ip4_addr2(ip);
207+
*optptr++ = ip4_addr3(ip);
208+
*optptr++ = ip4_addr4(ip);
209+
return optptr;
210+
}
211+
197212
/******************************************************************************
198213
* FunctionName : dhcps_option_info
199214
* Description : get the DHCP message option info
@@ -419,10 +434,7 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
419434

420435
*optptr++ = DHCP_OPTION_SUBNET_MASK;
421436
*optptr++ = 4;
422-
*optptr++ = ip4_addr1(&dhcps->dhcps_mask);
423-
*optptr++ = ip4_addr2(&dhcps->dhcps_mask);
424-
*optptr++ = ip4_addr3(&dhcps->dhcps_mask);
425-
*optptr++ = ip4_addr4(&dhcps->dhcps_mask);
437+
optptr = dhcps_option_ip(optptr, &dhcps->dhcps_mask);
426438

427439
*optptr++ = DHCP_OPTION_LEASE_TIME;
428440
*optptr++ = 4;
@@ -433,10 +445,7 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
433445

434446
*optptr++ = DHCP_OPTION_SERVER_ID;
435447
*optptr++ = 4;
436-
*optptr++ = ip4_addr1(&ipadd);
437-
*optptr++ = ip4_addr2(&ipadd);
438-
*optptr++ = ip4_addr3(&ipadd);
439-
*optptr++ = ip4_addr4(&ipadd);
448+
optptr = dhcps_option_ip(optptr, &ipadd);
440449

441450
if (dhcps_router_enabled(dhcps->dhcps_offer)) {
442451
ip_info_t if_ip = { 0 };
@@ -447,38 +456,37 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
447456
if (!ip4_addr_isany_val(*gw_ip)) {
448457
*optptr++ = DHCP_OPTION_ROUTER;
449458
*optptr++ = 4;
450-
*optptr++ = ip4_addr1(gw_ip);
451-
*optptr++ = ip4_addr2(gw_ip);
452-
*optptr++ = ip4_addr3(gw_ip);
453-
*optptr++ = ip4_addr4(gw_ip);
459+
optptr = dhcps_option_ip(optptr, gw_ip);
454460
}
455461
}
456462

463+
// In order of preference
457464
if (dhcps_dns_enabled(dhcps->dhcps_dns)) {
465+
uint8_t size = 4;
466+
467+
if (dhcps->dns_server[DNS_TYPE_BACKUP].addr) {
468+
size += 4;
469+
}
470+
458471
*optptr++ = DHCP_OPTION_DNS_SERVER;
459-
*optptr++ = 4;
460-
*optptr++ = ip4_addr1(&dhcps->dns_server);
461-
*optptr++ = ip4_addr2(&dhcps->dns_server);
462-
*optptr++ = ip4_addr3(&dhcps->dns_server);
463-
*optptr++ = ip4_addr4(&dhcps->dns_server);
472+
*optptr++ = size;
473+
optptr = dhcps_option_ip(optptr, &dhcps->dns_server[DNS_TYPE_MAIN]);
474+
475+
if (dhcps->dns_server[DNS_TYPE_BACKUP].addr) {
476+
optptr = dhcps_option_ip(optptr, &dhcps->dns_server[DNS_TYPE_BACKUP]);
477+
}
464478
#ifdef CONFIG_LWIP_DHCPS_ADD_DNS
465-
}else {
479+
} else {
466480
*optptr++ = DHCP_OPTION_DNS_SERVER;
467481
*optptr++ = 4;
468-
*optptr++ = ip4_addr1(&ipadd);
469-
*optptr++ = ip4_addr2(&ipadd);
470-
*optptr++ = ip4_addr3(&ipadd);
471-
*optptr++ = ip4_addr4(&ipadd);
482+
optptr = dhcps_option_ip(optptr, &ipadd);
472483
#endif /* CONFIG_LWIP_DHCPS_ADD_DNS */
473484
}
474485

475486
ip4_addr_t broadcast_addr = { .addr = (ipadd.addr & dhcps->dhcps_mask.addr) | ~dhcps->dhcps_mask.addr };
476487
*optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
477488
*optptr++ = 4;
478-
*optptr++ = ip4_addr1(&broadcast_addr);
479-
*optptr++ = ip4_addr2(&broadcast_addr);
480-
*optptr++ = ip4_addr3(&broadcast_addr);
481-
*optptr++ = ip4_addr4(&broadcast_addr);
489+
optptr = dhcps_option_ip(optptr, &broadcast_addr);
482490

483491
*optptr++ = DHCP_OPTION_INTERFACE_MTU;
484492
*optptr++ = 2;
@@ -490,8 +498,7 @@ static u8_t *add_offer_options(dhcps_t *dhcps, u8_t *optptr)
490498

491499
*optptr++ = DHCP_OPTION_CAPTIVEPORTAL_URI;
492500
*optptr++ = length;
493-
for (i = 0; i < length; i++)
494-
{
501+
for (i = 0; i < length; i++) {
495502
*optptr++ = dhcps->dhcps_captiveportal_uri[i];
496503
}
497504
}
@@ -1532,36 +1539,71 @@ bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip)
15321539
}
15331540

15341541
/******************************************************************************
1535-
* FunctionName : dhcps_dns_setserver
1536-
* Description : set DNS server address for dhcpserver
1542+
* FunctionName : dhcps_dns_setserver_by_type
1543+
* Description : Set the DNS server address for dhcpserver with a specific type
15371544
* Parameters : dnsserver -- The DNS server address
1538-
* Returns : ERR_ARG if invalid handle, ERR_OK on success
1545+
* type -- The DNS type
1546+
* Returns : ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
15391547
*******************************************************************************/
1540-
err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver)
1548+
err_t dhcps_dns_setserver_by_type(dhcps_t *dhcps, const ip_addr_t *dnsserver, dns_type_t type)
15411549
{
15421550
if (dhcps == NULL) {
15431551
return ERR_ARG;
15441552
}
1553+
1554+
if (type >= DNS_TYPE_MAX) {
1555+
return ERR_VAL;
1556+
}
1557+
15451558
if (dnsserver != NULL) {
1546-
dhcps->dns_server = *(ip_2_ip4(dnsserver));
1559+
dhcps->dns_server[type] = *(ip_2_ip4(dnsserver));
15471560
} else {
1548-
dhcps->dns_server = *(ip_2_ip4(IP_ADDR_ANY));
1561+
dhcps->dns_server[type] = *(ip_2_ip4(IP_ADDR_ANY));
15491562
}
15501563
return ERR_OK;
15511564
}
15521565

15531566
/******************************************************************************
1554-
* FunctionName : dhcps_dns_getserver
1555-
* Description : get DNS server address for dhcpserver
1556-
* Parameters : none
1557-
* Returns : ip4_addr_t
1567+
* FunctionName : dhcps_dns_setserver
1568+
* Description : Set the main DNS server address for dhcpserver
1569+
* Parameters : dnsserver -- The DNS server address
1570+
* Returns : ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
15581571
*******************************************************************************/
1559-
err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver)
1572+
err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver)
15601573
{
1561-
if (dhcps) {
1562-
*dnsserver = dhcps->dns_server;
1563-
return ERR_OK;
1574+
return dhcps_dns_setserver_by_type(dhcps, dnsserver, DNS_TYPE_MAIN);
1575+
}
1576+
1577+
/******************************************************************************
1578+
* FunctionName : dhcps_dns_getserver_by_type
1579+
* Description : Get the DNS server address for dhcpserver
1580+
* Parameters : dnsserver -- The DNS server address
1581+
* type -- The DNS type
1582+
* Returns : ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
1583+
*******************************************************************************/
1584+
err_t dhcps_dns_getserver_by_type(dhcps_t *dhcps, ip4_addr_t *dnsserver, dns_type_t type)
1585+
{
1586+
if ((dhcps == NULL) || (dnsserver == NULL)) {
1587+
return ERR_ARG;
1588+
}
1589+
1590+
if (type >= DNS_TYPE_MAX) {
1591+
return ERR_VAL;
15641592
}
1565-
return ERR_ARG;
1593+
1594+
*dnsserver = dhcps->dns_server[type];
1595+
return ERR_OK;
15661596
}
1597+
1598+
/******************************************************************************
1599+
* FunctionName : dhcps_dns_getserver_by_type
1600+
* Description : Get the main DNS server address for dhcpserver
1601+
* Parameters : dnsserver -- The DNS server address
1602+
* Returns : ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
1603+
*******************************************************************************/
1604+
err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver)
1605+
{
1606+
return dhcps_dns_getserver_by_type(dhcps, dnsserver, DNS_TYPE_MAIN);
1607+
}
1608+
15671609
#endif // ESP_DHCPS

components/lwip/include/apps/dhcpserver/dhcpserver.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -47,6 +47,13 @@ enum dhcps_offer_option{
4747
OFFER_END
4848
};
4949

50+
typedef enum
51+
{
52+
DNS_TYPE_MAIN = 0, /**< DNS main server address*/
53+
DNS_TYPE_BACKUP, /**< DNS backup server address (Wi-Fi STA and Ethernet only) */
54+
DNS_TYPE_MAX
55+
} dns_type_t;
56+
5057
/** @brief DHCP server's description of compile time configuration values in dhcpserver.c
5158
*
5259
* - DHCPS_DEBUG: Prints very detailed debug messages if set to 1, hardcoded to 0
@@ -161,21 +168,39 @@ err_t dhcps_set_option_info(dhcps_t *dhcps, u8_t op_id, void *opt_info, u32_t op
161168
bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip);
162169

163170
/**
164-
* @brief Sets DNS server address for the DHCP server
171+
* @brief Sets the DNS server address for the DHCP server
165172
* @param dhcps Pointer to the DHCP handle
166173
* @param dnsserver Address of the DNS server
167-
* @return ERR_ARG if invalid handle, ERR_OK on success
174+
* @return ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
168175
*/
169176
err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver);
170177

171178
/**
172-
* @brief Gets DNS server associated with this DHCP server
179+
* @brief Sets the DNS server address for the DHCP server with a specific type
173180
* @param dhcps Pointer to the DHCP handle
174181
* @param dnsserver Address of the DNS server
175-
* @return ERR_ARG if invalid handle, ERR_OK on success
182+
* @param type Type of the DNS server
183+
* @return ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
184+
*/
185+
err_t dhcps_dns_setserver_by_type(dhcps_t *dhcps, const ip_addr_t *dnsserver, dns_type_t type);
186+
187+
/**
188+
* @brief Gets the DNS server associated with this DHCP server
189+
* @param dhcps Pointer to the DHCP handle
190+
* @param dnsserver Address of the DNS server
191+
* @return ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
176192
*/
177193
err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver);
178194

195+
/**
196+
* @brief Gets the DNS server associated with this DHCP server with a specific type
197+
* @param dhcps Pointer to the DHCP handle
198+
* @param dnsserver Address of the DNS server
199+
* @param type Type of the DNS server
200+
* @return ERR_ARG if invalid handle, ERR_VAL if invalid type, ERR_OK on success
201+
*/
202+
err_t dhcps_dns_getserver_by_type(dhcps_t *dhcps, ip4_addr_t *dnsserver, dns_type_t type);
203+
179204
/**
180205
* @brief Sets callback on assigning an IP to the connected client
181206
* @param dhcps Pointer to the DHCP handle

0 commit comments

Comments
 (0)