Go Down

Topic: Get the Remote IP and port from the server- solved (Read 2110 times) previous topic - next topic

david-

Thanks to Sandeep Mistry, who addressed the issue of being unable to obtain the remote IP of a client connected to the WiFi101 shield, acting as a server.

The issue is detailed at:
https://github.com/arduino-libraries/WiFi101/issues/40

Code: [Select]

IPAddress rip; // remote IP;
long rport; // remote port


// ************* Remote IP & port callback ******************************************

static void myResolve_cb(uint8_t * /* hostName */, uint32_t hostIp) {
WiFi._resolve = hostIp;
}

void mySocketBufferCb(SOCKET sock, uint8 u8Msg, void *pvMsg) {
socketBufferCb(sock, u8Msg, pvMsg); // call the original callback
  if( u8Msg == SOCKET_MSG_ACCEPT) {
  tstrSocketAcceptMsg *pstrAccept = (tstrSocketAcceptMsg *)pvMsg;
  rip = pstrAccept->strAddr.sin_addr.s_addr;
  rport = pstrAccept->strAddr.sin_port;
  Serial.print(F("\nRemote connection from: "));
  Serial.print(rip); Serial.print(":"); Serial.println(rport);
  }
}

// ************* End Remote IP callback ******************************************


void setup(){

// ...

// after connecting to the wifi network

delay(1000);

// overide the original callbacks

registerSocketCallback(mySocketBufferCb, myResolve_cb);


// start the server:

server.begin();

}


void loop() {
// wait for a new client:

WiFiClient client = server.available();

   if (client){

   // remote ip is now available in global variable rip
   // remote port is available in rport
   // Log the client if required

 // ...
 }



Each time a client connects the callback routine intercepts
u8Msg == SOCKET_MSG_ACCEPT

(There are a number of other messages- see socket.h in library)

The Remote IP and remote port are sent to the serial monitor and the global variables updated.

I have used the code to update a client log on my server.
It is also possible to reject the client by comparing rip against a file of bad client IP's.

David

CraigF

This is an EXTREMELY useful addition.  It should be easier to find.  And there is no way we should have to override a callback in sockets.h in order to have this data exposed -- it should be part of the server (client) interface. In fact, without something like this remote IP address (though really it's the mac address we need) I'm not sure how you could distinguish one client from another in any multi-client setting.

** HOWEVER ** I must point out that the published code will cause intellisense errors if compiled in Visual Studio (Visual Micro) because the sockets.h library defines registerSocketCallback as:


Quote
NMI_API void registerSocketCallback(tpfAppSocketCb socket_cb, tpfAppResolveCb resolve_cb);
where tpfAppResolveCb is defined as

Quote
typedef void (*tpfAppResolveCb) (uint8* pu8DomainName, uint32 u32ServerIP);
while the new callback myResolve_cb is defined as

Quote
static void myResolve_cb(uint8_t* /* hostName */, uint32_t hostIp)
To resolve this problem, in myResolve_cb you must change uint8_t to uint8 and change uint32_t to uint32.




Go Up