mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01: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:
parent
cd57469e06
commit
d42f35de5d
11 changed files with 112 additions and 20 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue