diff --git a/contrib/ports/win32/msvc/lwip_unittests.vcxproj b/contrib/ports/win32/msvc/lwip_unittests.vcxproj index 270ba284..85e327d4 100644 --- a/contrib/ports/win32/msvc/lwip_unittests.vcxproj +++ b/contrib/ports/win32/msvc/lwip_unittests.vcxproj @@ -165,6 +165,7 @@ + @@ -188,6 +189,7 @@ + diff --git a/contrib/ports/win32/msvc/lwip_unittests.vcxproj.filters b/contrib/ports/win32/msvc/lwip_unittests.vcxproj.filters index bbac4e7b..d4e20251 100644 --- a/contrib/ports/win32/msvc/lwip_unittests.vcxproj.filters +++ b/contrib/ports/win32/msvc/lwip_unittests.vcxproj.filters @@ -37,6 +37,9 @@ {4d24c808-c024-4aba-a214-e5bc276e124d} + + {7b1a7667-b6c5-4f47-85ff-edfe74a7f7c7} + @@ -100,6 +103,9 @@ tcp + + lowpan6 + @@ -164,5 +170,8 @@ tcp + + lowpan6 + \ No newline at end of file diff --git a/src/netif/lowpan6.c b/src/netif/lowpan6.c index 8eb751c0..7f6849c2 100644 --- a/src/netif/lowpan6.c +++ b/src/netif/lowpan6.c @@ -726,7 +726,8 @@ lowpan6_input(struct pbuf *p, struct netif *netif) if (lrh->reass == NULL) { /* decompression failed */ mem_free(lrh); - goto lowpan6_input_discard; + MIB2_STATS_NETIF_INC(netif, ifindiscards); + return ERR_OK; } } /* TODO: handle the case where we already have FRAGN received */ diff --git a/test/unit/Filelists.cmake b/test/unit/Filelists.cmake index b3db893c..16469221 100644 --- a/test/unit/Filelists.cmake +++ b/test/unit/Filelists.cmake @@ -27,6 +27,7 @@ set(LWIP_TESTFILES ${LWIP_TESTDIR}/etharp/test_etharp.c ${LWIP_TESTDIR}/ip4/test_ip4.c ${LWIP_TESTDIR}/ip6/test_ip6.c + ${LWIP_TESTDIR}/lowpan6/test_lowpan6.c ${LWIP_TESTDIR}/mdns/test_mdns.c ${LWIP_TESTDIR}/mqtt/test_mqtt.c ${LWIP_TESTDIR}/tcp/tcp_helper.c diff --git a/test/unit/Filelists.mk b/test/unit/Filelists.mk index c33e1b04..578cc697 100644 --- a/test/unit/Filelists.mk +++ b/test/unit/Filelists.mk @@ -43,6 +43,7 @@ TESTFILES=$(TESTDIR)/lwip_unittests.c \ $(TESTDIR)/etharp/test_etharp.c \ $(TESTDIR)/ip4/test_ip4.c \ $(TESTDIR)/ip6/test_ip6.c \ + $(TESTDIR)/lowpan6/test_lowpan6.c \ $(TESTDIR)/mdns/test_mdns.c \ $(TESTDIR)/mqtt/test_mqtt.c \ $(TESTDIR)/tcp/tcp_helper.c \ diff --git a/test/unit/lowpan6/test_lowpan6.c b/test/unit/lowpan6/test_lowpan6.c new file mode 100644 index 00000000..b5540721 --- /dev/null +++ b/test/unit/lowpan6/test_lowpan6.c @@ -0,0 +1,148 @@ +#include "test_lowpan6.h" + +#include "netif/lowpan6.h" + +#include "lwip/tcpip.h" + +#if LWIP_IPV6 /* allow to build the unit tests without IPv6 support */ + +static struct netif test_netif_lowpan6; +static int linkoutput_ctr; +static int linkoutput_byte_ctr; + +/* Helper functions */ +static err_t +default_netif_linkoutput(struct netif *netif, struct pbuf *p) +{ + fail_unless(netif == &test_netif_lowpan6); + fail_unless(p != NULL); + linkoutput_ctr++; + linkoutput_byte_ctr += p->tot_len; + return ERR_OK; +} + +static err_t +default_netif_init(struct netif *netif) +{ + fail_unless(netif == &test_netif_lowpan6); + netif->name[0] = 'L'; + netif->name[1] = '6'; + netif->output_ip6 = lowpan6_output; + netif->linkoutput = default_netif_linkoutput; + netif->mtu = IP6_MIN_MTU_LENGTH; + netif->hwaddr_len = 8; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_MLD6; + netif->hwaddr[0] = 0x00; + netif->hwaddr[1] = 0x23; + netif->hwaddr[2] = 0xC1; + netif->hwaddr[3] = 0xDE; + netif->hwaddr[4] = 0xD0; + netif->hwaddr[5] = 0x0D; +#if NETIF_MAX_HWADDR_LEN < 8 +#error "6LowPAN needs NETIF_MAX_HWADDR_LEN == 8" +#endif + netif->hwaddr[6] = 0x00; + netif->hwaddr[7] = 0x01; + netif_create_ip6_linklocal_address(netif, 1); + return ERR_OK; +} + +static void +default_netif_add(void) +{ + struct netif *n; + fail_unless(netif_default == NULL); + n = netif_add_noaddr(&test_netif_lowpan6, NULL, default_netif_init, lowpan6_input); + fail_unless(n == &test_netif_lowpan6); + netif_set_default(&test_netif_lowpan6); +} + +static void +default_netif_remove(void) +{ + fail_unless(netif_default == &test_netif_lowpan6); + netif_remove(&test_netif_lowpan6); +} + +/* Setups/teardown functions */ + +static void +lowpan6_setup(void) +{ + default_netif_add(); + lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT)); +} + +static void +lowpan6_teardown(void) +{ + if (netif_list->loop_first != NULL) { + pbuf_free(netif_list->loop_first); + netif_list->loop_first = NULL; + } + netif_list->loop_last = NULL; + /* poll until all memory is released... */ + tcpip_thread_poll_one(); + default_netif_remove(); + lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT)); +} + +START_TEST(test_6low_frag1_short) +{ + unsigned char frame[] = { + 0x61, 0xC8, /* Frame Control */ + 0x01, /* Sequence Number */ + 0xCD, 0xAB, /* Dst PAN ID (LE) */ + 0xFF, 0xFF, /* Dst Short Addr (LE) */ + 0x01, 0x00, 0x0D, 0xD0, 0xDE, 0xC1, 0x23, 0x00, /* Src Ext Addr */ + /* 6LoWPAN FRAG1 dispatch: b & 0xf8 == 0xc0 */ + 0xC0, 0x08, /* datagram_size=8, high bits */ + 0x00, 0x00, /* datagram_tag=0 */ + /* IPHC dispatch byte (0x60) - triggers lowpan6_decompress which will + * fail because there's not enough data for the IPHC header */ + 0x60 }; + + struct pbuf* p; + err_t err; + LWIP_UNUSED_ARG(_i); + + p = pbuf_alloc(PBUF_RAW, sizeof(frame), PBUF_POOL); + fail_unless(p != NULL); + if (p == NULL) { + return; + } + pbuf_take(p, frame, sizeof(frame)); + + err = lowpan6_input(p, &test_netif_lowpan6); + fail_unless(err == ERR_OK); +} +END_TEST + +/** Create the suite including all tests for this module */ +Suite * +lowpan6_suite(void) +{ + testfunc tests[] = { + TESTFUNC(test_6low_frag1_short) + }; + return create_suite("6LoWPAN", tests, sizeof(tests)/sizeof(testfunc), lowpan6_setup, lowpan6_teardown); +} + +#else /* LWIP_IPV6 */ + +/* allow to build the unit tests without IPv6 support */ +START_TEST(test_lowpan6_dummy) +{ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +Suite * +lowpan6_suite(void) +{ + testfunc tests[] = { + TESTFUNC(test_lowpan6_dummy), + }; + return create_suite("6LoWPAN", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL); +} +#endif /* LWIP_IPV6 */ diff --git a/test/unit/lowpan6/test_lowpan6.h b/test/unit/lowpan6/test_lowpan6.h new file mode 100644 index 00000000..4635ba92 --- /dev/null +++ b/test/unit/lowpan6/test_lowpan6.h @@ -0,0 +1,8 @@ +#ifndef LWIP_HDR_TEST_LOWPAN6_H +#define LWIP_HDR_TEST_LOWPAN6_H + +#include "../lwip_check.h" + +Suite* lowpan6_suite(void); + +#endif diff --git a/test/unit/lwip_unittests.c b/test/unit/lwip_unittests.c index d088a066..3dd9e9ac 100644 --- a/test/unit/lwip_unittests.c +++ b/test/unit/lwip_unittests.c @@ -18,6 +18,7 @@ #include "mqtt/test_mqtt.h" #include "api/test_sockets.h" #include "ppp/test_pppos.h" +#include "lowpan6//test_lowpan6.h" #include "lwip/init.h" #if !NO_SYS @@ -83,6 +84,7 @@ int main(void) suite_getter_fn* suites[] = { ip4_suite, ip6_suite, + lowpan6_suite, udp_suite, tcp_suite, tcp_oos_suite, diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h index 03579ee7..d42ff0bf 100644 --- a/test/unit/lwipopts.h +++ b/test/unit/lwipopts.h @@ -35,6 +35,7 @@ #define LWIP_TESTMODE 1 #define LWIP_IPV6 1 +#define NETIF_MAX_HWADDR_LEN 8U /* for 6LoWPAN tests */ #define LWIP_CHECKSUM_ON_COPY 1 #define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 1