From 96b59af98387f9f1d84b05c3a8c7cf0d5e016ed2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:42:07 -1000 Subject: [PATCH 1/3] all 3 --- esphome/components/socket/socket.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/esphome/components/socket/socket.cpp b/esphome/components/socket/socket.cpp index e5b0579b02..b81d05155e 100644 --- a/esphome/components/socket/socket.cpp +++ b/esphome/components/socket/socket.cpp @@ -15,10 +15,15 @@ static size_t format_sockaddr_to(const struct sockaddr_storage &storage, std::sp if (storage.ss_family == AF_INET) { const auto *addr = reinterpret_cast(&storage); #ifdef USE_SOCKET_IMPL_LWIP_TCP - // LWIP raw TCP only has inet_ntoa_r, not inet_ntop + // LWIP raw TCP (ESP8266) uses inet_ntoa_r inet_ntoa_r(addr->sin_addr, buf.data(), buf.size()); return strlen(buf.data()); +#elif defined(USE_SOCKET_IMPL_LWIP_SOCKETS) + // LWIP sockets (LibreTiny, ESP32 Arduino) uses lwip_inet_ntop + if (lwip_inet_ntop(AF_INET, &addr->sin_addr, buf.data(), buf.size()) != nullptr) + return strlen(buf.data()); #else + // BSD sockets (host, ESP32-IDF) if (inet_ntop(AF_INET, &addr->sin_addr, buf.data(), buf.size()) != nullptr) return strlen(buf.data()); #endif @@ -27,11 +32,20 @@ static size_t format_sockaddr_to(const struct sockaddr_storage &storage, std::sp else if (storage.ss_family == AF_INET6) { const auto *addr = reinterpret_cast(&storage); #ifdef USE_SOCKET_IMPL_LWIP_TCP - // LWIP raw TCP uses inet6_ntoa_r + // LWIP raw TCP (ESP8266) uses inet6_ntoa_r inet6_ntoa_r(addr->sin6_addr, buf.data(), buf.size()); return strlen(buf.data()); +#elif defined(USE_SOCKET_IMPL_LWIP_SOCKETS) + // LWIP sockets - format IPv4-mapped IPv6 as IPv4 + if (addr->sin6_addr.un.u32_addr[0] == 0 && addr->sin6_addr.un.u32_addr[1] == 0 && + addr->sin6_addr.un.u32_addr[2] == htonl(0xFFFF) && + lwip_inet_ntop(AF_INET, &addr->sin6_addr.un.u32_addr[3], buf.data(), buf.size()) != nullptr) { + return strlen(buf.data()); + } + if (lwip_inet_ntop(AF_INET6, &addr->sin6_addr, buf.data(), buf.size()) != nullptr) + return strlen(buf.data()); #else - // Format IPv4-mapped IPv6 addresses as regular IPv4 addresses + // BSD sockets - format IPv4-mapped IPv6 as IPv4 if (addr->sin6_addr.un.u32_addr[0] == 0 && addr->sin6_addr.un.u32_addr[1] == 0 && addr->sin6_addr.un.u32_addr[2] == htonl(0xFFFF) && inet_ntop(AF_INET, &addr->sin6_addr.un.u32_addr[3], buf.data(), buf.size()) != nullptr) { From 591b5fa25babdb2c21ca701e0c09470d07f04b2f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:45:27 -1000 Subject: [PATCH 2/3] all 3 --- esphome/components/socket/socket.cpp | 71 ++++++++++++++++------------ 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/esphome/components/socket/socket.cpp b/esphome/components/socket/socket.cpp index b81d05155e..8722e11158 100644 --- a/esphome/components/socket/socket.cpp +++ b/esphome/components/socket/socket.cpp @@ -10,50 +10,61 @@ namespace esphome::socket { Socket::~Socket() {} +// Platform-specific inet_ntop wrappers +#ifdef USE_SOCKET_IMPL_LWIP_TCP +// LWIP raw TCP (ESP8266) uses inet_ntoa_r which takes struct by value +static inline const char *esphome_inet_ntop4(const void *addr, char *buf, size_t size) { + inet_ntoa_r(*reinterpret_cast(addr), buf, size); + return buf; +} +#if USE_NETWORK_IPV6 +static inline const char *esphome_inet_ntop6(const void *addr, char *buf, size_t size) { + inet6_ntoa_r(*reinterpret_cast(addr), buf, size); + return buf; +} +#endif +#elif defined(USE_SOCKET_IMPL_LWIP_SOCKETS) +// LWIP sockets (LibreTiny, ESP32 Arduino) +static inline const char *esphome_inet_ntop4(const void *addr, char *buf, size_t size) { + return lwip_inet_ntop(AF_INET, addr, buf, size); +} +#if USE_NETWORK_IPV6 +static inline const char *esphome_inet_ntop6(const void *addr, char *buf, size_t size) { + return lwip_inet_ntop(AF_INET6, addr, buf, size); +} +#endif +#else +// BSD sockets (host, ESP32-IDF) +static inline const char *esphome_inet_ntop4(const void *addr, char *buf, size_t size) { + return inet_ntop(AF_INET, addr, buf, size); +} +#if USE_NETWORK_IPV6 +static inline const char *esphome_inet_ntop6(const void *addr, char *buf, size_t size) { + return inet_ntop(AF_INET6, addr, buf, size); +} +#endif +#endif + // Format sockaddr into caller-provided buffer, returns length written (excluding null) static size_t format_sockaddr_to(const struct sockaddr_storage &storage, std::span buf) { if (storage.ss_family == AF_INET) { const auto *addr = reinterpret_cast(&storage); -#ifdef USE_SOCKET_IMPL_LWIP_TCP - // LWIP raw TCP (ESP8266) uses inet_ntoa_r - inet_ntoa_r(addr->sin_addr, buf.data(), buf.size()); - return strlen(buf.data()); -#elif defined(USE_SOCKET_IMPL_LWIP_SOCKETS) - // LWIP sockets (LibreTiny, ESP32 Arduino) uses lwip_inet_ntop - if (lwip_inet_ntop(AF_INET, &addr->sin_addr, buf.data(), buf.size()) != nullptr) + if (esphome_inet_ntop4(&addr->sin_addr, buf.data(), buf.size()) != nullptr) return strlen(buf.data()); -#else - // BSD sockets (host, ESP32-IDF) - if (inet_ntop(AF_INET, &addr->sin_addr, buf.data(), buf.size()) != nullptr) - return strlen(buf.data()); -#endif } #if USE_NETWORK_IPV6 else if (storage.ss_family == AF_INET6) { const auto *addr = reinterpret_cast(&storage); -#ifdef USE_SOCKET_IMPL_LWIP_TCP - // LWIP raw TCP (ESP8266) uses inet6_ntoa_r - inet6_ntoa_r(addr->sin6_addr, buf.data(), buf.size()); - return strlen(buf.data()); -#elif defined(USE_SOCKET_IMPL_LWIP_SOCKETS) - // LWIP sockets - format IPv4-mapped IPv6 as IPv4 +#ifndef USE_SOCKET_IMPL_LWIP_TCP + // Format IPv4-mapped IPv6 addresses as regular IPv4 (not supported on ESP8266 raw TCP) if (addr->sin6_addr.un.u32_addr[0] == 0 && addr->sin6_addr.un.u32_addr[1] == 0 && addr->sin6_addr.un.u32_addr[2] == htonl(0xFFFF) && - lwip_inet_ntop(AF_INET, &addr->sin6_addr.un.u32_addr[3], buf.data(), buf.size()) != nullptr) { + esphome_inet_ntop4(&addr->sin6_addr.un.u32_addr[3], buf.data(), buf.size()) != nullptr) { return strlen(buf.data()); } - if (lwip_inet_ntop(AF_INET6, &addr->sin6_addr, buf.data(), buf.size()) != nullptr) - return strlen(buf.data()); -#else - // BSD sockets - format IPv4-mapped IPv6 as IPv4 - if (addr->sin6_addr.un.u32_addr[0] == 0 && addr->sin6_addr.un.u32_addr[1] == 0 && - addr->sin6_addr.un.u32_addr[2] == htonl(0xFFFF) && - inet_ntop(AF_INET, &addr->sin6_addr.un.u32_addr[3], buf.data(), buf.size()) != nullptr) { - return strlen(buf.data()); - } - if (inet_ntop(AF_INET6, &addr->sin6_addr, buf.data(), buf.size()) != nullptr) - return strlen(buf.data()); #endif + if (esphome_inet_ntop6(&addr->sin6_addr, buf.data(), buf.size()) != nullptr) + return strlen(buf.data()); } #endif buf[0] = '\0'; From aa30a1d008f0cbde6e4c7c2260b0426d5b121dff Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 4 Jan 2026 11:47:34 -1000 Subject: [PATCH 3/3] all 3 --- esphome/components/socket/socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/socket/socket.cpp b/esphome/components/socket/socket.cpp index 8722e11158..c92e33393b 100644 --- a/esphome/components/socket/socket.cpp +++ b/esphome/components/socket/socket.cpp @@ -11,7 +11,7 @@ namespace esphome::socket { Socket::~Socket() {} // Platform-specific inet_ntop wrappers -#ifdef USE_SOCKET_IMPL_LWIP_TCP +#if defined(USE_SOCKET_IMPL_LWIP_TCP) // LWIP raw TCP (ESP8266) uses inet_ntoa_r which takes struct by value static inline const char *esphome_inet_ntop4(const void *addr, char *buf, size_t size) { inet_ntoa_r(*reinterpret_cast(addr), buf, size);