Problém s ESP8266 a přidělováním IPv6 adresy

Odpovědět
jankop
Příspěvky: 1063
Registrován: 06 zář 2017, 20:04
Bydliště: Brno
Kontaktovat uživatele:

Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od jankop » 04 lis 2025, 22:55

Na ESP8266 mám LwIP variant: v2 IPv6 Higher Bandwigth. IPv6 dříve fungoval, protože starý router podporoval SLAAC. Mám nový modem/router Vodafone Station WiFi 6. Ten ale s podivem SLAAC nepodporuje. Dělá pouze stavové DHCPv6. Protože nemám a nebudu mít veřejnou IPv4, tak se na ESP8266 už z vnějšku nedostanu. ESP8266 má teď jen lokální adresu typu fe80::eadb:44af:fe56:6ccc.
Nemáte někdo nějakou radu, jak to bez dalšího HW vyřešit?

Uživatelský avatar
Caster
Příspěvky: 477
Registrován: 11 zář 2019, 09:02

Re: Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od Caster » 04 lis 2025, 23:31

1. Zkontroluj nastavení routeru
Vodafone Station by měl SLAAC podporovat, jen to může být špatně nakonfigurováno:

Hledej nastavení IPv6 → Router Advertisement (RA)
Měl bys najít možnost "SLAAC" nebo "Stateless" nebo "RA + SLAAC"
Případně režim "SLAAC + DHCPv6" (kombinovaný)

2. Statická IPv6 adresa
Pokud máš prefix od ISP (např. 2001:db8:1234::/64):

Kód: Vybrat vše

// V Arduino kódu
IPAddress local_IP(0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002);
IPAddress gateway(0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001);
WiFi.config(local_IP, gateway, subnet, dns);
3. Reverse SSH/VPN tunel (potřebuje VPS)
Pokud máš třeba levný VPS s IPv4:

Kód: Vybrat vše

# Na ESP8266 spusť reverse SSH tunel
ssh -R 8080:localhost:80 user@vps-server
4. Update firmware routeru
Zkus aktualizovat firmware Vodafone Station - novější verze mohou mít opraven SLAAC.

5. Bridge mód + vlastní router
Pokud máš doma starý router, přepnout Vodafone do bridge módu a použít vlastní router se SLAAC.

jankop
Příspěvky: 1063
Registrován: 06 zář 2017, 20:04
Bydliště: Brno
Kontaktovat uživatele:

Re: Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od jankop » 04 lis 2025, 23:49

Díky za odpověď. Ten modem/router bohužel nedovoluje nastavit prakticky vůbec nic. Bridge mód nastavit nejde a jediná položka IPv6 je Host Exposure. Je to kabelový modem. Firewall jde jen zapnout a vypnout. :D
Asi budu muset použít tu statickou IPv6 definovanou v programu. Nemůžu nastavit na routeru ani pool IPv6, ale kolize IPv6 je asi málo pravděpodobná.

jankop
Příspěvky: 1063
Registrován: 06 zář 2017, 20:04
Bydliště: Brno
Kontaktovat uživatele:

Re: Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od jankop » 05 lis 2025, 09:57

Ten kód neprojde kompilerem:

Kód: Vybrat vše

// V Arduino kódu
IPAddress local_IP(0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002);
IPAddress gateway(0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001);
WiFi.config(local_IP, gateway, subnet, dns);
Ale jsem na dobré cestě. Zjistil jsem, že můj program startuje příliš rychle a nepočká na přidělení global IPv6 adresy od routeru. Už to nejspíš dovedu ošetřit přes lwIP API. A také bych asi stejně dovedl nastavit statickou adresu IPv6.

Uživatelský avatar
Caster
Příspěvky: 477
Registrován: 11 zář 2019, 09:02

Re: Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od Caster » 05 lis 2025, 10:07

Proč nešel ten kód zkompilovat:

Třída IPAddress v Arduino nepodporuje přímo IPv6 adresy přes konstruktor s 8× 16bitovými čísly.

Kód: Vybrat vše

IPAddress local_IP(0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002);
Tento zápis je jen pro IPv4 (4× 8bitové oktety).
Pro IPv6 takový konstruktor neexistuje → kompilátor hlásí chybu.

Jak správně nastavit IPv6 na ESP32 / ESP8266?
Použij řetězec nebo pole uint16_t + funkci WiFi.config() s IPv6 parametry.

Řešení 1 – nejjednodušší (doporučeno)

Kód: Vybrat vše

// IPv6 adresa a brána jako řetězec
WiFi.config(
  IPv6Address("2001:db8:1234::2"),     // local IP
  IPv6Address("2001:db8:1234::1"),     // gateway
  IPv6Address("255.255.255.0"),        // subnet (IPv4-style, volitelné)
  IPv6Address("2001:db8::1")           // DNS (volitelné)
);
Řešení 2 – přes pole 16bitových slov

Kód: Vybrat vše

uint16_t ipv6[] = {0x2001, 0x0db8, 0x1234, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002};
WiFi.config(IPv6Address(ipv6));
Řešení 3 – přes uint8_t pole (128 bitů)

Kód: Vybrat vše

uint8_t ip6[16] = {
  0x20,0x01, 0x0d,0xb8, 0x12,0x34, 0x00,0x00,
  0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x02
};
WiFi.config(IPv6Address(ip6));
Kompletní funkční kód (ESP32)

Kód: Vybrat vše

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.begin("SSID", "heslo");

  // Nastavení statické IPv6 (a volitelně IPv4)
  WiFi.config(
    IPv6Address("2001:db8:1234::2"),     // statická IPv6
    IPv6Address("2001:db8:1234::1"),     // brána
    IPv6Address("ffff:ffff:ffff:ffff::"), // subnet /64 (nebo vynechat)
    IPv6Address("2001:db8::1")            // DNS
  );

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nPřipojeno!");
  Serial.print("IPv6: ");
  Serial.println(WiFi.localIPv6());
}

void loop() {}
Shrnutí

Ne: IPAddress(0x2001, …) → to je jen pro IPv4
Ano: IPv6Address("2001:db8:1234::2") nebo pole

jankop
Příspěvky: 1063
Registrován: 06 zář 2017, 20:04
Bydliště: Brno
Kontaktovat uživatele:

Re: Problém s ESP8266 a přidělováním IPv6 adresy

Příspěvek od jankop » 05 lis 2025, 23:05

Myslím, že vůbec žádný z těch příkladů není funkční na ESP8266. Něco z toho možná funguje na ESP32, ale i o tom dost pochybuji.
Moje řešení vychází z IwIP6 API a nakonec jsem vlastně neřešil statickou IPv6, ale detekci přidělení prefixu IPv6 routerem. Ale statickou IPv6 bych takto asi zvládl také.
Tohle je zjednodušený náčrt mého řešení

Kód: Vybrat vše

extern "C" {
#include "lwip/netif.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet.h"
}
// test na global IPv6 adresu
bool hasGlobalIPv6() {
  struct netif* n = netif_list;
  while (n) {
    for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
      // IPv6 je globalni, pokud neni link-local (fe80::/10) a je validní
      if (!ip6_addr_isinvalid(netif_ip6_addr_state(n, i)) &&
          !ip6_addr_islinklocal(netif_ip6_addr(n, i))) {
        return true; // mame globalni IPv6
      }
    }
    n = n->next;
  }
  return false; // zadna globalni IPv6
  void setup(void){
WiFi.begin(eGet.mySSID, eGet.myPassword);
   unsigned long startTime = millis();
    bool gotIPv6 = false;
    while ((millis() - startTime) < 30000) {  // 30 s timeout
      if (hasGlobalIPv6()) {
        gotIPv6 = true;
        break;
      }
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      delay(500);  // kontrola každých 0.5 s
    }
    digitalWrite(LED_BUILTIN, HIGH);  //LED OFF
   
}
}

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host