Pages: [1]   Go Down
Author Topic: How to obtain the remote client IP address when using the Ethernet Shield  (Read 3766 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This had baffled me for some time. There are many examples of how to do this in previous versions of the ID; however none appeared to work with v1.0 - so I thought I'd share my workaround.
I wanted to record the remote IP address of clients using my Arduino as a web server.

To make it work, I did the following:

I added the following lines to the end of the EthernetClient.cpp file:
uint8_t *EthernetClient::getRemoteIP(uint8_t remoteIP[])
{
  W5100.readSnDIPR(_sock, remoteIP);
  return remoteIP;
}


I then added the following line (under the virtual void stop(); line)to the EthernetClient.h file:
uint8_t *getRemoteIP(uint8_t RemoteIP[]);//adds remote ip address

Finally I used the following code in my sketch to access the remote IP:
client.getRemoteIP(rip); // where rip is defined as byte rip[] = {0,0,0,0 };

to display the IP in the serial monitor, I used:

for (int bcount= 0; bcount < 4; bcount++)
     {
        Serial.print(rip[bcount], DEC);
        if (bcount<3) Serial.print(".");
     }


I'm not sure that this is the most elegant way, but it works in the IDE v1.0
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9685
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried your example, but the "rip" in the below arduino code needs to be declared some where per the compiler. Where/how is this done?

Code:
Serial.print(rip[bcount], DEC);
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Zoomcat, it's in the comments of the sketch code.
Basically you need to define rip as a byte array:

either byte rip[] = {0,0,0,0 }; which assigns it as 0.0.0.0 by default or byte rip[4]; which defines it as null before use.
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9685
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Adding to some server code I already have below, I just get 0.0.0.0 printed to the serial monitor. Bottom is where your code is pasted in the .ccp and .h files. Such is the world of copy/paste. This is with the 1.0 IDE.

Code:
//zoomkat 12-8-11
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

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

byte rip[4];
//byte rip[] = {0,0,0,0};
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString;

//////////////////////

void setup(){

  pinMode(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print
  Serial.begin(9600);
  Serial.println("server LED test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging

for (int bcount= 0; bcount < 4; bcount++)
     {
        Serial.print(rip[bcount], DEC);
        if (bcount<3) Serial.print(".");
     }

Serial.println();
          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat");
               client.println();
               client.println(); 
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
         
          client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>");
          client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>");

          //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
          client.println("<IFRAME name=inlineframe style=\"display:none\" >");         
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

EthernetClient.h file:

Code:
  virtual void flush();
  virtual void stop();
  uint8_t *getRemoteIP(uint8_t RemoteIP[]);//adds remote ip address
  virtual uint8_t connected();
  virtual operator bool();

EthernetClient.cpp file:

Code:
// the next function allows us to use the client returned by
// EthernetServer::available() as the condition in an if-statement.

EthernetClient::operator bool() {
  return _sock != MAX_SOCK_NUM;
}
uint8_t *EthernetClient::getRemoteIP(uint8_t remoteIP[])
{
W5100.readSnDIPR(_sock, remoteIP);
return remoteIP;
}
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Zoomcat,

You've not put the client.getRemoteIP(rip); line in to actually read the remote IP prior to printing it.

client.getRemoteIP(rip); // this is the code that actually puts the IP into the variable rip
for (int bcount= 0; bcount < 4; bcount++)
     {
        Serial.print(rip[bcount], DEC);
        if (bcount<3) Serial.print("."); else Serial.println();
     }
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am a super newbee. I am not sure where to connected the ethernet cable if I want to get remote data from home. The router?

Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9685
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Added the client.getRemoteIP(rip); line, and voila!, it works.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Jr. Member
**
Karma: 1
Posts: 95
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am a super newbee. I am not sure where to connected the ethernet cable if I want to get remote data from home. The router?


samlro2, your question isn't directly related to this topic, but I will help you out.

If you want to connect to your Arduino via a network or internet you will need to plug it into a router.

Then, from within the network, you can access the arduino simply by entering the arduino's IP into a browser (the IP you set within the sketch).

Connecting via the internet, things get a little more complicated:
* First you will need to set up your router so it routes all port 80 requests to the arduino. google port forwarding and your router model.
* Second you will need some way of contacting your router from the internet, your external IP address is likely to vary, so the best way is to get a domain name. google about dynamic domain name providers (i.e. dyndns, no-ip etc).

There are a few guides that go into a lot more detail and give full sketches. Google should be able to help there.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I spend a lot of time to find a solution of error
Code:
no matching function for call to 'EthernetClient::getRemoteIP(byte* [4])'

The right way is to replace the line of code
Code:
byte *rip[4];
with
Code:
uint8_t rip[4];

Really thanks for the new Ethernet library, but why is the example wrong?

So there is an error on the 164 line in file EthernetClient.cpp too, the line must be
Code:
uint8_t *EthernetClient::getRemoteIP(uint8_t *remoteIP)

Could this solve your problem?
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9685
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Discussion that might be of interest.

http://forum.arduino.cc/index.php/topic,82416.0.html
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Pages: [1]   Go Up
Jump to: