mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Wrap ipv6 code a bit more (#4574)
* Wrap ipv6 code a bit more for when ipv6 support should not be compiled in * More checks * More uses * Fix
This commit is contained in:
		| @@ -45,7 +45,7 @@ void APIServer::setup() { | ||||
|  | ||||
|   struct sockaddr_storage server; | ||||
|  | ||||
|   socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), htons(this->port_)); | ||||
|   socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), this->port_); | ||||
|   if (sl == 0) { | ||||
|     ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno); | ||||
|     this->mark_failed(); | ||||
|   | ||||
| @@ -255,14 +255,22 @@ void EthernetComponent::start_connect_() { | ||||
|   if (this->manual_ip_.has_value()) { | ||||
|     if (uint32_t(this->manual_ip_->dns1) != 0) { | ||||
|       ip_addr_t d; | ||||
| #if LWIP_IPV6 | ||||
|       d.type = IPADDR_TYPE_V4; | ||||
|       d.u_addr.ip4.addr = static_cast<uint32_t>(this->manual_ip_->dns1); | ||||
| #else | ||||
|       d.addr = static_cast<uint32_t>(this->manual_ip_->dns1); | ||||
| #endif | ||||
|       dns_setserver(0, &d); | ||||
|     } | ||||
|     if (uint32_t(this->manual_ip_->dns1) != 0) { | ||||
|       ip_addr_t d; | ||||
| #if LWIP_IPV6 | ||||
|       d.type = IPADDR_TYPE_V4; | ||||
|       d.u_addr.ip4.addr = static_cast<uint32_t>(this->manual_ip_->dns2); | ||||
| #else | ||||
|       d.addr = static_cast<uint32_t>(this->manual_ip_->dns2); | ||||
| #endif | ||||
|       dns_setserver(1, &d); | ||||
|     } | ||||
|   } else { | ||||
| @@ -289,8 +297,13 @@ void EthernetComponent::dump_connect_params_() { | ||||
|   const ip_addr_t *dns_ip1 = dns_getserver(0); | ||||
|   const ip_addr_t *dns_ip2 = dns_getserver(1); | ||||
|  | ||||
| #if LWIP_IPV6 | ||||
|   ESP_LOGCONFIG(TAG, "  DNS1: %s", network::IPAddress(dns_ip1->u_addr.ip4.addr).str().c_str()); | ||||
|   ESP_LOGCONFIG(TAG, "  DNS2: %s", network::IPAddress(dns_ip2->u_addr.ip4.addr).str().c_str()); | ||||
| #else | ||||
|   ESP_LOGCONFIG(TAG, "  DNS1: %s", network::IPAddress(dns_ip1->addr).str().c_str()); | ||||
|   ESP_LOGCONFIG(TAG, "  DNS2: %s", network::IPAddress(dns_ip2->addr).str().c_str()); | ||||
| #endif | ||||
|  | ||||
|   esp_err_t err; | ||||
|  | ||||
|   | ||||
| @@ -2,16 +2,16 @@ | ||||
|  | ||||
| #ifdef USE_MQTT | ||||
|  | ||||
| #include <utility> | ||||
| #include "esphome/components/network/util.h" | ||||
| #include "esphome/core/application.h" | ||||
| #include "esphome/core/helpers.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/components/network/util.h" | ||||
| #include <utility> | ||||
| #ifdef USE_LOGGER | ||||
| #include "esphome/components/logger/logger.h" | ||||
| #endif | ||||
| #include "lwip/err.h" | ||||
| #include "lwip/dns.h" | ||||
| #include "lwip/err.h" | ||||
| #include "mqtt_component.h" | ||||
|  | ||||
| namespace esphome { | ||||
| @@ -104,7 +104,11 @@ void MQTTClientComponent::start_dnslookup_() { | ||||
|       // Got IP immediately | ||||
|       this->dns_resolved_ = true; | ||||
| #ifdef USE_ESP32 | ||||
| #if LWIP_IPV6 | ||||
|       this->ip_ = addr.u_addr.ip4.addr; | ||||
| #else | ||||
|       this->ip_ = addr.addr; | ||||
| #endif | ||||
| #endif | ||||
| #ifdef USE_ESP8266 | ||||
|       this->ip_ = addr.addr; | ||||
| @@ -160,8 +164,12 @@ void MQTTClientComponent::dns_found_callback(const char *name, const ip_addr_t * | ||||
|     a_this->dns_resolve_error_ = true; | ||||
|   } else { | ||||
| #ifdef USE_ESP32 | ||||
| #if LWIP_IPV6 | ||||
|     a_this->ip_ = ipaddr->u_addr.ip4.addr; | ||||
| #else | ||||
|     a_this->ip_ = ipaddr->addr; | ||||
| #endif | ||||
| #endif  // USE_ESP32 | ||||
| #ifdef USE_ESP8266 | ||||
|     a_this->ip_ = ipaddr->addr; | ||||
| #endif | ||||
|   | ||||
| @@ -22,6 +22,8 @@ CONFIG_SCHEMA = cv.Schema( | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     if CONF_ENABLE_IPV6 in config and config[CONF_ENABLE_IPV6]: | ||||
|         add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", True) | ||||
|         add_idf_sdkconfig_option("CONFIG_LWIP_IPV6_AUTOCONFIG", True) | ||||
|     if CONF_ENABLE_IPV6 in config: | ||||
|         add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) | ||||
|         add_idf_sdkconfig_option( | ||||
|             "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] | ||||
|         ) | ||||
|   | ||||
| @@ -65,7 +65,7 @@ void OTAComponent::setup() { | ||||
|  | ||||
|   struct sockaddr_storage server; | ||||
|  | ||||
|   socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), htons(this->port_)); | ||||
|   socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), this->port_); | ||||
|   if (sl == 0) { | ||||
|     ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno); | ||||
|     this->mark_failed(); | ||||
|   | ||||
| @@ -20,7 +20,9 @@ std::string format_sockaddr(const struct sockaddr_storage &storage) { | ||||
|     char buf[INET_ADDRSTRLEN]; | ||||
|     if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) != nullptr) | ||||
|       return std::string{buf}; | ||||
|   } else if (storage.ss_family == AF_INET6) { | ||||
|   } | ||||
| #if LWIP_IPV6 | ||||
|   else if (storage.ss_family == AF_INET6) { | ||||
|     const struct sockaddr_in6 *addr = reinterpret_cast<const struct sockaddr_in6 *>(&storage); | ||||
|     char buf[INET6_ADDRSTRLEN]; | ||||
|     // Format IPv4-mapped IPv6 addresses as regular IPv4 addresses | ||||
| @@ -32,6 +34,7 @@ std::string format_sockaddr(const struct sockaddr_storage &storage) { | ||||
|     if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) != nullptr) | ||||
|       return std::string{buf}; | ||||
|   } | ||||
| #endif | ||||
|   return {}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -15,19 +15,28 @@ | ||||
| /* Address families.  */ | ||||
| #define AF_UNSPEC 0 | ||||
| #define AF_INET 2 | ||||
| #define AF_INET6 10 | ||||
| #define PF_INET AF_INET | ||||
| #define PF_INET6 AF_INET6 | ||||
| #define PF_UNSPEC AF_UNSPEC | ||||
|  | ||||
| #define IPPROTO_IP 0 | ||||
| #define IPPROTO_TCP 6 | ||||
|  | ||||
| #if LWIP_IPV6 | ||||
| #define AF_INET6 10 | ||||
| #define PF_INET6 AF_INET6 | ||||
|  | ||||
| #define IPPROTO_IPV6 41 | ||||
| #define IPPROTO_ICMPV6 58 | ||||
| #endif | ||||
|  | ||||
| #define TCP_NODELAY 0x01 | ||||
|  | ||||
| #define F_GETFL 3 | ||||
| #define F_SETFL 4 | ||||
|  | ||||
| #ifdef O_NONBLOCK | ||||
| #undef O_NONBLOCK | ||||
| #endif | ||||
| #define O_NONBLOCK 1 | ||||
|  | ||||
| #define SHUT_RD 0 | ||||
| @@ -58,6 +67,7 @@ struct sockaddr_in { | ||||
|   char sin_zero[SIN_ZERO_LEN]; | ||||
| }; | ||||
|  | ||||
| #if LWIP_IPV6 | ||||
| // NOLINTNEXTLINE(readability-identifier-naming) | ||||
| struct sockaddr_in6 { | ||||
|   uint8_t sin6_len;          /* length of this structure    */ | ||||
| @@ -67,6 +77,7 @@ struct sockaddr_in6 { | ||||
|   struct in6_addr sin6_addr; /* IPv6 address                */ | ||||
|   uint32_t sin6_scope_id;    /* Set of interfaces for scope */ | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| // NOLINTNEXTLINE(readability-identifier-naming) | ||||
| struct sockaddr { | ||||
|   | ||||
| @@ -14,6 +14,34 @@ std::unique_ptr<Socket> socket_ip(int type, int protocol) { | ||||
| #endif | ||||
| } | ||||
|  | ||||
| socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const char *ip_address, uint16_t port) { | ||||
| #if LWIP_IPV6 | ||||
|   if (addrlen < sizeof(sockaddr_in6)) { | ||||
|     errno = EINVAL; | ||||
|     return 0; | ||||
|   } | ||||
|   auto *server = reinterpret_cast<sockaddr_in6 *>(addr); | ||||
|   memset(server, 0, sizeof(sockaddr_in6)); | ||||
|   server->sin6_family = AF_INET6; | ||||
|   server->sin6_port = htons(port); | ||||
|   ip6_addr_t ip6; | ||||
|   inet6_aton(ip_address, &ip6); | ||||
|   memcpy(server->sin6_addr.un.u32_addr, ip6.addr, sizeof(ip6.addr)); | ||||
|   return sizeof(sockaddr_in6); | ||||
| #else | ||||
|   if (addrlen < sizeof(sockaddr_in)) { | ||||
|     errno = EINVAL; | ||||
|     return 0; | ||||
|   } | ||||
|   auto *server = reinterpret_cast<sockaddr_in *>(addr); | ||||
|   memset(server, 0, sizeof(sockaddr_in)); | ||||
|   server->sin_family = AF_INET; | ||||
|   server->sin_addr.s_addr = inet_addr(ip_address); | ||||
|   server->sin_port = htons(port); | ||||
|   return sizeof(sockaddr_in); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port) { | ||||
| #if LWIP_IPV6 | ||||
|   if (addrlen < sizeof(sockaddr_in6)) { | ||||
| @@ -23,7 +51,7 @@ socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t po | ||||
|   auto *server = reinterpret_cast<sockaddr_in6 *>(addr); | ||||
|   memset(server, 0, sizeof(sockaddr_in6)); | ||||
|   server->sin6_family = AF_INET6; | ||||
|   server->sin6_port = port; | ||||
|   server->sin6_port = htons(port); | ||||
|   server->sin6_addr = in6addr_any; | ||||
|   return sizeof(sockaddr_in6); | ||||
| #else | ||||
| @@ -35,7 +63,7 @@ socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t po | ||||
|   memset(server, 0, sizeof(sockaddr_in)); | ||||
|   server->sin_family = AF_INET; | ||||
|   server->sin_addr.s_addr = ESPHOME_INADDR_ANY; | ||||
|   server->sin_port = port; | ||||
|   server->sin_port = htons(port); | ||||
|   return sizeof(sockaddr_in); | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -44,7 +44,10 @@ std::unique_ptr<Socket> socket(int domain, int type, int protocol); | ||||
| /// Create a socket in the newest available IP domain (IPv6 or IPv4) of the given type and protocol. | ||||
| std::unique_ptr<Socket> socket_ip(int type, int protocol); | ||||
|  | ||||
| /// Set a sockaddr to the any address for the IP version used by socket_ip(). | ||||
| /// Set a sockaddr to the specified address and port for the IP version used by socket_ip(). | ||||
| socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const char *ip_address, uint16_t port); | ||||
|  | ||||
| /// Set a sockaddr to the any address and specified port for the IP version used by socket_ip(). | ||||
| socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port); | ||||
|  | ||||
| }  // namespace socket | ||||
|   | ||||
| @@ -4,19 +4,19 @@ | ||||
|  | ||||
| #include <esp_wifi.h> | ||||
|  | ||||
| #include <utility> | ||||
| #include <algorithm> | ||||
| #include <utility> | ||||
| #ifdef USE_WIFI_WPA2_EAP | ||||
| #include <esp_wpa2.h> | ||||
| #endif | ||||
| #include "lwip/err.h" | ||||
| #include "lwip/dns.h" | ||||
| #include "lwip/apps/sntp.h" | ||||
| #include "lwip/dns.h" | ||||
| #include "lwip/err.h" | ||||
|  | ||||
| #include "esphome/core/application.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/helpers.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/application.h" | ||||
| #include "esphome/core/util.h" | ||||
|  | ||||
| namespace esphome { | ||||
| @@ -128,13 +128,23 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) { | ||||
|   } | ||||
|  | ||||
|   ip_addr_t dns; | ||||
| #if LWIP_IPV6 | ||||
|   dns.type = IPADDR_TYPE_V4; | ||||
| #endif | ||||
|   if (uint32_t(manual_ip->dns1) != 0) { | ||||
| #if LWIP_IPV6 | ||||
|     dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns1); | ||||
| #else | ||||
|     dns.addr = static_cast<uint32_t>(manual_ip->dns1); | ||||
| #endif | ||||
|     dns_setserver(0, &dns); | ||||
|   } | ||||
|   if (uint32_t(manual_ip->dns2) != 0) { | ||||
| #if LWIP_IPV6 | ||||
|     dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns2); | ||||
| #else | ||||
|     dns.addr = static_cast<uint32_t>(manual_ip->dns2); | ||||
| #endif | ||||
|     dns_setserver(1, &dns); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -451,13 +451,23 @@ bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) { | ||||
|   } | ||||
|  | ||||
|   ip_addr_t dns; | ||||
| #if LWIP_IPV6 | ||||
|   dns.type = IPADDR_TYPE_V4; | ||||
| #endif | ||||
|   if (uint32_t(manual_ip->dns1) != 0) { | ||||
| #if LWIP_IPV6 | ||||
|     dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns1); | ||||
| #else | ||||
|     dns.addr = static_cast<uint32_t>(manual_ip->dns1); | ||||
| #endif | ||||
|     dns_setserver(0, &dns); | ||||
|   } | ||||
|   if (uint32_t(manual_ip->dns2) != 0) { | ||||
| #if LWIP_IPV6 | ||||
|     dns.u_addr.ip4.addr = static_cast<uint32_t>(manual_ip->dns2); | ||||
| #else | ||||
|     dns.addr = static_cast<uint32_t>(manual_ip->dns2); | ||||
| #endif | ||||
|     dns_setserver(1, &dns); | ||||
|   } | ||||
|  | ||||
| @@ -639,7 +649,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { | ||||
|  | ||||
|   } else if (data->event_base == IP_EVENT && data->event_id == IP_EVENT_STA_GOT_IP) { | ||||
|     const auto &it = data->data.ip_got_ip; | ||||
| #ifdef LWIP_IPV6_AUTOCONFIG | ||||
| #if LWIP_IPV6_AUTOCONFIG | ||||
|     tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); | ||||
| #endif | ||||
|     ESP_LOGV(TAG, "Event: Got IP static_ip=%s gateway=%s", format_ip4_addr(it.ip_info.ip).c_str(), | ||||
| @@ -912,7 +922,11 @@ network::IPAddress WiFiComponent::wifi_gateway_ip_() { | ||||
| } | ||||
| network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { | ||||
|   const ip_addr_t *dns_ip = dns_getserver(num); | ||||
| #if LWIP_IPV6 | ||||
|   return {dns_ip->u_addr.ip4.addr}; | ||||
| #else | ||||
|   return {dns_ip->addr}; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| }  // namespace wifi | ||||
|   | ||||
		Reference in New Issue
	
	Block a user