Skip to content

Commit 89d0c78

Browse files
authoredJun 13, 2020
emulation on host: fix binding from a particular interface (#7372)
allows to effectively use virtual interfaces (ifconfig eth0:1) with a different IP address
1 parent a70e834 commit 89d0c78

File tree

5 files changed

+27
-15
lines changed

5 files changed

+27
-15
lines changed
 

‎tests/host/common/Arduino.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#ifndef Arduino_h
2121
#define Arduino_h
2222

23-
#define MOCK "mock: "
23+
#define MOCK "(mock) "
2424

2525
#ifdef __cplusplus
2626
extern "C" {

‎tests/host/common/MockWiFiServerSocket.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void WiFiServer::begin ()
101101

102102
server.sin_family = AF_INET;
103103
server.sin_port = htons(mockport);
104-
server.sin_addr.s_addr = htonl(INADDR_ANY);
104+
server.sin_addr.s_addr = htonl(global_source_address);
105105
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
106106
{
107107
perror(MOCK "bind()");

‎tests/host/common/UdpContextSocket.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,8 @@ bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
7676

7777
// Filling server information
7878
servaddr.sin_family = AF_INET;
79-
//servaddr.sin_addr.s_addr = global_ipv4_netfmt?: dstaddr;
8079
(void) dstaddr;
81-
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
80+
servaddr.sin_addr.s_addr = htonl(global_source_address);
8281
servaddr.sin_port = htons(mockport);
8382

8483
// Bind the socket with the server address
@@ -97,8 +96,7 @@ bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
9796

9897
struct ip_mreq mreq;
9998
mreq.imr_multiaddr.s_addr = mcast;
100-
//mreq.imr_interface.s_addr = global_ipv4_netfmt?: htonl(INADDR_ANY);
101-
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
99+
mreq.imr_interface.s_addr = htonl(global_source_address);
102100
if (global_ipv4_netfmt)
103101
{
104102
#if __APPLE__

‎tests/host/common/mock.h

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ extern const char* host_interface; // cmdline parameter
112112
extern bool serial_timestamp;
113113
extern int mock_port_shifter;
114114
extern bool blocking_uart;
115+
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
115116

116117
#define NO_GLOBAL_BINDING 0xffffffff
117118
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to

‎tests/host/common/user_interface.cpp

+22-9
Original file line numberDiff line numberDiff line change
@@ -117,41 +117,54 @@ void wifi_fpm_set_sleep_type (sleep_type_t type)
117117
uint32_t global_ipv4_netfmt = 0; // global binding
118118

119119
netif netif0;
120+
uint32_t global_source_address = INADDR_ANY;
120121

121122
bool wifi_get_ip_info (uint8 if_index, struct ip_info *info)
122123
{
124+
// emulate wifi_get_ip_info()
125+
// ignore if_index
126+
// use global option -i (host_interface) to select bound interface/address
127+
123128
struct ifaddrs * ifAddrStruct = NULL, * ifa = NULL;
124129
uint32_t ipv4 = lwip_htonl(0x7f000001);
125130
uint32_t mask = lwip_htonl(0xff000000);
131+
global_source_address = INADDR_ANY; // =0
126132

127133
if (getifaddrs(&ifAddrStruct) != 0)
128134
{
129135
perror("getifaddrs");
130136
exit(EXIT_FAILURE);
131137
}
138+
if (host_interface)
139+
mockverbose("host: looking for interface '%s':\n", host_interface);
140+
else
141+
mockverbose("host: looking the first for non-local IPv4 interface:\n");
132142
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
133143
{
144+
mockverbose("host: interface: %s", ifa->ifa_name);
134145
if ( ifa->ifa_addr
135146
&& ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
136147
)
137148
{
138-
if (lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*) ifa->ifa_netmask)->sin_addr) != 0xff000000)
149+
auto test_ipv4 = lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
150+
mockverbose(" IPV4 (0x%08lx)", test_ipv4);
151+
if ((test_ipv4 & 0xff000000) == 0x7f000000)
152+
// 127./8
153+
mockverbose(" (local, ignored)");
154+
else
139155
{
140-
if (ipv4 == lwip_htonl(0x7f000001))
141-
{
142-
// take the first by default
143-
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
144-
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
145-
}
146-
if (host_interface && strcmp(ifa->ifa_name, host_interface) == 0)
156+
if (!host_interface || (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
147157
{
148-
// .. or the one specified by user on cmdline
158+
// use the first non-local interface, or, if specified, the one selected by user on cmdline
149159
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
150160
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
161+
mockverbose(" (selected)\n");
162+
global_source_address = ntohl(ipv4);
151163
break;
152164
}
153165
}
154166
}
167+
mockverbose("\n");
155168
}
156169
if (ifAddrStruct != NULL)
157170
freeifaddrs(ifAddrStruct);

0 commit comments

Comments
 (0)