Wireguard does not work with w5500

Dear all,
I have a project with ESP32 and using Wifi or Ethernet (W5500), selectable via UI, and connecting via Wireguard to Home Assistant.
Over Wifi, Wireguard working fine. But over ethernet not.
I discused it with @Juraj , use ESP platform 3+.

This thread is closed

If I compilling code, I get this error

C:\Users\j.jirutka\Documents\Arduino\libraries\WireGuard-ESP32\src\wireguardif.c:51:10: fatal error: tcpip_adapter.h: No such file or directory
   51 | #include "tcpip_adapter.h"
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.

Then, here is described some changes in wireguard src
https://docs.espressif.com/projects/esp-idf/en/v4.2/esp32/api-reference/network/tcpip_adapter_migration.html

After change, I get another error during compile

C:\Users\j.jirutka\Documents\Arduino\libraries\WireGuard-ESP32\src\wireguardif.c:925:33: error: 'TCPIP_ADAPTER_IF_STA' undeclared (first use in this function)
  925 |         tcpip_adapter_get_netif(TCPIP_ADAPTER_IF_STA, &underlying_netif);
      |                                 ^~~~~~~~~~~~~~~~~~~~
C:\Users\j.jirutka\Documents\Arduino\libraries\WireGuard-ESP32\src\wireguardif.c:925:33: note: each undeclared identifier is reported only once for each function it appears in

Is there a straightforward solution to my problem please?

You'l have to go over the library code and make a modified version that does not use wifi features.

not quite, the library must be universal for both wifi and ethernet W5500

The device used in tcpip is decided by the metric value assigned to that device.
How are you determining which network device is handling your traffic?

A connection object is not defined in the Wireguard examples.
Only then does the communication object itself determine the client, in my case Home Assistant Integration, to use

WiFiClient wificlient;
EthernetClient ethernetclient;

HADevice device;
HAMqtt wifi_mqtt( wificlient , device , 20 );
HAMqtt ethernet_mqtt( ethernetclient , device , 40 );

Post your code and the libraries you are using.

Okay. Here is testing code only for Wireguard and ethernet. For connection test.

#include <SPI.h>
#include <Ethernet.h>

#include <WiFi.h>
#include <WireGuard-ESP32.h>

#define W5500_RST_PIN 13

#define VSPI_SCK 26
#define VSPI_MISO 25
#define VSPI_MOSI 33
#define W5500_CS 27
#define W5500_INT_PIN 4

#define debug Serial

// Set the static IP address to use if the DHCP fails to assign
#define MYIPADDR 192, 168, 1, 28
#define MYIPMASK 255, 255, 255, 0
#define MYDNS 192, 168, 1, 1
#define MYGW 192, 168, 1, 1

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):

byte mac[6];

int endpoint_port = 51820;              // [Peer] Endpoint
static constexpr const uint32_t UPDATE_INTERVAL_MS = 5000;
static WireGuard wg;

void setup() {
  Serial.begin(115200);
  pinMode(W5500_RST_PIN, OUTPUT);

  pinMode(W5500_CS, INPUT);
  pinMode(W5500_INT_PIN, INPUT);
  pinMode(VSPI_SCK, INPUT);
  pinMode(VSPI_MISO, INPUT);
  pinMode(VSPI_MOSI, INPUT);

  digitalWrite(W5500_RST_PIN, HIGH);
  delay(1000);
  Serial.println("Begin Ethernet");

  Ethernet.init(5);  // MKR ETH Shield

  WiFi.macAddress( mac );
  if (Ethernet.begin(mac)) {  // Dynamic IP setup
    Serial.println("DHCP OK!");
  } else {
    Serial.println("Failed to configure Ethernet using DHCP");
    // Check for Ethernet hardware present
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
      while (true) {
        delay(1);  // do nothing, no point running without Ethernet hardware
      }
    }
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }

    IPAddress ip(MYIPADDR);
    IPAddress dns(MYDNS);
    IPAddress gw(MYGW);
    IPAddress sn(MYIPMASK);
    Ethernet.begin(mac, ip, dns, gw, sn);
    Serial.println("STATIC OK!");
  }
  delay(5000);

  Serial.print("Local IP : ");
  Serial.println(Ethernet.localIP());
  Serial.print("Subnet Mask : ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Gateway IP : ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("DNS Server : ");
  Serial.println(Ethernet.dnsServerIP());

  Serial.println("Ethernet Successfully Initialized");

#define ELMAX_DNS "haiot.mydomain.sk" // replaced for security
  char private_key[] = "**************************************";  // replaced for security
  IPAddress local_ip( 10 , 10 , 10 , 10 );            // [Interface] Address
  char public_key[] = "**************************************";     // replaced for security
  char endpoint_address[] = ELMAX_DNS;    // [Peer] Endpoint

  configTime(9 * 60 * 60, 0, "ntp.jst.mfeed.ad.jp", "ntp.nict.jp", "time.google.com");
  byte wg_resp = wg.begin( local_ip , private_key , endpoint_address , public_key , endpoint_port );
  if ( !wg_resp) {
    debug.println( F("WireGuard not connected...") );
  } else debug.println( F("WireGuard connected...") );
  debug.println( "WG response: " + String( wg_resp ));

}

void loop() {}

With the ethernet shield you must set the mac address. DEAD BEEF FEED works.

// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

Edit: If you are using the hardware SPI, pin 13 is off limits. It's SCK

#define W5500_RST_PIN 13

...and this will cause problems. Duplicate mac addresses?

 WiFi.macAddress( mac );
  if (Ethernet.begin(mac)) {  // Dynamic IP setup

No, this about mac, working fine.

I still have the main program where everything works except wireguard. Ethernet connects, web interface works. It is too large for publication.
I first test each software component in simple programs based on examples from the libraries.
I don't use wifi and ethernet at the same time, just one of them. But the choice is given by the user in UI, not defined in the source code. So, in main program is bool for choice.

It works by loading the MAC address of the ESP from Wifi into a byte array, and using that mac address for ethernet. I have tried it.

So you have 2 network devices with duplicate mac addresses connected to the same router? Is that correct?

Edit: This can be done, but not at the same time. I've done this before. It's called "mac spoofing". Connect to a wifi net, watch traffic. Determine which mac addresses get immediate access without logging in. Change your wifi device to that mac. Connect.

No, only one device connects at a time. The user chooses the connection method (Wifi or ethernet) in the UI.
Here is part of the source code for the full main connection initialization program.

Ethernet.init( 5 );
if ( !exchange_data.wifi_enable ) {
  debug.println( F("Setup Ethernet..."));
  if ( ethernet_config.use_dhcp ) {
    if ( Ethernet.begin( mac )) {  // Dynamic IP setup
      debug.println( F("   ETH DHCP OK!"));
      debug.print( F("   ETH Status: "));
      debug.print( String( Ethernet.linkStatus()));
      if ( Ethernet.linkStatus() == 1 ) ethernet_connected = true; else ethernet_connected = false;
    } else {
      debug.println( F("Failed to configure Ethernet using DHCP"));
    }
    delay( 2000 );
    debug.print( F("   Local IP : "));
    debug.println( Ethernet.localIP());
    debug.print( F("   Subnet Mask : "));
    debug.println( Ethernet.subnetMask());
    debug.print( F("   Gateway IP : "));
    debug.println( Ethernet.gatewayIP());
    debug.print( F("   DNS Server : "));
    debug.println( Ethernet.dnsServerIP());
    debug.println( F("   Ethernet Successfully Initialized"));
  } else {
    Ethernet.begin( mac , ethernet_config.ip , ethernet_config.dns_server , ethernet_config.gateway , ethernet_config.subnet );
    if ( Ethernet.linkStatus() == LinkON ) ethernet_connected = true; else ethernet_connected = false;
    debug.println( F("   ETH STATIC OK!"));
  }
}

// WIFI
if ( exchange_data.wifi_enable ) {
  debug.println( F("Setup Wifi..."));
  WiFi.mode( WIFI_STA );
  if ( ethernet_config.use_dhcp ) {
    if ( WiFi.begin( exchange_data.wifi_ssid , exchange_data.wifi_psw )) {
      debug.println( F("   WIFI DHCP OK!"));
      debug.print( F("   WIFI Status: "));
      debug.println( String( WiFi.status()));
      if ( WiFi.status() == 6 ) wifi_connected = true; else wifi_connected = false;
    } else {
      debug.println( F("Failed to configure Wifi using DHCP"));
    }
    delay( 2000 );
    debug.print( F("   Local IP : "));
    debug.println( WiFi.localIP());
    debug.print( F("   Subnet Mask : "));
    debug.println( WiFi.subnetMask());
    debug.print( F("   Gateway IP : "));
    debug.println( WiFi.gatewayIP());
    debug.println( F("   Wifi Successfully Initialized"));
  } else {
    WiFi.config( ethernet_config.ip , ethernet_config.gateway , ethernet_config.subnet , ethernet_config.dns_server );
    if ( WiFi.begin( exchange_data.wifi_ssid , exchange_data.wifi_psw )) {
      debug.println( F("   WIFI STATIC OK!"));
      if ( WiFi.status() == WL_CONNECTED ) wifi_connected = true; else wifi_connected = false;
    }
    if ( WiFi.status() == WL_CONNECTED ) wifi_connected = true; else wifi_connected = false;
  }
}

As you see, the bool

exchange_data.wifi_enable

is choice, what connection is selected.
The entire device has a uniform mac address, extracted from Wifi.
This ethernet/wifi init code working fine.

In the project, I has another device services, as a WebUI, MODBUS TCP and this working via selected connection.
But Wireguard not, only over Wifi.

How are you adapting the Wireguard library to use the ethernet device?

As far as I can see, the Wireguard library is designed for WiFi only. Changing the network settings to the same values won't solve that.

I don't edit the library, I can't.

If you can't change the library, then you are limited to WiFi transport only.

Thank you. Then it's clear. I thought there might be a solution.

You can still use both devices IF you use separate mac/ip addresses, but that WireGuard library will work only on WiFi.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.