Skip to content

Commit add482a

Browse files
committed
WiFiClient::remoteIP and remoteIP6 IPv6 support
For RemoteIP and AF_INET6 socket i added support ip6 to ip4 mapping, so .remoteIP will return IPv4 address on dual stack socket, if available. Scenarios tested: WiFiTelnetToSerial, wifiMulti.IPv6(true), connect both from IPv4 and IPv6 WiFiTelnetToSerial, wifiMulti.IPv6(true); but set to listen on IPv4 only. WiFiTelnetToSerial, IPv6 disabled, with or without bind to specific IP4. AsyncUDPServer, without IPv6 support. Signed-off-by: Denys Fedoryshchenko <[email protected]>
1 parent cf31166 commit add482a

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

libraries/WiFi/src/WiFiClient.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
#include <lwip/netdb.h>
2424
#include <errno.h>
2525

26+
#define IN6_IS_ADDR_V4MAPPED(a) \
27+
((((__const uint32_t *) (a))[0] == 0) \
28+
&& (((__const uint32_t *) (a))[1] == 0) \
29+
&& (((__const uint32_t *) (a))[2] == htonl (0xffff)))
30+
2631
#define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000)
2732
#define WIFI_CLIENT_MAX_WRITE_RETRY (10)
2833
#define WIFI_CLIENT_SELECT_TIMEOUT_US (1000000)
@@ -562,8 +567,24 @@ IPAddress WiFiClient::remoteIP(int fd) const
562567
struct sockaddr_storage addr;
563568
socklen_t len = sizeof addr;
564569
getpeername(fd, (struct sockaddr*)&addr, &len);
565-
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
566-
return IPAddress((uint32_t)(s->sin_addr.s_addr));
570+
571+
// IPv4 socket, old way
572+
if (((struct sockaddr*)&addr)->sa_family == AF_INET) {
573+
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
574+
return IPAddress((uint32_t)(s->sin_addr.s_addr));
575+
}
576+
577+
// IPv6, but it might be IPv4 mapped address
578+
if (((struct sockaddr*)&addr)->sa_family == AF_INET6) {
579+
struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&addr;
580+
if (IN6_IS_ADDR_V4MAPPED(saddr6->sin6_addr.un.u32_addr)) {
581+
return IPAddress(IPv4, (uint8_t*)saddr6->sin6_addr.s6_addr+12);
582+
} else {
583+
return IPAddress(IPv6, (uint8_t*)(saddr6->sin6_addr.s6_addr));
584+
}
585+
}
586+
log_e("WiFiClient::remoteIP Not AF_INET or AF_INET6?");
587+
return (IPAddress(0,0,0,0));
567588
}
568589

569590
uint16_t WiFiClient::remotePort(int fd) const

0 commit comments

Comments
 (0)