Go Down

Topic: How to get remote IP without modding the core. (Read 4037 times) previous topic - next topic

pYro_65

Jan 15, 2014, 01:01 pm Last Edit: Jan 15, 2014, 01:04 pm by pYro_65 Reason: 1
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: http://forum.arduino.cc/index.php?topic=82416.msg619420#msg619420

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.

Code: [Select]


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.
Code: (EthernetFix.h) [Select]
//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:
Quote

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.
Forum Mod anyone?
https://arduino.land/Moduino/

SurferTim

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.

pYro_65

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.
Forum Mod anyone?
https://arduino.land/Moduino/

SurferTim

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.

pYro_65

#4
Jan 15, 2014, 01:37 pm Last Edit: Jan 15, 2014, 01:39 pm by pYro_65 Reason: 1
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: http://forum.arduino.cc/index.php?topic=197103.msg1458910#msg1458910

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.
Forum Mod anyone?
https://arduino.land/Moduino/

ntruchsess


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.

SurferTim

#6
Jan 15, 2014, 11:25 pm Last Edit: Jan 15, 2014, 11:37 pm by SurferTim Reason: 1


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.

ntruchsess

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

SurferTim

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.

pYro_65

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.
Forum Mod anyone?
https://arduino.land/Moduino/

ntruchsess

#10
Jan 16, 2014, 01:51 pm Last Edit: Jan 16, 2014, 03:15 pm by ntruchsess Reason: 1
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

SurferTim

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.
https://github.com/arduino/Arduino/commit/ffb8a557e6743b982dd54f1243ed8fe050c9d717
Code: [Select]
Ethernet.begin(mac, ip, gateway, subnet);
Was the dns server parameter deleted and nobody changed the online reference?
http://arduino.cc/en/Reference/EthernetBegin
You should get that reference page changed.

ntruchsess

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

Go Up