diff --git a/test/fuzz/Makefile b/test/fuzz/Makefile
index 67ffb195..ccbe9561 100644
--- a/test/fuzz/Makefile
+++ b/test/fuzz/Makefile
@@ -34,13 +34,14 @@ all compile: lwip_fuzz
CC=afl-gcc
LDFLAGS=-lm
-CFLAGS=-O0
+# use 'make D=-DUSER_DEFINE' to pass a user define to gcc
+CFLAGS=-O0 $(D)
CONTRIBDIR=../../../lwip-contrib
include $(CONTRIBDIR)/ports/unix/Common.mk
clean:
- rm -f *.o $(LWIPLIBCOMMON) lwip_fuzz *.s .depend* *.core core
+ rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) lwip_fuzz *.s .depend* *.core core
depend dep: .depend
@@ -49,5 +50,5 @@ include .depend
.depend: fuzz.c $(LWIPFILES) $(APPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
-lwip_fuzz: .depend $(LWIPLIBCOMMON) fuzz.o
- $(CC) $(CFLAGS) -o lwip_fuzz fuzz.o $(LWIPLIBCOMMON) $(LDFLAGS)
+lwip_fuzz: .depend $(LWIPLIBCOMMON) $(APPLIB) fuzz.o
+ $(CC) $(CFLAGS) -o lwip_fuzz fuzz.o $(APPLIB) $(LWIPLIBCOMMON) $(LDFLAGS)
diff --git a/test/fuzz/README b/test/fuzz/README
index 1d1e3d8d..de6fb756 100644
--- a/test/fuzz/README
+++ b/test/fuzz/README
@@ -10,6 +10,9 @@ the code and keeping track of which code is executed.
Just running make will produce the test program.
+Running make with parameter 'D=-DLWIP_FUZZ_MULTI_PACKET' will produce a binary
+that parses the input data as multiple packets (experimental!).
+
Then run afl with:
afl-fuzz -i inputs/ -o output ./lwip_fuzz
diff --git a/test/fuzz/fuzz.c b/test/fuzz/fuzz.c
index a9157f13..36383329 100644
--- a/test/fuzz/fuzz.c
+++ b/test/fuzz/fuzz.c
@@ -32,14 +32,31 @@
#include "lwip/init.h"
#include "lwip/netif.h"
+#include "lwip/dns.h"
#include "netif/etharp.h"
#if LWIP_IPV6
#include "lwip/ethip6.h"
#include "lwip/nd6.h"
#endif
+
+#include "lwip/apps/httpd.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/lwiperf.h"
+#include "lwip/apps/mdns.h"
+
#include
#include
+/* This define enables multi packet processing.
+ * For this, the input is interpreted as 2 byte length + data + 2 byte length + data...
+ * #define LWIP_FUZZ_MULTI_PACKET
+*/
+#ifdef LWIP_FUZZ_MULTI_PACKET
+u8_t pktbuf[20000];
+#else
+u8_t pktbuf[2000];
+#endif
+
/* no-op send function */
static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
{
@@ -56,7 +73,7 @@ static err_t testif_init(struct netif *netif)
netif->linkoutput = lwip_tx_func;
netif->mtu = 1500;
netif->hwaddr_len = 6;
- netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
netif->hwaddr[0] = 0x00;
netif->hwaddr[1] = 0x23;
@@ -93,13 +110,38 @@ static void input_pkt(struct netif *netif, const u8_t *data, size_t len)
}
}
+static void input_pkts(struct netif *netif, const u8_t *data, size_t len)
+{
+#ifdef LWIP_FUZZ_MULTI_PACKET
+ const u16_t max_packet_size = 1514;
+ const u8_t *ptr = data;
+ size_t rem_len = len;
+
+ while (rem_len > sizeof(u16_t)) {
+ u16_t frame_len;
+ memcpy(&frame_len, ptr, sizeof(u16_t));
+ ptr += sizeof(u16_t);
+ rem_len -= sizeof(u16_t);
+ frame_len = htons(frame_len) & 0x7FF;
+ frame_len = LWIP_MIN(frame_len, max_packet_size);
+ if (frame_len > rem_len) {
+ frame_len = rem_len;
+ }
+ input_pkt(netif, ptr, frame_len);
+ ptr += frame_len;
+ rem_len -= frame_len;
+ }
+#else /* LWIP_FUZZ_MULTI_PACKET */
+ input_pkt(netif, data, len);
+#endif /* LWIP_FUZZ_MULTI_PACKET */
+}
+
int main(int argc, char** argv)
{
struct netif net_test;
ip4_addr_t addr;
ip4_addr_t netmask;
ip4_addr_t gw;
- u8_t pktbuf[2000];
size_t len;
lwip_init();
@@ -110,10 +152,19 @@ int main(int argc, char** argv)
netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
netif_set_up(&net_test);
+ netif_set_link_up(&net_test);
#if LWIP_IPV6
nd6_tmr(); /* tick nd to join multicast groups */
#endif
+ dns_setserver(0, &net_test.gw);
+
+ /* initialize apps */
+ httpd_init();
+ lwiperf_start_tcp_server_default(NULL, NULL);
+ mdns_resp_init();
+ mdns_resp_add_netif(&net_test, "hostname", 255);
+ snmp_init();
if(argc > 1) {
FILE* f;
@@ -130,7 +181,7 @@ int main(int argc, char** argv)
} else {
len = fread(pktbuf, 1, sizeof(pktbuf), stdin);
}
- input_pkt(&net_test, pktbuf, len);
+ input_pkts(&net_test, pktbuf, len);
return 0;
}
diff --git a/test/fuzz/lwipopts.h b/test/fuzz/lwipopts.h
index 4aff09ba..4ab26f28 100644
--- a/test/fuzz/lwipopts.h
+++ b/test/fuzz/lwipopts.h
@@ -42,8 +42,14 @@
#define IPV6_FRAG_COPYHEADER 1
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
-/* Enable DHCP to test it */
+/* Enable some protocols to test them */
#define LWIP_DHCP 1
+#define LWIP_AUTOIP 1
+
+#define LWIP_IGMP 1
+#define LWIP_DNS 1
+
+#define LWIP_ALTCP 1
/* Turn off checksum verification of fuzzed data */
#define CHECKSUM_CHECK_IP 0
@@ -56,13 +62,19 @@
#define MEM_SIZE 16000
#define TCP_SND_QUEUELEN 40
#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
+#define TCP_OVERSIZE 1
#define TCP_SND_BUF (12 * TCP_MSS)
#define TCP_WND (10 * TCP_MSS)
#define LWIP_WND_SCALE 1
-#define TCP_RCV_SCALE 0
+#define TCP_RCV_SCALE 2
#define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */
/* Minimal changes to opt.h required for etharp unit tests: */
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
+#define LWIP_NUM_NETIF_CLIENT_DATA 1
+#define LWIP_SNMP 1
+#define MIB2_STATS 1
+#define LWIP_MDNS_RESPONDER 1
+
#endif /* LWIP_HDR_LWIPOPTS_H__ */