Ethernet shield cannot communicate over cisco router

The basic use of my sketch is to measure the themperature in the cabinet the box with the arduino is placed in and the temperature in the arduino box, bypass the UPS if it fails, activate and deactivate my alarmsystem and reset my router, POE camera and HDD recorder.

I have a cisco 881-3G router and a VPN connection to my home all is working fine for normal use (streaming video, documents, pictures and so on).
if i use my sketch on my local network (HP switch) I can send the alarm messages to my TCP receiver at home, but if i try to do so with the arduino behind the cisco router over the VPN tunnel nothing is received bij the TCP receiver (no single hit on wireshark).

I can ping the arduino from all places in both networks. I also can connect the web interface on the arduino.
The only thing that is not working is the TCPsend function to the TCP receiver at home.

The complete sketch is attatched as .txt .

void TCPsend(){   
       
    Serial.println("Bezig met verbinden...");
    delay(100);
    
    // Maak de TCP verbinding en geef aan als er een verbinding is
    Serial.println(ipserver);
    Serial.println(serverpoort);
    if (TCPclient.connect(ipserver, serverpoort)) {
      Serial.println("Verbonden");
      //delay(100);
      // Verstuur het alarmbericht naar de server en de seriële poort 
      Serial.print("Verzend bericht : ");
      TCPclient.print(String(AlarmMSG));
      Serial.println(AlarmMSG);
      AlarmMSG = "";
    }
    
    else {
    // Als de verbinding mislukt is geef dit dan aan
    Serial.println("Verbinding mislukt");
    delay(1000);
    TCPsend(); // probeer opnieuw te versturen
    }
 
    // Als er een reactie van de server komt print 
    // deze dan op de seriële poort 
    
    // Even de server de tijd geven om iets terug te sturen
    delay (50); 
    if (TCPclient.available() > 0) {
    Serial.print("Antwoord van server : ");
    }
    // Ontvang de daadwerkelijke reactie van de server
    while (TCPclient.available() > 0) {
    char c = TCPclient.read();
    Serial.print(c);
    }

    TCPclient.stop();
    serverpoort = 900;
    
        
    // Als de server verbinding verbroken is, stop dan de client:
    if (!TCPclient.connected()) {
      Serial.println();
      Serial.println("Verbinding verbroken.");
      TCPclient.stop();
      } 
    
  }

complete sketch.txt (12.9 KB)

What does "that is not working" mean? What's the output you get? What's a TCP receiver? Do you have installed some kind of server on that IP address? If yes, what software do you use there? Are you able to connect to that server manually (by using the telnet command on you PC)? How does the non-working TCPsend function correspond to the title of your post? What's the role of the Cisco server? In my view of the situation it's not taking part in this communication (everything on the LAN).

Hello Pylon,

The only thing of my sketch that is not working is the sending of the TCP messages with the function TCPsend (witch is the code embedded in the post) when the project is at the remote location.

The TCP receiver software is Hercules from HWgroup.

The PC at home uses the LAN IP address 192.168.150.40, the arduino has IP address 192.168.174.30 witch segments are conected togerther with a VPN connection over the cisco routers. The 3G router at the second location also is used as switch for the camera, arduino, computer and recorder.

Because the whole sketch is working when i use it at home (rename the IP address in 192.168.150.30) al i try to send using the function TCPsend i conclude the problem is in the ethernet shield and not the sketch (but i can be wrong)

The PC at home uses the LAN IP address 192.168.150.40

In this case I found the error:

IPAddress ipserver(192, 168, 174, 40);

Do you see the difference?

This IP address is in the code as result of an experiment at the remote location.

Only using the cisco as switch resulted in the same problem, no message send to the TCP receiver software, but ping is possible from the TCP receiver computer.

I also tried no gateway and / or no subnet (almost all examples don't use them).

With the arduino and the receiver connected to the cisco and wireshark on the receiver pc not one peice of tcp communication is detected...

It's been years since I worked with anything made by Cisco. (It was in the Cisco CCNA course)

The thing that immediately occurs to me that's worth checking is port-security. Have you checked that it's not enabled for the port that the Arduino is connected to?

I suspect that it isn't, but it seems worth checking so it can be dismissed.

Please post a picture of your network setup. Where is your router, what networks are at which side of it, etc.

This IP address is in the code as result of an experiment at the remote location.

What kind of experiment was that, that needs to connect to a wrong IP address? If the PC is in the 150 network you cannot connect to it using a 174 network IP. Is it possible that the Router has some kind of firewall activated?

@enhzflep
No port security is used in the router, thanks for thinking with me.

@pylon
The firewall was one of the reasons to try to put the arduino and the receiver on both sides of the network.
The arduino ip address at home was 192.168.150.30 and the receiver at home 192.168.150.40.
At the remote location the IP address of the arduino was 192.168.174.30 and the receiver 192.168.174.40.
As it should be all in the correct subnet of that location.

I'm at home nou and i will try to connect the arduino and the receiver at this sides cisco router in stead of the HP Switch on wich it is working.
I will post the result later this evening.

If you put your server and arduino side by side does it work?
I belive you have a NAT problem
Did you route the traffic from remote host to the server TCP client?
What type of VPN are you using PPTP, L2TP, OVPN ,IPSEC ?
Remote client opens a vpn tunnel in the cisco AND if have route for the subnet 192.168.150.0/24 it will able to see the arduino connected to 192.168.150.30
Try to use a telnet connection from remote ip to remote TCP server opening the remote port
If that does not work, well send that CISCO to junkyard and buy mikrotiks :grin: :grin: :grin:

Hello HugoPT,

Yes, side by side it works like charm, on my HP switch at home it works great.
But, if connected at the remote location (both on the cisco router FE1 and FE3) no communication from the function TCPsend, the rest is working fine (HTTP, Ping and XML).

Traffic routing is correct, the used encryption is IPSEC (but it doesn’t come that far for TCPsend), HTTP, ping and XML works over the VPN connection.

Everything is working EXCEPT function TCPsend when the arduino is connected to the cisco router, it looks like the Ethernet shield is not working with the cisco router ports.

I’ve tried some new things here at home, if the arduino and the receiver are both connected to the cisco here at home, it also not works.
Conclusion: No defect/problem in the remote router.

If the receiver is connected to the router and the arduino is connected to the HP switch (all other devices disconnected except the router), eureka, it works
If the receiver is connected to the HP switch and the arduino is connected to the router, it again does not work.

Now I tried to connect the arduino to a Netgear switch, from that to the router and the receiver to the router. That also works.

So the arduino does not work on cisco router ports (for my function TCPsend) but WHY … i’m confused…

The Cisco routers are only 3 months old, putting them in the junkbox is not an option…

I don't know if this is the problem here, but be careful about this. If the gateway is 192.168.174.254, then nothing will go over the gateway with this setup. The default gateway used by the Arduino is 192.168.174.1.

byte mac[] = { 0x00, 0x05, 0xB1, 0xFF, 0xFF, 0x03 };
IPAddress local_ip(192, 168, 174, 30); 
IPAddress gateway(192, 168, 174, 254);
IPAddress subnet(255, 255, 255, 0);

// then in your setup(), replace this
    Ethernet.begin(mac, local_ip);  
// with this
    Ethernet.begin(mac, local_ip, gateway, gateway, subnet);

@HugoPT: I'm a MikroTik guy too. SurferTim on that forum too. :slight_smile:

If the receiver is connected to the router and the arduino is connected to the HP switch (all other devices disconnected except the router), eureka, it works

From a point of view how is the HP Switch connected to the router?
------>CISCO port|--->>switchHP |--->>arduino ???

Hello SurferTim,

Why is the Arduino using 192.168.174.1 in stead of the 254 i told him ?

and why use 2 times gateway, the cisco is not configured as DNS.

I will certainly try but i will use my network configured DNS.

What i thougt was that as all traffic is direct IP i did not need an DNS.

@ HugoPT

The port 1 of the switch is on FE0 from the router, the receiver is on FE2 from the router and the arduino is on port 7 of the HP switch, the other cables are disconnected

You declared and assigned values to gateway and subnet, but did not include them in the Ethernet.begin() call. If you do not include them in the begin() call, it doesn't use them.

These are the Ethernet.begin() functions available in Ethernet.h in the ethernet library.

int begin(uint8_t *mac_address);
void begin(uint8_t *mac_address, IPAddress local_ip);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);

...and these are those functions from Ethernet.cpp. Note if you do not provide that parameter, the functions construct the remaining ips from your ip address used in the begin() call, then calls the next begin() function below it. Read the comments.

void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip)
{
  // Assume the DNS server will be the machine on the same network as the local IP
  // but with last octet being '1'
  IPAddress dns_server = local_ip;
  dns_server[3] = 1;
  begin(mac_address, local_ip, dns_server);
}

void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server)
{
  // Assume the gateway will be the machine on the same network as the local IP
  // but with last octet being '1'
  IPAddress gateway = local_ip;
  gateway[3] = 1;
  begin(mac_address, local_ip, dns_server, gateway);
}

void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
{
  IPAddress subnet(255, 255, 255, 0);
  begin(mac_address, local_ip, dns_server, gateway, subnet);
}

void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
{
  W5100.init();
  W5100.setMACAddress(mac);
  W5100.setIPAddress(local_ip._address);
  W5100.setGatewayIp(gateway._address);
  W5100.setSubnetMask(subnet._address);
  _dnsServerAddress = dns_server;
}

edit: Changed Ethernet.h to Ethernet.cpp.
And as I stated, this may not be your problem here, but it would certainly be a problem if you tried to go anywhere but localnet.

SurferTim,

Thanks, I didn't look at that section of the library, and in the examples on the net they often make that error.

Unfortunately it was not the solution for this problem but could have been the next problem i would encounter.

I'm not a VPN expert, but from what I know, there may be an intermediate step you are missing. Read this:

The part about "Example use of a VPN tunnel" may be the challenge. Note the first action of the VPN server is to assign another ip to the client in the localnet range of the VPN server.

Most of the VPNs I deal with have the same localnet range on both ends.

Just a thought...

Thanks SurferTim,

The problem is in the start that the arduino does not fully function on a Fast Ethernet port of the cisco router, the VPN part is the possible next problem that may occur.

In the current configuration is all TCP/UDP traffic allowed between the two network segments, so I do not expect any problems on that to be honest.