Skip to content

Commit 3bd9d24

Browse files
committed
Adds DHCP Range Setup to APMode
1 parent a9d77ac commit 3bd9d24

File tree

5 files changed

+51
-21
lines changed

5 files changed

+51
-21
lines changed

Diff for: libraries/Ethernet/src/ETH.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I
407407
esp_err_t err = ESP_OK;
408408
tcpip_adapter_ip_info_t info;
409409

410-
if(local_ip != (uint32_t)0x00000000 && local_ip != INADDR_NONE){
410+
if(static_cast<uint32_t>(local_ip) != 0){
411411
info.ip.addr = static_cast<uint32_t>(local_ip);
412412
info.gw.addr = static_cast<uint32_t>(gateway);
413413
info.netmask.addr = static_cast<uint32_t>(subnet);
@@ -443,13 +443,13 @@ bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, I
443443
ip_addr_t d;
444444
d.type = IPADDR_TYPE_V4;
445445

446-
if(dns1 != (uint32_t)0x00000000 && dns1 != INADDR_NONE) {
446+
if(static_cast<uint32_t>(dns1) != 0) {
447447
// Set DNS1-Server
448448
d.u_addr.ip4.addr = static_cast<uint32_t>(dns1);
449449
dns_setserver(0, &d);
450450
}
451451

452-
if(dns2 != (uint32_t)0x00000000 && dns2 != INADDR_NONE) {
452+
if(static_cast<uint32_t>(dns2) != 0) {
453453
// Set DNS2-Server
454454
d.u_addr.ip4.addr = static_cast<uint32_t>(dns2);
455455
dns_setserver(1, &d);

Diff for: libraries/WiFi/src/WiFiAP.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern "C" {
4747
// -----------------------------------------------------------------------------------------------------------------------
4848

4949
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
50-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
50+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress(), IPAddress dhcp_lease_start=INADDR_NONE);
5151
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
5252

5353
static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){
@@ -195,7 +195,7 @@ String WiFiAPClass::softAPSSID() const
195195
* @param gateway gateway IP
196196
* @param subnet subnet mask
197197
*/
198-
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
198+
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start)
199199
{
200200
esp_err_t err = ESP_OK;
201201

@@ -204,7 +204,7 @@ bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress
204204
return false;
205205
}
206206

207-
err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet);
207+
err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet, dhcp_lease_start);
208208
return err == ESP_OK;
209209
}
210210

Diff for: libraries/WiFi/src/WiFiAP.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class WiFiAPClass
3838
public:
3939

4040
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false);
41-
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
41+
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start = INADDR_NONE);
4242
bool softAPdisconnect(bool wifioff = false);
4343

4444
uint8_t softAPgetStationNum();

Diff for: libraries/WiFi/src/WiFiGeneric.cpp

+43-13
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ esp_err_t set_esp_interface_hostname(esp_interface_t interface, const char * hos
8282
return ESP_FAIL;
8383
}
8484

85-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress()){
85+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress(), IPAddress dhcp_lease_start=INADDR_NONE){
8686
esp_netif_t *esp_netif = esp_netifs[interface];
8787
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT;
8888
esp_netif_ip_info_t info;
@@ -138,19 +138,49 @@ esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPA
138138

139139
dhcps_lease_t lease;
140140
lease.enable = true;
141-
uint32_t dhcp_ipaddr = static_cast<uint32_t>(local_ip);
142-
// prevents DHCP lease range to overflow subnet/24 range
143-
// there will be 11 addresses for DHCP to lease
144-
uint8_t leaseStart = (uint8_t)(~subnet[3] - 12);
145-
if ((local_ip[3]) < leaseStart) {
146-
lease.start_ip.addr = dhcp_ipaddr + (1 << 24);
147-
lease.end_ip.addr = dhcp_ipaddr + (11 << 24);
148-
} else {
149-
// make range stay in the begining of the netmask range
150-
dhcp_ipaddr = (dhcp_ipaddr & 0x00FFFFFF);
151-
lease.start_ip.addr = dhcp_ipaddr + (1 << 24);
152-
lease.end_ip.addr = dhcp_ipaddr + (11 << 24);
141+
uint8_t CIDR = WiFiGenericClass::calculateSubnetCIDR(subnet);
142+
// netmask must have room for at least 12 IP addresses (AP + GW + 10 DHCP Leasing addresses)
143+
// netmask also must be limited to the last 8 bits of IPv4, otherwise this function won't work
144+
if (CIDR > 28 || CIDR < 24) {
145+
log_e("Bad netmask. It must be from /24 to /28 (255.255.255. 0<->240)");
146+
return ESP_FAIL; // ESP_FAIL if initializing failed
147+
}
148+
uint32_t netmask = static_cast<uint32_t>(subnet);
149+
uint32_t ap_ipaddr = static_cast<uint32_t>(local_ip);
150+
uint32_t dhcp_ipaddr = static_cast<uint32_t>(dhcp_lease_start);
151+
dhcp_ipaddr = dhcp_ipaddr == 0 ? ap_ipaddr + (1 << 24) : dhcp_ipaddr;
152+
uint32_t leaseStartMax = ~netmask - (10 << 24);
153+
// there will be 10 addresses for DHCP to lease
154+
lease.start_ip.addr = dhcp_ipaddr;
155+
lease.end_ip.addr = lease.start_ip.addr + (10 << 24);
156+
// prevents DHCP lease range to overflow subnet range
157+
if ((dhcp_ipaddr & ~netmask) >= leaseStartMax) {
158+
// make first DHCP lease addr stay in the begining of the netmask range
159+
lease.start_ip.addr = (dhcp_ipaddr & netmask) + (1 << 24);
160+
lease.end_ip.addr = lease.start_ip.addr + (10 << 24);
161+
log_w("Changing DHCP leasing start address to %s", IPAddress(lease.start_ip.addr).toString().c_str());
162+
}
163+
// Check if local_ip is in the same subnet as the dhcp leasing range initial address
164+
if ((ap_ipaddr & netmask) != (dhcp_ipaddr & netmask)) {
165+
log_e("The AP IP address (%s) and the DHCP start address (%s) must be in the same subnetwork",
166+
local_ip.toString().c_str(), IPAddress(dhcp_ipaddr).toString().c_str());
167+
return ESP_FAIL; // ESP_FAIL if initializing failed
168+
}
169+
// Check if local_ip is within DHCP range
170+
if (ap_ipaddr >= lease.start_ip.addr && ap_ipaddr <= lease.end_ip.addr) {
171+
log_e("The AP IP address (%s) can't be within the DHCP range (%s -- %s)",
172+
local_ip.toString().c_str(), IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str());
173+
return ESP_FAIL; // ESP_FAIL if initializing failed
174+
}
175+
// Check if gateway is within DHCP range
176+
uint32_t gw_ipaddr = static_cast<uint32_t>(gateway);
177+
bool gw_in_same_subnet = (gw_ipaddr & netmask) == (ap_ipaddr & netmask);
178+
if (gw_in_same_subnet && gw_ipaddr >= lease.start_ip.addr && gw_ipaddr <= lease.end_ip.addr) {
179+
log_e("The GatewayP address (%s) can't be within the DHCP range (%s -- %s)",
180+
gateway.toString().c_str(), IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str());
181+
return ESP_FAIL; // ESP_FAIL if initializing failed
153182
}
183+
log_v("SoftAP: %s | Gateway: %s | Netmask: %s", local_ip.toString().c_str(),gateway.toString().c_str(),subnet.toString().c_str());
154184
log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str());
155185
err = tcpip_adapter_dhcps_option(
156186
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,

Diff for: libraries/WiFi/src/WiFiSTA.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extern "C" {
5151

5252
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
5353
esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress());
54-
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
54+
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress(), IPAddress dhcp_lease_start=INADDR_NONE);
5555
static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
5656

5757
static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){

0 commit comments

Comments
 (0)