Get IP Address of Anyone Connected to my Arduino set up as server

After modifying files you might need to restart all instances of the IDE.

Which version of the IDE are you using?

Rob

OK, here is what I have now... It took me a while to figure out that in your snippets of the .h and .cpp file I was supposed to find some of the text and add the pertinant stuff right after it... Got that done now. I am running Ver0022 and yes, every time I make a change to the files, I close and reopen all the Arduino IDE's. When I compile now, this is what I get:

C:\Users\Jeremy\Desktop\arduino-0022\libraries\Ethernet\Client.cpp: In member function 'void Client::IP_address(uint8_t*)':
C:\Users\Jeremy\Desktop\arduino-0022\libraries\Ethernet\Client.cpp:26: error: 'getSn_DIPR' was not declared in this scope

???

Jeremy

@ Jeremy :

See my previous post, but here again:
The ethernet lib changed in version 19. The patch proposed here was for version 18.


  1. #include <SPI.h> should be added for version 19 and up
  2. 'getSn_DIPR' was not declared in this scope

The first was solved easily, do you know how to fix the second? Fixed!!
The second is to use the code below in Client.cpp

void Client::IP_address(uint8_t * addr)
{
W5100.readSnDIPR(_sock, addr); // replaces the getSn_DIPR(_sock, addr); V18 and below
}

Hopes this helps,
Rob

@Rob

I am not used to going back and looking for edits in post. On most forums, a new post is made. This is not your fault. I am just explaining why I missed it and will learn to re-read and look for edits. Thank you for your help.

I made the change that you edited and got a few more errors that I will not bother to post because, I read through them and managed to understand what was wrong! When I copied the code into the Client.h file, I missed copying the semicolon. Now it all compiles and uploads fine. Thanks!

Any idea now, how to make the arduino scan the connected computer for credit card info?

Yes, the previous line of text was a JOKE!!! :slight_smile: Thanks everyone that help straighten me out!

Jeremy

Jeremy-arduino:
Any idea now, how to make the arduino scan the connected computer for credit card info?

Ohhh, just when I thought I had found a new day project to get me busy.

Glad you got it working.

OK, so this has worked great for everything that I have tried so far except one thing. I'm sure it's something simple but I am trying to store the IP to a variable instead of just printing the IP at the present time. This is what I have but it does not work.

client.IP_address(&client_ip[0]);//added 
           //client.println("Your IP is:");//added 
           int currentIP;  // My addition
           for (int n = 0; n<=3; n++)//added 
            {//added 
            lcd.print((int)client_ip[n]);//added --  I changed this and it works
            currentIP += ((int)client_ip[n]);  // My addition
            if(n < 3){
              lcd.print(".");//added -- I changed this and it works
              currentIP += '.';  // My addition
            }//added

I would have thought that would work but it might not be the right data type? Not sure what it is that I should do. Thanks.

Jeremy

An IP address is four bytes, that cannot be storeds in an int of two bytes. You need a long

pack:
for (int i=0; i<3; i++)
{
long_ip = 256;
long_ip += client_ip
;*
}
unpack;
temp = long_ip;
for (int i=0; i<3; i++)
{
client_ip = (byte) temp & 0xFF;
* temp /= 256;*
}

I know I had this working at one time and now when I compile, after I made changes to an unrelated part of code, it fails. Here is the part that is failing.

client.IP_address(&client_ip[0]);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
long long_ip;
for (int n = 0; n<=3; n++)
{
long_ip *= 256;
long_ip += client_ip; // This part here is where I get my errors.....which are posted below...
}

long temp = long_ip;
for (int i=0; i<3; i++)
{
client_ip = (byte) temp & 0xFF; // This part here is where I get my errors.....which are posted below...
temp /= 256;
}

gate_garage_NewHTML.cpp: In function 'void loop()':
gate_garage_NewHTML:129: error: invalid conversion from 'byte*' to 'long int'
gate_garage_NewHTML:135: error: incompatible types in assignment of 'int' to 'byte [4]'

client_ip is declared before the setup function...
What is supposed to be happening here is the clients ip is to be written to a long and then printed to the LCD16X2. I have it working on the arduino right now, but that was from a burn about a month ago and I don't seem to have saved the correct way to do it... Any ideas?

long_ip += client_ip[n]; // need to add the index of the array you want to add

client_ip = (byte) temp & 0xFF; // idem

OK, adding the index fixed the first issue. Thanks. But I have now idea what "idem" means. I googled it, and found some results, but they didn't make any sense...

What were you planning to achieve with this:

for (int i=0; i<3; i++) 
            {
              client_ip = (byte) temp & 0xFF; // This part here is where I get my errors.....which are posted below...
              temp /= 256;
            }

?

I don't quite know what that does, I didn't write it. It was given a few posts back and at one time, I had it working, must have forgot to save my work after the last burn, and lost it. If there is a simpler idea, I'm open to it.

What were you planning to achieve with this:

It looks like splitting a long into 4 separate bytes, but the index [n] is missing.

Jeremy-arduino:
I don't quite know what that does, I didn't write it. It was given a few posts back and at one time, I had it working, must have forgot to save my work after the last burn, and lost it. If there is a simpler idea, I'm open to it.

And what were you planning to achieve when that code was given to you? If you don't know what it does... and it is given you trouble. Delete it, and run the program. See if something's missing... if not, you just fixed it. :wink:

Well, when robtillaart gave that code bit, I wanted the clients IP written to a string that could be printed to the LCD. I'm not sure if the question was supposed to be sarcastic or not, but when I answered the question with "I don't quit know...", of course I know what I want it to do, BUT, I don't necessarily know what each line is actually doing.

So, I changed this...

           for (int i=0; i<3; i++) 
            {
              client_ip[i] = () temp & 0xFF; // I added the index thing here...
              temp /= 256;
            }

So, I'm not sure what this is going to do when I upload it to my board, so is there a way to download the working previous version from my board, even if it's not pretty and upload it later if this breaks my program?

I'm running IDE 21 and I have the ip of the incoming printing just fine using code I took from this thread.

to Client.cpp I added:

void Client::getRemoteIP_address(uint8_t * addr){ // added by me
W5100.readSnDIPR(_sock, addr); // replaces the getSn_DIPR(_sock, addr); V18 and below
}

and to Client.h:

void getRemoteIP_address(uint8_t * addr);//added by me

Then in my code to get the address:

uint8_t clientIp[4];

incoming.getRemoteIP_address(&clientIp[0]);

to format the ip address so you can display it you can call the routine below:

// format an IP address. (I stole this)
const char* ip_to_str(const uint8_t* ipAddr)
{
strcpy_P(Dbuf2,PSTR("%d.%d.%d.%d\0"));
sprintf(Dbuf, Dbuf2, ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); //see how its a 4 byte array?
return (Dbuf);
}

Dbuf and Dbuf2 are string arrays declared at the beginning of the program and used as scratch buffers throughout. Call the routine like this to see what you get:

Serial.println(clientIp); // where clientIp is the result of the incoming.getRemoteIP_address above

I do not recommend converting the ip address to a long or anything else except a string for display. Use it as a 4 byte array since that is the way it is handed to the various ethernet routines. The format routine above will create a nnn.nnn.nnn.nnn type of string so you'll see 192.168.0.25 or some such for addresses inside your router. You can even compare it in the array form. For example:

#define maskcmp(addr1, addr2, mask)
(((((uint16_t *)addr1)[0] & ((uint16_t *)mask)[0]) ==
(((uint16_t *)addr2)[0] & ((uint16_t *)mask)[0])) &&
((((uint16_t *)addr1)[1] & ((uint16_t *)mask)[1]) ==
(((uint16_t *)addr2)[1] & ((uint16_t *)mask)[1])))

This mess of a macro (just copy and paste it, do not try to type that crap in) will compare the ip address (as an array) using the netmask to tell you if the machine that is coming in is inside your router or outside. If you call it like this:

maskcmp(incomingIp,thisBoardsIp,subnet_mask)

will return true if it is a local address. Nice for protecting something from the outside.

DON'T GIVE UP ! You can do this and it will make a cool display that you can brag about for months.

i tried this code but the only ip it show's is allways : 254.237.192.1

where is the problem in the code?

byte client_ip[4];

..

client.IP_address(&client_ip[0]);
int c1=client_ip[1];
int c2=client_ip[2];
int c3=client_ip[3];
int c4=client_ip[4];
Serial.println("");
Serial.print(c1);
Serial.print(".");
Serial.print(c2);
Serial.print(".");
Serial.print(c3);
Serial.print(".");
Serial.print(c4);

Post the code from client.h and client.cpp for this function.

client.IP_address(&client_ip[0]);

And this will only be valid while a client is connected.

Client client = server.available();

if(client)
{
   client.IP_address(client_ip);

   // rest of your code
}

Has anyone managed to get this working with v1.0 of the IDE?
I tried changing the Client references to EthernetClient but cannot manage to get it to compile without errors.
I had hoped that remote IP would have been part of the library by now.
Any help would be appreciated.
Phil.