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
|
#ifndef Arduino_h
|
||||||
#define Arduino_h
|
#define Arduino_h
|
||||||
|
|
||||||
#define MOCK "mock: "
|
#define MOCK "(mock) "
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -101,7 +101,7 @@ void WiFiServer::begin ()
|
|||||||
|
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
server.sin_port = htons(mockport);
|
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)
|
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||||
{
|
{
|
||||||
perror(MOCK "bind()");
|
perror(MOCK "bind()");
|
||||||
|
@ -76,9 +76,8 @@ bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
|||||||
|
|
||||||
// Filling server information
|
// Filling server information
|
||||||
servaddr.sin_family = AF_INET;
|
servaddr.sin_family = AF_INET;
|
||||||
//servaddr.sin_addr.s_addr = global_ipv4_netfmt?: dstaddr;
|
|
||||||
(void) 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);
|
servaddr.sin_port = htons(mockport);
|
||||||
|
|
||||||
// Bind the socket with the server address
|
// 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;
|
struct ip_mreq mreq;
|
||||||
mreq.imr_multiaddr.s_addr = mcast;
|
mreq.imr_multiaddr.s_addr = mcast;
|
||||||
//mreq.imr_interface.s_addr = global_ipv4_netfmt?: htonl(INADDR_ANY);
|
mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
|
||||||
if (global_ipv4_netfmt)
|
if (global_ipv4_netfmt)
|
||||||
{
|
{
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
|
@ -112,6 +112,7 @@ extern const char* host_interface; // cmdline parameter
|
|||||||
extern bool serial_timestamp;
|
extern bool serial_timestamp;
|
||||||
extern int mock_port_shifter;
|
extern int mock_port_shifter;
|
||||||
extern bool blocking_uart;
|
extern bool blocking_uart;
|
||||||
|
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||||
|
|
||||||
#define NO_GLOBAL_BINDING 0xffffffff
|
#define NO_GLOBAL_BINDING 0xffffffff
|
||||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
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
|
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||||
|
|
||||||
netif netif0;
|
netif netif0;
|
||||||
|
uint32_t global_source_address = INADDR_ANY;
|
||||||
|
|
||||||
bool wifi_get_ip_info (uint8 if_index, struct ip_info *info)
|
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;
|
struct ifaddrs * ifAddrStruct = NULL, * ifa = NULL;
|
||||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||||
uint32_t mask = lwip_htonl(0xff000000);
|
uint32_t mask = lwip_htonl(0xff000000);
|
||||||
|
global_source_address = INADDR_ANY; // =0
|
||||||
|
|
||||||
if (getifaddrs(&ifAddrStruct) != 0)
|
if (getifaddrs(&ifAddrStruct) != 0)
|
||||||
{
|
{
|
||||||
perror("getifaddrs");
|
perror("getifaddrs");
|
||||||
exit(EXIT_FAILURE);
|
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)
|
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
||||||
{
|
{
|
||||||
|
mockverbose("host: interface: %s", ifa->ifa_name);
|
||||||
if ( ifa->ifa_addr
|
if ( ifa->ifa_addr
|
||||||
&& ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
&& 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
|
// 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;
|
|
||||||
}
|
|
||||||
if (host_interface && strcmp(ifa->ifa_name, host_interface) == 0)
|
|
||||||
{
|
|
||||||
// .. or the one specified by user on cmdline
|
|
||||||
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||||
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||||
|
mockverbose(" (selected)\n");
|
||||||
|
global_source_address = ntohl(ipv4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mockverbose("\n");
|
||||||
}
|
}
|
||||||
if (ifAddrStruct != NULL)
|
if (ifAddrStruct != NULL)
|
||||||
freeifaddrs(ifAddrStruct);
|
freeifaddrs(ifAddrStruct);
|
||||||
|
Reference in New Issue
Block a user