mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-13 13:01:55 +03:00
emulation on host: fix binding from a particular interface (#7372)
allows to effectively use virtual interfaces (ifconfig eth0:1) with a different IP address
This commit is contained in:
@ -20,7 +20,7 @@
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#define MOCK "mock: "
|
||||
#define MOCK "(mock) "
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -101,7 +101,7 @@ void WiFiServer::begin ()
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(mockport);
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
server.sin_addr.s_addr = htonl(global_source_address);
|
||||
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "bind()");
|
||||
|
@ -76,9 +76,8 @@ bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
|
||||
// Filling server information
|
||||
servaddr.sin_family = AF_INET;
|
||||
//servaddr.sin_addr.s_addr = global_ipv4_netfmt?: dstaddr;
|
||||
(void) dstaddr;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_addr.s_addr = htonl(global_source_address);
|
||||
servaddr.sin_port = htons(mockport);
|
||||
|
||||
// Bind the socket with the server address
|
||||
@ -97,8 +96,7 @@ bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = mcast;
|
||||
//mreq.imr_interface.s_addr = global_ipv4_netfmt?: htonl(INADDR_ANY);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||
if (global_ipv4_netfmt)
|
||||
{
|
||||
#if __APPLE__
|
||||
|
@ -112,6 +112,7 @@ extern const char* host_interface; // cmdline parameter
|
||||
extern bool serial_timestamp;
|
||||
extern int mock_port_shifter;
|
||||
extern bool blocking_uart;
|
||||
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||
|
||||
#define NO_GLOBAL_BINDING 0xffffffff
|
||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
||||
|
@ -117,41 +117,54 @@ void wifi_fpm_set_sleep_type (sleep_type_t type)
|
||||
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||
|
||||
netif netif0;
|
||||
uint32_t global_source_address = INADDR_ANY;
|
||||
|
||||
bool wifi_get_ip_info (uint8 if_index, struct ip_info *info)
|
||||
{
|
||||
// emulate wifi_get_ip_info()
|
||||
// ignore if_index
|
||||
// use global option -i (host_interface) to select bound interface/address
|
||||
|
||||
struct ifaddrs * ifAddrStruct = NULL, * ifa = NULL;
|
||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||
uint32_t mask = lwip_htonl(0xff000000);
|
||||
global_source_address = INADDR_ANY; // =0
|
||||
|
||||
if (getifaddrs(&ifAddrStruct) != 0)
|
||||
{
|
||||
perror("getifaddrs");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (host_interface)
|
||||
mockverbose("host: looking for interface '%s':\n", host_interface);
|
||||
else
|
||||
mockverbose("host: looking the first for non-local IPv4 interface:\n");
|
||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
mockverbose("host: interface: %s", ifa->ifa_name);
|
||||
if ( ifa->ifa_addr
|
||||
&& ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
||||
)
|
||||
{
|
||||
if (lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*) ifa->ifa_netmask)->sin_addr) != 0xff000000)
|
||||
auto test_ipv4 = lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
|
||||
mockverbose(" IPV4 (0x%08lx)", test_ipv4);
|
||||
if ((test_ipv4 & 0xff000000) == 0x7f000000)
|
||||
// 127./8
|
||||
mockverbose(" (local, ignored)");
|
||||
else
|
||||
{
|
||||
if (ipv4 == lwip_htonl(0x7f000001))
|
||||
if (!host_interface || (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
|
||||
{
|
||||
// take the first by default
|
||||
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
}
|
||||
if (host_interface && strcmp(ifa->ifa_name, host_interface) == 0)
|
||||
{
|
||||
// .. or the one specified by user on cmdline
|
||||
// use the first non-local interface, or, if specified, the one selected by user on cmdline
|
||||
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
mockverbose(" (selected)\n");
|
||||
global_source_address = ntohl(ipv4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mockverbose("\n");
|
||||
}
|
||||
if (ifAddrStruct != NULL)
|
||||
freeifaddrs(ifAddrStruct);
|
||||
|
Reference in New Issue
Block a user