Changing Default route on Arduino UNO Ethernet Shield

Hi,

I connected Arduino UNO to an ethernet switch. In the same switch there are two computers connected, let's call them host1 and host2. I manage to connect from Arduino to host1 using sockets and the EthernetClient. Now I want to force Arduino to communicate through host2(that introduces latencies) with host1 and not directly with host1. I tried with a third computer instead of the arduino and it works. I can ping arduino from host1 and I get the expected result. How can I force arduino to connect through host2? Is there any way to change default routes? I tried to use host2 as gateway but did not work. Everything in the network has static ips. There are no DNS or DHCP servers.
Any ideas?

The default route is determined by the gateway parameter in the Ethernet.begin() call.

If host1 and host2 are on the same localnet as the Arduino, the default gateway will not change the route to any localnet computers. The default gateway is used only if the destination IP is not on the same localnet.

Yes I know. This is why it did not surprise me the result. So it is not possible to force communicate through host1? Because on normal computers you can.

I'm a network guy, so I can route almost anything to anywhere. You might try the connection to host1 and put a "Host: host2" parameter in the header. If that doesn't work, try adding the host2 IP to the GET line. Those are normally the techniques used to route through a proxy server. That is basically what you are trying.

Because I am not (at all) a network guy I have some questions. I do not use the arduino for HTTP requests so I do not use a GET command. I just transfer some computation and the server responds results. So, how can I add the "Host:host2" to the header? I did not get that... I use server's ip to connect to it.. Should I use a host name????

Post your code. Maybe that will help me figure out how to help you.

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xC4, 0x42 };

IPAddress ip(138,221,206,30);
//IPAddress gateway(138,221,206,41);
//IPAddress subnet(255, 255, 255, 0);
//IPAddress DNS(138, 227, 181, 150);
//// Enter the IP address of the server you're connecting to:
IPAddress server(138,221,206,73); 

EthernetClient client;

char message[50];

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Ethernet.begin(mac,ip);


  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");
  
  // if you get a connection, report back via serial:
  if (client.connect(server, 51717)) {
    Serial.println("connected");
  } 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  message[0] = '1';
  message[1] = '\0';
  message[2] = '\n';
}
int i = 0;
int counter = 0;

void loop()
{
  
    //Send a message  
    if (client.connected()) {
      client.print(message); 
    }
   //print the message to the serial
    Serial.print("I send:");
    Serial.println(message);
   
   //get message
    if(client.available()) {
      message[i] = client.read();
      i++;
    }
     //print to the serial
    Serial.print("I got:");
    Serial.println(message);
    
    //print time
    Serial.print("Millis: ");
    Serial.print(millis());    
    Serial.println();

    message[0]++;
    i=0;
    

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    // do nothing:
    while(true);
  }
}

It is just a simple example... the arduino sends 1 the servers answers 2 and then the arduino sends 3 and so on....

What type server is this on host2? How is host1 supposed to know it is needs to forward that request to host2?

host2 is WANEM.. it is a software from a company.. If you traceroute from the computer to the arduino it passes through wanem. If two computers communicate it passes through wanem. If tries to communicate it does not pass through wanem. So host2 is meant to induce latencies. Host1 is an ubuntu server and I have added a default route that passed trhough wanem.

here is the routing table from host1
138.221.206.30 -> arduino
138.221.206.41 -> wanem
138.221.206.73 -> server(host1)

iot4@iot4:~$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 138.221.206.4 0.0.0.0 UG 0 0 0 br0
138.221.206.0 138.221.206.41 255.255.255.0 UG 0 0 0 br0
138.221.206.0 0.0.0.0 255.255.255.0 U 0 0 0 br0
138.221.206.30 138.221.206.41 255.255.255.255 UGH 0 0 0 br0
138.221.206.58 138.221.206.41 255.255.255.255 UGH 0 0 0 br0
138.221.206.73 138.221.206.41 255.255.255.255 UGH 0 0 0 br0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0

Is there any chance that the socket enstablishes a connection and skips the wanem?

Why are you using a Wide Area Network emulator? That seems to me to be a network savvy technician's tool. Isn't all this difficult enough without adding complexity?

edit: Here is the deal. If the destination IP address is on the localnet, the computer will attempt to contact the destination computer directly without going through the gateway. In that respect, the Arduino may bypass the WANem.

There are some exceptions to this. I have routers that will ARP poison the localnet, and claim to be the destination device for all IP addresses on the localnet.

The answer to my question is probably no... Arduino Ethernet Shield does not support routing (99%) . The problem was in my code.. I should poll until the message is available!! It is always the stupidest thing... thanks.

Axinar:
I can ping arduino from host1 and I get the expected result. How can I force arduino to connect through host2? Is there any way to change default routes?

As far as I know, the Ethernet shield does not maintain a routing table, so there is no default route as such.

What you can do is force all hosts to be remote, by configuring the subnet mask as 255.255.255.255 All traffic will then be forwarded to the default gateway IP, which you set to the WanEm interface.

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xC4, 0x42 };

IPAddress ip(138,221,206,30);
IPAddress gateway(138,221,206,41);     //<-- WanEm interface address
IPAddress subnet(255, 255, 255, 255);  //<-- All hosts are remote 

//IPAddress DNS(138, 227, 181, 150);

//// Enter the IP address of the server you're connecting to:
IPAddress server(138,221,206,73);  //<-host1 address 


//..Etc

@MattS_UK: There is a default route. Anything outside the device localnet will be sent to the gateway (default route). edit: Since there is no routing table, everything except localnet will be sent through the gateway, so I guess in a way that could be right in the fact that it is the "only route".

I like your solution tho. Some devices will not access a gateway if outside the localnet without a routing table, but my testing today shows that the w5100 is not one of those devices. It will use the gateway even if outside the localnet.

Good solution, :slight_smile:

@MattS-UK thanks for the answer.. I made something similar before reading you answer. I set the subnet mask to 255.255.255.128 and gave the server the IP 138.221.206.200 while the arduino is 138.221.206.30 and it works!! It is so easy if you know more about networks! thanks though!