IP stack compatible with new Core3 IPv6 implementation (#20509)

* IP stack compatible with new Core3 IPv6 implementation

* Fix compilation

* Forece CI
This commit is contained in:
s-hadinger 2024-01-15 21:05:40 +01:00 committed by GitHub
parent d0a9f0d15d
commit 9045a7da83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 69 deletions

View File

@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
### Breaking Changed
### Changed
- IP stack compatible with new Core3 IPv6 implementation ()
### Fixed
- Scripter memory leak in `>w x` (#20473)

View File

@ -89,10 +89,12 @@ void WiFiClass32::scrubDNS(void) {
const IPAddress ip_dns = IPAddress(dns_getserver(i));
// Step 1. save valid values from DNS
if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) {
if (ip_dns.isV4() && has_v4) {
dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot
} else if (ip_dns.isV6() && has_v6) {
dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 slot
if (ip_dns.type() == IPv4 && has_v4) {
ip_dns.to_ip_addr_t(&dns_save4[i]);
// dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot
} else if (has_v6) {
ip_dns.to_ip_addr_t(&dns_save6[i]);
// dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 slot
}
}
@ -213,7 +215,7 @@ static void wifi32_dns_found_callback(const char *name, const ip_addr_t *ipaddr,
}
// We need this helper method to access protected methods from WiFiGeneric
void WiFiClass32::dnsDone(void) {
setStatusBits(WIFI_DNS_DONE_BIT);
setStatusBits(NET_DNS_DONE_BIT);
}
/**
@ -231,7 +233,7 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t
scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use
ip_addr_counter++; // increase counter, from now ignore previous responses
clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT);
clearStatusBits(NET_DNS_IDLE_BIT | NET_DNS_DONE_BIT);
uint8_t v4v6priority = LWIP_DNS_ADDRTYPE_IPV4;
#ifdef USE_IPV6
v4v6priority = WifiDNSGetIPv6Priority() ? LWIP_DNS_ADDRTYPE_IPV6_IPV4 : LWIP_DNS_ADDRTYPE_IPV4_IPV6;
@ -240,18 +242,18 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t
// Serial.printf("DNS: dns_gethostbyname_addrtype errg=%i counter=%i\n", err, ip_addr_counter);
if(err == ERR_OK && !ip_addr_isany_val(dns_ipaddr)) {
#ifdef USE_IPV6
aResult = dns_ipaddr;
aResult.from_ip_addr_t(&dns_ipaddr);
#else // USE_IPV6
aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
#endif // USE_IPV6
} else if(err == ERR_INPROGRESS) {
waitStatusBits(WIFI_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s]
clearStatusBits(WIFI_DNS_DONE_BIT);
waitStatusBits(NET_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s]
clearStatusBits(NET_DNS_DONE_BIT);
}
if (!ip_addr_isany_val(dns_ipaddr)) {
#ifdef USE_IPV6
aResult = dns_ipaddr;
aResult.from_ip_addr_t(&dns_ipaddr);
#else // USE_IPV6
aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
#endif // USE_IPV6

View File

@ -32,12 +32,14 @@ extern "C" const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len)
IPAddress ip;
if (ip.fromString(ip_str)) {
#ifdef USE_IPV6
if (ip.isV4()) {
if (ip.type() == IPv4) {
uint32_t ip_32 = ip;
memcpy(ip_bytes, &ip_32, 4);
*ret_len = 4;
} else {
memcpy(ip_bytes, ip.raw6(), 16);
ip_addr_t ip_addr;
ip.to_ip_addr_t(&ip_addr);
memcpy(ip_bytes, &ip_addr.u_addr.ip6, 16);
*ret_len = 16;
}
#else

View File

@ -209,7 +209,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) {
WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
#if defined(USE_IPV6) && defined(ESP32)
WiFi.IPv6(true);
WiFi.enableIPv6(true);
#endif
#ifdef USE_WIFI_RANGE_EXTENDER
@ -545,6 +545,11 @@ String EthernetGetIPv4Str(void)
}
#ifdef USE_IPV6
bool IPv6isLocal(const IPAddress & ip) {
return ip.addr_type() == ESP_IP6_ADDR_IS_LINK_LOCAL; // TODO
}
#include "lwip/netif.h"
//
// Scan through all interfaces to find a global or local IPv6 address
// Arg:
@ -557,7 +562,7 @@ bool WifiFindIPv6(IPAddress *ip, bool is_local, const char * if_type = "st") {
for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
ip_addr_t *ipv6 = &intf->ip6_addr[i];
if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && !ip_addr_isany(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) {
if (ip != nullptr) { *ip = *ipv6; }
if (ip != nullptr) { ip->from_ip_addr_t(ipv6); }
return true;
}
}
@ -579,7 +584,7 @@ bool WifiHasIPv6(void)
String WifiGetIPv6Str(void)
{
IPAddress ip;
return WifiGetIPv6(&ip) ? ip.toString() : String();
return WifiGetIPv6(&ip) ? ip.toString(true) : String();
}
bool WifiGetIPv6LinkLocal(IPAddress *ip)
@ -589,7 +594,7 @@ bool WifiGetIPv6LinkLocal(IPAddress *ip)
String WifiGetIPv6LinkLocalStr(void)
{
IPAddress ip;
return WifiGetIPv6LinkLocal(&ip) ? ip.toString() : String();
return WifiGetIPv6LinkLocal(&ip) ? ip.toString(true) : String();
}
@ -605,7 +610,7 @@ bool EthernetHasIPv6(void)
String EthernetGetIPv6Str(void)
{
IPAddress ip;
return EthernetGetIPv6(&ip) ? ip.toString() : String();
return EthernetGetIPv6(&ip) ? ip.toString(true) : String();
}
bool EthernetGetIPv6LinkLocal(IPAddress *ip)
@ -619,7 +624,7 @@ bool EthernetHasIPv6LinkLocal(void)
String EthernetGetIPv6LinkLocalStr(void)
{
IPAddress ip;
return EthernetGetIPv6LinkLocal(&ip) ? ip.toString() : String();
return EthernetGetIPv6LinkLocal(&ip) ? ip.toString(true) : String();
}
bool DNSGetIP(IPAddress *ip, uint32_t idx)
@ -629,16 +634,16 @@ bool DNSGetIP(IPAddress *ip, uint32_t idx)
#endif
const ip_addr_t *ip_dns = dns_getserver(idx);
if (!ip_addr_isany(ip_dns)) {
if (ip != nullptr) { *ip = *ip_dns; }
if (ip != nullptr) { ip->from_ip_addr_t((ip_addr_t*)ip_dns); }
return true;
}
if (ip != nullptr) { *ip = *IP4_ADDR_ANY; }
if (ip != nullptr) { ip->from_ip_addr_t((ip_addr_t*)IP4_ADDR_ANY); }
return false;
}
String DNSGetIPStr(uint32_t idx)
{
IPAddress ip;
return DNSGetIP(&ip, idx) ? ip.toString() : String(F("0.0.0.0"));
return DNSGetIP(&ip, idx) ? ip.toString(true) : String(F("0.0.0.0"));
}
//
@ -646,15 +651,15 @@ String DNSGetIPStr(uint32_t idx)
void WifiDumpAddressesIPv6(void)
{
for (netif* intf = netif_list; intf != nullptr; intf = intf->next) {
if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(intf->ip_addr).toString().c_str());
if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(&intf->ip_addr).toString(true).c_str());
for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (!ip_addr_isany_val(intf->ip6_addr[i]))
AddLog(LOG_LEVEL_DEBUG, "IP : '%c%c%i' IPv6 %s %s", intf->name[0], intf->name[1], intf->num,
IPAddress(intf->ip6_addr[i]).toString().c_str(),
IPAddress(&intf->ip6_addr[i]).toString(true).c_str(),
ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : "");
}
}
AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str());
AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString(true).c_str());
AddLog(LOG_LEVEL_DEBUG, "WIF: v4IP: %_I v6IP: %s mainIP: %s", (uint32_t) WiFi.localIP(), WifiGetIPv6Str().c_str(), WifiGetIPStr().c_str());
#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET)
AddLog(LOG_LEVEL_DEBUG, "ETH: v4IP %_I v6IP: %s mainIP: %s", (uint32_t) EthernetLocalIP(), EthernetGetIPv6Str().c_str(), EthernetGetIPStr().c_str());
@ -680,8 +685,8 @@ bool IPGetListeningAddress(IPAddress * ip)
IPAddress ip_eth;
bool has_eth = EthernetGetIP(&ip_eth);
if (has_wifi && has_eth) {
if (ip_eth.isV4()) { *ip = ip_eth; return true; }
if (ip_wifi.isV4()) { *ip = ip_wifi; return true; }
if (ip_eth.type() == IPv4) { *ip = ip_eth; return true; }
if (ip_wifi.type() == IPv4) { *ip = ip_wifi; return true; }
// both addresses are v6, return ETH
*ip = ip_eth;
return true;
@ -707,11 +712,11 @@ bool IPGetListeningAddress(IPAddress * ip)
String IPGetListeningAddressStr(void)
{
IPAddress ip;
if (IPGetListeningAddress(&ip)) {
return ip.toString();
} else {
return String();
}
#ifdef USE_IPV6
return IPGetListeningAddress(&ip) ? ip.toString(true) : String();
#else
return IPGetListeningAddress(&ip) ? ip.toString() : String();
#endif
}
// Because of IPv6, we can't test an IP address agains (uint32_t)0L anymore
@ -732,11 +737,11 @@ inline bool IPIsValid(const IPAddress & ip)
String IPForUrl(const IPAddress & ip)
{
#ifdef USE_IPV6
if (ip.isV4()) {
if (ip.type() == IPv4) {
return ip.toString().c_str();
} else {
String s('[');
s += ip.toString().c_str();
s += ip.toString(true).c_str();
s += ']';
return s;
}
@ -789,7 +794,11 @@ bool WifiHasIP(void) {
String WifiGetIPStr(void)
{
IPAddress ip;
#ifdef USE_IPV6
return WifiGetIP(&ip) ? ip.toString(true) : String();
#else
return WifiGetIP(&ip) ? ip.toString() : String();
#endif
}
// Has a routable IP, whether IPv4 or IPv6, Wifi or Ethernet
@ -809,9 +818,9 @@ void WifiCheckIp(void) {
if (WL_CONNECTED == WiFi.status()) {
#ifdef ESP32
if (!Wifi.ipv6_local_link_called) {
WiFi.enableIpV6();
WiFi.enableIPv6(true); // TODO
Wifi.ipv6_local_link_called = true;
// AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIpV6"));
// AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIPV6"));
}
#endif
}
@ -1279,18 +1288,6 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
uint32_t dns_end = millis();
if (success) {
// Host name resolved
#ifdef USE_IPV6
#if ESP_IDF_VERSION_MAJOR >= 5
// check if there is a zone-id
// look for '%' in string
const char *s = aHostname;
while (*s && *s != '%') { s++; }
if (*s == '%') {
// we have a zone id
aResult.setZone(netif_name_to_index(s + 1));
}
#endif
#endif // USE_IPV6
if (0xFFFFFFFF != (uint32_t)aResult) {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI "DNS resolved '%s' (%s) in %i ms"), aHostname, aResult.toString().c_str(), dns_end - dns_start);
return true;
@ -1376,7 +1373,11 @@ uint64_t WifiGetNtp(void) {
uint32_t attempts = 3;
while (attempts > 0) {
uint32_t port = random(1025, 65535); // Create a random port for the UDP connection.
#ifdef USE_IPV6
if (udp.begin(IPAddress(IPv6), port) != 0) {
#else
if (udp.begin(port) != 0) {
#endif
break;
}
attempts--;
@ -1454,6 +1455,8 @@ uint64_t WifiGetNtp(void) {
// Respond to some Arduino/esp-idf events for better IPv6 support
// --------------------------------------------------------------------------------
#ifdef ESP32
extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
// typedef void (*WiFiEventSysCb)(arduino_event_t *event);
void WifiEvents(arduino_event_t *event) {
switch (event->event_id) {
@ -1461,17 +1464,17 @@ void WifiEvents(arduino_event_t *event) {
#ifdef USE_IPV6
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
{
ip_addr_t ip_addr6;
ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip);
IPAddress addr(ip_addr6);
// Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP6 \n");
IPAddress addr(IPv6, (const uint8_t*)event->event_info.got_ip6.ip6_info.ip.addr, event->event_info.got_ip6.ip6_info.ip.zone);
AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"),
event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF",
addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str());
IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString(true).c_str());
}
break;
#endif // USE_IPV6
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
{
// Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP \n");
ip_addr_t ip_addr4;
ip_addr_copy_from_ip4(ip_addr4, event->event_info.got_ip.ip_info.ip);
AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv4 %_I, mask %_I, gateway %_I"),
@ -1482,6 +1485,18 @@ void WifiEvents(arduino_event_t *event) {
break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
// workaround for the race condition in LWIP, see https://github.com/espressif/arduino-esp32/pull/9016#discussion_r1451774885
{
uint32_t i = 5; // try 5 times only
while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA)) != ESP_OK) {
delay(1);
if (i-- == 0) {
break;
}
}
}
// WiFi.enableIPv6();
// AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: Received ARDUINO_EVENT_WIFI_STA_CONNECTED"));
Wifi.ipv6_local_link_called = false; // not sure if this is needed, make sure link-local is restored at each reconnect
break;

View File

@ -311,7 +311,7 @@ extern "C" {
ip_addr_t ip;
ip_addr_set_any_val(false, ip);
#ifdef USE_IPV6
ip = (ip_addr_t)ipfull;
ipfull.to_ip_addr_t(&ip);
#else
ip_addr_set_ip4_u32_val(ip, (uint32_t)ipfull);
#endif
@ -384,7 +384,7 @@ void PingResponsePoll(void) {
ping->hostname.c_str(),
success ? PSTR("true") : PSTR("false"),
#ifdef USE_IPV6
IPAddress(ping->ip).toString().c_str(),
IPAddress(&ping->ip).toString(true).c_str(),
#else
IPAddress(ip_addr_get_ip4_u32(&ping->ip)).toString().c_str(),
#endif

View File

@ -239,12 +239,14 @@ extern "C" {
#ifdef USE_IPV6
//
ip_addr_t *ip_addr = (ip_addr_t*) ip;
head->addr.type = ip_addr->type;
if (ip_addr->type == ESP_IPADDR_TYPE_V6) {
memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16);
// ip_addr_t *ip_addr = (ip_addr_t*) ip;
ip_addr_t ip_addr;
ip.to_ip_addr_t(&ip_addr);
head->addr.type = ip_addr.type;
if (ip_addr.type == ESP_IPADDR_TYPE_V6) {
memcpy(head->addr.u_addr.ip6.addr, ip_addr.u_addr.ip6.addr, 16);
} else {
head->addr.u_addr.ip4.addr = ip_addr->u_addr.ip4.addr;
head->addr.u_addr.ip4.addr = ip_addr.u_addr.ip4.addr;
}
#else
head->addr.u_addr.ip4.addr = (uint32_t) ip;
@ -332,10 +334,11 @@ extern "C" {
} else {
continue;
}
be_pushstring(vm, IPAddress(&ip_addr).toString(true).c_str());
#else
uint32_t ip_addr = a->addr.u_addr.ip4.addr;
#endif
be_pushstring(vm, IPAddress(ip_addr).toString().c_str());
#endif
be_data_push(vm, -2);
be_pop(vm, 1);
}

View File

@ -504,10 +504,10 @@ extern "C" {
tcp->update_local_addr_port();
if (tcp->local_port > 0) {
be_map_insert_int(vm, "local_port", tcp->local_port);
be_map_insert_str(vm, "local_addr", tcp->local_addr.toString().c_str());
be_map_insert_str(vm, "local_addr", tcp->local_addr.toString(true).c_str());
}
be_map_insert_int(vm, "remote_port", tcp->remotePort());
be_map_insert_str(vm, "remote_addr", tcp->remoteIP().toString().c_str());
be_map_insert_str(vm, "remote_addr", tcp->remoteIP().toString(true).c_str());
}
be_pop(vm, 1);
be_return(vm);

View File

@ -240,7 +240,7 @@ extern "C" {
WiFiClient * client_ptr = nullptr;
if (server_tcp->hasClient()) {
WiFiClient new_client = server_tcp->available();
AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", new_client.remoteIP().toString().c_str(), new_client.remotePort(), new_client.localIP().toString().c_str(), new_client.localPort());
AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", new_client.remoteIP().toString(true).c_str(), new_client.remotePort(), new_client.localIP().toString().c_str(), new_client.localPort());
client_ptr = new WiFiClient();
*client_ptr = new_client;
} else {
@ -254,7 +254,7 @@ extern "C" {
AsyncTCPClient * client_ptr = nullptr;
if (server_tcp->hasClient()) {
client_ptr = server_tcp->availableAsync();
AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", client_ptr->remoteIP().toString().c_str(), client_ptr->remotePort(), client_ptr->localIP().toString().c_str(), client_ptr->localPort());
AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", client_ptr->remoteIP().toString(true).c_str(), client_ptr->remotePort(), client_ptr->localIP().toString().c_str(), client_ptr->localPort());
} else {
be_raise(vm, "internal_error", "tcpserver has no client connected");
}

View File

@ -51,7 +51,11 @@ extern "C" {
// udp.begin(interface:string, port:int) -> bool
int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) {
#ifdef USE_IPV6
IPAddress addr(IPv6);
#else
IPAddress addr;
#endif
// if no host or host is "" then we defult to INADDR_ANY
if(host && (*host != 0) && !WifiHostByName(host, addr)){
return 0;
@ -66,7 +70,11 @@ extern "C" {
// udp.begin_multicast(address:string, port:int) -> nil
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
#ifdef USE_IPV6
IPAddress addr(IPv6);
#else
IPAddress addr;
#endif
if(!WifiHostByName(host, addr)){
return 0;
}
@ -127,7 +135,7 @@ extern "C" {
// set remotet ip
IPAddress remote_ip = udp->remoteIP();
be_pushstring(vm, remote_ip.toString().c_str());
be_pushstring(vm, remote_ip.toString(true).c_str());
be_setmember(vm, 1, "remote_ip");
be_pop(vm, 1);

View File

@ -85,6 +85,8 @@
char eth_hostname[sizeof(TasmotaGlobal.hostname)];
uint8_t eth_config_change;
extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
void EthernetEvent(arduino_event_t *event);
void EthernetEvent(arduino_event_t *event) {
switch (event->event_id) {
@ -95,14 +97,27 @@ void EthernetEvent(arduino_event_t *event) {
case ARDUINO_EVENT_ETH_CONNECTED:
#ifdef USE_IPV6
ETH.enableIpV6(); // enable Link-Local
ETH.enableIPv6(); // enable Link-Local
// workaround for the race condition in LWIP, see https://github.com/espressif/arduino-esp32/pull/9016#discussion_r1451774885
{
uint32_t i = 5; // try 5 times only
while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)) != ESP_OK) {
delay(1);
if (i-- == 0) {
AddLog(LOG_LEVEL_INFO, ">>>> HELP");
break;
}
}
AddLog(LOG_LEVEL_INFO, ">>>> ESP_IF_ETH i=%i", i);
}
#endif // USE_IPV6
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"),
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "",
ETH.macAddress().c_str(), eth_hostname
);
// AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIpV6() -> %i", ETH.enableIpV6());
// AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIPV6() -> %i", ETH.enableIPV6());
break;
case ARDUINO_EVENT_ETH_GOT_IP:
@ -128,11 +143,11 @@ void EthernetEvent(arduino_event_t *event) {
{
ip_addr_t ip_addr6;
ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip);
IPAddress addr(ip_addr6);
IPAddress addr(&ip_addr6);
AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"),
event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF",
addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str());
if (!addr.isLocal()) { // declare network up on IPv6
IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str());
if (!IPv6isLocal(addr)) { // declare network up on IPv6
TasmotaGlobal.rules_flag.eth_connected = 1;
TasmotaGlobal.global_state.eth_down = 0;
}