napt: Added unit tests for napt

This commit is contained in:
Abhik Roy
2025-02-04 02:36:10 +00:00
parent fa4dffdfac
commit 865d7d0cae
8 changed files with 267 additions and 2 deletions
+1
View File
@@ -36,6 +36,7 @@ add_executable(lwip_unittests ${LWIP_TESTFILES})
target_include_directories(lwip_unittests PRIVATE ${LWIP_INCLUDE_DIRS})
target_compile_options(lwip_unittests PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwip_unittests PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_link_options(lwip_unittests PRIVATE -Wl,--wrap=mem_free)
find_library(LIBCHECK check)
find_library(LIBM m)
+1 -1
View File
@@ -51,7 +51,7 @@ endif
SYSARCH?=
include ../Common.mk
LDFLAGS:=-lcheck -lm $(LDFLAGS)
LDFLAGS:=-lcheck -lm $(LDFLAGS) -Wl,--wrap=mem_free
ifneq ($(UNAME_S),Darwin)
# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
+1 -1
View File
@@ -24,7 +24,7 @@ make -j 4 check
make clean
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
make -j 4 check
# test only ip4_route with debug options enabled
# test only ip4_route and ip4_napt with debug options enabled
make clean
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DESP_TEST_DEBUG=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
make -j 4 check
+1
View File
@@ -24,6 +24,7 @@ set(LWIP_TESTFILES
${LWIP_TESTDIR}/core/test_pbuf.c
${LWIP_TESTDIR}/core/test_timers.c
${LWIP_TESTDIR}/core/test_ip4_route.c
${LWIP_TESTDIR}/core/test_ip4_napt.c
${LWIP_TESTDIR}/dhcp/test_dhcp.c
${LWIP_TESTDIR}/etharp/test_etharp.c
${LWIP_TESTDIR}/ip4/test_ip4.c
+1
View File
@@ -38,6 +38,7 @@ TESTFILES=$(TESTDIR)/lwip_unittests.c \
$(TESTDIR)/core/test_mem.c \
$(TESTDIR)/core/test_netif.c \
$(TESTDIR)/core/test_ip4_route.c \
$(TESTDIR)/core/test_ip4_napt.c \
$(TESTDIR)/core/test_pbuf.c \
$(TESTDIR)/core/test_timers.c \
$(TESTDIR)/dhcp/test_dhcp.c \
+236
View File
@@ -0,0 +1,236 @@
#include "test_ip4_napt.h"
#include "lwip/netif.h"
#include "netif/ethernet.h"
#include "lwip/lwip_napt.h"
#if IP_NAPT
/* Initialize a test network interface with standard ethernet settings */
static err_t
testif_init_netif(struct netif *netif)
{
netif->name[0] = 's';
netif->name[1] = 't';
netif->mtu = 1500;
netif->hwaddr_len = 6;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x03;
netif->hwaddr[2] = 0x04;
netif->hwaddr[3] = 0x05;
netif->hwaddr[4] = 0x06;
netif->hwaddr[5] = 0x08;
return ERR_OK;
}
/* Helper function to setup test network interfaces with given IP configuration */
static struct netif *setup_test_netifs(struct netif *netif_o, const char *addr_str, const char *netmask_str, const char *gw_str)
{
ip4_addr_t addr, netmask, gw;
struct netif *netif_p;
memset(netif_o, 0, sizeof(struct netif));
/* Setup network interface with given parameters */
ip4addr_aton(addr_str, &addr);
ip4addr_aton(netmask_str, &netmask);
ip4addr_aton(gw_str, &gw);
netif_p = netif_add(netif_o, &addr, &netmask, &gw, netif_o, testif_init_netif, ethernet_input);
if (netif_p != NULL) {
netif_set_up(netif_o);
}
return netif_p;
}
/* Test enabling NAPT on a valid IP address */
START_TEST(test_ip_napt_enable_enable_napt)
{
struct netif netif1, netif2, *ret_netif;
ip4_addr_t addr;
/* Setup interfaces with proper gateway format */
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10"); /* Fixed gateway IP format */
fail_unless(ret_netif != NULL, "Failed to setup netif2");
/* Test enabling NAPT for netif1's IP address */
ip4addr_aton("192.168.1.1", &addr);
ip_napt_enable(addr.addr, 1);
fail_unless(netif1.napt == 1, "NAPT should be enabled for netif1");
fail_unless(netif2.napt == 0, "NAPT should remain disabled for netif2");
/* Cleanup in reverse order of creation */
netif_remove(&netif2);
netif_remove(&netif1);
}
END_TEST
/* Test that NAPT cannot be enabled on an invalid IP address (0.0.0.0) */
START_TEST(test_ip_napt_enable_enable_invalid_addr)
{
struct netif netif1, *ret_netif;
ip4_addr_t addr;
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
/* Test valid enable then disable */
ip4addr_aton("192.168.1.1", &addr);
ip_napt_enable(addr.addr, 1);
fail_unless(netif1.napt == 1, "Initial enable failed");
/* Disable napt */
ip_napt_enable(addr.addr, 0);
fail_unless(netif1.napt == 0, "Disable failed");
/* Test invalid enable attempt */
ip4addr_aton("0.0.0.0", &addr);
ip_napt_enable(addr.addr, 1);
fail_unless(netif1.napt == 0, "NAPT enabled with invalid address");
netif_remove(&netif1);
}
END_TEST
/* Test disabling NAPT on a specific IP address */
START_TEST(test_ip_napt_enable_disable_napt)
{
struct netif netif1, netif2, *ret_netif;
ip4_addr_t addr1, addr2;
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10"); /* Fixed gateway IP format */
fail_unless(ret_netif != NULL, "Failed to setup netif2");
/* Initialize both to enabled state */
ip4addr_aton("192.168.1.1", &addr1);
ip4addr_aton("1.2.4.4", &addr2);
ip_napt_enable(addr1.addr, 1);
ip_napt_enable(addr2.addr, 1);
/* Disable first interface */
ip_napt_enable(addr1.addr, 0);
fail_unless(netif1.napt == 0, "NAPT disable failed for netif1");
fail_unless(netif2.napt == 1, "netif2 napt state changed unexpectedly");
netif_remove(&netif2);
netif_remove(&netif1);
}
END_TEST
/* Test enabling and disabling NAPT using interface number */
START_TEST(test_ip_napt_enable_no_enable_disable_napt)
{
struct netif netif1, netif2, *ret_netif;
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10");
fail_unless(ret_netif != NULL, "Failed to setup netif2");
/* Assign unique numbers */
netif1.num = 1;
netif2.num = 2;
/* Test enable/disable by interface number */
ip_napt_enable_no(1, 1);
ip_napt_enable_no(2, 1);
fail_unless(netif1.napt == 1 && netif2.napt == 1, "Enable by number failed");
ip_napt_enable_no(1, 0);
/* Verify the state changes */
fail_unless(netif1.napt == 0, "Disable by number failed");
fail_unless(netif2.napt == 1, "netif2 NAPT state changed unexpectedly");
/* Clean up */
netif_remove(&netif2);
netif_remove(&netif1);
}
END_TEST
/* Test netif pointer based NAPT control */
START_TEST(test_ip_napt_enable_netif_enable_disable_napt)
{
struct netif netif1, *ret_netif;
int ret=0;
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
fail_unless(netif1.napt == 0, "Default state should be disabled");
ret = ip_napt_enable_netif(&netif1, 1);
fail_unless(ret == 1, "NAPT enable returned error");
fail_unless(netif1.napt == 1, "NAPT enable failed");
ret = ip_napt_enable_netif(&netif1, 0);
fail_unless(ret == 1, "NAPT disable returned error");
fail_unless(netif1.napt == 0, "NAPT disable failed");
netif_remove(&netif1);
}
END_TEST
/* Test independent interface NAPT control */
START_TEST(test_ip_napt_enable_netif_disable_napt_with_other_enabled)
{
struct netif netif1, netif2, *ret_netif;
int ret=0;
ret_netif = setup_test_netifs(&netif1, "192.168.1.1", "255.255.255.0", "192.168.1.1");
fail_unless(ret_netif != NULL, "Failed to setup netif1");
ret_netif = setup_test_netifs(&netif2, "1.2.4.4", "255.255.255.0", "1.2.4.10");
fail_unless(ret_netif != NULL, "Failed to setup netif2");
ret = ip_napt_enable_netif(&netif1, 1);
fail_unless(ret == 1, "NAPT enable returned error");
ret = ip_napt_enable_netif(&netif2, 1);
fail_unless(ret == 1, "NAPT enable returned error");
/* Verify the napt is enabled */
fail_unless(netif1.napt == 1, "NAPT disabled for netif1");
fail_unless(netif2.napt == 1, "NAPT disabled for netif2");
/* Disable NAPT for netif1 */
ret = ip_napt_enable_netif(&netif1, 0);
fail_unless(ret == 1, "NAPT disable returned error");
/* Verify the state change */
fail_unless(netif1.napt == 0, "NAPT not disabled for netif1");
fail_unless(netif2.napt == 1, "NAPT state of netif2 changed unexpectedly");
netif_remove(&netif2);
netif_remove(&netif1);
}
END_TEST
#endif /* IP_NAPT */
/* Create test suite containing all NAPT enable/disable tests */
Suite *
ip4napt_suite(void)
{
testfunc tests[] = {
#if IP_NAPT
TESTFUNC(test_ip_napt_enable_enable_napt),
TESTFUNC(test_ip_napt_enable_enable_invalid_addr),
TESTFUNC(test_ip_napt_enable_disable_napt),
TESTFUNC(test_ip_napt_enable_no_enable_disable_napt),
TESTFUNC(test_ip_napt_enable_netif_enable_disable_napt),
TESTFUNC(test_ip_napt_enable_netif_disable_napt_with_other_enabled),
#else
TESTFUNC(NULL),
#endif
};
return create_suite("IP4_NAPT", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef LWIP_HDR_TEST_IP4NAPT_H
#define LWIP_HDR_TEST_IP4NAPT_H
#include "../lwip_check.h"
Suite *ip4napt_suite(void);
#endif
+18
View File
@@ -11,6 +11,7 @@
#include "core/test_mem.h"
#include "core/test_netif.h"
#include "core/test_ip4_route.h"
#include "core/test_ip4_napt.h"
#include "core/test_pbuf.h"
#include "core/test_timers.h"
#include "etharp/test_etharp.h"
@@ -25,6 +26,22 @@
#include "lwip/tcpip.h"
#endif
/* Adding the wrapper as lwip mem_free doesn't perform
* NULL pointer check assertion for unit tests.
* Declare the real mem_free function
*/
extern void __real_mem_free(void *ptr);
extern void __wrap_mem_free(void *ptr);
/* Wrapper for mem_free that adds NULL pointer check assertion */
void __wrap_mem_free(void *rmem)
{
fail_unless(rmem != NULL, "rmem should not be NULL");
/* Call the real mem_free function */
__real_mem_free(rmem);
}
/* This function is used for LWIP_RAND by some ports... */
unsigned int
lwip_port_rand(void)
@@ -98,6 +115,7 @@ int main(void)
pppos_suite,
#endif /* PPP_SUPPORT && PPPOS_SUPPORT */
#endif /* ESP_TEST_DEBUG */
ip4napt_suite,
ip4route_suite
};
size_t num = sizeof(suites)/sizeof(void*);