Skip to content

Commit 865d7d0

Browse files
committed
napt: Added unit tests for napt
1 parent fa4dffd commit 865d7d0

File tree

8 files changed

+267
-2
lines changed

8 files changed

+267
-2
lines changed

contrib/ports/unix/check/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ add_executable(lwip_unittests ${LWIP_TESTFILES})
3636
target_include_directories(lwip_unittests PRIVATE ${LWIP_INCLUDE_DIRS})
3737
target_compile_options(lwip_unittests PRIVATE ${LWIP_COMPILER_FLAGS})
3838
target_compile_definitions(lwip_unittests PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
39+
target_link_options(lwip_unittests PRIVATE -Wl,--wrap=mem_free)
3940

4041
find_library(LIBCHECK check)
4142
find_library(LIBM m)

contrib/ports/unix/check/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ endif
5151
SYSARCH?=
5252
include ../Common.mk
5353

54-
LDFLAGS:=-lcheck -lm $(LDFLAGS)
54+
LDFLAGS:=-lcheck -lm $(LDFLAGS) -Wl,--wrap=mem_free
5555

5656
ifneq ($(UNAME_S),Darwin)
5757
# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)

test/ci/unit_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ make -j 4 check
2424
make clean
2525
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
2626
make -j 4 check
27-
# test only ip4_route with debug options enabled
27+
# test only ip4_route and ip4_napt with debug options enabled
2828
make clean
2929
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DESP_TEST_DEBUG=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
3030
make -j 4 check

test/unit/Filelists.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(LWIP_TESTFILES
2424
${LWIP_TESTDIR}/core/test_pbuf.c
2525
${LWIP_TESTDIR}/core/test_timers.c
2626
${LWIP_TESTDIR}/core/test_ip4_route.c
27+
${LWIP_TESTDIR}/core/test_ip4_napt.c
2728
${LWIP_TESTDIR}/dhcp/test_dhcp.c
2829
${LWIP_TESTDIR}/etharp/test_etharp.c
2930
${LWIP_TESTDIR}/ip4/test_ip4.c

test/unit/Filelists.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ TESTFILES=$(TESTDIR)/lwip_unittests.c \
3838
$(TESTDIR)/core/test_mem.c \
3939
$(TESTDIR)/core/test_netif.c \
4040
$(TESTDIR)/core/test_ip4_route.c \
41+
$(TESTDIR)/core/test_ip4_napt.c \
4142
$(TESTDIR)/core/test_pbuf.c \
4243
$(TESTDIR)/core/test_timers.c \
4344
$(TESTDIR)/dhcp/test_dhcp.c \

test/unit/core/test_ip4_napt.c

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#include "test_ip4_napt.h"
2+
3+
#include "lwip/netif.h"
4+
#include "netif/ethernet.h"
5+
#include "lwip/lwip_napt.h"
6+
7+
8+
#if IP_NAPT
9+
10+
/* Initialize a test network interface with standard ethernet settings */
11+
static err_t
12+
testif_init_netif(struct netif *netif)
13+
{
14+
netif->name[0] = 's';
15+
netif->name[1] = 't';
16+
netif->mtu = 1500;
17+
netif->hwaddr_len = 6;
18+
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
19+
20+
netif->hwaddr[0] = 0x02;
21+
netif->hwaddr[1] = 0x03;
22+
netif->hwaddr[2] = 0x04;
23+
netif->hwaddr[3] = 0x05;
24+
netif->hwaddr[4] = 0x06;
25+
netif->hwaddr[5] = 0x08;
26+
27+
return ERR_OK;
28+
}
29+
30+
/* Helper function to setup test network interfaces with given IP configuration */
31+
static struct netif *setup_test_netifs(struct netif *netif_o, const char *addr_str, const char *netmask_str, const char *gw_str)
32+
{
33+
ip4_addr_t addr, netmask, gw;
34+
struct netif *netif_p;
35+
36+
memset(netif_o, 0, sizeof(struct netif));
37+
38+
/* Setup network interface with given parameters */
39+
ip4addr_aton(addr_str, &addr);
40+
ip4addr_aton(netmask_str, &netmask);
41+
ip4addr_aton(gw_str, &gw);
42+
netif_p = netif_add(netif_o, &addr, &netmask, &gw, netif_o, testif_init_netif, ethernet_input);
43+
if (netif_p != NULL) {
44+
netif_set_up(netif_o);
45+
}
46+
47+
return netif_p;
48+
}
49+
50+
/* Test enabling NAPT on a valid IP address */
51+
START_TEST(test_ip_napt_enable_enable_napt)
52+
{
53+
struct netif netif1, netif2, *ret_netif;
54+
ip4_addr_t addr;
55+
56+
/* Setup interfaces with proper gateway format */
57+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
58+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
59+
60+
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10"); /* Fixed gateway IP format */
61+
fail_unless(ret_netif != NULL, "Failed to setup netif2");
62+
63+
/* Test enabling NAPT for netif1's IP address */
64+
ip4addr_aton("192.168.1.1", &addr);
65+
ip_napt_enable(addr.addr, 1);
66+
67+
fail_unless(netif1.napt == 1, "NAPT should be enabled for netif1");
68+
fail_unless(netif2.napt == 0, "NAPT should remain disabled for netif2");
69+
70+
/* Cleanup in reverse order of creation */
71+
netif_remove(&netif2);
72+
netif_remove(&netif1);
73+
}
74+
END_TEST
75+
76+
/* Test that NAPT cannot be enabled on an invalid IP address (0.0.0.0) */
77+
START_TEST(test_ip_napt_enable_enable_invalid_addr)
78+
{
79+
struct netif netif1, *ret_netif;
80+
ip4_addr_t addr;
81+
82+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
83+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
84+
85+
/* Test valid enable then disable */
86+
ip4addr_aton("192.168.1.1", &addr);
87+
ip_napt_enable(addr.addr, 1);
88+
fail_unless(netif1.napt == 1, "Initial enable failed");
89+
90+
/* Disable napt */
91+
ip_napt_enable(addr.addr, 0);
92+
fail_unless(netif1.napt == 0, "Disable failed");
93+
94+
/* Test invalid enable attempt */
95+
ip4addr_aton("0.0.0.0", &addr);
96+
ip_napt_enable(addr.addr, 1);
97+
fail_unless(netif1.napt == 0, "NAPT enabled with invalid address");
98+
99+
netif_remove(&netif1);
100+
}
101+
END_TEST
102+
103+
/* Test disabling NAPT on a specific IP address */
104+
START_TEST(test_ip_napt_enable_disable_napt)
105+
{
106+
struct netif netif1, netif2, *ret_netif;
107+
ip4_addr_t addr1, addr2;
108+
109+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
110+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
111+
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10"); /* Fixed gateway IP format */
112+
fail_unless(ret_netif != NULL, "Failed to setup netif2");
113+
114+
/* Initialize both to enabled state */
115+
ip4addr_aton("192.168.1.1", &addr1);
116+
ip4addr_aton("1.2.4.4", &addr2);
117+
ip_napt_enable(addr1.addr, 1);
118+
ip_napt_enable(addr2.addr, 1);
119+
120+
/* Disable first interface */
121+
ip_napt_enable(addr1.addr, 0);
122+
fail_unless(netif1.napt == 0, "NAPT disable failed for netif1");
123+
fail_unless(netif2.napt == 1, "netif2 napt state changed unexpectedly");
124+
125+
netif_remove(&netif2);
126+
netif_remove(&netif1);
127+
}
128+
END_TEST
129+
130+
/* Test enabling and disabling NAPT using interface number */
131+
START_TEST(test_ip_napt_enable_no_enable_disable_napt)
132+
{
133+
struct netif netif1, netif2, *ret_netif;
134+
135+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
136+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
137+
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10");
138+
fail_unless(ret_netif != NULL, "Failed to setup netif2");
139+
140+
/* Assign unique numbers */
141+
netif1.num = 1;
142+
netif2.num = 2;
143+
144+
/* Test enable/disable by interface number */
145+
ip_napt_enable_no(1, 1);
146+
ip_napt_enable_no(2, 1);
147+
fail_unless(netif1.napt == 1 && netif2.napt == 1, "Enable by number failed");
148+
149+
ip_napt_enable_no(1, 0);
150+
151+
/* Verify the state changes */
152+
fail_unless(netif1.napt == 0, "Disable by number failed");
153+
fail_unless(netif2.napt == 1, "netif2 NAPT state changed unexpectedly");
154+
155+
/* Clean up */
156+
netif_remove(&netif2);
157+
netif_remove(&netif1);
158+
}
159+
END_TEST
160+
161+
/* Test netif pointer based NAPT control */
162+
START_TEST(test_ip_napt_enable_netif_enable_disable_napt)
163+
{
164+
struct netif netif1, *ret_netif;
165+
int ret=0;
166+
167+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
168+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
169+
170+
fail_unless(netif1.napt == 0, "Default state should be disabled");
171+
172+
ret = ip_napt_enable_netif(&netif1, 1);
173+
fail_unless(ret == 1, "NAPT enable returned error");
174+
fail_unless(netif1.napt == 1, "NAPT enable failed");
175+
176+
ret = ip_napt_enable_netif(&netif1, 0);
177+
fail_unless(ret == 1, "NAPT disable returned error");
178+
fail_unless(netif1.napt == 0, "NAPT disable failed");
179+
180+
netif_remove(&netif1);
181+
}
182+
END_TEST
183+
184+
/* Test independent interface NAPT control */
185+
START_TEST(test_ip_napt_enable_netif_disable_napt_with_other_enabled)
186+
{
187+
struct netif netif1, netif2, *ret_netif;
188+
int ret=0;
189+
190+
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
191+
fail_unless(ret_netif != NULL, "Failed to setup netif1");
192+
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10");
193+
fail_unless(ret_netif != NULL, "Failed to setup netif2");
194+
195+
ret = ip_napt_enable_netif(&netif1, 1);
196+
fail_unless(ret == 1, "NAPT enable returned error");
197+
ret = ip_napt_enable_netif(&netif2, 1);
198+
fail_unless(ret == 1, "NAPT enable returned error");
199+
200+
/* Verify the napt is enabled */
201+
fail_unless(netif1.napt == 1, "NAPT disabled for netif1");
202+
fail_unless(netif2.napt == 1, "NAPT disabled for netif2");
203+
204+
/* Disable NAPT for netif1 */
205+
ret = ip_napt_enable_netif(&netif1, 0);
206+
fail_unless(ret == 1, "NAPT disable returned error");
207+
208+
/* Verify the state change */
209+
fail_unless(netif1.napt == 0, "NAPT not disabled for netif1");
210+
fail_unless(netif2.napt == 1, "NAPT state of netif2 changed unexpectedly");
211+
212+
netif_remove(&netif2);
213+
netif_remove(&netif1);
214+
}
215+
END_TEST
216+
#endif /* IP_NAPT */
217+
218+
/* Create test suite containing all NAPT enable/disable tests */
219+
Suite *
220+
ip4napt_suite(void)
221+
{
222+
testfunc tests[] = {
223+
#if IP_NAPT
224+
TESTFUNC(test_ip_napt_enable_enable_napt),
225+
TESTFUNC(test_ip_napt_enable_enable_invalid_addr),
226+
TESTFUNC(test_ip_napt_enable_disable_napt),
227+
TESTFUNC(test_ip_napt_enable_no_enable_disable_napt),
228+
TESTFUNC(test_ip_napt_enable_netif_enable_disable_napt),
229+
TESTFUNC(test_ip_napt_enable_netif_disable_napt_with_other_enabled),
230+
#else
231+
TESTFUNC(NULL),
232+
#endif
233+
};
234+
235+
return create_suite("IP4_NAPT", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
236+
}

test/unit/core/test_ip4_napt.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef LWIP_HDR_TEST_IP4NAPT_H
2+
#define LWIP_HDR_TEST_IP4NAPT_H
3+
4+
#include "../lwip_check.h"
5+
6+
Suite *ip4napt_suite(void);
7+
8+
#endif

test/unit/lwip_unittests.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "core/test_mem.h"
1212
#include "core/test_netif.h"
1313
#include "core/test_ip4_route.h"
14+
#include "core/test_ip4_napt.h"
1415
#include "core/test_pbuf.h"
1516
#include "core/test_timers.h"
1617
#include "etharp/test_etharp.h"
@@ -25,6 +26,22 @@
2526
#include "lwip/tcpip.h"
2627
#endif
2728

29+
/* Adding the wrapper as lwip mem_free doesn't perform
30+
* NULL pointer check assertion for unit tests.
31+
* Declare the real mem_free function
32+
*/
33+
extern void __real_mem_free(void *ptr);
34+
extern void __wrap_mem_free(void *ptr);
35+
36+
/* Wrapper for mem_free that adds NULL pointer check assertion */
37+
void __wrap_mem_free(void *rmem)
38+
{
39+
fail_unless(rmem != NULL, "rmem should not be NULL");
40+
41+
/* Call the real mem_free function */
42+
__real_mem_free(rmem);
43+
}
44+
2845
/* This function is used for LWIP_RAND by some ports... */
2946
unsigned int
3047
lwip_port_rand(void)
@@ -98,6 +115,7 @@ int main(void)
98115
pppos_suite,
99116
#endif /* PPP_SUPPORT && PPPOS_SUPPORT */
100117
#endif /* ESP_TEST_DEBUG */
118+
ip4napt_suite,
101119
ip4route_suite
102120
};
103121
size_t num = sizeof(suites)/sizeof(void*);

0 commit comments

Comments
 (0)