diff --git a/cores/esp8266/LwipDhcpServer-NonOS.cpp b/cores/esp8266/LwipDhcpServer-NonOS.cpp index 0a4d1298cd..a5324ec5d5 100644 --- a/cores/esp8266/LwipDhcpServer-NonOS.cpp +++ b/cores/esp8266/LwipDhcpServer-NonOS.cpp @@ -71,19 +71,21 @@ extern "C" uint32 wifi_softap_get_dhcps_lease_time() { auto& server = getNonOSDhcpServer(); - return server.get_dhcps_lease_time(); + return server.getLeaseTime(); } bool wifi_softap_set_dhcps_lease_time(uint32 minutes) { auto& server = getNonOSDhcpServer(); - return server.set_dhcps_lease_time(minutes); + server.setLeaseTime(minutes); + return true; } bool wifi_softap_reset_dhcps_lease_time() { auto& server = getNonOSDhcpServer(); - return server.reset_dhcps_lease_time(); + server.resetLeaseTime(); + return true; } bool wifi_softap_add_dhcps_lease(uint8* macaddr) diff --git a/cores/esp8266/LwipDhcpServer.cpp b/cores/esp8266/LwipDhcpServer.cpp index f5a85f24f7..ddae5dd4fe 100644 --- a/cores/esp8266/LwipDhcpServer.cpp +++ b/cores/esp8266/LwipDhcpServer.cpp @@ -50,6 +50,9 @@ #include "user_interface.h" #include "mem.h" +#include +#include + typedef struct dhcps_state { sint16_t state; @@ -78,12 +81,6 @@ struct dhcps_lease struct ipv4_addr end_ip; }; -enum dhcps_offer_option -{ - OFFER_START = 0x00, - OFFER_ROUTER = 0x01, - OFFER_END -}; #endif typedef enum @@ -107,7 +104,6 @@ struct dhcps_pool dhcps_state_t state; }; -#define DHCPS_LEASE_TIMER dhcps_lease_time // 0x05A0 #define DHCPS_MAX_LEASE 0x64 #define BOOTP_BROADCAST 0x8000 @@ -120,13 +116,13 @@ struct dhcps_pool #define DHCPS_SERVER_PORT 67 #define DHCPS_CLIENT_PORT 68 -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 +static constexpr uint8_t DHCPDISCOVER = 1; +static constexpr uint8_t DHCPOFFER = 2; +static constexpr uint8_t DHCPREQUEST = 3; +static constexpr uint8_t DHCPDECLINE = 4; +static constexpr uint8_t DHCPACK = 5; +static constexpr uint8_t DHCPNAK = 6; +static constexpr uint8_t DHCPRELEASE = 7; #define DHCP_OPTION_SUBNET_MASK 1 #define DHCP_OPTION_ROUTER 3 @@ -152,8 +148,6 @@ struct dhcps_pool #define DHCPS_STATE_IDLE 5 #define DHCPS_STATE_RELEASE 6 -#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) - #ifdef MEMLEAK_DEBUG const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif @@ -175,20 +169,35 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; //////////////////////////////////////////////////////////////////////////////////// -DhcpServer::DhcpServer(netif* netif) : _netif(netif) { } - -// wifi_softap_set_station_info is missing in user_interface.h: -extern "C" void wifi_softap_set_station_info(uint8_t* mac, struct ipv4_addr*); - -void DhcpServer::dhcps_set_dns(int num, const ipv4_addr_t* dns) +DhcpServer::OptionsBuffer& DhcpServer::OptionsBuffer::add(uint8_t code, const uint8_t* data, + size_t size) { - (void)num; - if (!ip4_addr_isany(dns)) + if (size >= UINT8_MAX) + { + return *this; + } + + if ((size_t)(_end - _it) < (size + 2)) { - ip4_addr_copy(dns_address, *dns); + return *this; } + + *_it++ = code; + *_it++ = size; + + memcpy_P(_it, data, size); + _it += size; + + return *this; } +//////////////////////////////////////////////////////////////////////////////////// + +DhcpServer::DhcpServer(netif* netif) : _netif(netif) { } + +// wifi_softap_set_station_info is missing in user_interface.h: +extern "C" void wifi_softap_set_station_info(uint8_t* mac, struct ipv4_addr*); + /****************************************************************************** FunctionName : node_insert_to_list Description : insert the node to the list @@ -286,8 +295,8 @@ bool DhcpServer::add_dhcps_lease(uint8* macaddr) struct dhcps_pool* pdhcps_pool = nullptr; list_node* pback_node = nullptr; - uint32 start_ip = dhcps_lease.start_ip.addr; - uint32 end_ip = dhcps_lease.end_ip.addr; + uint32 start_ip = lease.start_ip.addr; + uint32 end_ip = lease.end_ip.addr; for (pback_node = plist; pback_node != nullptr; pback_node = pback_node->pnext) { @@ -316,7 +325,7 @@ bool DhcpServer::add_dhcps_lease(uint8* macaddr) pdhcps_pool = (struct dhcps_pool*)zalloc(sizeof(struct dhcps_pool)); pdhcps_pool->ip.addr = start_ip; memcpy(pdhcps_pool->mac, macaddr, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pdhcps_pool->lease_timer = this->lease_time; pdhcps_pool->type = DHCPS_TYPE_STATIC; pdhcps_pool->state = DHCPS_STATE_ONLINE; pback_node = (list_node*)zalloc(sizeof(list_node)); @@ -329,145 +338,50 @@ bool DhcpServer::add_dhcps_lease(uint8* macaddr) /////////////////////////////////////////////////////////////////////////////////// /* - DHCP msg - - @param optptr -- DHCP msg - @param type -- option + Set DHCP msg offer options for the given server - @return uint8_t* DHCP msg + @param buffer -- DHCP options buffer + @param server -- DHCP server instance */ /////////////////////////////////////////////////////////////////////////////////// -uint8_t* DhcpServer::add_msg_type(uint8_t* optptr, uint8_t type) +void DhcpServer::add_offer_options(OptionsBuffer& options) { - *optptr++ = DHCP_OPTION_MSG_TYPE; - *optptr++ = 1; - *optptr++ = type; - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - DHCP msg offer + options.add(DHCP_OPTION_SUBNET_MASK, ip_2_ip4(&_netif->netmask)) + .add(DHCP_OPTION_SERVER_ID, ip_2_ip4(&_netif->ip_addr)); - @param optptr -- DHCP msg + // option units are seconds, while server opt is minutes + const uint32_t lease_time_seconds = lease_time * 60; + options.add(DHCP_OPTION_LEASE_TIME, lease_time_seconds); - @return uint8_t* DHCP msg -*/ -/////////////////////////////////////////////////////////////////////////////////// -uint8_t* DhcpServer::add_offer_options(uint8_t* optptr) -{ - // struct ipv4_addr ipadd; - // ipadd.addr = server_address.addr; -#define ipadd (_netif->ip_addr) - - // struct ip_info if_ip; - // bzero(&if_ip, sizeof(struct ip_info)); - // wifi_get_ip_info(SOFTAP_IF, &if_ip); -#define if_ip (*_netif) - - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; - *optptr++ = ip4_addr1(ip_2_ip4(&if_ip.netmask)); - *optptr++ = ip4_addr2(ip_2_ip4(&if_ip.netmask)); - *optptr++ = ip4_addr3(ip_2_ip4(&if_ip.netmask)); - *optptr++ = ip4_addr4(ip_2_ip4(&if_ip.netmask)); - - *optptr++ = DHCP_OPTION_LEASE_TIME; - *optptr++ = 4; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; - - *optptr++ = DHCP_OPTION_SERVER_ID; - *optptr++ = 4; - *optptr++ = ip4_addr1(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr2(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr3(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr4(ip_2_ip4(&ipadd)); - - if (dhcps_router_enabled(offer) && ip_2_ip4(&if_ip.gw)->addr) + if (offer_router && !ip4_addr_isany_val(*ip_2_ip4(&_netif->gw))) { - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1(ip_2_ip4(&if_ip.gw)); - *optptr++ = ip4_addr2(ip_2_ip4(&if_ip.gw)); - *optptr++ = ip4_addr3(ip_2_ip4(&if_ip.gw)); - *optptr++ = ip4_addr4(ip_2_ip4(&if_ip.gw)); + options.add(DHCP_OPTION_ROUTER, ip_2_ip4(&_netif->gw)); } #ifdef USE_DNS - *optptr++ = DHCP_OPTION_DNS_SERVER; - *optptr++ = 4; - if (dns_address.addr == 0) - { - *optptr++ = ip4_addr1(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr2(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr3(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr4(ip_2_ip4(&ipadd)); - } - else - { - *optptr++ = ip4_addr1(&dns_address); - *optptr++ = ip4_addr2(&dns_address); - *optptr++ = ip4_addr3(&dns_address); - *optptr++ = ip4_addr4(&dns_address); - } + options.add(DHCP_OPTION_DNS_SERVER, + !ip4_addr_isany_val(dns_address) ? &dns_address : ip_2_ip4(&_netif->ip_addr)); #endif - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - // XXXFIXME do better than that, we have netmask - *optptr++ = ip4_addr1(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr2(ip_2_ip4(&ipadd)); - *optptr++ = ip4_addr3(ip_2_ip4(&ipadd)); - *optptr++ = 255; - - *optptr++ = DHCP_OPTION_INTERFACE_MTU; - *optptr++ = 2; - *optptr++ = 0x05; - *optptr++ = 0xdc; // 1500 - - *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; - *optptr++ = 1; - *optptr++ = 0x00; - -#if 0 // vendor specific uninitialized (??) - *optptr++ = 43; // vendor specific - *optptr++ = 6; - // uninitialized ? -#endif + { + const auto* addr = ip_2_ip4(&_netif->ip_addr); + const auto* mask = ip_2_ip4(&_netif->netmask); + const auto broadcast = ip4_addr_t { .addr = (addr->addr & mask->addr) | ~mask->addr }; -#if 0 // already set (DHCP_OPTION_SUBNET_MASK==1) (??) - *optptr++ = 0x01; - *optptr++ = 4; - *optptr++ = 0; - *optptr++ = 0; - *optptr++ = 0; - *optptr++ = 2; -#endif + options.add(DHCP_OPTION_BROADCAST_ADDRESS, &broadcast); + } - return optptr; + // TODO: _netif->mtu ? + static constexpr uint16_t Mtu { 1500 }; + options.add(DHCP_OPTION_INTERFACE_MTU, Mtu); -#undef ipadd -#undef if_ip + static constexpr uint8_t RouterDiscovery { 0 }; + options.add(DHCP_OPTION_PERFORM_ROUTER_DISCOVERY, RouterDiscovery); } -/////////////////////////////////////////////////////////////////////////////////// -/* - DHCP msg - @param optptr -- DHCP msg - - @return uint8_t* DHCP msg -*/ -/////////////////////////////////////////////////////////////////////////////////// -uint8_t* DhcpServer::add_end(uint8_t* optptr) -{ - *optptr++ = DHCP_OPTION_END; - return optptr; -} /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// -void DhcpServer::create_msg(struct dhcps_msg* m) +DhcpServer::OptionsBuffer DhcpServer::create_msg(struct dhcps_msg* m) { struct ipv4_addr client; @@ -488,6 +402,8 @@ void DhcpServer::create_msg(struct dhcps_msg* m) memset((char*)m->file, 0, sizeof(m->file)); memset((char*)m->options, 0, sizeof(m->options)); memcpy((char*)m->options, &MagicCookie, sizeof(MagicCookie)); + + return { &m->options[sizeof(magic_cookie)], std::end(m->options) }; } /////////////////////////////////////////////////////////////////////////////////// /* @@ -498,16 +414,18 @@ void DhcpServer::create_msg(struct dhcps_msg* m) /////////////////////////////////////////////////////////////////////////////////// void DhcpServer::send_offer(struct dhcps_msg* m) { - uint8_t* end; struct pbuf *p, *q; - u8_t* data; - u16_t cnt = 0; - u16_t i; - create_msg(m); - end = add_msg_type(&m->options[4], DHCPOFFER); - end = add_offer_options(end); - end = add_end(end); + auto options = create_msg(m); + options.add(DHCP_OPTION_MSG_TYPE, DHCPOFFER); + + add_offer_options(options); + if (custom_offer_options) + { + custom_offer_options(*this, options); + } + + options.add(DHCP_OPTION_END); p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG @@ -523,12 +441,7 @@ void DhcpServer::send_offer(struct dhcps_msg* m) q = p; while (q != nullptr) { - data = (u8_t*)q->payload; - for (i = 0; i < q->len; i++) - { - data[i] = ((u8_t*)m)[cnt++]; - } - + std::memcpy((u8_t*)q->payload, reinterpret_cast(&m), q->len); q = q->next; } } @@ -562,15 +475,11 @@ void DhcpServer::send_offer(struct dhcps_msg* m) /////////////////////////////////////////////////////////////////////////////////// void DhcpServer::send_nak(struct dhcps_msg* m) { - u8_t* end; struct pbuf *p, *q; - u8_t* data; - u16_t cnt = 0; - u16_t i; - create_msg(m); - end = add_msg_type(&m->options[4], DHCPNAK); - end = add_end(end); + auto options = create_msg(m); + options.add(DHCP_OPTION_MSG_TYPE, DHCPNAK); + options.add(DHCP_OPTION_END); p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG @@ -586,12 +495,7 @@ void DhcpServer::send_nak(struct dhcps_msg* m) q = p; while (q != nullptr) { - data = (u8_t*)q->payload; - for (i = 0; i < q->len; i++) - { - data[i] = ((u8_t*)m)[cnt++]; - } - + std::memcpy((u8_t*)q->payload, (u8_t*)m, q->len); q = q->next; } } @@ -620,16 +524,18 @@ void DhcpServer::send_nak(struct dhcps_msg* m) /////////////////////////////////////////////////////////////////////////////////// void DhcpServer::send_ack(struct dhcps_msg* m) { - u8_t* end; struct pbuf *p, *q; - u8_t* data; - u16_t cnt = 0; - u16_t i; - create_msg(m); - end = add_msg_type(&m->options[4], DHCPACK); - end = add_offer_options(end); - end = add_end(end); + auto options = create_msg(m); + options.add(DHCP_OPTION_MSG_TYPE, DHCPACK); + + add_offer_options(options); + if (custom_offer_options) + { + custom_offer_options(*this, options); + } + + options.add(DHCP_OPTION_END); p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG @@ -645,12 +551,7 @@ void DhcpServer::send_ack(struct dhcps_msg* m) q = p; while (q != nullptr) { - data = (u8_t*)q->payload; - for (i = 0; i < q->len; i++) - { - data[i] = ((u8_t*)m)[cnt++]; - } - + std::memcpy((u8_t*)q->payload, (u8_t*)m, q->len); q = q->next; } } @@ -931,15 +832,15 @@ void DhcpServer::init_dhcps_lease(uint32 ip) uint32 softap_ip = 0, local_ip = 0; uint32 start_ip = 0; uint32 end_ip = 0; - if (dhcps_lease.enable == true) + if (lease.enable == true) { softap_ip = htonl(ip); - start_ip = htonl(dhcps_lease.start_ip.addr); - end_ip = htonl(dhcps_lease.end_ip.addr); + start_ip = htonl(lease.start_ip.addr); + end_ip = htonl(lease.end_ip.addr); /*config ip information can't contain local ip*/ if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { - dhcps_lease.enable = false; + lease.enable = false; } else { @@ -948,12 +849,12 @@ void DhcpServer::init_dhcps_lease(uint32 ip) if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) || (end_ip - start_ip > DHCPS_MAX_LEASE)) { - dhcps_lease.enable = false; + lease.enable = false; } } } - if (dhcps_lease.enable == false) + if (lease.enable == false) { local_ip = softap_ip = htonl(ip); softap_ip &= 0xFFFFFF00; @@ -967,15 +868,15 @@ void DhcpServer::init_dhcps_lease(uint32 ip) local_ip++; } - bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.addr = softap_ip | local_ip; - dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); - dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); - dhcps_lease.end_ip.addr = htonl(dhcps_lease.end_ip.addr); + bzero(&lease, sizeof(lease)); + lease.start_ip.addr = softap_ip | local_ip; + lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); + lease.start_ip.addr = htonl(lease.start_ip.addr); + lease.end_ip.addr = htonl(lease.end_ip.addr); } - // dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); - // dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); - // os_printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); + // lease.start_ip.addr = htonl(lease.start_ip.addr); + // lease.end_ip.addr= htonl(lease.end_ip.addr); + // os_printf("start_ip = 0x%x, end_ip = 0x%x\n",lease.start_ip, lease.end_ip); } /////////////////////////////////////////////////////////////////////////////////// @@ -1116,13 +1017,13 @@ bool DhcpServer::set_dhcps_lease(struct dhcps_lease* please) return false; } - bzero(&dhcps_lease, sizeof(dhcps_lease)); - // dhcps_lease.start_ip.addr = start_ip; - // dhcps_lease.end_ip.addr = end_ip; - dhcps_lease.start_ip.addr = please->start_ip.addr; - dhcps_lease.end_ip.addr = please->end_ip.addr; + bzero(&lease, sizeof(lease)); + // lease.start_ip.addr = start_ip; + // lease.end_ip.addr = end_ip; + lease.start_ip.addr = please->start_ip.addr; + lease.end_ip.addr = please->end_ip.addr; } - dhcps_lease.enable = please->enable; + lease.enable = please->enable; // dhcps_lease_flag = false; return true; } @@ -1151,7 +1052,7 @@ bool DhcpServer::get_dhcps_lease(struct dhcps_lease* please) } // if (dhcps_lease_flag){ - if (dhcps_lease.enable == false) + if (lease.enable == false) { if (isRunning()) { @@ -1160,20 +1061,20 @@ bool DhcpServer::get_dhcps_lease(struct dhcps_lease* please) } else { - // bzero(please, sizeof(dhcps_lease)); + // bzero(please, sizeof(*please)); // if (!isRunning()){ - // please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); - // please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); + // please->start_ip.addr = htonl(lease.start_ip.addr); + // please->end_ip.addr = htonl(lease.end_ip.addr); // } } // if (isRunning()){ - // bzero(please, sizeof(dhcps_lease)); - // please->start_ip.addr = dhcps_lease.start_ip.addr; - // please->end_ip.addr = dhcps_lease.end_ip.addr; + // bzero(please, sizeof(*please)); + // please->start_ip.addr = lease.start_ip.addr; + // please->end_ip.addr = lease.end_ip.addr; // } - please->start_ip.addr = dhcps_lease.start_ip.addr; - please->end_ip.addr = dhcps_lease.end_ip.addr; + please->start_ip.addr = lease.start_ip.addr; + please->end_ip.addr = lease.end_ip.addr; return true; } @@ -1243,81 +1144,6 @@ void DhcpServer::dhcps_coarse_tmr(void) } } -bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg) -{ - bool offer_flag = true; - // uint8 option = 0; - if (optarg == nullptr && !isRunning()) - { - return false; - } - - if (level <= OFFER_START || level >= OFFER_END) - { - return false; - } - - switch (level) - { - case OFFER_ROUTER: - offer = (*(uint8*)optarg) & 0x01; - offer_flag = true; - break; - default: - offer_flag = false; - break; - } - return offer_flag; -} - -bool DhcpServer::set_dhcps_lease_time(uint32 minute) -{ - if (_netif->num == SOFTAP_IF) - { - uint8 opmode = wifi_get_opmode(); - if (opmode == STATION_MODE || opmode == NULL_MODE) - { - return false; - } - } - - if (isRunning()) - { - return false; - } - - if (minute == 0) - { - return false; - } - dhcps_lease_time = minute; - return true; -} - -bool DhcpServer::reset_dhcps_lease_time(void) -{ - if (_netif->num == SOFTAP_IF) - { - uint8 opmode = wifi_get_opmode(); - if (opmode == STATION_MODE || opmode == NULL_MODE) - { - return false; - } - } - - if (isRunning()) - { - return false; - } - dhcps_lease_time = DefaultLeaseTime; - return true; -} - -uint32 DhcpServer::get_dhcps_lease_time(void) // minute -{ - return dhcps_lease_time; -} - void DhcpServer::dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force) { struct dhcps_pool* pdhcps_pool = nullptr; @@ -1374,8 +1200,8 @@ uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip) list_node* pmac_node = nullptr; list_node* pip_node = nullptr; bool flag = false; - uint32 start_ip = dhcps_lease.start_ip.addr; - uint32 end_ip = dhcps_lease.end_ip.addr; + uint32 start_ip = lease.start_ip.addr; + uint32 end_ip = lease.end_ip.addr; dhcps_type_t type = DHCPS_TYPE_DYNAMIC; if (bssid == nullptr) { @@ -1483,7 +1309,7 @@ uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip) type = DHCPS_TYPE_DYNAMIC; } - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pdhcps_pool->lease_timer = this->lease_time; pdhcps_pool->type = type; pdhcps_pool->state = DHCPS_STATE_ONLINE; } @@ -1504,7 +1330,7 @@ uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip) } node_remove_from_list(&plist, pmac_node); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pdhcps_pool->lease_timer = this->lease_time; pdhcps_pool->type = type; pdhcps_pool->state = DHCPS_STATE_ONLINE; node_insert_to_list(&plist, pmac_node); @@ -1520,7 +1346,7 @@ uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip) return IPADDR_ANY; } memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pdhcps_pool->lease_timer = this->lease_time; pdhcps_pool->type = type; pdhcps_pool->state = DHCPS_STATE_ONLINE; } @@ -1546,7 +1372,7 @@ uint32 DhcpServer::dhcps_client_update(u8* bssid, struct ipv4_addr* ip) return IPADDR_ANY; } memcpy(pdhcps_pool->mac, bssid, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pdhcps_pool->lease_timer = this->lease_time; pdhcps_pool->type = type; pdhcps_pool->state = DHCPS_STATE_ONLINE; pback_node = (list_node*)zalloc(sizeof(list_node)); diff --git a/cores/esp8266/LwipDhcpServer.h b/cores/esp8266/LwipDhcpServer.h index 3ec9263342..152e54c9e6 100644 --- a/cores/esp8266/LwipDhcpServer.h +++ b/cores/esp8266/LwipDhcpServer.h @@ -30,18 +30,141 @@ #pragma once -#include // LWIP_VERSION +#include + +#include +#include +#include + +#include +#include class DhcpServer { public: static constexpr int DefaultLeaseTime = 720; // minutes static constexpr uint32 MagicCookie = 0x63538263; // https://tools.ietf.org/html/rfc1497 - - DhcpServer(netif*); + // + struct OptionsBuffer + { + OptionsBuffer(uint8_t* begin, uint8_t* end) : _it(begin), _begin(begin), _end(end) { } + + OptionsBuffer& add(uint8_t code, const uint8_t* data, size_t size); + + OptionsBuffer& add(uint8_t code, const char* data, size_t size) + { + return add(code, reinterpret_cast(data), size); + } + + template + OptionsBuffer& add(uint8_t code, const char (&data)[Size]) + { + return add(code, &data[0], Size - 1); + } + + template + OptionsBuffer& add(uint8_t code, const uint8_t (&data)[Size]) + { + return add(code, &data[0], Size); + } + + OptionsBuffer& add(uint8_t code, std::initializer_list data) + { + return add(code, data.begin(), data.size()); + } + + OptionsBuffer& add(uint8_t code, const ip4_addr_t* addr) + { + return add(code, + { ip4_addr1(addr), ip4_addr2(addr), ip4_addr3(addr), ip4_addr4(addr) }); + } + + OptionsBuffer& add(uint8_t code, uint8_t value) + { + return add(code, { value }); + } + + OptionsBuffer& add(uint8_t code, uint16_t value) + { + return add(code, { static_cast((value >> 8) & 0xff), + static_cast(value & 0xff) }); + } + + OptionsBuffer& add(uint8_t code, uint32_t value) + { + return add(code, { static_cast((value >> 24) & 0xff), + static_cast((value >> 16) & 0xff), + static_cast((value >> 8) & 0xff), + static_cast((value & 0xff)) }); + } + + OptionsBuffer& add(uint8_t code) + { + if (_it != _end) + { + *_it++ = code; + } + return *this; + } + + private: + uint8_t* _it; + uint8_t* _begin; + uint8_t* _end; + }; + + using OptionsBufferHandler = void (*)(const DhcpServer&, OptionsBuffer&); + + DhcpServer(netif* netif); ~DhcpServer(); - void setDns(int num, const ipv4_addr_t* dns); + netif* getNetif() const + { + return _netif; + } + + void setRouter(bool value) + { + offer_router = value; + } + + bool getRouter() const + { + return offer_router; + } + + void setDns(ip4_addr_t addr) + { + dns_address = addr; + } + + ip4_addr_t getDns() const + { + return dns_address; + } + + void resetLeaseTime() + { + lease_time = DefaultLeaseTime; + } + + void setLeaseTime(uint32_t minutes) + { + lease_time = minutes; + } + + uint32_t getLeaseTime() const + { + return lease_time; + } + + // Will use provided callback for ACK and OFFER replies + // `options.add(...)` to append to the options list + // (does not check for duplicates!) + void onSendOptions(OptionsBufferHandler handler) + { + custom_offer_options = handler; + } bool begin(); void end(); @@ -54,18 +177,16 @@ class DhcpServer // legacy public C structure and API to eventually turn into C++ - void init_dhcps_lease(uint32 ip); - bool set_dhcps_lease(struct dhcps_lease* please); - bool get_dhcps_lease(struct dhcps_lease* please); - bool set_dhcps_offer_option(uint8 level, void* optarg); - bool set_dhcps_lease_time(uint32 minute); - bool reset_dhcps_lease_time(void); - uint32 get_dhcps_lease_time(void); - bool add_dhcps_lease(uint8* macaddr); + void init_dhcps_lease(uint32 ip); + bool set_dhcps_lease(struct dhcps_lease* please); + bool get_dhcps_lease(struct dhcps_lease* please); + bool add_dhcps_lease(uint8* macaddr); - void dhcps_set_dns(int num, const ipv4_addr_t* dns); + void offers(); protected: + void add_offer_options(OptionsBuffer&); + // legacy C structure and API to eventually turn into C++ typedef struct _list_node @@ -74,12 +195,11 @@ class DhcpServer struct _list_node* pnext; } list_node; - void node_insert_to_list(list_node** phead, list_node* pinsert); - void node_remove_from_list(list_node** phead, list_node* pdelete); - uint8_t* add_msg_type(uint8_t* optptr, uint8_t type); - uint8_t* add_offer_options(uint8_t* optptr); - uint8_t* add_end(uint8_t* optptr); - void create_msg(struct dhcps_msg* m); + void node_insert_to_list(list_node** phead, list_node* pinsert); + void node_remove_from_list(list_node** phead, list_node* pdelete); + + OptionsBuffer create_msg(struct dhcps_msg* m); + void send_offer(struct dhcps_msg* m); void send_nak(struct dhcps_msg* m); void send_ack(struct dhcps_msg* m); @@ -95,15 +215,22 @@ class DhcpServer netif* _netif = nullptr; - udp_pcb* pcb_dhcps = nullptr; - ip_addr_t broadcast_dhcps {}; - ipv4_addr server_address {}; - ipv4_addr client_address {}; - ipv4_addr dns_address {}; - uint32 dhcps_lease_time = DefaultLeaseTime; - - struct dhcps_lease dhcps_lease; - list_node* plist; - uint8 offer; - bool renew; + struct udp_pcb* pcb_dhcps = nullptr; + ip_addr_t broadcast_dhcps {}; + ip4_addr_t server_address {}; + ip4_addr_t client_address {}; + + uint32_t lease_time = DefaultLeaseTime; + + bool offer_router = true; + ip4_addr_t dns_address {}; + + dhcps_lease lease {}; + + list_node* plist = nullptr; + bool renew = false; + + OptionsBufferHandler custom_offer_options = nullptr; + + static const uint32 magic_cookie; }; diff --git a/libraries/ESP8266WiFi/examples/CustomOffer/CustomOffer.ino b/libraries/ESP8266WiFi/examples/CustomOffer/CustomOffer.ino new file mode 100644 index 0000000000..fa746277c9 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/CustomOffer/CustomOffer.ino @@ -0,0 +1,20 @@ +#include +#include + +void setup() { + auto& server = WiFi.softAPDhcpServer(); + server.onSendOptions([](const DhcpServer& server, auto& options) { + // VENDOR is... vendor specific + options.add(43, { 0xca, 0xfe, 0xca, 0xfe, 0xfe }); + + // Captive Portal URI + const IPAddress gateway = netif_ip4_addr(server.getNetif()); + const String captive = F("http://") + gateway.toString(); + options.add(114, captive.c_str(), captive.length()); + }); + WiFi.softAP("TEST", "testtesttest"); +} + +void loop() { + delay(100); +} diff --git a/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino b/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino index 3c9caee2fc..c431df572c 100644 --- a/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino +++ b/libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino @@ -52,10 +52,13 @@ void setup() { } Serial.printf("\nSTA: %s (dns: %s / %s)\n", WiFi.localIP().toString().c_str(), WiFi.dnsIP(0).toString().c_str(), WiFi.dnsIP(1).toString().c_str()); - // give DNS servers to AP side + // By default, DNS option will point to the interface IP + // Instead, point it to the real DNS server. + // Notice that: + // - DhcpServer class only supports IPv4 + // - Only a single IP can be set auto& server = WiFi.softAPDhcpServer(); - server.dhcps_set_dns(0, WiFi.dnsIP(0)); - server.dhcps_set_dns(1, WiFi.dnsIP(1)); + server.setDns(WiFi.dnsIP(0)); WiFi.softAPConfig( // enable AP, with android-compatible google domain IPAddress(172, 217, 28, 254), IPAddress(172, 217, 28, 254), IPAddress(255, 255, 255, 0)); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp index ffd536a0ba..2b7575d2f7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiAP.cpp @@ -176,9 +176,9 @@ bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* psk, int channel, if(ip.ip.addr == 0x00000000) { DEBUG_WIFI("[AP] IP config Invalid resetting...\n"); ret = softAPConfig( - 0x0104A8C0 /* 192.168.4.1 */, - 0x0104A8C0 /* 192.168.4.1 */, - 0x00FFFFFF /* 255.255.255.0 */); + IPAddress(192, 168, 4, 1), + IPAddress(192, 168, 4, 1), + IPAddress(255, 255, 255, 0)); if(!ret) { DEBUG_WIFI("[AP] softAPConfig failed!\n"); ret = false; @@ -227,9 +227,8 @@ bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPA info.gw.addr = gateway.v4(); info.netmask.addr = subnet.v4(); - if(!wifi_softap_dhcps_stop()) { - DEBUG_WIFI("[APConfig] wifi_softap_dhcps_stop failed!\n"); - } + auto& server = softAPDhcpServer(); + server.end(); if(!wifi_set_ip_info(SOFTAP_IF, &info)) { DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n"); @@ -247,24 +246,14 @@ bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPA dhcp_lease.end_ip.addr = ip.v4(); DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str()); - auto& server = softAPDhcpServer(); if(!server.set_dhcps_lease(&dhcp_lease)) { DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n"); ret = false; } - uint8 mode = info.gw.addr ? 1 : 0; - if(!server.set_dhcps_offer_option(OFFER_ROUTER, &mode)) - { - DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_offer_option failed!\n"); - ret = false; - } - - if(!wifi_softap_dhcps_start()) { - DEBUG_WIFI("[APConfig] wifi_softap_dhcps_start failed!\n"); - ret = false; - } + server.setRouter(true); // send ROUTER option with netif's gateway IP + server.begin(); // check config if(wifi_get_ip_info(SOFTAP_IF, &info)) { diff --git a/tests/host/common/DhcpServer.cpp b/tests/host/common/DhcpServer.cpp index 7e88ea88c4..c4f9dd158b 100644 --- a/tests/host/common/DhcpServer.cpp +++ b/tests/host/common/DhcpServer.cpp @@ -13,19 +13,6 @@ bool DhcpServer::set_dhcps_lease(struct dhcps_lease* please) return false; } -bool DhcpServer::set_dhcps_lease_time(uint32 minute) -{ - (void)minute; - return false; -} - -bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg) -{ - (void)level; - (void)optarg; - return false; -} - void DhcpServer::end() { } bool DhcpServer::begin() @@ -64,17 +51,4 @@ extern "C" (void)please; return true; } - - bool wifi_softap_set_dhcps_lease_time(uint32 minute) - { - (void)minute; - return true; - } - - bool wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) - { - (void)level; - (void)optarg; - return true; - } } diff --git a/tests/restyle.sh b/tests/restyle.sh index 5460ca25a0..fb3df24dba 100755 --- a/tests/restyle.sh +++ b/tests/restyle.sh @@ -54,11 +54,13 @@ done # TODO should not be matched, these are formatted externally # exclude=$(git submodule --quiet foreach git rev-parse --show-toplevel | grep libraries) -style=$(makeClangFormatStyle ${root}/tests/clang-format-arduino.yaml) -find libraries \ - -path libraries/ESP8266SdFat -prune -o \ - -path libraries/Ethernet -prune -o \ - -path libraries/SoftwareSerial -prune -o \ - -name '*.ino' -exec $CLANG_FORMAT --verbose --style="$style" -i {} \; +if [ -z $1 ] ; then + style=$(makeClangFormatStyle ${root}/tests/clang-format-arduino.yaml) + find libraries \ + -path libraries/ESP8266SdFat -prune -o \ + -path libraries/Ethernet -prune -o \ + -path libraries/SoftwareSerial -prune -o \ + -name '*.ino' -exec $CLANG_FORMAT --verbose --style="$style" -i {} \; +fi ######################################### diff --git a/tools/sdk/lwip2/include/lwip/arch.h b/tools/sdk/lwip2/include/lwip/arch.h index 58dae33aa1..16add89824 100644 --- a/tools/sdk/lwip2/include/lwip/arch.h +++ b/tools/sdk/lwip2/include/lwip/arch.h @@ -190,7 +190,7 @@ typedef uintptr_t mem_ptr_t; * sys/types or unistd.h are available). * Being like that, we define it to 'int' if SSIZE_MAX is not defined. */ -#ifdef SSIZE_MAX +#if !defined(SSIZE_MAX) || !defined(_SSIZE_T_DECLARED) /* If SSIZE_MAX is defined, unistd.h should provide the type as well */ #ifndef LWIP_NO_UNISTD_H #define LWIP_NO_UNISTD_H 0