How to get remote IP without modding the core.

People should never write open source libraries with private data members in classes, as you may know, this prevents you from deriving the class and adding your own extensions to it. This is what has happened to the Ethernet library, you cannot access private members needed to retrieve the remote IP.

You can mod the core yourself ( and every time you update the IDE ) using the intructions here: How to obtain the remote client IP address when using the Ethernet Shield - Networking, Protocols, and Devices - Arduino Forum

However I have a tiny library for use with your Arduino Ethernet shield projects that allows you to get this information without modifying the core libraries.

There is one function RemoteIP, it takes a reference to an EthernetClient object and returns an IPAddress object.
The IPAddress structure is part of the core and is printable.

EthernetClient client = server.available();

//...
Serial.print( "Remote IP: );
Serial.println( RemoteIP( client ) );

The library, create a new library folder called EthernetFix and a .h file with the same name. Then copy the code below into it.
You can just copy it into the sketch, however a library is more convenient for multiple projects.

//Requires your sketch to include Ethernet.h
#include <Arduino.h>
#include <utility/w5100.h>

template<typename Tag, typename Tag::type M>
  struct AccessMember{ 
    friend typename Tag::type get( Tag ){ return M; }
};

struct EthernetClient_Socket{ 
  typedef uint8_t EthernetClient::*type;
  friend type get( EthernetClient_Socket );
};

template struct AccessMember< EthernetClient_Socket, &EthernetClient::_sock >;

IPAddress RemoteIP( EthernetClient &c ){
  byte remoteIP[ 4 ];
  W5100.readSnDIPR( c.*get( EthernetClient_Socket() ), remoteIP );
  return ( remoteIP );
}

Using the output from surfer tims web server I got this result:

Client request #1: GET / HTTP/1.1
file = /
file type =
method = GET
params =
protocol = HTTP/1.1
Remote IP: 192.168.1.100
Home page SD file
filename format ok
File not found
disconnected
SRAM = 6483
SRAM = 6483

Happy programming!

NOTE: To use the library in multiple C++ files you may need to move the RemoteIP function to a cpp file with only the prototype in the header. Ask if you need help with this.

This is not a new topic. Here is basically the same code from a few years ago.
http://forum.arduino.cc/index.php?topic=74660.msg563006#msg563006

Both zoomkat and I have been a proponent of this for years now.

I understand this, however my version does not require modification to the core, or its libraries, whereas the method yourself and I linked both require the core to be changed in some way.

Why should it not be included in the standard ethernet library? That was our point. It is such a simple addition. The udp code has it. Why not tcp?

This only applies to the ethernet (w5100) shield. The wifi shield has no way of getting the client ip at all.

I agree its a feature that should be built in.

The point of providing it as a sit on top feature is for portability/compatibility reasons. Possibly even the same reason you had for this post: Ethernet shield server test (new code Uno ok) - #16 by SurferTim - Networking, Protocols, and Devices - Arduino Forum

When its added into the core then great, no need for a fix, however there is also now no need for delving into the Ethernet library until that time arrives.

I also pointed out it was for the Ethernet shield. After your experience ( and liudr ) with the Wifi shield, I don't think I'll have one for a while to even test.

SurferTim:
Why should it not be included in the standard ethernet library?

We had this topic recently on the Arduino Developers-list, the conclusion was that it would be a helpful method, but should not be an Ethernet-only addon but rather be included into all libraries implementing the abstract Client interface which is not an option for the 1.0 Arduino-api but for a later (API 2.0) version as it would break other libraries implementing Client.
Regarding WiFi-shield: Not imposible, but you'd have to modify the shields firmware to get remoteIp/remotePort.

ntruchsess:

SurferTim:
Why should it not be included in the standard ethernet library?

We had this topic recently on the Arduino Developers-list, the conclusion was that it would be a helpful method, but should not be an Ethernet-only addon but rather be included into all libraries implementing the abstract Client interface which is not an option for the 1.0 Arduino-api but for a later (API 2.0) version as it would break other libraries implementing Client.
Regarding WiFi-shield: Not imposible, but you'd have to modify the shields firmware to get remoteIp/remotePort.

Excuse me, but what other libraries use the ethernet client interface besides the ethernet shield?

edit: Never mind. It must be the Yun. That means the ethernet shield and the wifi shield are about to become EOL as far as support is concerned.

SurferTim:
Excuse me, but what other libraries use the ethernet client interface besides the ethernet shield?

Being a developer that is capable to handle this easily I totally agree. You have the code anyway and just add to methods when the interface has been extendet. But from a users perspective this could mean you install an updated version of the IDE and you sketch doesn't compile any more, because you happen to use some (not in the core) library that is no longer compatible. That is ok for major updates (say Arduino 1.0.x <-> 1.5.x library compatibility), but not minor ones. That's the crux of 'official' APIs.

I'd be glad you'd join the conversation in the Arduino-developers list as there is a complete lack of formal process to evolve the APIs

  • Norbert

I'm on the developer's list. I did not see that discussion, or I would have certainly joined in. I cannot see where that addition to the library would break the "core". I modify my library to add that function, and it isn't broken. The Wiznet C code has the function to get the remote (client) ip in it already.

If it were added to the Client class, it would have to be a virtual function. This would break all existing classes that derive from Client.

from the Arduino Developers list: Enhancement: add operator==, remoteIP and remotePort to EthernetClient

... the operator== has made it into the EthernetClient as it could'nt be part of Client anyway

I guess zoomkat and I don't have a clue about anything in the ethernet library. My bad. I didn't realize the Ethernet.begin() function call had changed.

Ethernet.begin(mac, ip, gateway, subnet);

Was the dns server parameter deleted and nobody changed the online reference?

You should get that reference page changed.

no, that's my bad not having verified that this line of the Chatserver-example is actually broken since 2008 :frowning: