Squashed 'lib/lwip/lwip/' content from commit 0a0452b2c39b
git-subtree-dir: lib/lwip/lwip
git-subtree-split: 0a0452b2c39bdd91e252aef045c115f88f6ca773
diff --git a/contrib/examples/ethernetif/ethernetif.c b/contrib/examples/ethernetif/ethernetif.c
new file mode 100644
index 0000000..79763e8
--- /dev/null
+++ b/contrib/examples/ethernetif/ethernetif.c
@@ -0,0 +1,337 @@
+/**
+ * @file
+ * Ethernet Interface Skeleton
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * This file is a skeleton for developing Ethernet network interface
+ * drivers for lwIP. Add code to the low_level functions and do a
+ * search-and-replace for the word "ethernetif" to replace it with
+ * something that better describes your network interface.
+ */
+
+#include "lwip/opt.h"
+
+#if 0 /* don't build, this is only a skeleton, see previous comment */
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/ethip6.h"
+#include "lwip/etharp.h"
+#include "netif/ppp/pppoe.h"
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+/**
+ * Helper struct to hold private data used to operate your ethernet interface.
+ * Keeping the ethernet address of the MAC in this struct is not necessary
+ * as it is already kept in the struct netif.
+ * But this is only an example, anyway...
+ */
+struct ethernetif {
+ struct eth_addr *ethaddr;
+ /* Add whatever per-interface state that is needed here. */
+};
+
+/* Forward declarations. */
+static void ethernetif_input(struct netif *netif);
+
+/**
+ * In this function, the hardware should be initialized.
+ * Called from ethernetif_init().
+ *
+ * @param netif the already initialized lwip network interface structure
+ * for this ethernetif
+ */
+static void
+low_level_init(struct netif *netif)
+{
+ struct ethernetif *ethernetif = netif->state;
+
+ /* set MAC hardware address length */
+ netif->hwaddr_len = ETHARP_HWADDR_LEN;
+
+ /* set MAC hardware address */
+ netif->hwaddr[0] = ;
+ ...
+ netif->hwaddr[5] = ;
+
+ /* maximum transfer unit */
+ netif->mtu = 1500;
+
+ /* device capabilities */
+ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+ /*
+ * For hardware/netifs that implement MAC filtering.
+ * All-nodes link-local is handled by default, so we must let the hardware know
+ * to allow multicast packets in.
+ * Should set mld_mac_filter previously. */
+ if (netif->mld_mac_filter != NULL) {
+ ip6_addr_t ip6_allnodes_ll;
+ ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
+ netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
+ }
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+ /* Do whatever else is needed to initialize interface. */
+}
+
+/**
+ * This function should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
+ * @return ERR_OK if the packet could be sent
+ * an err_t value if the packet couldn't be sent
+ *
+ * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+ * strange results. You might consider waiting for space in the DMA queue
+ * to become available since the stack doesn't retry to send a packet
+ * dropped because of memory failure (except for the TCP timers).
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+ struct ethernetif *ethernetif = netif->state;
+ struct pbuf *q;
+
+ initiate transfer();
+
+#if ETH_PAD_SIZE
+ pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+ for (q = p; q != NULL; q = q->next) {
+ /* Send the data from the pbuf to the interface, one pbuf at a
+ time. The size of the data in each pbuf is kept in the ->len
+ variable. */
+ send data from(q->payload, q->len);
+ }
+
+ signal that packet should be sent();
+
+ MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
+ if (((u8_t *)p->payload)[0] & 1) {
+ /* broadcast or multicast packet*/
+ MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
+ } else {
+ /* unicast packet */
+ MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
+ }
+ /* increase ifoutdiscards or ifouterrors on error */
+
+#if ETH_PAD_SIZE
+ pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+ LINK_STATS_INC(link.xmit);
+
+ return ERR_OK;
+}
+
+/**
+ * Should allocate a pbuf and transfer the bytes of the incoming
+ * packet from the interface into the pbuf.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return a pbuf filled with the received packet (including MAC header)
+ * NULL on memory error
+ */
+static struct pbuf *
+low_level_input(struct netif *netif)
+{
+ struct ethernetif *ethernetif = netif->state;
+ struct pbuf *p, *q;
+ u16_t len;
+
+ /* Obtain the size of the packet and put it into the "len"
+ variable. */
+ len = ;
+
+#if ETH_PAD_SIZE
+ len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+
+ /* We allocate a pbuf chain of pbufs from the pool. */
+ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+
+ if (p != NULL) {
+
+#if ETH_PAD_SIZE
+ pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+ /* We iterate over the pbuf chain until we have read the entire
+ * packet into the pbuf. */
+ for (q = p; q != NULL; q = q->next) {
+ /* Read enough bytes to fill this pbuf in the chain. The
+ * available data in the pbuf is given by the q->len
+ * variable.
+ * This does not necessarily have to be a memcpy, you can also preallocate
+ * pbufs for a DMA-enabled MAC and after receiving truncate it to the
+ * actually received size. In this case, ensure the tot_len member of the
+ * pbuf is the sum of the chained pbuf len members.
+ */
+ read data into(q->payload, q->len);
+ }
+ acknowledge that packet has been read();
+
+ MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
+ if (((u8_t *)p->payload)[0] & 1) {
+ /* broadcast or multicast packet*/
+ MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
+ } else {
+ /* unicast packet*/
+ MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
+ }
+#if ETH_PAD_SIZE
+ pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+ LINK_STATS_INC(link.recv);
+ } else {
+ drop packet();
+ LINK_STATS_INC(link.memerr);
+ LINK_STATS_INC(link.drop);
+ MIB2_STATS_NETIF_INC(netif, ifindiscards);
+ }
+
+ return p;
+}
+
+/**
+ * This function should be called when a packet is ready to be read
+ * from the interface. It uses the function low_level_input() that
+ * should handle the actual reception of bytes from the network
+ * interface. Then the type of the received packet is determined and
+ * the appropriate input function is called.
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ */
+static void
+ethernetif_input(struct netif *netif)
+{
+ struct ethernetif *ethernetif;
+ struct eth_hdr *ethhdr;
+ struct pbuf *p;
+
+ ethernetif = netif->state;
+
+ /* move received packet into a new pbuf */
+ p = low_level_input(netif);
+ /* if no packet could be read, silently ignore this */
+ if (p != NULL) {
+ /* pass all packets to ethernet_input, which decides what packets it supports */
+ if (netif->input(p, netif) != ERR_OK) {
+ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+ pbuf_free(p);
+ p = NULL;
+ }
+ }
+}
+
+/**
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ * This function should be passed as a parameter to netif_add().
+ *
+ * @param netif the lwip network interface structure for this ethernetif
+ * @return ERR_OK if the loopif is initialized
+ * ERR_MEM if private data couldn't be allocated
+ * any other err_t on error
+ */
+err_t
+ethernetif_init(struct netif *netif)
+{
+ struct ethernetif *ethernetif;
+
+ LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+ ethernetif = mem_malloc(sizeof(struct ethernetif));
+ if (ethernetif == NULL) {
+ LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+ return ERR_MEM;
+ }
+
+#if LWIP_NETIF_HOSTNAME
+ /* Initialize interface hostname */
+ netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+ /*
+ * Initialize the snmp variables and counters inside the struct netif.
+ * The last argument should be replaced with your link speed, in units
+ * of bits per second.
+ */
+ MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+
+ netif->state = ethernetif;
+ netif->name[0] = IFNAME0;
+ netif->name[1] = IFNAME1;
+ /* We directly use etharp_output() here to save a function call.
+ * You can instead declare your own function an call etharp_output()
+ * from it if you have to do some checks before sending (e.g. if link
+ * is available...) */
+#if LWIP_IPV4
+ netif->output = etharp_output;
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+ netif->output_ip6 = ethip6_output;
+#endif /* LWIP_IPV6 */
+ netif->linkoutput = low_level_output;
+
+ ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);
+
+ /* initialize the hardware */
+ low_level_init(netif);
+
+ return ERR_OK;
+}
+
+#endif /* 0 */
diff --git a/contrib/examples/example_app/default_netif.h b/contrib/examples/example_app/default_netif.h
new file mode 100644
index 0000000..1a64f02
--- /dev/null
+++ b/contrib/examples/example_app/default_netif.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef LWIP_DEFAULT_NETIF_H
+#define LWIP_DEFAULT_NETIF_H
+
+#include "lwip/ip_addr.h"
+
+#if LWIP_IPV4
+void init_default_netif(const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw);
+#else
+void init_default_netif(void);
+#endif
+
+void default_netif_poll(void);
+void default_netif_shutdown(void);
+
+#endif
diff --git a/contrib/examples/example_app/lwipcfg.h.ci b/contrib/examples/example_app/lwipcfg.h.ci
new file mode 100644
index 0000000..dc8477c
--- /dev/null
+++ b/contrib/examples/example_app/lwipcfg.h.ci
@@ -0,0 +1,73 @@
+/**
+ * Additional settings for the example app.
+ * Copy this to lwipcfg.h and make the config changes you need.
+ */
+
+/* configuration for this port */
+#define PPP_USERNAME "Admin"
+#define PPP_PASSWORD "pass"
+
+/** Define this to the index of the windows network adapter to use */
+#define PACKET_LIB_ADAPTER_NR 1
+/** Define this to the GUID of the windows network adapter to use
+ * or NOT define this if you want PACKET_LIB_ADAPTER_NR to be used */
+/*#define PACKET_LIB_ADAPTER_GUID "00000000-0000-0000-0000-000000000000"*/
+/*#define PACKET_LIB_GET_ADAPTER_NETADDRESS(addr) IP4_ADDR((addr), 192,168,1,0)*/
+/*#define PACKET_LIB_QUIET*/
+
+/* #define USE_PCAPIF 1 */
+#define LWIP_PORT_INIT_IPADDR(addr) IP4_ADDR((addr), 192,168,1,200)
+#define LWIP_PORT_INIT_GW(addr) IP4_ADDR((addr), 192,168,1,1)
+#define LWIP_PORT_INIT_NETMASK(addr) IP4_ADDR((addr), 255,255,255,0)
+
+/* remember to change this MAC address to suit your needs!
+ the last octet will be increased by netif->num for each netif */
+#define LWIP_MAC_ADDR_BASE {0x00,0x01,0x02,0x03,0x04,0x05}
+
+/* #define USE_SLIPIF 0 */
+/* #define SIO_USE_COMPORT 0 */
+#ifdef USE_SLIPIF
+#if USE_SLIPIF
+#define LWIP_PORT_INIT_SLIP1_IPADDR(addr) IP4_ADDR((addr), 192, 168, 2, 2)
+#define LWIP_PORT_INIT_SLIP1_GW(addr) IP4_ADDR((addr), 192, 168, 2, 1)
+#define LWIP_PORT_INIT_SLIP1_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0)
+#if USE_SLIPIF > 1
+#define LWIP_PORT_INIT_SLIP2_IPADDR(addr) IP4_ADDR((addr), 192, 168, 2, 1)
+#define LWIP_PORT_INIT_SLIP2_GW(addr) IP4_ADDR((addr), 0, 0, 0, 0)
+#define LWIP_PORT_INIT_SLIP2_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0)*/
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#endif /* USE_SLIPIF */
+
+/* configuration for applications */
+
+#define LWIP_CHARGEN_APP 1
+#define LWIP_DNS_APP 1
+#define LWIP_HTTPD_APP LWIP_TCP
+/* Set this to 1 to use the netconn http server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_HTTPD_APP_NETCONN */
+#define LWIP_NETBIOS_APP LWIP_IPV4 && LWIP_UDP
+#define LWIP_NETIO_APP 1
+#define LWIP_MDNS_APP LWIP_UDP
+#define LWIP_MQTT_APP LWIP_TCP
+#define LWIP_PING_APP 1
+#define LWIP_RTP_APP 1
+#define LWIP_SHELL_APP LWIP_TCP
+#define LWIP_SNMP_APP LWIP_UDP
+#define LWIP_SNTP_APP LWIP_UDP
+#define LWIP_SOCKET_EXAMPLES_APP 1
+#define LWIP_TCPECHO_APP LWIP_TCP
+/* Set this to 1 to use the netconn tcpecho server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_TCPECHO_APP_NETCONN */
+#define LWIP_TFTP_APP LWIP_UDP
+#define LWIP_TFTP_CLIENT_APP LWIP_UDP
+#define LWIP_UDPECHO_APP LWIP_UDP
+#define LWIP_LWIPERF_APP LWIP_TCP
+
+#define USE_DHCP LWIP_DHCP
+#define USE_AUTOIP LWIP_AUTOIP
+
+/* define this to your custom application-init function */
+/* #define LWIP_APP_INIT my_app_init() */
diff --git a/contrib/examples/example_app/lwipcfg.h.example b/contrib/examples/example_app/lwipcfg.h.example
new file mode 100644
index 0000000..b21e19b
--- /dev/null
+++ b/contrib/examples/example_app/lwipcfg.h.example
@@ -0,0 +1,77 @@
+/**
+ * Additional settings for the example app.
+ * Copy this to lwipcfg.h and make the config changes you need.
+ */
+
+/* configuration for this port */
+#define PPP_USERNAME "Admin"
+#define PPP_PASSWORD "pass"
+
+/** Define this to the index of the windows network adapter to use */
+#define PACKET_LIB_ADAPTER_NR 1
+/** Define this to the GUID of the windows network adapter to use
+ * or NOT define this if you want PACKET_LIB_ADAPTER_NR to be used */
+/*#define PACKET_LIB_ADAPTER_GUID "00000000-0000-0000-0000-000000000000"*/
+/*#define PACKET_LIB_GET_ADAPTER_NETADDRESS(addr) IP4_ADDR((addr), 192,168,1,0)*/
+/*#define PACKET_LIB_QUIET*/
+
+/* If these 2 are not defined, the corresponding config setting is used */
+/* #define USE_DHCP 0 */
+/* #define USE_AUTOIP 0 */
+
+/* #define USE_PCAPIF 1 */
+#define LWIP_PORT_INIT_IPADDR(addr) IP4_ADDR((addr), 192,168,1,200)
+#define LWIP_PORT_INIT_GW(addr) IP4_ADDR((addr), 192,168,1,1)
+#define LWIP_PORT_INIT_NETMASK(addr) IP4_ADDR((addr), 255,255,255,0)
+
+/* remember to change this MAC address to suit your needs!
+ the last octet will be increased by netif->num for each netif */
+#define LWIP_MAC_ADDR_BASE {0x00,0x01,0x02,0x03,0x04,0x05}
+
+/* #define USE_SLIPIF 0 */
+/* #define SIO_USE_COMPORT 0 */
+#ifdef USE_SLIPIF
+#if USE_SLIPIF
+#define LWIP_PORT_INIT_SLIP1_IPADDR(addr) IP4_ADDR((addr), 192, 168, 2, 2)
+#define LWIP_PORT_INIT_SLIP1_GW(addr) IP4_ADDR((addr), 192, 168, 2, 1)
+#define LWIP_PORT_INIT_SLIP1_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0)
+#if USE_SLIPIF > 1
+#define LWIP_PORT_INIT_SLIP2_IPADDR(addr) IP4_ADDR((addr), 192, 168, 2, 1)
+#define LWIP_PORT_INIT_SLIP2_GW(addr) IP4_ADDR((addr), 0, 0, 0, 0)
+#define LWIP_PORT_INIT_SLIP2_NETMASK(addr) IP4_ADDR((addr), 255, 255, 255, 0)*/
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#endif /* USE_SLIPIF */
+
+/* configuration for applications */
+
+#define LWIP_CHARGEN_APP 0
+#define LWIP_DNS_APP 0
+#define LWIP_HTTPD_APP 0
+/* Set this to 1 to use the netconn http server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_HTTPD_APP_NETCONN */
+#define LWIP_NETBIOS_APP 0
+#define LWIP_NETIO_APP 0
+#define LWIP_MDNS_APP 0
+#define LWIP_MQTT_APP 0
+#define LWIP_PING_APP 0
+#define LWIP_RTP_APP 0
+#define LWIP_SHELL_APP 0
+#define LWIP_SNMP_APP 0
+#define LWIP_SNTP_APP 0
+#define LWIP_SOCKET_EXAMPLES_APP 0
+#define LWIP_TCPECHO_APP 0
+/* Set this to 1 to use the netconn tcpecho server,
+ * otherwise the raw api server will be used. */
+/*#define LWIP_TCPECHO_APP_NETCONN */
+#define LWIP_TFTP_APP 0
+#define LWIP_TFTP_CLIENT_APP 0
+#define LWIP_UDPECHO_APP 0
+#define LWIP_LWIPERF_APP 0
+
+/*#define USE_DHCP 1*/
+/*#define USE_AUTOIP 1*/
+
+/* define this to your custom application-init function */
+/* #define LWIP_APP_INIT my_app_init() */
diff --git a/contrib/examples/example_app/lwipopts.h b/contrib/examples/example_app/lwipopts.h
new file mode 100644
index 0000000..ea2ca4bdae
--- /dev/null
+++ b/contrib/examples/example_app/lwipopts.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+#ifdef LWIP_OPTTEST_FILE
+#include "lwipopts_test.h"
+#else /* LWIP_OPTTEST_FILE */
+
+#define LWIP_IPV4 1
+#define LWIP_IPV6 1
+
+#define NO_SYS 0
+#define LWIP_SOCKET (NO_SYS==0)
+#define LWIP_NETCONN (NO_SYS==0)
+#define LWIP_NETIF_API (NO_SYS==0)
+
+#define LWIP_IGMP LWIP_IPV4
+#define LWIP_ICMP LWIP_IPV4
+
+#define LWIP_SNMP LWIP_UDP
+#define MIB2_STATS LWIP_SNMP
+#ifdef LWIP_HAVE_MBEDTLS
+#define LWIP_SNMP_V3 (LWIP_SNMP)
+#endif
+
+#define LWIP_DNS LWIP_UDP
+#define LWIP_MDNS_RESPONDER LWIP_UDP
+
+#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
+
+#define LWIP_HAVE_LOOPIF 1
+#define LWIP_NETIF_LOOPBACK 1
+#define LWIP_LOOPBACK_MAX_PBUFS 10
+
+#define TCP_LISTEN_BACKLOG 1
+
+#define LWIP_COMPAT_SOCKETS 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_RCVBUF 1
+
+#define LWIP_TCPIP_CORE_LOCKING 1
+
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
+
+#ifdef LWIP_DEBUG
+
+#define LWIP_DBG_MIN_LEVEL 0
+#define PPP_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#endif
+
+#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
+
+
+/* ---------- Memory options ---------- */
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+ lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+ byte alignment -> define MEM_ALIGNMENT to 2. */
+/* MSVC port: intel processors don't need 4-byte alignment,
+ but are faster that way! */
+#define MEM_ALIGNMENT 4U
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#define MEM_SIZE 10240
+
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
+ sends a lot of data out of ROM (or other static memory), this
+ should be set high. */
+#define MEMP_NUM_PBUF 16
+/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
+ per active RAW "connection". */
+#define MEMP_NUM_RAW_PCB 3
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ per active UDP "connection". */
+#define MEMP_NUM_UDP_PCB 8
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
+ connections. */
+#define MEMP_NUM_TCP_PCB 5
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
+ connections. */
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
+ segments. */
+#define MEMP_NUM_TCP_SEG 16
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
+ timeouts. */
+#define MEMP_NUM_SYS_TIMEOUT 17
+
+/* The following four are used only with the sequential API and can be
+ set to 0 if the application only will use the raw API. */
+/* MEMP_NUM_NETBUF: the number of struct netbufs. */
+#define MEMP_NUM_NETBUF 2
+/* MEMP_NUM_NETCONN: the number of struct netconns. */
+#define MEMP_NUM_NETCONN 12
+/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
+ for sequential API communication and incoming packets. Used in
+ src/api/tcpip.c. */
+#define MEMP_NUM_TCPIP_MSG_API 16
+#define MEMP_NUM_TCPIP_MSG_INPKT 16
+
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
+#define PBUF_POOL_SIZE 120
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#define PBUF_POOL_BUFSIZE 256
+
+/** SYS_LIGHTWEIGHT_PROT
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
+ * for certain critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
+
+
+/* ---------- TCP options ---------- */
+#define LWIP_TCP 1
+#define TCP_TTL 255
+
+#define LWIP_ALTCP (LWIP_TCP)
+#ifdef LWIP_HAVE_MBEDTLS
+#define LWIP_ALTCP_TLS (LWIP_TCP)
+#define LWIP_ALTCP_TLS_MBEDTLS (LWIP_TCP)
+#endif
+
+
+/* Controls if TCP should queue segments that arrive out of
+ order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ 1
+
+/* TCP Maximum segment size. */
+#define TCP_MSS 1024
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF 2048
+
+/* TCP sender buffer space (pbufs). This must be at least = 2 *
+ TCP_SND_BUF/TCP_MSS for things to work. */
+#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)
+
+/* TCP writable space (bytes). This must be less than or equal
+ to TCP_SND_BUF. It is the amount of space which must be
+ available in the tcp snd_buf for select to return writable */
+#define TCP_SNDLOWAT (TCP_SND_BUF/2)
+
+/* TCP receive window. */
+#define TCP_WND (20 * 1024)
+
+/* Maximum number of retransmissions of data segments. */
+#define TCP_MAXRTX 12
+
+/* Maximum number of retransmissions of SYN segments. */
+#define TCP_SYNMAXRTX 4
+
+
+/* ---------- ARP options ---------- */
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_QUEUEING 1
+
+
+/* ---------- IP options ---------- */
+/* Define IP_FORWARD to 1 if you wish to have the ability to forward
+ IP packets across network interfaces. If you are going to run lwIP
+ on a device with only one network interface, define this to 0. */
+#define IP_FORWARD 1
+
+/* IP reassembly and segmentation.These are orthogonal even
+ * if they both deal with IP fragments */
+#define IP_REASSEMBLY 1
+#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
+#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS
+#define IP_FRAG 1
+#define IPV6_FRAG_COPYHEADER 1
+
+/* ---------- ICMP options ---------- */
+#define ICMP_TTL 255
+
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+ interfaces. */
+#define LWIP_DHCP LWIP_UDP
+
+/* 1 if you want to do an ARP check on the offered address
+ (recommended). */
+#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
+
+
+/* ---------- AUTOIP options ------- */
+#define LWIP_AUTOIP (LWIP_DHCP)
+#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
+
+
+/* ---------- UDP options ---------- */
+#define LWIP_UDP 1
+#define LWIP_UDPLITE LWIP_UDP
+#define UDP_TTL 255
+
+
+/* ---------- RAW options ---------- */
+#define LWIP_RAW 1
+
+
+/* ---------- Statistics options ---------- */
+
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 1
+
+#if LWIP_STATS
+#define LINK_STATS 1
+#define IP_STATS 1
+#define ICMP_STATS 1
+#define IGMP_STATS 1
+#define IPFRAG_STATS 1
+#define UDP_STATS 1
+#define TCP_STATS 1
+#define MEM_STATS 1
+#define MEMP_STATS 1
+#define PBUF_STATS 1
+#define SYS_STATS 1
+#endif /* LWIP_STATS */
+
+/* ---------- NETBIOS options ---------- */
+#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
+
+/* ---------- PPP options ---------- */
+
+#define PPP_SUPPORT 1 /* Set > 0 for PPP */
+
+#if PPP_SUPPORT
+
+#define NUM_PPP 1 /* Max PPP sessions. */
+
+
+/* Select modules to enable. Ideally these would be set in the makefile but
+ * we're limited by the command line length so you need to modify the settings
+ * in this file.
+ */
+#define PPPOE_SUPPORT 1
+#define PPPOS_SUPPORT 1
+
+#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
+#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
+#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
+#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
+#define CCP_SUPPORT 0 /* Set > 0 for CCP */
+#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */
+#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
+
+#endif /* PPP_SUPPORT */
+
+#endif /* LWIP_OPTTEST_FILE */
+
+/* The following defines must be done even in OPTTEST mode: */
+
+#if !defined(NO_SYS) || !NO_SYS /* default is 0 */
+void sys_check_core_locking(void);
+#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
+#endif
+
+#ifndef LWIP_PLATFORM_ASSERT
+/* Define LWIP_PLATFORM_ASSERT to something to catch missing stdio.h includes */
+void lwip_example_app_platform_assert(const char *msg, int line, const char *file);
+#define LWIP_PLATFORM_ASSERT(x) lwip_example_app_platform_assert(x, __LINE__, __FILE__)
+#endif
+
+#endif /* LWIP_LWIPOPTS_H */
diff --git a/contrib/examples/example_app/lwippools.h b/contrib/examples/example_app/lwippools.h
new file mode 100644
index 0000000..f58aa59
--- /dev/null
+++ b/contrib/examples/example_app/lwippools.h
@@ -0,0 +1,20 @@
+/* OPTIONAL: Pools to replace heap allocation
+ * Optional: Pools can be used instead of the heap for mem_malloc. If
+ * so, these should be defined here, in increasing order according to
+ * the pool element size.
+ *
+ * LWIP_MALLOC_MEMPOOL(number_elements, element_size)
+ */
+#if MEM_USE_POOLS
+LWIP_MALLOC_MEMPOOL_START
+LWIP_MALLOC_MEMPOOL(100, 256)
+LWIP_MALLOC_MEMPOOL(50, 512)
+LWIP_MALLOC_MEMPOOL(20, 1024)
+LWIP_MALLOC_MEMPOOL(20, 1536)
+LWIP_MALLOC_MEMPOOL_END
+#endif /* MEM_USE_POOLS */
+
+/* Optional: Your custom pools can go here if you would like to use
+ * lwIP's memory pools for anything else.
+ */
+LWIP_MEMPOOL(SYS_MBOX, 22, 100, "SYS_MBOX")
diff --git a/contrib/examples/example_app/ppp_settings.h b/contrib/examples/example_app/ppp_settings.h
new file mode 100644
index 0000000..7b3ee1a
--- /dev/null
+++ b/contrib/examples/example_app/ppp_settings.h
@@ -0,0 +1,6 @@
+#ifdef _MSC_VER
+#pragma warning (disable: 4242) /* PPP only: conversion from 'x' to 'y', possible loss of data */
+#pragma warning (disable: 4244) /* PPP only: conversion from 'x' to 'y', possible loss of data (again?) */
+#pragma warning (disable: 4310) /* PPP only: cast truncates constant value */
+#pragma warning (disable: 4706) /* PPP only: assignment within conditional expression */
+#endif /* MSC_VER */
diff --git a/contrib/examples/example_app/test.c b/contrib/examples/example_app/test.c
new file mode 100644
index 0000000..4f4b5d7
--- /dev/null
+++ b/contrib/examples/example_app/test.c
@@ -0,0 +1,773 @@
+/*
+ * Copyright (c) 2001,2002 Florian Schulze.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the authors nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * test.c - This file is part of lwIP test
+ *
+ */
+
+/* C runtime includes */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+/* lwIP core includes */
+#include "lwip/opt.h"
+
+#include "lwip/sys.h"
+#include "lwip/timeouts.h"
+#include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/init.h"
+#include "lwip/tcpip.h"
+#include "lwip/netif.h"
+#include "lwip/api.h"
+
+#include "lwip/tcp.h"
+#include "lwip/udp.h"
+#include "lwip/dns.h"
+#include "lwip/dhcp.h"
+#include "lwip/autoip.h"
+
+/* lwIP netif includes */
+#include "lwip/etharp.h"
+#include "netif/ethernet.h"
+
+/* applications includes */
+#include "lwip/apps/netbiosns.h"
+#include "lwip/apps/httpd.h"
+#include "apps/httpserver/httpserver-netconn.h"
+#include "apps/netio/netio.h"
+#include "apps/ping/ping.h"
+#include "apps/rtp/rtp.h"
+#include "apps/chargen/chargen.h"
+#include "apps/shell/shell.h"
+#include "apps/tcpecho/tcpecho.h"
+#include "apps/udpecho/udpecho.h"
+#include "apps/tcpecho_raw/tcpecho_raw.h"
+#include "apps/socket_examples/socket_examples.h"
+
+#include "examples/lwiperf/lwiperf_example.h"
+#include "examples/mdns/mdns_example.h"
+#include "examples/snmp/snmp_example.h"
+#include "examples/tftp/tftp_example.h"
+#include "examples/sntp/sntp_example.h"
+#include "examples/mqtt/mqtt_example.h"
+
+#include "examples/httpd/cgi_example/cgi_example.h"
+#include "examples/httpd/fs_example/fs_example.h"
+#include "examples/httpd/https_example/https_example.h"
+#include "examples/httpd/ssi_example/ssi_example.h"
+
+#include "default_netif.h"
+
+#if NO_SYS
+/* ... then we need information about the timer intervals: */
+#include "lwip/ip4_frag.h"
+#include "lwip/igmp.h"
+#endif /* NO_SYS */
+
+#include "netif/ppp/ppp_opts.h"
+#if PPP_SUPPORT
+/* PPP includes */
+#include "lwip/sio.h"
+#include "netif/ppp/pppapi.h"
+#include "netif/ppp/pppos.h"
+#include "netif/ppp/pppoe.h"
+#if !NO_SYS && !LWIP_PPP_API
+#error With NO_SYS==0, LWIP_PPP_API==1 is required.
+#endif
+#endif /* PPP_SUPPORT */
+
+/* include the port-dependent configuration */
+#include "lwipcfg.h"
+
+#ifndef LWIP_EXAMPLE_APP_ABORT
+#define LWIP_EXAMPLE_APP_ABORT() 0
+#endif
+
+/** Define this to 1 to enable a port-specific ethernet interface as default interface. */
+#ifndef USE_DEFAULT_ETH_NETIF
+#define USE_DEFAULT_ETH_NETIF 1
+#endif
+
+/** Define this to 1 to enable a PPP interface. */
+#ifndef USE_PPP
+#define USE_PPP 0
+#endif
+
+/** Define this to 1 or 2 to support 1 or 2 SLIP interfaces. */
+#ifndef USE_SLIPIF
+#define USE_SLIPIF 0
+#endif
+
+/** Use an ethernet adapter? Default to enabled if port-specific ethernet netif or PPPoE are used. */
+#ifndef USE_ETHERNET
+#define USE_ETHERNET (USE_DEFAULT_ETH_NETIF || PPPOE_SUPPORT)
+#endif
+
+/** Use an ethernet adapter for TCP/IP? By default only if port-specific ethernet netif is used. */
+#ifndef USE_ETHERNET_TCPIP
+#define USE_ETHERNET_TCPIP (USE_DEFAULT_ETH_NETIF)
+#endif
+
+#if USE_SLIPIF
+#include <netif/slipif.h>
+#endif /* USE_SLIPIF */
+
+#ifndef USE_DHCP
+#define USE_DHCP LWIP_DHCP
+#endif
+#ifndef USE_AUTOIP
+#define USE_AUTOIP LWIP_AUTOIP
+#endif
+
+/* global variables for netifs */
+#if USE_ETHERNET
+#if LWIP_DHCP
+/* dhcp struct for the ethernet netif */
+static struct dhcp netif_dhcp;
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+/* autoip struct for the ethernet netif */
+static struct autoip netif_autoip;
+#endif /* LWIP_AUTOIP */
+#endif /* USE_ETHERNET */
+#if USE_PPP
+/* THE PPP PCB */
+static ppp_pcb *ppp;
+/* THE PPP interface */
+static struct netif ppp_netif;
+/* THE PPP descriptor */
+static u8_t sio_idx = 0;
+static sio_fd_t ppp_sio;
+#endif /* USE_PPP */
+#if USE_SLIPIF
+static struct netif slipif1;
+#if USE_SLIPIF > 1
+static struct netif slipif2;
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+
+
+#if USE_PPP
+static void
+pppLinkStatusCallback(ppp_pcb *pcb, int errCode, void *ctx)
+{
+ struct netif *pppif = ppp_netif(pcb);
+ LWIP_UNUSED_ARG(ctx);
+
+ switch(errCode) {
+ case PPPERR_NONE: { /* No error. */
+ printf("pppLinkStatusCallback: PPPERR_NONE\n");
+#if LWIP_IPV4
+ printf(" our_ipaddr = %s\n", ip4addr_ntoa(netif_ip4_addr(pppif)));
+ printf(" his_ipaddr = %s\n", ip4addr_ntoa(netif_ip4_gw(pppif)));
+ printf(" netmask = %s\n", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_DNS
+ printf(" dns1 = %s\n", ipaddr_ntoa(dns_getserver(0)));
+ printf(" dns2 = %s\n", ipaddr_ntoa(dns_getserver(1)));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+ printf(" our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+ break;
+ }
+ case PPPERR_PARAM: { /* Invalid parameter. */
+ printf("pppLinkStatusCallback: PPPERR_PARAM\n");
+ break;
+ }
+ case PPPERR_OPEN: { /* Unable to open PPP session. */
+ printf("pppLinkStatusCallback: PPPERR_OPEN\n");
+ break;
+ }
+ case PPPERR_DEVICE: { /* Invalid I/O device for PPP. */
+ printf("pppLinkStatusCallback: PPPERR_DEVICE\n");
+ break;
+ }
+ case PPPERR_ALLOC: { /* Unable to allocate resources. */
+ printf("pppLinkStatusCallback: PPPERR_ALLOC\n");
+ break;
+ }
+ case PPPERR_USER: { /* User interrupt. */
+ printf("pppLinkStatusCallback: PPPERR_USER\n");
+ break;
+ }
+ case PPPERR_CONNECT: { /* Connection lost. */
+ printf("pppLinkStatusCallback: PPPERR_CONNECT\n");
+ break;
+ }
+ case PPPERR_AUTHFAIL: { /* Failed authentication challenge. */
+ printf("pppLinkStatusCallback: PPPERR_AUTHFAIL\n");
+ break;
+ }
+ case PPPERR_PROTOCOL: { /* Failed to meet protocol. */
+ printf("pppLinkStatusCallback: PPPERR_PROTOCOL\n");
+ break;
+ }
+ case PPPERR_PEERDEAD: { /* Connection timeout */
+ printf("pppLinkStatusCallback: PPPERR_PEERDEAD\n");
+ break;
+ }
+ case PPPERR_IDLETIMEOUT: { /* Idle Timeout */
+ printf("pppLinkStatusCallback: PPPERR_IDLETIMEOUT\n");
+ break;
+ }
+ case PPPERR_CONNECTTIME: { /* Max connect time reached */
+ printf("pppLinkStatusCallback: PPPERR_CONNECTTIME\n");
+ break;
+ }
+ case PPPERR_LOOPBACK: { /* Loopback detected */
+ printf("pppLinkStatusCallback: PPPERR_LOOPBACK\n");
+ break;
+ }
+ default: {
+ printf("pppLinkStatusCallback: unknown errCode %d\n", errCode);
+ break;
+ }
+ }
+}
+
+#if PPPOS_SUPPORT
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, const void *data, u32_t len, void *ctx)
+{
+ LWIP_UNUSED_ARG(pcb);
+ LWIP_UNUSED_ARG(ctx);
+ return sio_write(ppp_sio, (const u8_t*)data, len);
+}
+#endif /* PPPOS_SUPPORT */
+#endif /* USE_PPP */
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+status_callback(struct netif *state_netif)
+{
+ if (netif_is_up(state_netif)) {
+#if LWIP_IPV4
+ printf("status_callback==UP, local interface IP is %s\n", ip4addr_ntoa(netif_ip4_addr(state_netif)));
+#else
+ printf("status_callback==UP\n");
+#endif
+ } else {
+ printf("status_callback==DOWN\n");
+ }
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_LINK_CALLBACK
+static void
+link_callback(struct netif *state_netif)
+{
+ if (netif_is_link_up(state_netif)) {
+ printf("link_callback==UP\n");
+ } else {
+ printf("link_callback==DOWN\n");
+ }
+}
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+/* This function initializes all network interfaces */
+static void
+test_netif_init(void)
+{
+#if LWIP_IPV4 && USE_ETHERNET
+ ip4_addr_t ipaddr, netmask, gw;
+#endif /* LWIP_IPV4 && USE_ETHERNET */
+#if USE_SLIPIF
+ u8_t num_slip1 = 0;
+#if LWIP_IPV4
+ ip4_addr_t ipaddr_slip1, netmask_slip1, gw_slip1;
+#endif
+#if USE_SLIPIF > 1
+ u8_t num_slip2 = 1;
+#if LWIP_IPV4
+ ip4_addr_t ipaddr_slip2, netmask_slip2, gw_slip2;
+#endif
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#if USE_DHCP || USE_AUTOIP
+ err_t err;
+#endif
+
+#if USE_PPP
+ const char *username = NULL, *password = NULL;
+#ifdef PPP_USERNAME
+ username = PPP_USERNAME;
+#endif
+#ifdef PPP_PASSWORD
+ password = PPP_PASSWORD;
+#endif
+ printf("ppp_connect: COM%d\n", (int)sio_idx);
+#if PPPOS_SUPPORT
+ ppp_sio = sio_open(sio_idx);
+ if (ppp_sio == NULL) {
+ printf("sio_open error\n");
+ } else {
+ ppp = pppos_create(&ppp_netif, ppp_output_cb, pppLinkStatusCallback, NULL);
+ if (ppp == NULL) {
+ printf("pppos_create error\n");
+ } else {
+ ppp_set_auth(ppp, PPPAUTHTYPE_ANY, username, password);
+ ppp_connect(ppp, 0);
+ }
+ }
+#endif /* PPPOS_SUPPORT */
+#endif /* USE_PPP */
+
+#if USE_ETHERNET
+#if LWIP_IPV4
+ ip4_addr_set_zero(&gw);
+ ip4_addr_set_zero(&ipaddr);
+ ip4_addr_set_zero(&netmask);
+#if USE_ETHERNET_TCPIP
+#if USE_DHCP
+ printf("Starting lwIP, local interface IP is dhcp-enabled\n");
+#elif USE_AUTOIP
+ printf("Starting lwIP, local interface IP is autoip-enabled\n");
+#else /* USE_DHCP */
+ LWIP_PORT_INIT_GW(&gw);
+ LWIP_PORT_INIT_IPADDR(&ipaddr);
+ LWIP_PORT_INIT_NETMASK(&netmask);
+ printf("Starting lwIP, local interface IP is %s\n", ip4addr_ntoa(&ipaddr));
+#endif /* USE_DHCP */
+#endif /* USE_ETHERNET_TCPIP */
+#else /* LWIP_IPV4 */
+ printf("Starting lwIP, IPv4 disable\n");
+#endif /* LWIP_IPV4 */
+
+#if LWIP_IPV4
+ init_default_netif(&ipaddr, &netmask, &gw);
+#else
+ init_default_netif();
+#endif
+#if LWIP_IPV6
+ netif_create_ip6_linklocal_address(netif_default, 1);
+ printf("ip6 linklocal address: %s\n", ip6addr_ntoa(netif_ip6_addr(netif_default, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+ netif_set_status_callback(netif_default, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+ netif_set_link_callback(netif_default, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#if USE_ETHERNET_TCPIP
+#if LWIP_AUTOIP
+ autoip_set_struct(netif_default, &netif_autoip);
+#endif /* LWIP_AUTOIP */
+#if LWIP_DHCP
+ dhcp_set_struct(netif_default, &netif_dhcp);
+#endif /* LWIP_DHCP */
+ netif_set_up(netif_default);
+#if USE_DHCP
+ err = dhcp_start(netif_default);
+ LWIP_ASSERT("dhcp_start failed", err == ERR_OK);
+#elif USE_AUTOIP
+ err = autoip_start(netif_default);
+ LWIP_ASSERT("autoip_start failed", err == ERR_OK);
+#endif /* USE_DHCP */
+#else /* USE_ETHERNET_TCPIP */
+ /* Use ethernet for PPPoE only */
+ netif.flags &= ~(NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP); /* no ARP */
+ netif.flags |= NETIF_FLAG_ETHERNET; /* but pure ethernet */
+#endif /* USE_ETHERNET_TCPIP */
+
+#if USE_PPP && PPPOE_SUPPORT
+ /* start PPPoE after ethernet netif is added! */
+ ppp = pppoe_create(&ppp_netif, netif_default, NULL, NULL, pppLinkStatusCallback, NULL);
+ if (ppp == NULL) {
+ printf("pppoe_create error\n");
+ } else {
+ ppp_set_auth(ppp, PPPAUTHTYPE_ANY, username, password);
+ ppp_connect(ppp, 0);
+ }
+#endif /* USE_PPP && PPPOE_SUPPORT */
+
+#endif /* USE_ETHERNET */
+#if USE_SLIPIF
+#if LWIP_IPV4
+#define SLIP1_ADDRS &ipaddr_slip1, &netmask_slip1, &gw_slip1,
+ LWIP_PORT_INIT_SLIP1_IPADDR(&ipaddr_slip1);
+ LWIP_PORT_INIT_SLIP1_GW(&gw_slip1);
+ LWIP_PORT_INIT_SLIP1_NETMASK(&netmask_slip1);
+ printf("Starting lwIP slipif, local interface IP is %s\n", ip4addr_ntoa(&ipaddr_slip1));
+#else
+#define SLIP1_ADDRS
+ printf("Starting lwIP slipif\n");
+#endif
+#if defined(SIO_USE_COMPORT) && SIO_USE_COMPORT
+ num_slip1++; /* COM ports cannot be 0-based */
+#endif
+ netif_add(&slipif1, SLIP1_ADDRS &num_slip1, slipif_init, ip_input);
+#if !USE_ETHERNET
+ netif_set_default(&slipif1);
+#endif /* !USE_ETHERNET */
+#if LWIP_IPV6
+ netif_create_ip6_linklocal_address(&slipif1, 1);
+ printf("SLIP ip6 linklocal address: %s\n", ip6addr_ntoa(netif_ip6_addr(&slipif1, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+ netif_set_status_callback(&slipif1, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+ netif_set_link_callback(&slipif1, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+ netif_set_up(&slipif1);
+
+#if USE_SLIPIF > 1
+#if LWIP_IPV4
+#define SLIP2_ADDRS &ipaddr_slip2, &netmask_slip2, &gw_slip2,
+ LWIP_PORT_INIT_SLIP2_IPADDR(&ipaddr_slip2);
+ LWIP_PORT_INIT_SLIP2_GW(&gw_slip2);
+ LWIP_PORT_INIT_SLIP2_NETMASK(&netmask_slip2);
+ printf("Starting lwIP SLIP if #2, local interface IP is %s\n", ip4addr_ntoa(&ipaddr_slip2));
+#else
+#define SLIP2_ADDRS
+ printf("Starting lwIP SLIP if #2\n");
+#endif
+#if defined(SIO_USE_COMPORT) && SIO_USE_COMPORT
+ num_slip2++; /* COM ports cannot be 0-based */
+#endif
+ netif_add(&slipif2, SLIP2_ADDRS &num_slip2, slipif_init, ip_input);
+#if LWIP_IPV6
+ netif_create_ip6_linklocal_address(&slipif1, 1);
+ printf("SLIP2 ip6 linklocal address: ");
+ ip6_addr_debug_print(0xFFFFFFFF & ~LWIP_DBG_HALT, netif_ip6_addr(&slipif2, 0));
+ printf("\n");
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_STATUS_CALLBACK
+ netif_set_status_callback(&slipif2, status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+ netif_set_link_callback(&slipif2, link_callback);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+ netif_set_up(&slipif2);
+#endif /* USE_SLIPIF > 1*/
+#endif /* USE_SLIPIF */
+}
+
+#if LWIP_DNS_APP && LWIP_DNS
+static void
+dns_found(const char *name, const ip_addr_t *addr, void *arg)
+{
+ LWIP_UNUSED_ARG(arg);
+ printf("%s: %s\n", name, addr ? ipaddr_ntoa(addr) : "<not found>");
+}
+
+static void
+dns_dorequest(void *arg)
+{
+ const char* dnsname = "3com.com";
+ ip_addr_t dnsresp;
+ LWIP_UNUSED_ARG(arg);
+
+ if (dns_gethostbyname(dnsname, &dnsresp, dns_found, NULL) == ERR_OK) {
+ dns_found(dnsname, &dnsresp, NULL);
+ }
+}
+#endif /* LWIP_DNS_APP && LWIP_DNS */
+
+/* This function initializes applications */
+static void
+apps_init(void)
+{
+#if LWIP_DNS_APP && LWIP_DNS
+ /* wait until the netif is up (for dhcp, autoip or ppp) */
+ sys_timeout(5000, dns_dorequest, NULL);
+#endif /* LWIP_DNS_APP && LWIP_DNS */
+
+#if LWIP_CHARGEN_APP && LWIP_SOCKET
+ chargen_init();
+#endif /* LWIP_CHARGEN_APP && LWIP_SOCKET */
+
+#if LWIP_PING_APP && LWIP_RAW && LWIP_ICMP
+ ping_init(&netif_default->gw);
+#endif /* LWIP_PING_APP && LWIP_RAW && LWIP_ICMP */
+
+#if LWIP_NETBIOS_APP && LWIP_UDP
+ netbiosns_init();
+#ifndef NETBIOS_LWIP_NAME
+#if LWIP_NETIF_HOSTNAME
+ netbiosns_set_name(netif_default->hostname);
+#else
+ netbiosns_set_name("NETBIOSLWIPDEV");
+#endif
+#endif
+#endif /* LWIP_NETBIOS_APP && LWIP_UDP */
+
+#if LWIP_HTTPD_APP && LWIP_TCP
+#ifdef LWIP_HTTPD_APP_NETCONN
+ http_server_netconn_init();
+#else /* LWIP_HTTPD_APP_NETCONN */
+#if defined(LWIP_HTTPD_EXAMPLE_CUSTOMFILES) && LWIP_HTTPD_EXAMPLE_CUSTOMFILES && defined(LWIP_HTTPD_EXAMPLE_CUSTOMFILES_ROOTDIR)
+ fs_ex_init(LWIP_HTTPD_EXAMPLE_CUSTOMFILES_ROOTDIR);
+#endif
+ httpd_init();
+#if defined(LWIP_HTTPD_EXAMPLE_SSI_SIMPLE) && LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+ ssi_ex_init();
+#endif
+#if defined(LWIP_HTTPD_EXAMPLE_CGI_SIMPLE) && LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+ cgi_ex_init();
+#endif
+#if defined(LWIP_HTTPD_EXAMPLE_HTTPS) && LWIP_HTTPD_EXAMPLE_HTTPS
+ https_ex_init();
+#endif
+#endif /* LWIP_HTTPD_APP_NETCONN */
+#endif /* LWIP_HTTPD_APP && LWIP_TCP */
+
+#if LWIP_NETIO_APP && LWIP_TCP
+ netio_init();
+#endif /* LWIP_NETIO_APP && LWIP_TCP */
+
+#if LWIP_RTP_APP && LWIP_SOCKET && LWIP_IGMP
+ rtp_init();
+#endif /* LWIP_RTP_APP && LWIP_SOCKET && LWIP_IGMP */
+
+#if LWIP_SHELL_APP && LWIP_NETCONN
+ shell_init();
+#endif /* LWIP_SHELL_APP && LWIP_NETCONN */
+#if LWIP_TCPECHO_APP
+#if LWIP_NETCONN && defined(LWIP_TCPECHO_APP_NETCONN)
+ tcpecho_init();
+#else /* LWIP_NETCONN && defined(LWIP_TCPECHO_APP_NETCONN) */
+ tcpecho_raw_init();
+#endif
+#endif /* LWIP_TCPECHO_APP && LWIP_NETCONN */
+#if LWIP_UDPECHO_APP && LWIP_NETCONN
+ udpecho_init();
+#endif /* LWIP_UDPECHO_APP && LWIP_NETCONN */
+#if LWIP_SOCKET_EXAMPLES_APP && LWIP_SOCKET
+ socket_examples_init();
+#endif /* LWIP_SOCKET_EXAMPLES_APP && LWIP_SOCKET */
+#if LWIP_MDNS_APP
+ mdns_example_init();
+#endif
+#if LWIP_SNMP_APP
+ snmp_example_init();
+#endif
+#if LWIP_SNTP_APP
+ sntp_example_init();
+#endif
+#if LWIP_TFTP_APP
+ tftp_example_init_server();
+#endif
+#if LWIP_TFTP_CLIENT_APP
+ tftp_example_init_client();
+#endif
+#if LWIP_LWIPERF_APP
+ lwiperf_example_init();
+#endif
+#if LWIP_MQTT_APP
+ mqtt_example_init();
+#endif
+
+#ifdef LWIP_APP_INIT
+ LWIP_APP_INIT();
+#endif
+}
+
+/* This function initializes this lwIP test. When NO_SYS=1, this is done in
+ * the main_loop context (there is no other one), when NO_SYS=0, this is done
+ * in the tcpip_thread context */
+static void
+test_init(void * arg)
+{ /* remove compiler warning */
+#if NO_SYS
+ LWIP_UNUSED_ARG(arg);
+#else /* NO_SYS */
+ sys_sem_t *init_sem;
+ LWIP_ASSERT("arg != NULL", arg != NULL);
+ init_sem = (sys_sem_t*)arg;
+#endif /* NO_SYS */
+
+ /* init randomizer again (seed per thread) */
+ srand((unsigned int)time(NULL));
+
+ /* init network interfaces */
+ test_netif_init();
+
+ /* init apps */
+ apps_init();
+
+#if !NO_SYS
+ sys_sem_signal(init_sem);
+#endif /* !NO_SYS */
+}
+
+/* This is somewhat different to other ports: we have a main loop here:
+ * a dedicated task that waits for packets to arrive. This would normally be
+ * done from interrupt context with embedded hardware, but we don't get an
+ * interrupt in windows for that :-) */
+static void
+main_loop(void)
+{
+#if !NO_SYS
+ err_t err;
+ sys_sem_t init_sem;
+#endif /* NO_SYS */
+#if USE_PPP
+#if !USE_ETHERNET
+ int count;
+ u8_t rxbuf[1024];
+#endif
+ volatile int callClosePpp = 0;
+#endif /* USE_PPP */
+
+ /* initialize lwIP stack, network interfaces and applications */
+#if NO_SYS
+ lwip_init();
+ test_init(NULL);
+#else /* NO_SYS */
+ err = sys_sem_new(&init_sem, 0);
+ LWIP_ASSERT("failed to create init_sem", err == ERR_OK);
+ LWIP_UNUSED_ARG(err);
+ tcpip_init(test_init, &init_sem);
+ /* we have to wait for initialization to finish before
+ * calling update_adapter()! */
+ sys_sem_wait(&init_sem);
+ sys_sem_free(&init_sem);
+#endif /* NO_SYS */
+
+#if (LWIP_SOCKET || LWIP_NETCONN) && LWIP_NETCONN_SEM_PER_THREAD
+ netconn_thread_init();
+#endif
+
+ /* MAIN LOOP for driver update (and timers if NO_SYS) */
+ while (!LWIP_EXAMPLE_APP_ABORT()) {
+#if NO_SYS
+ /* handle timers (already done in tcpip.c when NO_SYS=0) */
+ sys_check_timeouts();
+#endif /* NO_SYS */
+
+#if USE_ETHERNET
+ default_netif_poll();
+#else /* USE_ETHERNET */
+ /* try to read characters from serial line and pass them to PPPoS */
+ count = sio_read(ppp_sio, (u8_t*)rxbuf, 1024);
+ if(count > 0) {
+ pppos_input(ppp, rxbuf, count);
+ } else {
+ /* nothing received, give other tasks a chance to run */
+ sys_msleep(1);
+ }
+
+#endif /* USE_ETHERNET */
+#if USE_SLIPIF
+ slipif_poll(&slipif1);
+#if USE_SLIPIF > 1
+ slipif_poll(&slipif2);
+#endif /* USE_SLIPIF > 1 */
+#endif /* USE_SLIPIF */
+#if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING
+ /* check for loopback packets on all netifs */
+ netif_poll_all();
+#endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#if USE_PPP
+ {
+ int do_hup = 0;
+ if(do_hup) {
+ ppp_close(ppp, 1);
+ do_hup = 0;
+ }
+ }
+ if(callClosePpp && ppp) {
+ /* make sure to disconnect PPP before stopping the program... */
+ callClosePpp = 0;
+#if NO_SYS
+ ppp_close(ppp, 0);
+#else
+ pppapi_close(ppp, 0);
+#endif
+ ppp = NULL;
+ }
+#endif /* USE_PPP */
+ }
+
+#if USE_PPP
+ if(ppp) {
+ u32_t started;
+ printf("Closing PPP connection...\n");
+ /* make sure to disconnect PPP before stopping the program... */
+#if NO_SYS
+ ppp_close(ppp, 0);
+#else
+ pppapi_close(ppp, 0);
+#endif
+ ppp = NULL;
+ /* Wait for some time to let PPP finish... */
+ started = sys_now();
+ do
+ {
+#if USE_ETHERNET
+ default_netif_poll();
+#endif
+ /* @todo: need a better check here: only wait until PPP is down */
+ } while(sys_now() - started < 5000);
+ }
+#endif /* USE_PPP */
+#if (LWIP_SOCKET || LWIP_NETCONN) && LWIP_NETCONN_SEM_PER_THREAD
+ netconn_thread_cleanup();
+#endif
+#if USE_ETHERNET
+ default_netif_shutdown();
+#endif /* USE_ETHERNET */
+}
+
+#if USE_PPP && PPPOS_SUPPORT
+int main(int argc, char **argv)
+#else /* USE_PPP && PPPOS_SUPPORT */
+int main(void)
+#endif /* USE_PPP && PPPOS_SUPPORT */
+{
+#if USE_PPP && PPPOS_SUPPORT
+ if(argc > 1) {
+ sio_idx = (u8_t)atoi(argv[1]);
+ }
+ printf("Using serial port %d for PPP\n", sio_idx);
+#endif /* USE_PPP && PPPOS_SUPPORT */
+ /* no stdio-buffering, please! */
+ setvbuf(stdout, NULL,_IONBF, 0);
+
+ main_loop();
+
+ return 0;
+}
+
+/* This function is only required to prevent arch.h including stdio.h
+ * (which it does if LWIP_PLATFORM_ASSERT is undefined)
+ */
+void lwip_example_app_platform_assert(const char *msg, int line, const char *file)
+{
+ printf("Assertion \"%s\" failed at line %d in %s\n", msg, line, file);
+ fflush(NULL);
+ abort();
+}
diff --git a/contrib/examples/example_app/test_configs/opt_default.h b/contrib/examples/example_app/test_configs/opt_default.h
new file mode 100644
index 0000000..67b69d2
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_default.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 1
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 1
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 1
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 0
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_dualstack.h b/contrib/examples/example_app/test_configs/opt_dualstack.h
new file mode 100644
index 0000000..4caf490
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_dualstack.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 1
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP LWIP_UDP
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 1
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 1
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 1
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_ipv4only.h b/contrib/examples/example_app/test_configs/opt_ipv4only.h
new file mode 100644
index 0000000..82ba467
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_ipv4only.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 1
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP LWIP_UDP
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 1
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 1
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 0
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_ipv6only.h b/contrib/examples/example_app/test_configs/opt_ipv6only.h
new file mode 100644
index 0000000..b3cb1e0
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_ipv6only.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 0
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP 0
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 1
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 1
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 1
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_tcp_dualstack.h b/contrib/examples/example_app/test_configs/opt_no_tcp_dualstack.h
new file mode 100644
index 0000000..9d70ace
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_tcp_dualstack.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_dualstack.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_tcp_ipv4only.h b/contrib/examples/example_app/test_configs/opt_no_tcp_ipv4only.h
new file mode 100644
index 0000000..bd22831
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_tcp_ipv4only.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv4only.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_tcp_ipv6only.h b/contrib/examples/example_app/test_configs/opt_no_tcp_ipv6only.h
new file mode 100644
index 0000000..9f956e3
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_tcp_ipv6only.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv6only.h"
+
+#undef LWIP_TCP
+#define LWIP_TCP 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_udp_dualstack.h b/contrib/examples/example_app/test_configs/opt_no_udp_dualstack.h
new file mode 100644
index 0000000..c9b9e9a
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_udp_dualstack.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_dualstack.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_udp_ipv4only.h b/contrib/examples/example_app/test_configs/opt_no_udp_ipv4only.h
new file mode 100644
index 0000000..7aa3ace
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_udp_ipv4only.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv4only.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
diff --git a/contrib/examples/example_app/test_configs/opt_no_udp_ipv6only.h b/contrib/examples/example_app/test_configs/opt_no_udp_ipv6only.h
new file mode 100644
index 0000000..0572798
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_no_udp_ipv6only.h
@@ -0,0 +1,4 @@
+#include "test_configs/opt_ipv6only.h"
+
+#undef LWIP_UDP
+#define LWIP_UDP 0
diff --git a/contrib/examples/example_app/test_configs/opt_none.h b/contrib/examples/example_app/test_configs/opt_none.h
new file mode 100644
index 0000000..3c39321
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_none.h
@@ -0,0 +1,2 @@
+/* test and empty lwipopts.h file */
+
diff --git a/contrib/examples/example_app/test_configs/opt_nosys_dual.h b/contrib/examples/example_app/test_configs/opt_nosys_dual.h
new file mode 100644
index 0000000..17ee97f
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_nosys_dual.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 1
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 0
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 0
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 1
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_nosys_ipv4.h b/contrib/examples/example_app/test_configs/opt_nosys_ipv4.h
new file mode 100644
index 0000000..024d79b
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_nosys_ipv4.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 1
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 0
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 0
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 0
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/example_app/test_configs/opt_nosys_ipv6.h b/contrib/examples/example_app/test_configs/opt_nosys_ipv6.h
new file mode 100644
index 0000000..d027352
--- /dev/null
+++ b/contrib/examples/example_app/test_configs/opt_nosys_ipv6.h
@@ -0,0 +1,295 @@
+/* test an lwipopts.h file with default contents */
+#define NO_SYS 0
+#define NO_SYS_NO_TIMERS 0
+#define LWIP_TIMERS 1
+#define LWIP_TIMERS_CUSTOM 0
+#define LWIP_MPU_COMPATIBLE 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 0
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 1
+#define MEM_SIZE 1600
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+#define MEM_USE_POOLS 0
+#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
+#define MEMP_USE_CUSTOM_POOLS 0
+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
+/*#define MEMP_NUM_PBUF 16
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 4
+#define MEMP_NUM_TCP_PCB 5
+#define MEMP_NUM_TCP_PCB_LISTEN 8
+#define MEMP_NUM_TCP_SEG 16
+#define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB
+#define MEMP_NUM_REASSDATA 5
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 30
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2)
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API
+#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ARP_MAXAGE 300
+#define ARP_QUEUEING 0
+#define ARP_QUEUE_LEN 3
+#define ETHARP_SUPPORT_VLAN 0
+#define LWIP_ETHERNET LWIP_ARP
+#define ETH_PAD_SIZE 0
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF
+#define LWIP_IPV4 0
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAXAGE 15
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 255
+#define IP_SOF_BROADCAST 0
+#define IP_SOF_BROADCAST_RECV 0
+#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0
+#define LWIP_ICMP 1
+#define ICMP_TTL (IP_DEFAULT_TTL)
+#define LWIP_BROADCAST_PING 0
+#define LWIP_MULTICAST_PING 0
+#define LWIP_RAW 0
+#define RAW_TTL (IP_DEFAULT_TTL)
+#define LWIP_DHCP 0
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+#define LWIP_MIB2_CALLBACKS 0
+#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW))
+#define LWIP_IGMP 0
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+#define DNS_MAX_SERVERS 2
+#define DNS_MAX_RETRIES 4
+#define DNS_DOES_NAME_CHECK 1
+#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)
+#define DNS_LOCAL_HOSTLIST 0
+#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0
+#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+#define UDP_TTL (IP_DEFAULT_TTL)
+#define LWIP_NETBUF_RECVINFO 0
+#define LWIP_TCP 1
+#define TCP_TTL (IP_DEFAULT_TTL)
+#define TCP_WND (4 * TCP_MSS)
+#define TCP_MAXRTX 12
+#define TCP_SYNMAXRTX 6
+#define TCP_QUEUE_OOSEQ (LWIP_TCP)
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 536
+#define TCP_CALCULATE_EFF_SEND_MSS 1
+#define TCP_SND_BUF (2 * TCP_MSS)
+#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
+#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
+#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS
+#define TCP_LISTEN_BACKLOG 0
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define TCP_OVERSIZE TCP_MSS
+#define LWIP_TCP_TIMESTAMPS 0
+#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE)
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define LWIP_PBUF_REF_T u8_t
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 0
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 0
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 0
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#define LWIP_NUM_NETIF_CLIENT_DATA 0
+#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF)
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
+/*#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define LWIP_TCPIP_THREAD_ALIVE()
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0*/
+#define LWIP_NETCONN 0
+#define LWIP_TCPIP_TIMEOUT 0
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+#define LWIP_SOCKET 0
+#define LWIP_COMPAT_SOCKETS 1 /* 0..2 */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_SOCKET_OFFSET 0
+#define LWIP_TCP_KEEPALIVE 0
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_FIONREAD_LINUXMODE 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+#define LWIP_STATS 1
+#define LWIP_STATS_DISPLAY 0
+#define LINK_STATS 1
+#define ETHARP_STATS (LWIP_ARP)
+#define IP_STATS 1
+#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
+#define ICMP_STATS 1
+#define IGMP_STATS (LWIP_IGMP)
+#define UDP_STATS (LWIP_UDP)
+#define TCP_STATS (LWIP_TCP)
+#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
+#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
+#define SYS_STATS (NO_SYS == 0)
+#define IP6_STATS (LWIP_IPV6)
+#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
+#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
+#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
+#define ND6_STATS (LWIP_IPV6)
+#define MIB2_STATS 0
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+#define CHECKSUM_GEN_IP 1
+#define CHECKSUM_GEN_UDP 1
+#define CHECKSUM_GEN_TCP 1
+#define CHECKSUM_GEN_ICMP 1
+#define CHECKSUM_GEN_ICMP6 1
+#define CHECKSUM_CHECK_IP 1
+#define CHECKSUM_CHECK_UDP 1
+#define CHECKSUM_CHECK_TCP 1
+#define CHECKSUM_CHECK_ICMP 1
+#define CHECKSUM_CHECK_ICMP6 1
+#define LWIP_CHECKSUM_ON_COPY 0
+#define LWIP_IPV6 1
+#define IPV6_REASS_MAXAGE 60
+#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
+#define LWIP_IPV6_SCOPES_DEBUG 0
+#define LWIP_IPV6_NUM_ADDRESSES 3
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS (LWIP_IPV6)
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6)
+#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG)
+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
+#define LWIP_ICMP6 (LWIP_IPV6)
+#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_HL 255
+#define LWIP_IPV6_MLD (LWIP_IPV6)
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_QUEUEING (LWIP_IPV6)
+#define MEMP_NUM_ND6_QUEUE 20
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3
+#define LWIP_ND6_MAX_UNICAST_SOLICIT 3
+#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000
+#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3
+#define LWIP_ND6_REACHABLE_TIME 30000
+#define LWIP_ND6_RETRANS_TIMER 1000
+#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
+
+/* TODO: check hooks */
+
+#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
+#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#define NETIF_DEBUG LWIP_DBG_OFF
+#define PBUF_DEBUG LWIP_DBG_OFF
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#define ICMP_DEBUG LWIP_DBG_OFF
+#define IGMP_DEBUG LWIP_DBG_OFF
+#define INET_DEBUG LWIP_DBG_OFF
+#define IP_DEBUG LWIP_DBG_OFF
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#define RAW_DEBUG LWIP_DBG_OFF
+#define MEM_DEBUG LWIP_DBG_OFF
+#define MEMP_DEBUG LWIP_DBG_OFF
+#define SYS_DEBUG LWIP_DBG_OFF
+#define TIMERS_DEBUG LWIP_DBG_OFF
+#define TCP_DEBUG LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#define UDP_DEBUG LWIP_DBG_OFF
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#define SLIP_DEBUG LWIP_DBG_OFF
+#define DHCP_DEBUG LWIP_DBG_OFF
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#define DNS_DEBUG LWIP_DBG_OFF
+#define IP6_DEBUG LWIP_DBG_OFF
+#define DHCP6_DEBUG LWIP_DBG_OFF
+#define LWIP_TESTMODE 0
+
+#define LWIP_PERF 0
diff --git a/contrib/examples/httpd/cgi_example/cgi_example.c b/contrib/examples/httpd/cgi_example/cgi_example.c
new file mode 100644
index 0000000..c9c7476
--- /dev/null
+++ b/contrib/examples/httpd/cgi_example/cgi_example.c
@@ -0,0 +1,107 @@
+/**
+ * @file
+ * HTTPD simple CGI example
+ *
+ * This file demonstrates how to add support for basic CGI.
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "cgi_example.h"
+
+#include "lwip/apps/httpd.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_CGI_SIMPLE to 1 to enable this cgi example */
+#ifndef LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+#define LWIP_HTTPD_EXAMPLE_CGI_SIMPLE 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CGI_SIMPLE
+
+#if !LWIP_HTTPD_CGI
+#error LWIP_HTTPD_EXAMPLE_CGI_SIMPLE needs LWIP_HTTPD_CGI
+#endif
+
+static const char *cgi_handler_basic(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]);
+
+static const tCGI cgi_handlers[] = {
+ {
+ "/basic_cgi",
+ cgi_handler_basic
+ },
+ {
+ "/basic_cgi_2",
+ cgi_handler_basic
+ }
+};
+
+void
+cgi_ex_init(void)
+{
+ http_set_cgi_handlers(cgi_handlers, LWIP_ARRAYSIZE(cgi_handlers));
+}
+
+/** This basic CGI function can parse param/value pairs and return an url that
+ * is sent as a response by httpd.
+ *
+ * This example function just checks that the input url has two key value
+ * parameter pairs: "foo=bar" and "test=123"
+ * If not, it returns 404
+ */
+static const char *
+cgi_handler_basic(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
+{
+ LWIP_ASSERT("check index", iIndex < LWIP_ARRAYSIZE(cgi_handlers));
+
+ if (iNumParams == 2) {
+ if (!strcmp(pcParam[0], "foo")) {
+ if (!strcmp(pcValue[0], "bar")) {
+ if (!strcmp(pcParam[1], "test")) {
+ if (!strcmp(pcValue[1], "123")) {
+ return "/index.html";
+ }
+ }
+ }
+ }
+ }
+ return "/404.html";
+}
+
+#endif /* LWIP_HTTPD_EXAMPLE_CGI_SIMPLE */
diff --git a/contrib/examples/httpd/cgi_example/cgi_example.h b/contrib/examples/httpd/cgi_example/cgi_example.h
new file mode 100644
index 0000000..b655661
--- /dev/null
+++ b/contrib/examples/httpd/cgi_example/cgi_example.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE
+
+void cgi_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_CGI_EXAMPLE */
diff --git a/contrib/examples/httpd/examples_fs/404.html b/contrib/examples/httpd/examples_fs/404.html
new file mode 100644
index 0000000..40b343a
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/404.html
@@ -0,0 +1,21 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+ <tr valign="top"><td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif"
+ border="0" alt="SICS logo" title="SICS logo"></a>
+ </td><td width="500">
+ <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+ <h2>404 - Page not found</h2>
+ <p>
+ Sorry, the page you are requesting was not found on this
+ server.
+ </p>
+ </td><td>
+
+ </td></tr>
+ </table>
+</body>
+</html>
diff --git a/contrib/examples/httpd/examples_fs/img/sics.gif b/contrib/examples/httpd/examples_fs/img/sics.gif
new file mode 100644
index 0000000..0a4fc7b
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/img/sics.gif
Binary files differ
diff --git a/contrib/examples/httpd/examples_fs/index.html b/contrib/examples/httpd/examples_fs/index.html
new file mode 100644
index 0000000..ab575ef
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/index.html
@@ -0,0 +1,47 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+ <tr valign="top"><td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif"
+ border="0" alt="SICS logo" title="SICS logo"></a>
+ </td><td width="500">
+ <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+ <p>
+ The web page you are watching was served by a simple web
+ server running on top of the lightweight TCP/IP stack <a
+ href="http://www.sics.se/~adam/lwip/">lwIP</a>.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ The focus of the lwIP TCP/IP implementation is to reduce
+ the RAM usage while still having a full scale TCP. This
+ makes lwIP suitable for use in embedded systems with tens
+ of kilobytes of free RAM and room for around 40 kilobytes
+ of code ROM.
+ </p>
+ <p>
+ More information about lwIP can be found at the lwIP
+ homepage at <a
+ href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
+ or at the lwIP wiki at <a
+ href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
+ </p>
+ </td><td>
+
+ </td></tr>
+ </table>
+</body>
+</html>
+
diff --git a/contrib/examples/httpd/examples_fs/login.html b/contrib/examples/httpd/examples_fs/login.html
new file mode 100644
index 0000000..71c535b
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/login.html
@@ -0,0 +1,28 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+<table width="100%">
+ <tr valign="top">
+ <td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+ </td>
+ <td width="500">
+ <h1>Login</h1>
+ <form name="login" action="login.cgi" method="post">
+ <div>
+ <label><b>Username</b></label>
+ <input type="text" placeholder="Enter Username" name="user" required>
+ <label><b>Password</b></label>
+ <input type="password" placeholder="Enter Password" name="pass" required>
+ <button type="submit">Login</button>
+ </div>
+ </form>
+ </td>
+ <td>
+
+ </td>
+ </tr>
+</table>
+</body>
+</html>
diff --git a/contrib/examples/httpd/examples_fs/loginfail.html b/contrib/examples/httpd/examples_fs/loginfail.html
new file mode 100644
index 0000000..6d5c742
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/loginfail.html
@@ -0,0 +1,25 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+ <tr valign="top">
+ <td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+ </td>
+ <td width="500">
+ <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+ <p>
+ Login failed.
+ </p>
+ <p>
+ Click <a href="login.html">here</a> to retry login.
+ </p>
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ </table>
+</body>
+</html>
diff --git a/contrib/examples/httpd/examples_fs/session.html b/contrib/examples/httpd/examples_fs/session.html
new file mode 100644
index 0000000..72d3bff
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/session.html
@@ -0,0 +1,25 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+ <tr valign="top">
+ <td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif" border="0" alt="SICS logo" title="SICS logo"/></a>
+ </td>
+ <td width="500">
+ <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+ <p>
+ Login succeeded, session active.
+ </p>
+ <p>
+ Click <a href="login.html">here</a> to retry login.
+ </p>
+ </td>
+ <td>
+
+ </td>
+ </tr>
+ </table>
+</body>
+</html>
diff --git a/contrib/examples/httpd/examples_fs/ssi.shtml b/contrib/examples/httpd/examples_fs/ssi.shtml
new file mode 100644
index 0000000..153d016
--- /dev/null
+++ b/contrib/examples/httpd/examples_fs/ssi.shtml
@@ -0,0 +1,315 @@
+<html>
+<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
+<body bgcolor="white" text="black">
+
+ <table width="100%">
+ <tr valign="top"><td width="80">
+ <a href="http://www.sics.se/"><img src="/img/sics.gif"
+ border="0" alt="SICS logo" title="SICS logo"></a>
+ </td><td width="500">
+ <h1>lwIP - A Lightweight TCP/IP Stack</h1>
+ <h1><!--#HellWorl--></h1>
+ <p>
+ The web page you are watching was served by a simple web
+ server running on top of the lightweight TCP/IP stack <a
+ href="http://www.sics.se/~adam/lwip/">lwIP</a>.
+ </p>
+ <p>
+ This page is here to test SSI, so here is a counter as
+ an example of content changing for every request:
+ "<!--#counter-->"
+ </p>
+ <p>
+ And here is an example of a tag result buffer return in
+ multiple parts: "<!--#MultPart-->"
+ </p>
+ <p>
+ To test LWIP_HTTPD_CGI_SSI, here are the CGI parameters:
+ <!--#CgiParam-->
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ lwIP is an open source implementation of the TCP/IP
+ protocol suite that was originally written by <a
+ href="http://www.sics.se/~adam/lwip/">Adam Dunkels
+ of the Swedish Institute of Computer Science</a> but now is
+ being actively developed by a team of developers
+ distributed world-wide. Since it's release, lwIP has
+ spurred a lot of interest and has been ported to several
+ platforms and operating systems. lwIP can be used either
+ with or without an underlying OS.
+ </p>
+ <p>
+ The focus of the lwIP TCP/IP implementation is to reduce
+ the RAM usage while still having a full scale TCP. This
+ makes lwIP suitable for use in embedded systems with tens
+ of kilobytes of free RAM and room for around 40 kilobytes
+ of code ROM.
+ </p>
+ <p>
+ More information about lwIP can be found at the lwIP
+ homepage at <a
+ href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
+ or at the lwIP wiki at <a
+ href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
+ </p>
+ </td><td>
+
+ </td></tr>
+ </table>
+</body>
+</html>
+
diff --git a/contrib/examples/httpd/examples_fsdata.c b/contrib/examples/httpd/examples_fsdata.c
new file mode 100644
index 0000000..7eed926
--- /dev/null
+++ b/contrib/examples/httpd/examples_fsdata.c
@@ -0,0 +1,1543 @@
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+
+
+#define file_NULL (struct fsdata_file *) NULL
+
+
+#ifndef FS_FILE_FLAGS_HEADER_INCLUDED
+#define FS_FILE_FLAGS_HEADER_INCLUDED 1
+#endif
+#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT
+#define FS_FILE_FLAGS_HEADER_PERSISTENT 0
+#endif
+/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */
+#ifndef FSDATA_FILE_ALIGNMENT
+#define FSDATA_FILE_ALIGNMENT 0
+#endif
+#ifndef FSDATA_ALIGN_PRE
+#define FSDATA_ALIGN_PRE
+#endif
+#ifndef FSDATA_ALIGN_POST
+#define FSDATA_ALIGN_POST
+#endif
+#if FSDATA_FILE_ALIGNMENT==2
+#include "fsdata_alignment.h"
+#endif
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__img_sics_gif = 0;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__img_sics_gif[] FSDATA_ALIGN_POST = {
+/* /img/sics.gif (14 chars) */
+0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 724
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x37,0x32,0x34,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: image/gif
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d,
+0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (724 bytes) */
+0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39,
+0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6,
+0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e,
+0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99,
+0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5,
+0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b,
+0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,
+0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f,
+0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac,
+0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31,
+0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9,
+0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51,
+0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78,
+0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0,
+0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07,
+0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42,
+0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c,
+0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01,
+0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10,
+0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8,
+0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4,
+0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86,
+0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06,
+0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07,
+0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29,
+0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a,
+0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97,
+0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9,
+0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70,
+0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c,
+0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01,
+0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24,
+0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29,
+0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73,
+0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab,
+0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45,
+0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8,
+0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5,
+0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10,
+0x41,0x00,0x00,0x3b,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__404_html = 1;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__404_html[] FSDATA_ALIGN_POST = {
+/* /404.html (10 chars) */
+0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 404 File not found
+" (29 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c,
+0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 565
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x36,0x35,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (565 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20,
+0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72,
+0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,
+0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20,
+0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e,
+0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,
+0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__index_html = 2;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__index_html[] FSDATA_ALIGN_POST = {
+/* /index.html (12 chars) */
+0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 1751
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x31,0x37,0x35,0x31,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (1751 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,
+0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,
+0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,
+0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,
+0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,
+0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,
+0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,
+0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
+0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
+0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
+0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
+0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
+0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
+0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
+0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
+0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
+0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
+0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
+0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
+0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
+0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
+0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
+0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
+0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
+0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
+0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
+0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
+0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
+0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
+0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67,
+0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61,
+0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c,
+0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e,
+0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
+0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f,
+0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72,
+0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34,
+0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,
+0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61,
+0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
+0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,
+0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,
+0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,
+0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74,
+0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61,
+0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
+0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,
+0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c,
+0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e,
+0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,
+0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,
+0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__login_html = 3;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__login_html[] FSDATA_ALIGN_POST = {
+/* /login.html (12 chars) */
+0x2f,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 768
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x37,0x36,0x38,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (768 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x3c,0x74,
+0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,0x25,
+0x22,0x3e,0x0d,0x0a,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,
+0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x61,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,
+0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,
+0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,
+0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,
+0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,
+0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,
+0x0d,0x0a,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x35,
+0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x68,0x31,0x3e,0x4c,0x6f,0x67,
+0x69,0x6e,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x66,0x6f,0x72,
+0x6d,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x22,0x20,0x61,
+0x63,0x74,0x69,0x6f,0x6e,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x63,0x67,0x69,
+0x22,0x20,0x6d,0x65,0x74,0x68,0x6f,0x64,0x3d,0x22,0x70,0x6f,0x73,0x74,0x22,0x3e,
+0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x64,0x69,0x76,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x20,0x20,0x3c,0x6c,0x61,0x62,0x65,0x6c,0x3e,0x3c,0x62,0x3e,0x55,0x73,0x65,0x72,
+0x6e,0x61,0x6d,0x65,0x3c,0x2f,0x62,0x3e,0x3c,0x2f,0x6c,0x61,0x62,0x65,0x6c,0x3e,
+0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x74,0x79,
+0x70,0x65,0x3d,0x22,0x74,0x65,0x78,0x74,0x22,0x20,0x70,0x6c,0x61,0x63,0x65,0x68,
+0x6f,0x6c,0x64,0x65,0x72,0x3d,0x22,0x45,0x6e,0x74,0x65,0x72,0x20,0x55,0x73,0x65,
+0x72,0x6e,0x61,0x6d,0x65,0x22,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x75,0x73,0x65,
+0x72,0x22,0x20,0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x20,0x3c,0x6c,0x61,0x62,0x65,0x6c,0x3e,0x3c,0x62,0x3e,0x50,0x61,0x73,
+0x73,0x77,0x6f,0x72,0x64,0x3c,0x2f,0x62,0x3e,0x3c,0x2f,0x6c,0x61,0x62,0x65,0x6c,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x74,
+0x79,0x70,0x65,0x3d,0x22,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x22,0x20,0x70,
+0x6c,0x61,0x63,0x65,0x68,0x6f,0x6c,0x64,0x65,0x72,0x3d,0x22,0x45,0x6e,0x74,0x65,
+0x72,0x20,0x50,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x22,0x20,0x6e,0x61,0x6d,0x65,
+0x3d,0x22,0x70,0x61,0x73,0x73,0x22,0x20,0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,
+0x74,0x79,0x70,0x65,0x3d,0x22,0x73,0x75,0x62,0x6d,0x69,0x74,0x22,0x3e,0x4c,0x6f,
+0x67,0x69,0x6e,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x2f,0x64,0x69,0x76,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x66,
+0x6f,0x72,0x6d,0x3e,0x20,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,
+0x20,0x20,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,
+0x3b,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x3c,0x2f,0x74,
+0x72,0x3e,0x0d,0x0a,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,
+0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,
+};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__loginfail_html = 4;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__loginfail_html[] FSDATA_ALIGN_POST = {
+/* /loginfail.html (16 chars) */
+0x2f,0x6c,0x6f,0x67,0x69,0x6e,0x66,0x61,0x69,0x6c,0x2e,0x68,0x74,0x6d,0x6c,0x00,
+
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 559
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x35,0x39,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (559 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x3c,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,
+0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,
+0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,
+0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,
+0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,
+0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,
+0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,
+0x6c,0x6f,0x67,0x6f,0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,0x67,
+0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,
+0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x4c,0x6f,0x67,0x69,0x6e,0x20,
+0x66,0x61,0x69,0x6c,0x65,0x64,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x20,0x43,0x6c,0x69,0x63,0x6b,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,
+0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x68,0x65,0x72,0x65,
+0x3c,0x2f,0x61,0x3e,0x20,0x74,0x6f,0x20,0x72,0x65,0x74,0x72,0x79,0x20,0x6c,0x6f,
+0x67,0x69,0x6e,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,0x0d,0x0a,0x20,
+0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x74,0x72,0x3e,
+0x0d,0x0a,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,0x62,
+0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__session_html = 5;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__session_html[] FSDATA_ALIGN_POST = {
+/* /session.html (14 chars) */
+0x2f,0x73,0x65,0x73,0x73,0x69,0x6f,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Content-Length: 578
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x37,0x38,0x0d,0x0a,
+/* "Connection: keep-alive
+" (24 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x6b,0x65,0x65,0x70,
+0x2d,0x61,0x6c,0x69,0x76,0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+
+" (27 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (578 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x3c,
+0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x30,0x30,
+0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x74,0x72,0x20,0x76,0x61,0x6c,0x69,0x67,
+0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,
+0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x22,0x3e,
+0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,0x6d,0x67,0x2f,0x73,
+0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,
+0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,
+0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,
+0x6c,0x6f,0x67,0x6f,0x22,0x2f,0x3e,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,0x67,
+0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,
+0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x4c,0x6f,0x67,0x69,0x6e,0x20,
+0x73,0x75,0x63,0x63,0x65,0x65,0x64,0x65,0x64,0x2c,0x20,0x73,0x65,0x73,0x73,0x69,
+0x6f,0x6e,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,
+0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x20,
+0x20,0x20,0x20,0x20,0x43,0x6c,0x69,0x63,0x6b,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x68,
+0x65,0x72,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x74,0x6f,0x20,0x72,0x65,0x74,0x72,0x79,
+0x20,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,
+0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,
+0x0d,0x0a,0x20,0x20,0x20,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,
+0x74,0x72,0x3e,0x0d,0x0a,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,
+0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,
+0x0d,0x0a,};
+
+#if FSDATA_FILE_ALIGNMENT==1
+static const unsigned int dummy_align__ssi_shtml = 6;
+#endif
+static const unsigned char FSDATA_ALIGN_PRE data__ssi_shtml[] FSDATA_ALIGN_POST = {
+/* /ssi.shtml (11 chars) */
+0x2f,0x73,0x73,0x69,0x2e,0x73,0x68,0x74,0x6d,0x6c,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/2.0.3d (http://savannah.nongnu.org/projects/lwip)
+" (64 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x32,0x2e,0x30,
+0x2e,0x33,0x64,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,
+0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,
+0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+
+/* "Connection: Close
+" (19 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x43,0x6c,0x6f,0x73,
+0x65,0x0d,0x0a,
+/* "Content-Type: text/html
+Expires: Fri, 10 Apr 2008 14:00:00 GMT
+Pragma: no-cache
+
+" (85 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x45,0x78,0x70,0x69,0x72,0x65,0x73,
+0x3a,0x20,0x46,0x72,0x69,0x2c,0x20,0x31,0x30,0x20,0x41,0x70,0x72,0x20,0x32,0x30,
+0x30,0x38,0x20,0x31,0x34,0x3a,0x30,0x30,0x3a,0x30,0x30,0x20,0x47,0x4d,0x54,0x0d,
+0x0a,0x50,0x72,0x61,0x67,0x6d,0x61,0x3a,0x20,0x6e,0x6f,0x2d,0x63,0x61,0x63,0x68,
+0x65,0x0d,0x0a,0x0d,0x0a,
+/* raw file data (14429 bytes) */
+0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,
+0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69,
+0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f,
+0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63,
+0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78,
+0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20,
+0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,
+0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74,
+0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c,
+0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20,
+0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69,
+0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d,
+0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c,
+0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f,
+0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69,
+0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,
+0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x68,0x31,0x3e,0x3c,0x21,0x2d,0x2d,0x23,0x48,0x65,0x6c,0x6c,0x57,0x6f,
+0x72,0x6c,0x2d,0x2d,0x3e,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77,0x65,0x62,
+0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20,0x77,0x61,
+0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72,0x76,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20,0x77,0x65,
+0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72,0x20,0x72,
+0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c,0x77,0x49,
+0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,
+0x69,0x73,0x20,0x70,0x61,0x67,0x65,0x20,0x69,0x73,0x20,0x68,0x65,0x72,0x65,0x20,
+0x74,0x6f,0x20,0x74,0x65,0x73,0x74,0x20,0x53,0x53,0x49,0x2c,0x20,0x73,0x6f,0x20,
+0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x61,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,
+0x72,0x20,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x61,0x6e,0x20,0x65,0x78,
+0x61,0x6d,0x70,0x6c,0x65,0x20,0x6f,0x66,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,
+0x20,0x63,0x68,0x61,0x6e,0x67,0x69,0x6e,0x67,0x20,0x66,0x6f,0x72,0x20,0x65,0x76,
+0x65,0x72,0x79,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x3a,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x22,0x3c,0x21,0x2d,0x2d,0x23,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,
+0x2d,0x2d,0x3e,0x22,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x41,0x6e,0x64,0x20,
+0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x65,0x78,0x61,0x6d,0x70,
+0x6c,0x65,0x20,0x6f,0x66,0x20,0x61,0x20,0x74,0x61,0x67,0x20,0x72,0x65,0x73,0x75,
+0x6c,0x74,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,
+0x20,0x69,0x6e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6d,0x75,0x6c,0x74,0x69,0x70,
+0x6c,0x65,0x20,0x70,0x61,0x72,0x74,0x73,0x3a,0x20,0x22,0x3c,0x21,0x2d,0x2d,0x23,
+0x4d,0x75,0x6c,0x74,0x50,0x61,0x72,0x74,0x2d,0x2d,0x3e,0x22,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x54,0x6f,0x20,0x74,0x65,0x73,0x74,0x20,0x4c,0x57,0x49,0x50,
+0x5f,0x48,0x54,0x54,0x50,0x44,0x5f,0x43,0x47,0x49,0x5f,0x53,0x53,0x49,0x2c,0x20,
+0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x74,0x68,0x65,0x20,0x43,0x47,0x49,
+0x20,0x70,0x61,0x72,0x61,0x6d,0x65,0x74,0x65,0x72,0x73,0x3a,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x3c,0x21,0x2d,0x2d,0x23,0x43,0x67,0x69,0x50,0x61,0x72,0x61,0x6d,
+0x2d,0x2d,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,
+0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,
+0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,
+0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,
+0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,
+0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,
+0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,
+0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,
+0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,
+0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,
+0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,
+0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,
+0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,
+0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,
+0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,
+0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,
+0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,
+0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,
+0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,
+0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,
+0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,
+0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,
+0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,
+0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,
+0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,
+0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,
+0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,
+0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,
+0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,
+0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,
+0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,
+0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,
+0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,
+0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,
+0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,
+0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,
+0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,
+0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,
+0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,
+0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,
+0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,
+0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,
+0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,
+0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,
+0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,
+0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,
+0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,
+0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,
+0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,
+0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,
+0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,
+0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,
+0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,
+0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,
+0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,
+0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,
+0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,
+0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,
+0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,
+0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,
+0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,
+0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,
+0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,
+0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,
+0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,
+0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,
+0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,
+0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,
+0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,
+0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,
+0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,
+0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,
+0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,
+0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,
+0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,
+0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
+0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,
+0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,
+0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,
+0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,
+0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,
+0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,
+0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,
+0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,
+0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,
+0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,
+0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,
+0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,
+0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,
+0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,
+0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,
+0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,
+0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,
+0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,
+0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,
+0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,
+0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,
+0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,
+0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,
+0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,
+0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,
+0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,
+0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,
+0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,
+0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,
+0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,
+0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,
+0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,
+0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,
+0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,
+0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,
+0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,
+0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,
+0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,
+0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,
+0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,
+0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,
+0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,
+0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,
+0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,
+0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,
+0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,
+0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,
+0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,
+0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,
+0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,
+0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,
+0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,
+0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,
+0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,
+0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,
+0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,
+0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,
+0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,
+0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,
+0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,
+0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,
+0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,
+0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,
+0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,
+0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
+0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,
+0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,
+0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,
+0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,
+0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,
+0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,
+0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,
+0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,
+0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,
+0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,
+0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,
+0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,
+0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,
+0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,
+0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,
+0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,
+0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,
+0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,
+0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,
+0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,
+0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,
+0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,
+0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,
+0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,
+0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,
+0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,
+0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,
+0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,
+0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,
+0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,
+0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,
+0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,
+0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,
+0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,
+0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,
+0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,
+0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,
+0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,
+0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,
+0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,
+0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,
+0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,
+0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,
+0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,
+0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,
+0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,
+0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,
+0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,
+0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,
+0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,
+0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,
+0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,
+0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,
+0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,
+0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,
+0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,
+0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,
+0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,
+0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,
+0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,
+0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,
+0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,
+0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,
+0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,
+0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,
+0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,
+0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,
+0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,
+0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,
+0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,
+0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,
+0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,
+0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,
+0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,
+0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,
+0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,
+0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,
+0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,
+0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,
+0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,
+0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,
+0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,
+0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,
+0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,
+0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,
+0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,
+0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,
+0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,
+0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,
+0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,
+0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,
+0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,
+0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,
+0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,
+0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,
+0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,
+0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,
+0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,
+0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,
+0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,
+0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,
+0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,
+0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,
+0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,
+0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,
+0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,
+0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,
+0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,
+0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,
+0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,
+0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,
+0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,
+0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,
+0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,
+0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,
+0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,
+0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,
+0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,
+0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,
+0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,
+0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,
+0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,
+0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,
+0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,
+0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,
+0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,
+0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,
+0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,
+0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,
+0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,
+0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,
+0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,
+0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,
+0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,
+0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,
+0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,
+0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,
+0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,
+0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,
+0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,
+0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,
+0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,
+0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,
+0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,
+0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,
+0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,
+0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,
+0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,
+0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,
+0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,
+0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,
+0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,
+0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,
+0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,
+0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,
+0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,
+0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,
+0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,
+0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,
+0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,
+0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,
+0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,
+0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,
+0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,
+0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,
+0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,
+0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,
+0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,
+0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,
+0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,
+0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,
+0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,
+0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,
+0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,
+0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,
+0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,
+0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,
+0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,
+0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,
+0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,
+0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,
+0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
+0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,
+0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,
+0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,
+0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,
+0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,
+0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,
+0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,
+0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,
+0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,
+0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,
+0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,
+0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,
+0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,
+0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,
+0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,
+0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,
+0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,
+0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,
+0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,
+0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,
+0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,
+0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,
+0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,
+0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,
+0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,
+0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,
+0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,
+0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,
+0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,
+0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,
+0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,
+0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,
+0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,
+0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,
+0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,
+0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,
+0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,
+0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,
+0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,
+0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,
+0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,
+0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,
+0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,
+0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,
+0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,
+0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,
+0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,
+0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,
+0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,
+0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,
+0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,
+0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,
+0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,
+0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,
+0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,
+0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,
+0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
+0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,
+0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,
+0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,
+0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,
+0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,
+0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,
+0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,
+0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,
+0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,
+0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,
+0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,
+0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,
+0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,
+0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,
+0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,
+0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,
+0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,
+0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,
+0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,
+0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,
+0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,
+0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,
+0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,
+0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,
+0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,
+0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,
+0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,
+0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,
+0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,
+0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,
+0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,
+0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,
+0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,
+0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,
+0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,
+0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,
+0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,
+0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,
+0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,
+0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,
+0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,
+0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,
+0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,
+0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,
+0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,
+0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,
+0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,
+0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,
+0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,
+0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,
+0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,
+0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,
+0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,
+0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,
+0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,
+0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,
+0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,
+0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,
+0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,
+0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,
+0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,
+0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,
+0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,
+0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,
+0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,
+0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,
+0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,
+0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,
+0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,
+0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,
+0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,
+0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,
+0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,
+0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,
+0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,
+0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,
+0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
+0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,
+0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,
+0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,
+0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
+0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,
+0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,
+0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,
+0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,
+0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,
+0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,
+0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,
+0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,
+0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,
+0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,
+0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,
+0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,
+0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,
+0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,
+0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,
+0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,
+0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,
+0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,
+0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,
+0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,
+0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,
+0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,
+0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,
+0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,
+0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,
+0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,
+0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,
+0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,
+0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,
+0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,
+0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,
+0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,
+0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,
+0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,
+0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,
+0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,
+0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,
+0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,
+0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,
+0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,
+0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,
+0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,
+0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,
+0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,
+0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,
+0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,
+0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,
+0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,
+0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,
+0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,
+0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,
+0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,
+0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,
+0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,
+0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,
+0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,
+0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,
+0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,
+0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,
+0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,
+0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,
+0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,
+0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,
+0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,
+0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,
+0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,
+0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,
+0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,
+0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,
+0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,
+0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,
+0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,
+0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,
+0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,
+0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,
+0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
+0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,
+0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,
+0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,
+0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,
+0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,
+0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,
+0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,
+0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,
+0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,
+0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,
+0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,
+0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,
+0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,
+0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,
+0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,
+0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,
+0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,
+0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,
+0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,
+0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,
+0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,
+0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,
+0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x20,0x20,0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,
+0x20,0x6f,0x70,0x65,0x6e,0x20,0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,
+0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,
+0x68,0x65,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,
+0x68,0x61,0x74,0x20,0x77,0x61,0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,
+0x6c,0x79,0x20,0x77,0x72,0x69,0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,
+0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,
+0x6d,0x20,0x44,0x75,0x6e,0x6b,0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,
+0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,
+0x6e,0x73,0x74,0x69,0x74,0x75,0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,
+0x75,0x74,0x65,0x72,0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,
+0x20,0x62,0x75,0x74,0x20,0x6e,0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x62,0x65,0x69,0x6e,0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,
+0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,
+0x74,0x65,0x61,0x6d,0x20,0x6f,0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,
+0x72,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,
+0x75,0x74,0x65,0x64,0x20,0x77,0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,
+0x20,0x53,0x69,0x6e,0x63,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,
+0x61,0x73,0x65,0x2c,0x20,0x6c,0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,
+0x20,0x20,0x20,0x20,0x73,0x70,0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,
+0x74,0x20,0x6f,0x66,0x20,0x69,0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,
+0x64,0x20,0x68,0x61,0x73,0x20,0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,
+0x64,0x20,0x74,0x6f,0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,
+0x20,0x20,0x20,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,
+0x20,0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,
+0x6d,0x73,0x2e,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,
+0x75,0x73,0x65,0x64,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,
+0x20,0x20,0x77,0x69,0x74,0x68,0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,
+0x74,0x20,0x61,0x6e,0x20,0x75,0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,
+0x4f,0x53,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,
+0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,
+0x6f,0x63,0x75,0x73,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,
+0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
+0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,
+0x75,0x63,0x65,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,
+0x4d,0x20,0x75,0x73,0x61,0x67,0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,
+0x69,0x6c,0x6c,0x20,0x68,0x61,0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,
+0x6c,0x20,0x73,0x63,0x61,0x6c,0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,
+0x49,0x50,0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,
+0x75,0x73,0x65,0x20,0x69,0x6e,0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,
+0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,
+0x79,0x74,0x65,0x73,0x20,0x6f,0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,
+0x20,0x61,0x6e,0x64,0x20,0x72,0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,
+0x6f,0x75,0x6e,0x64,0x20,0x34,0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,
+0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,
+0x52,0x4f,0x4d,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,
+0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,
+0x20,0x69,0x6e,0x66,0x6f,0x72,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,
+0x75,0x74,0x20,0x6c,0x77,0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,
+0x6f,0x75,0x6e,0x64,0x20,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,
+0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,
+0x61,0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,
+0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,
+0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,
+0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,
+0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,
+0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,
+0x2f,0x6c,0x77,0x69,0x70,0x2f,0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x6f,0x72,0x20,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,
+0x77,0x69,0x6b,0x69,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,
+0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,
+0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,
+0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,
+0x2e,0x63,0x6f,0x6d,0x2f,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,
+0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,
+0x0a,0x09,0x20,0x20,0x26,0x6e,0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,
+0x64,0x3e,0x3c,0x2f,0x74,0x72,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,
+0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,
+0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,};
+
+
+
+const struct fsdata_file file__img_sics_gif[] = { {
+file_NULL,
+data__img_sics_gif,
+data__img_sics_gif + 16,
+sizeof(data__img_sics_gif) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__404_html[] = { {
+file__img_sics_gif,
+data__404_html,
+data__404_html + 12,
+sizeof(data__404_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__index_html[] = { {
+file__404_html,
+data__index_html,
+data__index_html + 12,
+sizeof(data__index_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__login_html[] = { {
+file__index_html,
+data__login_html,
+data__login_html + 12,
+sizeof(data__login_html) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__loginfail_html[] = { {
+file__login_html,
+data__loginfail_html,
+data__loginfail_html + 16,
+sizeof(data__loginfail_html) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__session_html[] = { {
+file__loginfail_html,
+data__session_html,
+data__session_html + 16,
+sizeof(data__session_html) - 16,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT | FS_FILE_FLAGS_HEADER_HTTPVER_1_1,
+}};
+
+const struct fsdata_file file__ssi_shtml[] = { {
+file__session_html,
+data__ssi_shtml,
+data__ssi_shtml + 12,
+sizeof(data__ssi_shtml) - 12,
+FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_SSI,
+}};
+
+#define FS_ROOT file__ssi_shtml
+#define FS_NUMFILES 7
+
diff --git a/contrib/examples/httpd/fs_example/fs_example.c b/contrib/examples/httpd/fs_example/fs_example.c
new file mode 100644
index 0000000..e3552b1
--- /dev/null
+++ b/contrib/examples/httpd/fs_example/fs_example.c
@@ -0,0 +1,324 @@
+/**
+ * @file
+ * HTTPD custom file system example
+ *
+ * This file demonstrates how to add support for an external file system to httpd.
+ * It provides access to the specified root directory and uses stdio.h file functions
+ * to read files.
+ *
+ * ATTENTION: This implementation is *not* secure: no checks are added to ensure
+ * files are only read below the specified root directory!
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "fs_example.h"
+
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES 0
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED to 1 to delay open and read
+ * as if e.g. reading from external SPI flash */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED 1
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ to the number of bytes
+ * to read to emulate limited transfer buffers and don't read whole files in
+ * one chunk.
+ * WARNING: lowering this slows down the connection!
+ */
+#ifndef LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+#define LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES
+
+#if !LWIP_HTTPD_CUSTOM_FILES
+#error This needs LWIP_HTTPD_CUSTOM_FILES
+#endif
+#if !LWIP_HTTPD_DYNAMIC_HEADERS
+#error This needs LWIP_HTTPD_DYNAMIC_HEADERS
+#endif
+#if !LWIP_HTTPD_DYNAMIC_FILE_READ
+#error This wants to demonstrate read-after-open, so LWIP_HTTPD_DYNAMIC_FILE_READ is required!
+#endif
+#if !LWIP_HTTPD_FS_ASYNC_READ
+#error This needs LWIP_HTTPD_FS_ASYNC_READ
+#endif
+#if !LWIP_HTTPD_FILE_EXTENSION
+#error This needs LWIP_HTTPD_FILE_EXTENSION
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+#include "lwip/tcpip.h"
+#endif
+
+struct fs_custom_data {
+ FILE *f;
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+ int delay_read;
+ fs_wait_cb callback_fn;
+ void *callback_arg;
+#endif
+};
+
+const char* fs_ex_root_dir;
+
+void
+fs_ex_init(const char *httpd_root_dir)
+{
+ fs_ex_root_dir = strdup(httpd_root_dir);
+}
+
+#if LWIP_HTTPD_CUSTOM_FILES
+int
+fs_open_custom(struct fs_file *file, const char *name)
+{
+ char full_filename[256];
+ FILE *f;
+
+ snprintf(full_filename, 255, "%s%s", fs_ex_root_dir, name);
+ full_filename[255] = 0;
+
+ f = fopen(full_filename, "rb");
+ if (f != NULL) {
+ if (!fseek(f, 0, SEEK_END)) {
+ int len = (int)ftell(f);
+ if(!fseek(f, 0, SEEK_SET)) {
+ struct fs_custom_data *data = (struct fs_custom_data *)mem_malloc(sizeof(struct fs_custom_data));
+ LWIP_ASSERT("out of memory?", data != NULL);
+ memset(file, 0, sizeof(struct fs_file));
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+ file->len = 0; /* read size delayed */
+ data->delay_read = 3;
+ LWIP_UNUSED_ARG(len);
+#else
+ file->len = len;
+#endif
+ file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
+ data->f = f;
+ file->pextension = data;
+ return 1;
+ }
+ }
+ fclose(f);
+ }
+ return 0;
+}
+
+void
+fs_close_custom(struct fs_file *file)
+{
+ if (file && file->pextension) {
+ struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+ if (data->f != NULL) {
+ fclose(data->f);
+ data->f = NULL;
+ }
+ mem_free(data);
+ }
+}
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+u8_t
+fs_canread_custom(struct fs_file *file)
+{
+ /* This function is only necessary for asynchronous I/O:
+ If reading would block, return 0 and implement fs_wait_read_custom() to call the
+ supplied callback if reading works. */
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+ struct fs_custom_data *data;
+ LWIP_ASSERT("file != NULL", file != NULL);
+ data = (struct fs_custom_data *)file->pextension;
+ if (data == NULL) {
+ /* file transfer has been completed already */
+ LWIP_ASSERT("transfer complete", file->index == file->len);
+ return 1;
+ }
+ LWIP_ASSERT("data != NULL", data != NULL);
+ /* This just simulates a simple delay. This delay would normally come e.g. from SPI transfer */
+ if (data->delay_read == 3) {
+ /* delayed file size mode */
+ data->delay_read = 1;
+ LWIP_ASSERT("", file->len == 0);
+ if (!fseek(data->f, 0, SEEK_END)) {
+ int len = (int)ftell(data->f);
+ if(!fseek(data->f, 0, SEEK_SET)) {
+ file->len = len; /* read size delayed */
+ data->delay_read = 1;
+ return 0;
+ }
+ }
+ /* if we come here, something is wrong with the file */
+ LWIP_ASSERT("file error", 0);
+ }
+ if (data->delay_read == 1) {
+ /* tell read function to delay further */
+ }
+#endif
+ LWIP_UNUSED_ARG(file);
+ return 1;
+}
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+static void
+fs_example_read_cb(void *arg)
+{
+ struct fs_custom_data *data = (struct fs_custom_data *)arg;
+ fs_wait_cb callback_fn = data->callback_fn;
+ void *callback_arg = data->callback_arg;
+ data->callback_fn = NULL;
+ data->callback_arg = NULL;
+
+ LWIP_ASSERT("no callback_fn", callback_fn != NULL);
+
+ callback_fn(callback_arg);
+}
+#endif
+
+u8_t
+fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
+{
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+ err_t err;
+ struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+ LWIP_ASSERT("data not set", data != NULL);
+ data->callback_fn = callback_fn;
+ data->callback_arg = callback_arg;
+ err = tcpip_try_callback(fs_example_read_cb, data);
+ LWIP_ASSERT("out of queue elements?", err == ERR_OK);
+ LWIP_UNUSED_ARG(err);
+#else
+ LWIP_ASSERT("not implemented in this example configuration", 0);
+#endif
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(callback_fn);
+ LWIP_UNUSED_ARG(callback_arg);
+ /* Return
+ - 0 if ready to read (at least one byte)
+ - 1 if reading should be delayed (call 'tcpip_callback(callback_fn, callback_arg)' when ready) */
+ return 1;
+}
+
+int
+fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
+{
+ struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+ FILE *f;
+ int len;
+ int read_count = count;
+ LWIP_ASSERT("data not set", data != NULL);
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_DELAYED
+ /* This just simulates a delay. This delay would normally come e.g. from SPI transfer */
+ LWIP_ASSERT("invalid state", data->delay_read >= 0 && data->delay_read <= 2);
+ if (data->delay_read == 2) {
+ /* no delay next time */
+ data->delay_read = 0;
+ return FS_READ_DELAYED;
+ } else if (data->delay_read == 1) {
+ err_t err;
+ /* execute requested delay */
+ data->delay_read = 2;
+ LWIP_ASSERT("duplicate callback request", data->callback_fn == NULL);
+ data->callback_fn = callback_fn;
+ data->callback_arg = callback_arg;
+ err = tcpip_try_callback(fs_example_read_cb, data);
+ LWIP_ASSERT("out of queue elements?", err == ERR_OK);
+ LWIP_UNUSED_ARG(err);
+ return FS_READ_DELAYED;
+ }
+ /* execute this read but delay the next one */
+ data->delay_read = 1;
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+ read_count = LWIP_MIN(read_count, LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ);
+#endif
+
+ f = data->f;
+ len = (int)fread(buffer, 1, read_count, f);
+
+ LWIP_UNUSED_ARG(callback_fn);
+ LWIP_UNUSED_ARG(callback_arg);
+
+ file->index += len;
+
+ /* Return
+ - FS_READ_EOF if all bytes have been read
+ - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+ if (len == 0) {
+ /* all bytes read already */
+ return FS_READ_EOF;
+ }
+ return len;
+}
+
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int
+fs_read_custom(struct fs_file *file, char *buffer, int count)
+{
+ struct fs_custom_data *data = (struct fs_custom_data *)file->pextension;
+ FILE *f;
+ int len;
+ int read_count = count;
+ LWIP_ASSERT("data not set", data != NULL);
+
+#if LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ
+ read_count = LWIP_MIN(read_count, LWIP_HTTPD_EXAMPLE_CUSTOMFILES_LIMIT_READ);
+#endif
+
+ f = data->f;
+ len = (int)fread(buffer, 1, read_count, f);
+
+ file->index += len;
+
+ /* Return FS_READ_EOF if all bytes have been read */
+ return len;
+}
+
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+#endif /* LWIP_HTTPD_CUSTOM_FILES */
+
+#endif /* LWIP_HTTPD_EXAMPLE_CUSTOMFILES */
diff --git a/contrib/examples/httpd/fs_example/fs_example.h b/contrib/examples/httpd/fs_example/fs_example.h
new file mode 100644
index 0000000..b399e4d
--- /dev/null
+++ b/contrib/examples/httpd/fs_example/fs_example.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE
+
+void fs_ex_init(const char *httpd_root_dir);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_FS_EXAMPLE */
diff --git a/contrib/examples/httpd/genfiles_example/genfiles_example.c b/contrib/examples/httpd/genfiles_example/genfiles_example.c
new file mode 100644
index 0000000..b96df2a
--- /dev/null
+++ b/contrib/examples/httpd/genfiles_example/genfiles_example.c
@@ -0,0 +1,186 @@
+/**
+ * @file
+ * HTTPD custom file system example for runtime generated files
+ *
+ * This file demonstrates how to add support for generated files to httpd.
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "genfiles_example.h"
+
+#include "lwip/apps/fs.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_GENERATEDFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_GENERATEDFILES
+#define LWIP_HTTPD_EXAMPLE_GENERATEDFILES 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_GENERATEDFILES
+
+#if !LWIP_HTTPD_CUSTOM_FILES
+#error This needs LWIP_HTTPD_CUSTOM_FILES
+#endif
+#if !LWIP_HTTPD_FILE_EXTENSION
+#error This needs LWIP_HTTPD_FILE_EXTENSION
+#endif
+#if !LWIP_HTTPD_DYNAMIC_HEADERS
+#error This needs LWIP_HTTPD_DYNAMIC_HEADERS
+#endif
+
+/* This is the page we send. It's not generated, as you see.
+ * Generating custom things instead of memcpy is left to your imagination :-)
+ */
+const char generated_html[] =
+"<html>\n"
+"<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>\n"
+" <body bgcolor=\"white\" text=\"black\">\n"
+" <table width=\"100%\">\n"
+" <tr valign=\"top\">\n"
+" <td width=\"80\">\n"
+" <a href=\"http://www.sics.se/\"><img src=\"/img/sics.gif\"\n"
+" border=\"0\" alt=\"SICS logo\" title=\"SICS logo\"></a>\n"
+" </td>\n"
+" <td width=\"500\">\n"
+" <h1>lwIP - A Lightweight TCP/IP Stack</h1>\n"
+" <h2>Generated page</h2>\n"
+" <p>This page might be generated in-memory at runtime</p>\n"
+" </td>\n"
+" <td>\n"
+" \n"
+" </td>\n"
+" </tr>\n"
+" </table>\n"
+" </body>\n"
+"</html>";
+
+
+void
+genfiles_ex_init(void)
+{
+ /* nothing to do here yet */
+}
+
+int
+fs_open_custom(struct fs_file *file, const char *name)
+{
+ /* this example only provides one file */
+ if (!strcmp(name, "/generated.html")) {
+ /* initialize fs_file correctly */
+ memset(file, 0, sizeof(struct fs_file));
+ file->pextension = mem_malloc(sizeof(generated_html));
+ if (file->pextension != NULL) {
+ /* instead of doing memcpy, you would generate e.g. a JSON here */
+ memcpy(file->pextension, generated_html, sizeof(generated_html));
+ file->data = (const char *)file->pextension;
+ file->len = sizeof(generated_html) - 1; /* don't send the trailing 0 */
+ file->index = file->len;
+ /* allow persisteng connections */
+ file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+fs_close_custom(struct fs_file *file)
+{
+ if (file && file->pextension) {
+ mem_free(file->pextension);
+ file->pextension = NULL;
+ }
+}
+
+#if LWIP_HTTPD_FS_ASYNC_READ
+u8_t
+fs_canread_custom(struct fs_file *file)
+{
+ LWIP_UNUSED_ARG(file);
+ /* This example does not use delayed/async reading */
+ return 1;
+}
+
+u8_t
+fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
+{
+ LWIP_ASSERT("not implemented in this example configuration", 0);
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(callback_fn);
+ LWIP_UNUSED_ARG(callback_arg);
+ /* Return
+ - 1 if ready to read (at least one byte)
+ - 0 if reading should be delayed (call 'tcpip_callback(callback_fn, callback_arg)' when ready) */
+ return 1;
+}
+
+int
+fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
+{
+ LWIP_ASSERT("not implemented in this example configuration", 0);
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(buffer);
+ LWIP_UNUSED_ARG(count);
+ LWIP_UNUSED_ARG(callback_fn);
+ LWIP_UNUSED_ARG(callback_arg);
+ /* Return
+ - FS_READ_EOF if all bytes have been read
+ - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+ /* all bytes read already */
+ return FS_READ_EOF;
+}
+
+#else /* LWIP_HTTPD_FS_ASYNC_READ */
+int
+fs_read_custom(struct fs_file *file, char *buffer, int count)
+{
+ LWIP_ASSERT("not implemented in this example configuration", 0);
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(buffer);
+ LWIP_UNUSED_ARG(count);
+ /* Return
+ - FS_READ_EOF if all bytes have been read
+ - FS_READ_DELAYED if reading is delayed (call 'tcpip_callback(callback_fn, callback_arg)' when done) */
+ /* all bytes read already */
+ return FS_READ_EOF;
+}
+
+#endif /* LWIP_HTTPD_FS_ASYNC_READ */
+
+#endif /* LWIP_HTTPD_EXAMPLE_GENERATEDFILES */
diff --git a/contrib/examples/httpd/genfiles_example/genfiles_example.h b/contrib/examples/httpd/genfiles_example/genfiles_example.h
new file mode 100644
index 0000000..dd9731e
--- /dev/null
+++ b/contrib/examples/httpd/genfiles_example/genfiles_example.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE
+
+void genfiles_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_GENFILES_EXAMPLE */
diff --git a/contrib/examples/httpd/https_example/https_example.c b/contrib/examples/httpd/https_example/https_example.c
new file mode 100644
index 0000000..7619896
--- /dev/null
+++ b/contrib/examples/httpd/https_example/https_example.c
@@ -0,0 +1,144 @@
+/**
+ * @file
+ * HTTPD https example
+ *
+ * This file demonstrates how to initialize httpd for https.
+ * To do this, it needs 2 files:
+ * - server certificate
+ * - server private key
+ *
+ * In addition to that, watch out for resource shortage. You'll need plenty of
+ * heap (start with MEM_SIZE >= 200 KByte or monitor its err counters) and be
+ * sure to at least set the following settings high enough (monitor
+ * lwip_stats for an idea of what's needed):
+ * - MEMP_NUM_TCP_PCB/MEMP_NUM_ALTCP_PCB
+ * - MEMP_NUM_TCPIP_MSG_INPKT
+ * - MEMP_NUM_TCP_SEG
+ */
+
+ /*
+ * Copyright (c) 2017-2019 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "https_example.h"
+
+#include "lwip/altcp_tls.h"
+#include "lwip/apps/httpd.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_HTTPS to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_HTTPS
+#define LWIP_HTTPD_EXAMPLE_HTTPS 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_HTTPS && LWIP_ALTCP_TLS
+
+#ifndef LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE
+#error "define LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE to the created server private key"
+#endif
+
+/* If the key file is password-protected, define LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS */
+#ifdef LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS
+#ifndef LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS_LEN
+#define LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS_LEN strlen(LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS)
+#endif
+#else
+#define LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS NULL
+#define LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS_LEN 0
+#endif
+
+#ifndef LWIP_HTTPD_EXAMPLE_HTTPS_CERT_FILE
+#error "define LWIP_HTTPD_EXAMPLE_HTTPS_CERT_FILE to the created server certificate"
+#endif
+
+static u8_t *read_file(const char *filename, size_t *file_size)
+{
+ u8_t *buf;
+ long fsize;
+ FILE *f = fopen(filename, "rb");
+ if (!f) {
+ return NULL;
+ }
+ fseek(f, 0, SEEK_END);
+ fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ buf = (u8_t *)malloc(fsize + 1);
+ if (!buf) {
+ fclose(f);
+ return NULL;
+ }
+ fread(buf, 1, fsize, f);
+ fclose(f);
+
+ buf[fsize] = 0;
+ if (file_size) {
+ /* Note: the '+ 1' is required for mbedTLS to correctly parse the buffer */
+ *file_size = (size_t)(fsize + 1);
+ }
+ return buf;
+}
+
+/** This function loads a server certificate and private key as x509 from disk.
+ * For information how to create such files, see mbedTLS tutorial ("How to
+ * generate a self-signed certificate") or OpenSSL documentation ("How to
+ * generate a self-signed certificate and private key using OpenSSL"), e.g.
+ * 'openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt'
+ * Copy the resulting files and define the path to them
+ */
+void
+https_ex_init(void)
+{
+ struct altcp_tls_config *conf;
+ u8_t *privkey, *cert;
+ size_t privkey_size, cert_size;
+
+ privkey = read_file(LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE, &privkey_size);
+ LWIP_ASSERT("Failed to open https server private key", privkey != NULL);
+ cert = read_file(LWIP_HTTPD_EXAMPLE_HTTPS_CERT_FILE, &cert_size);
+ LWIP_ASSERT("Failed to open https server certificate", cert != NULL);
+
+ conf = altcp_tls_create_config_server_privkey_cert(privkey, privkey_size,
+ LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS, LWIP_HTTPD_EXAMPLE_HTTPS_KEY_FILE_PASS_LEN, cert, cert_size);
+ LWIP_ASSERT("Failed to create https server config", conf != NULL);
+
+ httpd_inits(conf);
+
+ /* secure erase should be done in production environment */
+ free(privkey);
+ free(cert);
+}
+
+#endif /* LWIP_HTTPD_EXAMPLE_HTTPS */
diff --git a/contrib/examples/httpd/https_example/https_example.h b/contrib/examples/httpd/https_example/https_example.h
new file mode 100644
index 0000000..c1525e6
--- /dev/null
+++ b/contrib/examples/httpd/https_example/https_example.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_HTTPS_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_HTTPS_EXAMPLE
+
+void https_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_HTTPS_EXAMPLE */
diff --git a/contrib/examples/httpd/post_example/post_example.c b/contrib/examples/httpd/post_example/post_example.c
new file mode 100644
index 0000000..f4e4369
--- /dev/null
+++ b/contrib/examples/httpd/post_example/post_example.c
@@ -0,0 +1,167 @@
+/**
+ * @file
+ * HTTPD example for simple POST
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#include "lwip/apps/httpd.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_GENERATEDFILES to 1 to enable this file system */
+#ifndef LWIP_HTTPD_EXAMPLE_SIMPLEPOST
+#define LWIP_HTTPD_EXAMPLE_SIMPLEPOST 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_SIMPLEPOST
+
+#if !LWIP_HTTPD_SUPPORT_POST
+#error This needs LWIP_HTTPD_SUPPORT_POST
+#endif
+
+#define USER_PASS_BUFSIZE 16
+
+static void *current_connection;
+static void *valid_connection;
+static char last_user[USER_PASS_BUFSIZE];
+
+err_t
+httpd_post_begin(void *connection, const char *uri, const char *http_request,
+ u16_t http_request_len, int content_len, char *response_uri,
+ u16_t response_uri_len, u8_t *post_auto_wnd)
+{
+ LWIP_UNUSED_ARG(connection);
+ LWIP_UNUSED_ARG(http_request);
+ LWIP_UNUSED_ARG(http_request_len);
+ LWIP_UNUSED_ARG(content_len);
+ LWIP_UNUSED_ARG(post_auto_wnd);
+ if (!memcmp(uri, "/login.cgi", 11)) {
+ if (current_connection != connection) {
+ current_connection = connection;
+ valid_connection = NULL;
+ /* default page is "login failed" */
+ snprintf(response_uri, response_uri_len, "/loginfail.html");
+ /* e.g. for large uploads to slow flash over a fast connection, you should
+ manually update the rx window. That way, a sender can only send a full
+ tcp window at a time. If this is required, set 'post_aut_wnd' to 0.
+ We do not need to throttle upload speed here, so: */
+ *post_auto_wnd = 1;
+ return ERR_OK;
+ }
+ }
+ return ERR_VAL;
+}
+
+err_t
+httpd_post_receive_data(void *connection, struct pbuf *p)
+{
+ err_t ret;
+
+ LWIP_ASSERT("NULL pbuf", p != NULL);
+
+ if (current_connection == connection) {
+ u16_t token_user = pbuf_memfind(p, "user=", 5, 0);
+ u16_t token_pass = pbuf_memfind(p, "pass=", 5, 0);
+ if ((token_user != 0xFFFF) && (token_pass != 0xFFFF)) {
+ u16_t value_user = token_user + 5;
+ u16_t value_pass = token_pass + 5;
+ u16_t len_user = 0;
+ u16_t len_pass = 0;
+ u16_t tmp;
+ /* find user len */
+ tmp = pbuf_memfind(p, "&", 1, value_user);
+ if (tmp != 0xFFFF) {
+ len_user = tmp - value_user;
+ } else {
+ len_user = p->tot_len - value_user;
+ }
+ /* find pass len */
+ tmp = pbuf_memfind(p, "&", 1, value_pass);
+ if (tmp != 0xFFFF) {
+ len_pass = tmp - value_pass;
+ } else {
+ len_pass = p->tot_len - value_pass;
+ }
+ if ((len_user > 0) && (len_user < USER_PASS_BUFSIZE) &&
+ (len_pass > 0) && (len_pass < USER_PASS_BUFSIZE)) {
+ /* provide contiguous storage if p is a chained pbuf */
+ char buf_user[USER_PASS_BUFSIZE];
+ char buf_pass[USER_PASS_BUFSIZE];
+ char *user = (char *)pbuf_get_contiguous(p, buf_user, sizeof(buf_user), len_user, value_user);
+ char *pass = (char *)pbuf_get_contiguous(p, buf_pass, sizeof(buf_pass), len_pass, value_pass);
+ if (user && pass) {
+ user[len_user] = 0;
+ pass[len_pass] = 0;
+ if (!strcmp(user, "lwip") && !strcmp(pass, "post")) {
+ /* user and password are correct, create a "session" */
+ valid_connection = connection;
+ memcpy(last_user, user, sizeof(last_user));
+ }
+ }
+ }
+ }
+ /* not returning ERR_OK aborts the connection, so return ERR_OK unless the
+ connection is unknown */
+ ret = ERR_OK;
+ } else {
+ ret = ERR_VAL;
+ }
+
+ /* this function must ALWAYS free the pbuf it is passed or it will leak memory */
+ pbuf_free(p);
+
+ return ret;
+}
+
+void
+httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len)
+{
+ /* default page is "login failed" */
+ snprintf(response_uri, response_uri_len, "/loginfail.html");
+ if (current_connection == connection) {
+ if (valid_connection == connection) {
+ /* login succeeded */
+ snprintf(response_uri, response_uri_len, "/session.html");
+ }
+ current_connection = NULL;
+ valid_connection = NULL;
+ }
+}
+
+#endif /* LWIP_HTTPD_EXAMPLE_SIMPLEPOST*/
diff --git a/contrib/examples/httpd/ssi_example/ssi_example.c b/contrib/examples/httpd/ssi_example/ssi_example.c
new file mode 100644
index 0000000..2024e2e
--- /dev/null
+++ b/contrib/examples/httpd/ssi_example/ssi_example.c
@@ -0,0 +1,264 @@
+/**
+ * @file
+ * HTTPD simple SSI example
+ *
+ * This file demonstrates how to add support for SSI.
+ * It does this in a very simple way by providing the three tags 'HelloWorld'
+ * 'counter', and 'MultiPart'.
+ *
+ * This file also demonstrates how to integrate CGI with SSI.
+ */
+
+ /*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#include "lwip/opt.h"
+#include "ssi_example.h"
+
+#include "lwip/apps/httpd.h"
+
+#include "lwip/def.h"
+#include "lwip/mem.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE to 1 to enable this ssi example*/
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE 0
+#endif
+
+/** define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION to 1 to show how to
+ * integrate CGI into SSI (LWIP_HTTPD_CGI_SSI) */
+#ifndef LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#define LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION 0
+#endif
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+#if !LWIP_HTTPD_FILE_STATE
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_FILE_STATE
+#endif
+#if !LWIP_HTTPD_CGI_SSI
+#error LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION needs LWIP_HTTPD_CGI_SSI
+#endif
+
+#define MAX_CGI_LEN 16
+#endif
+
+const char * ssi_example_tags[] = {
+ "HellWorl",
+ "counter",
+ "MultPart"
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+ ,"CgiParam"
+#endif
+};
+
+u16_t ssi_example_ssi_handler(
+#if LWIP_HTTPD_SSI_RAW
+ const char* ssi_tag_name,
+#else /* LWIP_HTTPD_SSI_RAW */
+ int iIndex,
+#endif /* LWIP_HTTPD_SSI_RAW */
+ char *pcInsert, int iInsertLen
+#if LWIP_HTTPD_SSI_MULTIPART
+ , u16_t current_tag_part, u16_t *next_tag_part
+#endif /* LWIP_HTTPD_SSI_MULTIPART */
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+ )
+{
+ size_t printed;
+#if LWIP_HTTPD_SSI_RAW
+ /* a real application could use if(!strcmp) blocks here, but we want to keep
+ the differences between configurations small, so translate string to index here */
+ int iIndex;
+ for (iIndex = 0; iIndex < LWIP_ARRAYSIZE(ssi_example_tags); iIndex++) {
+ if(!strcmp(ssi_tag_name, ssi_example_tags[iIndex])) {
+ break;
+ }
+ }
+#endif
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ LWIP_UNUSED_ARG(connection_state);
+#endif
+
+ switch (iIndex) {
+ case 0: /* "HelloWorld" */
+ printed = snprintf(pcInsert, iInsertLen, "Hello World!");
+ break;
+ case 1: /* "counter" */
+ {
+ static int counter;
+ counter++;
+ printed = snprintf(pcInsert, iInsertLen, "%d", counter);
+ }
+ break;
+ case 2: /* "MultPart" */
+#if LWIP_HTTPD_SSI_MULTIPART
+ switch (current_tag_part) {
+ case 0:
+ printed = snprintf(pcInsert, iInsertLen, "part0");
+ *next_tag_part = 1;
+ break;
+ case 1:
+ printed = snprintf(pcInsert, iInsertLen, "part1");
+ *next_tag_part = 2;
+ break;
+ case 2:
+ printed = snprintf(pcInsert, iInsertLen, "part2");
+ break;
+ default:
+ printed = snprintf(pcInsert, iInsertLen, "unhandled part: %d", (int)current_tag_part);
+ break;
+ }
+#else
+ printed = snprintf(pcInsert, iInsertLen, "LWIP_HTTPD_SSI_MULTIPART disabled");
+#endif
+ break;
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+ case 3:
+ if (connection_state) {
+ char *params = (char *)connection_state;
+ if (*params) {
+ printed = snprintf(pcInsert, iInsertLen, "%s", (char *)params);
+ } else {
+ printed = snprintf(pcInsert, iInsertLen, "none");
+ }
+ } else {
+ printed = snprintf(pcInsert, iInsertLen, "NULL");
+ }
+ break;
+#endif
+ default: /* unknown tag */
+ printed = 0;
+ break;
+ }
+ LWIP_ASSERT("sane length", printed <= 0xFFFF);
+ return (u16_t)printed;
+}
+
+void
+ssi_ex_init(void)
+{
+ int i;
+ for (i = 0; i < LWIP_ARRAYSIZE(ssi_example_tags); i++) {
+ LWIP_ASSERT("tag too long for LWIP_HTTPD_MAX_TAG_NAME_LEN",
+ strlen(ssi_example_tags[i]) <= LWIP_HTTPD_MAX_TAG_NAME_LEN);
+ }
+
+ http_set_ssi_handler(ssi_example_ssi_handler,
+#if LWIP_HTTPD_SSI_RAW
+ NULL, 0
+#else
+ ssi_example_tags, LWIP_ARRAYSIZE(ssi_example_tags)
+#endif
+ );
+}
+
+#if LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION
+void *
+fs_state_init(struct fs_file *file, const char *name)
+{
+ char *ret;
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(name);
+ ret = (char *)mem_malloc(MAX_CGI_LEN);
+ if (ret) {
+ *ret = 0;
+ }
+ return ret;
+}
+
+void
+fs_state_free(struct fs_file *file, void *state)
+{
+ LWIP_UNUSED_ARG(file);
+ if (state != NULL) {
+ mem_free(state);
+ }
+}
+
+void
+httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
+ char **pcParam, char **pcValue
+#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
+ , void *connection_state
+#endif /* LWIP_HTTPD_FILE_STATE */
+ )
+{
+ LWIP_UNUSED_ARG(file);
+ LWIP_UNUSED_ARG(uri);
+ if (connection_state != NULL) {
+ char *start = (char *)connection_state;
+ char *end = start + MAX_CGI_LEN;
+ int i;
+ memset(start, 0, MAX_CGI_LEN);
+ /* print a string of the arguments: */
+ for (i = 0; i < iNumParams; i++) {
+ size_t len;
+ len = end - start;
+ if (len) {
+ size_t inlen = strlen(pcParam[i]);
+ size_t copylen = LWIP_MIN(inlen, len);
+ memcpy(start, pcParam[i], copylen);
+ start += copylen;
+ len -= copylen;
+ }
+ if (len) {
+ *start = '=';
+ start++;
+ len--;
+ }
+ if (len) {
+ size_t inlen = strlen(pcValue[i]);
+ size_t copylen = LWIP_MIN(inlen, len);
+ memcpy(start, pcValue[i], copylen);
+ start += copylen;
+ len -= copylen;
+ }
+ if (len) {
+ *start = ';';
+ len--;
+ }
+ /* ensure NULL termination */
+ end--;
+ *end = 0;
+ }
+ }
+}
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE_CGI_INTEGRATION */
+
+#endif /* LWIP_HTTPD_EXAMPLE_SSI_SIMPLE */
diff --git a/contrib/examples/httpd/ssi_example/ssi_example.h b/contrib/examples/httpd/ssi_example/ssi_example.h
new file mode 100644
index 0000000..b7ec298
--- /dev/null
+++ b/contrib/examples/httpd/ssi_example/ssi_example.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Simon Goldschmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Simon Goldschmidt <goldsimon@gmx.de>
+ *
+ */
+
+#ifndef LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE
+#define LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE
+
+void ssi_ex_init(void);
+
+#endif /* LWIP_HDR_HTTP_EXAMPLES_SSI_EXAMPLE */
diff --git a/contrib/examples/lwiperf/lwiperf_example.c b/contrib/examples/lwiperf/lwiperf_example.c
new file mode 100644
index 0000000..a33bc6f
--- /dev/null
+++ b/contrib/examples/lwiperf/lwiperf_example.c
@@ -0,0 +1,50 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/lwiperf.h"
+#include "lwiperf_example.h"
+
+static void
+lwiperf_report(void *arg, enum lwiperf_report_type report_type,
+ const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
+ u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
+{
+ LWIP_UNUSED_ARG(arg);
+ LWIP_UNUSED_ARG(local_addr);
+ LWIP_UNUSED_ARG(local_port);
+
+ LWIP_PLATFORM_DIAG(("IPERF report: type=%d, remote: %s:%d, total bytes: %"U32_F", duration in ms: %"U32_F", kbits/s: %"U32_F"\n",
+ (int)report_type, ipaddr_ntoa(remote_addr), (int)remote_port, bytes_transferred, ms_duration, bandwidth_kbitpsec));
+}
+
+void
+lwiperf_example_init(void)
+{
+ lwiperf_start_tcp_server_default(lwiperf_report, NULL);
+}
diff --git a/contrib/examples/lwiperf/lwiperf_example.h b/contrib/examples/lwiperf/lwiperf_example.h
new file mode 100644
index 0000000..d7b35c8
--- /dev/null
+++ b/contrib/examples/lwiperf/lwiperf_example.h
@@ -0,0 +1,43 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef LWIPERF_EXAMPLE_H
+#define LWIPERF_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lwiperf_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIPERF_EXAMPLE_H */
diff --git a/contrib/examples/mdns/mdns_example.c b/contrib/examples/mdns/mdns_example.c
new file mode 100644
index 0000000..49625ef
--- /dev/null
+++ b/contrib/examples/mdns/mdns_example.c
@@ -0,0 +1,63 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/mdns.h"
+#include "mdns_example.h"
+
+#if LWIP_MDNS_RESPONDER
+static void
+srv_txt(struct mdns_service *service, void *txt_userdata)
+{
+ err_t res;
+ LWIP_UNUSED_ARG(txt_userdata);
+
+ res = mdns_resp_add_service_txtitem(service, "path=/", 6);
+ LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
+}
+#endif
+
+#if LWIP_MDNS_RESPONDER
+static void
+mdns_example_report(struct netif* netif, u8_t result, s8_t service)
+{
+ LWIP_PLATFORM_DIAG(("mdns status[netif %d][service %d]: %d\n", netif->num, service, result));
+}
+#endif
+
+void
+mdns_example_init(void)
+{
+#if LWIP_MDNS_RESPONDER
+ mdns_resp_register_name_result_cb(mdns_example_report);
+ mdns_resp_init();
+ mdns_resp_add_netif(netif_default, "lwip");
+ mdns_resp_add_service(netif_default, "myweb", "_http", DNSSD_PROTO_TCP, 80, srv_txt, NULL);
+ mdns_resp_announce(netif_default);
+#endif
+}
diff --git a/contrib/examples/mdns/mdns_example.h b/contrib/examples/mdns/mdns_example.h
new file mode 100644
index 0000000..ab51ade
--- /dev/null
+++ b/contrib/examples/mdns/mdns_example.h
@@ -0,0 +1,43 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef MDNS_EXAMPLE_H
+#define MDNS_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mdns_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MDNS_EXAMPLE_H */
diff --git a/contrib/examples/mqtt/mqtt_example.c b/contrib/examples/mqtt/mqtt_example.c
new file mode 100644
index 0000000..bb277d6
--- /dev/null
+++ b/contrib/examples/mqtt/mqtt_example.c
@@ -0,0 +1,128 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/apps/mqtt.h"
+#include "mqtt_example.h"
+
+#if LWIP_TCP
+
+/** Define this to a compile-time IP address initialization
+ * to connect anything else than IPv4 loopback
+ */
+#ifndef LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#if LWIP_IPV4
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT = IPADDR4_INIT(PP_HTONL(IPADDR_LOOPBACK))
+#else
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT
+#endif
+#endif
+
+static ip_addr_t mqtt_ip LWIP_MQTT_EXAMPLE_IPADDR_INIT;
+static mqtt_client_t* mqtt_client;
+
+static const struct mqtt_connect_client_info_t mqtt_client_info =
+{
+ "test",
+ NULL, /* user */
+ NULL, /* pass */
+ 100, /* keep alive */
+ NULL, /* will_topic */
+ NULL, /* will_msg */
+ 0, /* will_qos */
+ 0 /* will_retain */
+#if LWIP_ALTCP && LWIP_ALTCP_TLS
+ , NULL
+#endif
+};
+
+static void
+mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
+{
+ const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+ LWIP_UNUSED_ARG(data);
+
+ LWIP_PLATFORM_DIAG(("MQTT client \"%s\" data cb: len %d, flags %d\n", client_info->client_id,
+ (int)len, (int)flags));
+}
+
+static void
+mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
+{
+ const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+ LWIP_PLATFORM_DIAG(("MQTT client \"%s\" publish cb: topic %s, len %d\n", client_info->client_id,
+ topic, (int)tot_len));
+}
+
+static void
+mqtt_request_cb(void *arg, err_t err)
+{
+ const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+
+ LWIP_PLATFORM_DIAG(("MQTT client \"%s\" request cb: err %d\n", client_info->client_id, (int)err));
+}
+
+static void
+mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
+{
+ const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
+ LWIP_UNUSED_ARG(client);
+
+ LWIP_PLATFORM_DIAG(("MQTT client \"%s\" connection cb: status %d\n", client_info->client_id, (int)status));
+
+ if (status == MQTT_CONNECT_ACCEPTED) {
+ mqtt_sub_unsub(client,
+ "topic_qos1", 1,
+ mqtt_request_cb, LWIP_CONST_CAST(void*, client_info),
+ 1);
+ mqtt_sub_unsub(client,
+ "topic_qos0", 0,
+ mqtt_request_cb, LWIP_CONST_CAST(void*, client_info),
+ 1);
+ }
+}
+#endif /* LWIP_TCP */
+
+void
+mqtt_example_init(void)
+{
+#if LWIP_TCP
+ mqtt_client = mqtt_client_new();
+
+ mqtt_set_inpub_callback(mqtt_client,
+ mqtt_incoming_publish_cb,
+ mqtt_incoming_data_cb,
+ LWIP_CONST_CAST(void*, &mqtt_client_info));
+
+ mqtt_client_connect(mqtt_client,
+ &mqtt_ip, MQTT_PORT,
+ mqtt_connection_cb, LWIP_CONST_CAST(void*, &mqtt_client_info),
+ &mqtt_client_info);
+#endif /* LWIP_TCP */
+}
diff --git a/contrib/examples/mqtt/mqtt_example.h b/contrib/examples/mqtt/mqtt_example.h
new file mode 100644
index 0000000..797678b
--- /dev/null
+++ b/contrib/examples/mqtt/mqtt_example.h
@@ -0,0 +1,43 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef MQTT_EXAMPLE_H
+#define MQTT_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mqtt_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MQTT_EXAMPLE_H */
diff --git a/contrib/examples/ppp/pppos_example.c b/contrib/examples/ppp/pppos_example.c
new file mode 100644
index 0000000..0d18ce5
--- /dev/null
+++ b/contrib/examples/ppp/pppos_example.c
@@ -0,0 +1,221 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/dns.h"
+
+#ifndef PPPOS_SUPPORT
+#define PPPOS_SUPPORT 0
+#endif /* PPPOS_SUPPORT */
+
+#if PPPOS_SUPPORT
+#include "netif/ppp/pppos.h"
+#include "lwip/sio.h"
+#define PPP_PTY_TEST 1
+#endif /* PPPOS_SUPPORT */
+
+#include "pppos_example.h"
+
+#include <stdio.h>
+
+#if PPPOS_SUPPORT
+static sio_fd_t ppp_sio;
+static ppp_pcb *ppp;
+static struct netif pppos_netif;
+
+static void
+pppos_rx_thread(void *arg)
+{
+ u32_t len;
+ u8_t buffer[128];
+ LWIP_UNUSED_ARG(arg);
+
+ /* Please read the "PPPoS input path" chapter in the PPP documentation. */
+ while (1) {
+ len = sio_read(ppp_sio, buffer, sizeof(buffer));
+ if (len > 0) {
+ /* Pass received raw characters from PPPoS to be decoded through lwIP
+ * TCPIP thread using the TCPIP API. This is thread safe in all cases
+ * but you should avoid passing data byte after byte. */
+ pppos_input_tcpip(ppp, buffer, len);
+ }
+ }
+}
+
+static void
+ppp_link_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
+{
+ struct netif *pppif = ppp_netif(pcb);
+ LWIP_UNUSED_ARG(ctx);
+
+ switch(err_code) {
+ case PPPERR_NONE: /* No error. */
+ {
+#if LWIP_DNS
+ const ip_addr_t *ns;
+#endif /* LWIP_DNS */
+ fprintf(stderr, "ppp_link_status_cb: PPPERR_NONE\n\r");
+#if LWIP_IPV4
+ fprintf(stderr, " our_ip4addr = %s\n\r", ip4addr_ntoa(netif_ip4_addr(pppif)));
+ fprintf(stderr, " his_ipaddr = %s\n\r", ip4addr_ntoa(netif_ip4_gw(pppif)));
+ fprintf(stderr, " netmask = %s\n\r", ip4addr_ntoa(netif_ip4_netmask(pppif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+ fprintf(stderr, " our_ip6addr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* LWIP_IPV6 */
+
+#if LWIP_DNS
+ ns = dns_getserver(0);
+ fprintf(stderr, " dns1 = %s\n\r", ipaddr_ntoa(ns));
+ ns = dns_getserver(1);
+ fprintf(stderr, " dns2 = %s\n\r", ipaddr_ntoa(ns));
+#endif /* LWIP_DNS */
+#if PPP_IPV6_SUPPORT
+ fprintf(stderr, " our6_ipaddr = %s\n\r", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
+#endif /* PPP_IPV6_SUPPORT */
+ }
+ break;
+
+ case PPPERR_PARAM: /* Invalid parameter. */
+ printf("ppp_link_status_cb: PPPERR_PARAM\n");
+ break;
+
+ case PPPERR_OPEN: /* Unable to open PPP session. */
+ printf("ppp_link_status_cb: PPPERR_OPEN\n");
+ break;
+
+ case PPPERR_DEVICE: /* Invalid I/O device for PPP. */
+ printf("ppp_link_status_cb: PPPERR_DEVICE\n");
+ break;
+
+ case PPPERR_ALLOC: /* Unable to allocate resources. */
+ printf("ppp_link_status_cb: PPPERR_ALLOC\n");
+ break;
+
+ case PPPERR_USER: /* User interrupt. */
+ printf("ppp_link_status_cb: PPPERR_USER\n");
+ break;
+
+ case PPPERR_CONNECT: /* Connection lost. */
+ printf("ppp_link_status_cb: PPPERR_CONNECT\n");
+ break;
+
+ case PPPERR_AUTHFAIL: /* Failed authentication challenge. */
+ printf("ppp_link_status_cb: PPPERR_AUTHFAIL\n");
+ break;
+
+ case PPPERR_PROTOCOL: /* Failed to meet protocol. */
+ printf("ppp_link_status_cb: PPPERR_PROTOCOL\n");
+ break;
+
+ case PPPERR_PEERDEAD: /* Connection timeout. */
+ printf("ppp_link_status_cb: PPPERR_PEERDEAD\n");
+ break;
+
+ case PPPERR_IDLETIMEOUT: /* Idle Timeout. */
+ printf("ppp_link_status_cb: PPPERR_IDLETIMEOUT\n");
+ break;
+
+ case PPPERR_CONNECTTIME: /* PPPERR_CONNECTTIME. */
+ printf("ppp_link_status_cb: PPPERR_CONNECTTIME\n");
+ break;
+
+ case PPPERR_LOOPBACK: /* Connection timeout. */
+ printf("ppp_link_status_cb: PPPERR_LOOPBACK\n");
+ break;
+
+ default:
+ printf("ppp_link_status_cb: unknown errCode %d\n", err_code);
+ break;
+ }
+}
+
+static u32_t
+ppp_output_cb(ppp_pcb *pcb, const void *data, u32_t len, void *ctx)
+{
+ LWIP_UNUSED_ARG(pcb);
+ LWIP_UNUSED_ARG(ctx);
+ return sio_write(ppp_sio, (const u8_t*)data, len);
+}
+
+#if LWIP_NETIF_STATUS_CALLBACK
+static void
+netif_status_callback(struct netif *nif)
+{
+ printf("PPPNETIF: %c%c%d is %s\n", nif->name[0], nif->name[1], nif->num,
+ netif_is_up(nif) ? "UP" : "DOWN");
+#if LWIP_IPV4
+ printf("IPV4: Host at %s ", ip4addr_ntoa(netif_ip4_addr(nif)));
+ printf("mask %s ", ip4addr_ntoa(netif_ip4_netmask(nif)));
+ printf("gateway %s\n", ip4addr_ntoa(netif_ip4_gw(nif)));
+#endif /* LWIP_IPV4 */
+#if LWIP_IPV6
+ printf("IPV6: Host at %s\n", ip6addr_ntoa(netif_ip6_addr(nif, 0)));
+#endif /* LWIP_IPV6 */
+#if LWIP_NETIF_HOSTNAME
+ printf("FQDN: %s\n", netif_get_hostname(nif));
+#endif /* LWIP_NETIF_HOSTNAME */
+}
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#endif
+
+void
+pppos_example_init(void)
+{
+#if PPPOS_SUPPORT
+#if PPP_PTY_TEST
+ ppp_sio = sio_open(2);
+#else
+ ppp_sio = sio_open(0);
+#endif
+ if(!ppp_sio)
+ {
+ perror("PPPOS example: Error opening device");
+ return;
+ }
+
+ ppp = pppos_create(&pppos_netif, ppp_output_cb, ppp_link_status_cb, NULL);
+ if (!ppp)
+ {
+ printf("PPPOS example: Could not create PPP control interface");
+ return;
+ }
+
+#ifdef LWIP_PPP_CHAP_TEST
+ ppp_set_auth(ppp, PPPAUTHTYPE_CHAP, "lwip", "mysecret");
+#endif
+
+ ppp_connect(ppp, 0);
+
+#if LWIP_NETIF_STATUS_CALLBACK
+ netif_set_status_callback(&pppos_netif, netif_status_callback);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+ sys_thread_new("pppos_rx_thread", pppos_rx_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
+#endif /* PPPOS_SUPPORT */
+}
diff --git a/contrib/examples/ppp/pppos_example.h b/contrib/examples/ppp/pppos_example.h
new file mode 100644
index 0000000..726961c
--- /dev/null
+++ b/contrib/examples/ppp/pppos_example.h
@@ -0,0 +1,43 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef PPPOS_EXAMPLE_H
+#define PPPOS_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pppos_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PPPOS_EXAMPLE_H */
diff --git a/contrib/examples/snmp/snmp_example.c b/contrib/examples/snmp/snmp_example.c
new file mode 100644
index 0000000..5952474
--- /dev/null
+++ b/contrib/examples/snmp/snmp_example.c
@@ -0,0 +1,80 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include "lwip/netif.h"
+#include "lwip/apps/snmp.h"
+#include "lwip/apps/snmp_mib2.h"
+#include "lwip/apps/snmpv3.h"
+#include "lwip/apps/snmp_snmpv2_framework.h"
+#include "lwip/apps/snmp_snmpv2_usm.h"
+#include "examples/snmp/snmp_v3/snmpv3_dummy.h"
+#include "examples/snmp/snmp_private_mib/private_mib.h"
+#include "snmp_example.h"
+
+#if LWIP_SNMP
+static const struct snmp_mib *mibs[] = {
+ &mib2,
+ &mib_private
+#if LWIP_SNMP_V3
+ , &snmpframeworkmib
+ , &snmpusmmib
+#endif
+};
+#endif /* LWIP_SNMP */
+
+void
+snmp_example_init(void)
+{
+#if LWIP_SNMP
+ s32_t req_nr;
+ lwip_privmib_init();
+#if SNMP_LWIP_MIB2
+#if SNMP_USE_NETCONN
+ snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
+#endif /* SNMP_USE_NETCONN */
+ snmp_mib2_set_syscontact_readonly((const u8_t*)"root", NULL);
+ snmp_mib2_set_syslocation_readonly((const u8_t*)"lwIP development PC", NULL);
+ snmp_mib2_set_sysdescr((const u8_t*)"lwIP example", NULL);
+#endif /* SNMP_LWIP_MIB2 */
+
+#if LWIP_SNMP_V3
+ snmpv3_dummy_init();
+#endif
+
+ snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
+ snmp_init();
+
+ snmp_trap_dst_ip_set(0, &netif_default->gw);
+ snmp_trap_dst_enable(0, 1);
+
+ snmp_send_inform_generic(SNMP_GENTRAP_COLDSTART, NULL, &req_nr);
+ snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART);
+
+#endif /* LWIP_SNMP */
+}
diff --git a/contrib/examples/snmp/snmp_example.h b/contrib/examples/snmp/snmp_example.h
new file mode 100644
index 0000000..fafcd68
--- /dev/null
+++ b/contrib/examples/snmp/snmp_example.h
@@ -0,0 +1,43 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef SNMP_EXAMPLE_H
+#define SNMP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void snmp_example_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SNMP_EXAMPLE_H */
diff --git a/contrib/examples/snmp/snmp_private_mib/lwip_prvmib.c b/contrib/examples/snmp/snmp_private_mib/lwip_prvmib.c
new file mode 100644
index 0000000..51a49fe
--- /dev/null
+++ b/contrib/examples/snmp/snmp_private_mib/lwip_prvmib.c
@@ -0,0 +1,401 @@
+/**
+ * @file
+ * lwip Private MIB
+ *
+ * @todo create MIB file for this example
+ * @note the lwip enterprise tree root (26381) is owned by the lwIP project.
+ * It is NOT allowed to allocate new objects under this ID (26381) without our,
+ * the lwip developers, permission!
+ *
+ * Please apply for your own ID with IANA: http://www.iana.org/numbers.html
+ *
+ * lwip OBJECT IDENTIFIER ::= { enterprises 26381 }
+ * example OBJECT IDENTIFIER ::= { lwip 1 }
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "private_mib.h"
+
+#if LWIP_SNMP
+
+/** Directory where the sensor files are */
+#define SENSORS_DIR "w:\\sensors"
+/** Set to 1 to read sensor values from files (in directory defined by SENSORS_DIR) */
+#define SENSORS_USE_FILES 0
+/** Set to 1 to search sensor files at startup (in directory defined by SENSORS_DIR) */
+#define SENSORS_SEARCH_FILES 0
+
+#if SENSORS_SEARCH_FILES
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#endif /* SENSORS_SEARCH_FILES */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "lwip/apps/snmp_table.h"
+#include "lwip/apps/snmp_scalar.h"
+
+#if !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES
+/** When not using & searching files, defines the number of sensors */
+#define SENSOR_COUNT 4
+#endif /* !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES */
+
+/*
+ This example presents a table for a few (at most 10) sensors.
+ Sensor detection takes place at initialization (once only).
+ Sensors may and can not be added or removed after agent
+ has started. Note this is only a limitation of this crude example,
+ the agent does support dynamic object insertions and removals.
+
+ You'll need to manually create a directory called "sensors" and
+ a few single line text files with an integer temperature value.
+ The files must be called [0..9].txt.
+
+ ./sensors/0.txt [content: 20]
+ ./sensors/3.txt [content: 75]
+
+ The sensor values may be changed in runtime by editing the
+ text files in the "sensors" directory.
+*/
+
+#define SENSOR_MAX 10
+#define SENSOR_NAME_LEN 20
+
+struct sensor_inf
+{
+ u8_t num;
+
+ char file[SENSOR_NAME_LEN + 1];
+
+#if !SENSORS_USE_FILES
+ /** When not using files, contains the value of the sensor */
+ s32_t value;
+#endif /* !SENSORS_USE_FILES */
+};
+
+static struct sensor_inf sensors[SENSOR_MAX];
+
+static s16_t sensor_count_get_value(struct snmp_node_instance* instance, void* value);
+static snmp_err_t sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
+static snmp_err_t sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
+static s16_t sensor_table_get_value(struct snmp_node_instance* instance, void* value);
+static snmp_err_t sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value);
+
+/* sensorentry .1.3.6.1.4.1.26381.1.1.1 (.level0.level1)
+ where level 0 is the table column (temperature/file name)
+ and level 1 the table row (sensor index) */
+static const struct snmp_table_col_def sensor_table_columns[] = {
+ { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE },
+ { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }
+};
+
+/* sensortable .1.3.6.1.4.1.26381.1.1 */
+static const struct snmp_table_node sensor_table = SNMP_TABLE_CREATE(
+ 1, sensor_table_columns,
+ sensor_table_get_cell_instance, sensor_table_get_next_cell_instance,
+ sensor_table_get_value, snmp_set_test_ok, sensor_table_set_value);
+
+/* sensorcount .1.3.6.1.4.1.26381.1.2 */
+static const struct snmp_scalar_node sensor_count = SNMP_SCALAR_CREATE_NODE_READONLY(
+ 2, SNMP_ASN1_TYPE_INTEGER, sensor_count_get_value);
+
+/* example .1.3.6.1.4.1.26381.1 */
+static const struct snmp_node* const example_nodes[] = {
+ &sensor_table.node.node,
+ &sensor_count.node.node
+};
+static const struct snmp_tree_node example_node = SNMP_CREATE_TREE_NODE(1, example_nodes);
+
+static const u32_t prvmib_base_oid[] = { 1,3,6,1,4,1,26381,1 };
+const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &example_node.node);
+
+#if 0
+/* for reference: we could also have expressed it like this: */
+
+/* lwip .1.3.6.1.4.1.26381 */
+static const struct snmp_node* const lwip_nodes[] = {
+ &example_node.node
+};
+static const struct snmp_tree_node lwip_node = SNMP_CREATE_TREE_NODE(26381, lwip_nodes);
+
+/* enterprises .1.3.6.1.4.1 */
+static const struct snmp_node* const enterprises_nodes[] = {
+ &lwip_node.node
+};
+static const struct snmp_tree_node enterprises_node = SNMP_CREATE_TREE_NODE(1, enterprises_nodes);
+
+/* private .1.3.6.1.4 */
+static const struct snmp_node* const private_nodes[] = {
+ &enterprises_node.node
+};
+static const struct snmp_tree_node private_root = SNMP_CREATE_TREE_NODE(4, private_nodes);
+
+static const u32_t prvmib_base_oid[] = { 1,3,6,1,4 };
+const struct snmp_mib mib_private = SNMP_MIB_CREATE(prvmib_base_oid, &private_root.node);
+#endif
+
+/**
+ * Initialises this private MIB before use.
+ * @see main.c
+ */
+void
+lwip_privmib_init(void)
+{
+#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
+ char *buf, *ebuf, *cp;
+ size_t bufsize;
+ int nbytes;
+ struct stat sb;
+ struct dirent *dp;
+ int fd;
+#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+ u8_t i;
+#endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+
+ memset(sensors, 0, sizeof(sensors));
+
+ printf("SNMP private MIB start, detecting sensors.\n");
+
+#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES
+ /* look for sensors in sensors directory */
+ fd = open(SENSORS_DIR, O_RDONLY);
+ if (fd > -1)
+ {
+ fstat(fd, &sb);
+ bufsize = sb.st_size;
+ if (bufsize < (size_t)sb.st_blksize)
+ {
+ bufsize = sb.st_blksize;
+ }
+ buf = (char*)malloc(bufsize);
+ if (buf != NULL)
+ {
+ do
+ {
+ long base;
+
+ nbytes = getdirentries(fd, buf, bufsize, &base);
+ if (nbytes > 0)
+ {
+ ebuf = buf + nbytes;
+ cp = buf;
+ while (cp < ebuf)
+ {
+ dp = (struct dirent *)cp;
+ if (lwip_isdigit(dp->d_name[0]))
+ {
+ unsigned char idx = dp->d_name[0] - '0';
+
+ sensors[idx].num = idx+1;
+ strncpy(&sensors[idx].file[0], dp->d_name, SENSOR_NAME_LEN);
+ printf("%s\n", sensors[idx].file);
+ }
+ cp += dp->d_reclen;
+ }
+ }
+ }
+ while (nbytes > 0);
+
+ free(buf);
+ }
+ close(fd);
+ }
+#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */
+ for (i = 0; i < SENSOR_COUNT; i++) {
+ sensors[i].num = (u8_t)(i + 1);
+ snprintf(sensors[i].file, sizeof(sensors[i].file), "%d.txt", i);
+
+#if !SENSORS_USE_FILES
+ /* initialize sensor value to != zero */
+ sensors[i].value = 11 * (i+1);
+#endif /* !SENSORS_USE_FILES */
+ }
+#endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */
+}
+
+/* sensorcount .1.3.6.1.4.1.26381.1.2 */
+static s16_t
+sensor_count_get_value(struct snmp_node_instance* instance, void* value)
+{
+ size_t count = 0;
+ u32_t *uint_ptr = (u32_t*)value;
+
+ LWIP_UNUSED_ARG(instance);
+
+ for(count=0; count<LWIP_ARRAYSIZE(sensors); count++) {
+ if(sensors[count].num == 0) {
+ *uint_ptr = (u32_t)count;
+ return sizeof(*uint_ptr);
+ }
+ }
+
+ return 0;
+}
+
+/* sensortable .1.3.6.1.4.1.26381.1.1 */
+/* list of allowed value ranges for incoming OID */
+static const struct snmp_oid_range sensor_table_oid_ranges[] = {
+ { 1, SENSOR_MAX+1 }
+};
+
+static snmp_err_t
+sensor_table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance)
+{
+ u32_t sensor_num;
+ size_t i;
+
+ LWIP_UNUSED_ARG(column);
+
+ /* check if incoming OID length and if values are in plausible range */
+ if(!snmp_oid_in_range(row_oid, row_oid_len, sensor_table_oid_ranges, LWIP_ARRAYSIZE(sensor_table_oid_ranges))) {
+ return SNMP_ERR_NOSUCHINSTANCE;
+ }
+
+ /* get sensor index from incoming OID */
+ sensor_num = row_oid[0];
+
+ /* find sensor with index */
+ for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
+ if(sensors[i].num != 0) {
+ if(sensors[i].num == sensor_num) {
+ /* store sensor index for subsequent operations (get/test/set) */
+ cell_instance->reference.u32 = (u32_t)i;
+ return SNMP_ERR_NOERROR;
+ }
+ }
+ }
+
+ /* not found */
+ return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static snmp_err_t
+sensor_table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance)
+{
+ size_t i;
+ struct snmp_next_oid_state state;
+ u32_t result_temp[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
+
+ LWIP_UNUSED_ARG(column);
+
+ /* init struct to search next oid */
+ snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(sensor_table_oid_ranges));
+
+ /* iterate over all possible OIDs to find the next one */
+ for(i=0; i<LWIP_ARRAYSIZE(sensors); i++) {
+ if(sensors[i].num != 0) {
+ u32_t test_oid[LWIP_ARRAYSIZE(sensor_table_oid_ranges)];
+
+ test_oid[0] = sensors[i].num;
+
+ /* check generated OID: is it a candidate for the next one? */
+ snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(sensor_table_oid_ranges), (void*)i);
+ }
+ }
+
+ /* did we find a next one? */
+ if(state.status == SNMP_NEXT_OID_STATUS_SUCCESS) {
+ snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len);
+ /* store sensor index for subsequent operations (get/test/set) */
+ cell_instance->reference.u32 = LWIP_CONST_CAST(u32_t, state.reference);
+ return SNMP_ERR_NOERROR;
+ }
+
+ /* not found */
+ return SNMP_ERR_NOSUCHINSTANCE;
+}
+
+static s16_t
+sensor_table_get_value(struct snmp_node_instance* instance, void* value)
+{
+ u32_t i = instance->reference.u32;
+ s32_t *temperature = (s32_t *)value;
+
+ switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id))
+ {
+ case 1: /* sensor value */
+#if SENSORS_USE_FILES
+ FILE* sensf;
+ char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
+
+ strncpy(&senspath[sizeof(SENSORS_DIR)],
+ sensors[i].file,
+ SENSOR_NAME_LEN);
+ sensf = fopen(senspath,"r");
+ if (sensf != NULL)
+ {
+ fscanf(sensf,"%"S32_F,temperature);
+ fclose(sensf);
+ }
+#else /* SENSORS_USE_FILES */
+ *temperature = sensors[i].value;
+#endif /* SENSORS_USE_FILES */
+ return sizeof(s32_t);
+ case 2: /* file name */
+ MEMCPY(value, sensors[i].file, strlen(sensors[i].file));
+ return (s16_t)strlen(sensors[i].file);
+ default:
+ return 0;
+ }
+}
+
+static snmp_err_t
+sensor_table_set_value(struct snmp_node_instance* instance, u16_t len, void *value)
+{
+ u32_t i = instance->reference.u32;
+ s32_t *temperature = (s32_t *)value;
+#if SENSORS_USE_FILES
+ FILE* sensf;
+ char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/";
+
+ strncpy(&senspath[sizeof(SENSORS_DIR)],
+ sensors[i].file,
+ SENSOR_NAME_LEN);
+ sensf = fopen(senspath, "w");
+ if (sensf != NULL)
+ {
+ fprintf(sensf, "%"S32_F, *temperature);
+ fclose(sensf);
+ }
+#else /* SENSORS_USE_FILES */
+ sensors[i].value = *temperature;
+#endif /* SENSORS_USE_FILES */
+
+ LWIP_UNUSED_ARG(len);
+
+ return SNMP_ERR_NOERROR;
+}
+
+#endif /* LWIP_SNMP */
diff --git a/contrib/examples/snmp/snmp_private_mib/private_mib.h b/contrib/examples/snmp/snmp_private_mib/private_mib.h
new file mode 100644
index 0000000..69be8a4
--- /dev/null
+++ b/contrib/examples/snmp/snmp_private_mib/private_mib.h
@@ -0,0 +1,26 @@
+/**
+ * @file
+ * Exports Private lwIP MIB
+ */
+
+#ifndef LWIP_HDR_PRIVATE_MIB_H
+#define LWIP_HDR_PRIVATE_MIB_H
+
+#include "lwip/apps/snmp_opts.h"
+
+#include "lwip/apps/snmp_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* export MIB */
+extern const struct snmp_mib mib_private;
+
+void lwip_privmib_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/examples/snmp/snmp_v3/snmpv3_dummy.c b/contrib/examples/snmp/snmp_v3/snmpv3_dummy.c
new file mode 100644
index 0000000..a7c53ed
--- /dev/null
+++ b/contrib/examples/snmp/snmp_v3/snmpv3_dummy.c
@@ -0,0 +1,395 @@
+/**
+ * @file
+ * Dummy SNMPv3 functions.
+ */
+
+/*
+ * Copyright (c) 2016 Elias Oenal.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Elias Oenal <lwip@eliasoenal.com>
+ * Dirk Ziegelmeier <dirk@ziegelmeier.net>
+ */
+
+#include "lwip/apps/snmpv3.h"
+#include "snmpv3_dummy.h"
+#include <string.h>
+#include "lwip/err.h"
+#include "lwip/def.h"
+#include "lwip/timeouts.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+struct user_table_entry {
+ char username[32];
+ snmpv3_auth_algo_t auth_algo;
+ u8_t auth_key[20];
+ snmpv3_priv_algo_t priv_algo;
+ u8_t priv_key[20];
+};
+
+static struct user_table_entry user_table[] = {
+ { "lwip", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
+ { "piwl", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" },
+ { "test", SNMP_V3_AUTH_ALGO_INVAL, "" , SNMP_V3_PRIV_ALGO_INVAL, "" }
+};
+
+static char snmpv3_engineid[32];
+static u8_t snmpv3_engineid_len;
+
+static u32_t enginetime = 0;
+
+/* In this implementation engineboots is volatile. In a real world application this value should be stored in non-volatile memory.*/
+static u32_t engineboots = 0;
+
+/**
+ * @brief Get the user table entry for the given username.
+ *
+ * @param[in] username pointer to the username
+ *
+ * @return pointer to the user table entry or NULL if not found.
+ */
+static struct user_table_entry*
+get_user(const char *username)
+{
+ size_t i;
+
+ for (i = 0; i < LWIP_ARRAYSIZE(user_table); i++) {
+ if (strnlen(username, 32) != strnlen(user_table[i].username, 32)) {
+ continue;
+ }
+
+ if (memcmp(username, user_table[i].username, strnlen(username, 32)) == 0) {
+ return &user_table[i];
+ }
+ }
+
+ return NULL;
+}
+
+u8_t
+snmpv3_get_amount_of_users(void)
+{
+ return LWIP_ARRAYSIZE(user_table);
+}
+
+/**
+ * @brief Get the username of a user number (index)
+ * @param username is a pointer to a string.
+ * @param index is the user index.
+ * @return ERR_OK if user is found, ERR_VAL is user is not found.
+ */
+err_t
+snmpv3_get_username(char *username, u8_t index)
+{
+ if (index < LWIP_ARRAYSIZE(user_table)) {
+ MEMCPY(username, user_table[index].username, sizeof(user_table[0].username));
+ return ERR_OK;
+ }
+
+ return ERR_VAL;
+}
+
+/**
+ * Timer callback function that increments enginetime and reschedules itself.
+ *
+ * @param arg unused argument
+ */
+static void
+snmpv3_enginetime_timer(void *arg)
+{
+ LWIP_UNUSED_ARG(arg);
+
+ enginetime++;
+
+ /* This handles the engine time reset */
+ snmpv3_get_engine_time_internal();
+
+ /* restart timer */
+ sys_timeout(1000, snmpv3_enginetime_timer, NULL);
+}
+
+err_t
+snmpv3_set_user_auth_algo(const char *username, snmpv3_auth_algo_t algo)
+{
+ struct user_table_entry *p = get_user(username);
+
+ if (p) {
+ switch (algo) {
+ case SNMP_V3_AUTH_ALGO_INVAL:
+ if (p->priv_algo != SNMP_V3_PRIV_ALGO_INVAL) {
+ /* Privacy MUST be disabled before configuring authentication */
+ break;
+ } else {
+ p->auth_algo = algo;
+ return ERR_OK;
+ }
+#if LWIP_SNMP_V3_CRYPTO
+ case SNMP_V3_AUTH_ALGO_MD5:
+ case SNMP_V3_AUTH_ALGO_SHA:
+#endif
+ p->auth_algo = algo;
+ return ERR_OK;
+ default:
+ break;
+ }
+ }
+
+ return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_priv_algo(const char *username, snmpv3_priv_algo_t algo)
+{
+ struct user_table_entry *p = get_user(username);
+
+ if (p) {
+ switch (algo) {
+#if LWIP_SNMP_V3_CRYPTO
+ case SNMP_V3_PRIV_ALGO_AES:
+ case SNMP_V3_PRIV_ALGO_DES:
+ if (p->auth_algo == SNMP_V3_AUTH_ALGO_INVAL) {
+ /* Authentication MUST be enabled before configuring privacy */
+ break;
+ } else {
+ p->priv_algo = algo;
+ return ERR_OK;
+ }
+#endif
+ case SNMP_V3_PRIV_ALGO_INVAL:
+ p->priv_algo = algo;
+ return ERR_OK;
+ default:
+ break;
+ }
+ }
+
+ return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_auth_key(const char *username, const char *password)
+{
+ struct user_table_entry *p = get_user(username);
+ const char *engineid;
+ u8_t engineid_len;
+
+ if (p) {
+ /* password should be at least 8 characters long */
+ if (strlen(password) >= 8) {
+ memset(p->auth_key, 0, sizeof(p->auth_key));
+ snmpv3_get_engine_id(&engineid, &engineid_len);
+ switch (p->auth_algo) {
+ case SNMP_V3_AUTH_ALGO_INVAL:
+ return ERR_OK;
+#if LWIP_SNMP_V3_CRYPTO
+ case SNMP_V3_AUTH_ALGO_MD5:
+ snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
+ return ERR_OK;
+ case SNMP_V3_AUTH_ALGO_SHA:
+ snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->auth_key);
+ return ERR_OK;
+#endif
+ default:
+ return ERR_VAL;
+ }
+ }
+ }
+
+ return ERR_VAL;
+}
+
+err_t
+snmpv3_set_user_priv_key(const char *username, const char *password)
+{
+ struct user_table_entry *p = get_user(username);
+ const char *engineid;
+ u8_t engineid_len;
+
+ if (p) {
+ /* password should be at least 8 characters long */
+ if (strlen(password) >= 8) {
+ memset(p->priv_key, 0, sizeof(p->priv_key));
+ snmpv3_get_engine_id(&engineid, &engineid_len);
+ switch (p->auth_algo) {
+ case SNMP_V3_AUTH_ALGO_INVAL:
+ return ERR_OK;
+#if LWIP_SNMP_V3_CRYPTO
+ case SNMP_V3_AUTH_ALGO_MD5:
+ snmpv3_password_to_key_md5((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
+ return ERR_OK;
+ case SNMP_V3_AUTH_ALGO_SHA:
+ snmpv3_password_to_key_sha((const u8_t*)password, strlen(password), (const u8_t*)engineid, engineid_len, p->priv_key);
+ return ERR_OK;
+#endif
+ default:
+ return ERR_VAL;
+ }
+ }
+ }
+
+ return ERR_VAL;
+}
+
+/**
+ * @brief Get the storage type of the given username.
+ *
+ * @param[in] username pointer to the username
+ * @param[out] type the storage type
+ *
+ * @return ERR_OK if the user was found, ERR_VAL if not.
+ */
+err_t
+snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *type)
+{
+ if (get_user(username) != NULL) {
+ /* Found user in user table
+ * In this dummy implementation, storage is permanent because no user can be deleted.
+ * All changes to users are lost after a reboot.*/
+ *type = SNMP_V3_USER_STORAGETYPE_PERMANENT;
+ return ERR_OK;
+ }
+
+ return ERR_VAL;
+}
+
+/**
+ * @param username is a pointer to a string.
+ * @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found.
+ * @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
+ * @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found.
+ * @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found.
+ */
+err_t
+snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key)
+{
+ const struct user_table_entry *p;
+
+ /* The msgUserName specifies the user (principal) on whose behalf the
+ message is being exchanged. Note that a zero-length userName will
+ not match any user, but it can be used for snmpEngineID discovery. */
+ if(strlen(username) == 0) {
+ return ERR_OK;
+ }
+
+ p = get_user(username);
+
+ if (!p) {
+ return ERR_VAL;
+ }
+
+ if (auth_algo != NULL) {
+ *auth_algo = p->auth_algo;
+ }
+ if(auth_key != NULL) {
+ MEMCPY(auth_key, p->auth_key, sizeof(p->auth_key));
+ }
+ if (priv_algo != NULL) {
+ *priv_algo = p->priv_algo;
+ }
+ if(priv_key != NULL) {
+ MEMCPY(priv_key, p->priv_key, sizeof(p->priv_key));
+ }
+ return ERR_OK;
+}
+
+/**
+ * Get engine ID from persistence
+ */
+void
+snmpv3_get_engine_id(const char **id, u8_t *len)
+{
+ *id = snmpv3_engineid;
+ *len = snmpv3_engineid_len;
+}
+
+/**
+ * Store engine ID in persistence
+ */
+err_t
+snmpv3_set_engine_id(const char *id, u8_t len)
+{
+ MEMCPY(snmpv3_engineid, id, len);
+ snmpv3_engineid_len = len;
+ return ERR_OK;
+}
+
+/**
+ * Get engine boots from persistence. Must be increased on each boot.
+ */
+u32_t
+snmpv3_get_engine_boots(void)
+{
+ return engineboots;
+}
+
+/**
+ * Store engine boots in persistence
+ */
+void
+snmpv3_set_engine_boots(u32_t boots)
+{
+ engineboots = boots;
+}
+
+/**
+ * RFC3414 2.2.2.
+ * Once the timer reaches 2147483647 it gets reset to zero and the
+ * engine boot ups get incremented.
+ */
+u32_t
+snmpv3_get_engine_time(void)
+{
+ return enginetime;
+}
+
+/**
+ * Reset current engine time to 0
+ */
+void
+snmpv3_reset_engine_time(void)
+{
+ enginetime = 0;
+}
+
+/**
+ * Initialize dummy SNMPv3 implementation
+ */
+void
+snmpv3_dummy_init(void)
+{
+ snmpv3_set_engine_id("FOO", 3);
+
+ snmpv3_set_user_auth_algo("lwip", SNMP_V3_AUTH_ALGO_SHA);
+ snmpv3_set_user_auth_key("lwip", "maplesyrup");
+
+ snmpv3_set_user_priv_algo("lwip", SNMP_V3_PRIV_ALGO_DES);
+ snmpv3_set_user_priv_key("lwip", "maplesyrup");
+
+ /* Start the engine time timer */
+ snmpv3_enginetime_timer(NULL);
+}
+
+#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
diff --git a/contrib/examples/snmp/snmp_v3/snmpv3_dummy.h b/contrib/examples/snmp/snmp_v3/snmpv3_dummy.h
new file mode 100644
index 0000000..ba25b6d
--- /dev/null
+++ b/contrib/examples/snmp/snmp_v3/snmpv3_dummy.h
@@ -0,0 +1,53 @@
+/**
+ * @file
+ * Dummy SNMPv3 functions.
+ */
+
+/*
+ * Copyright (c) 2017 Dirk Ziegelmeier.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ */
+
+#ifndef LWIP_HDR_APPS_SNMP_V3_DUMMY_H
+#define LWIP_HDR_APPS_SNMP_V3_DUMMY_H
+
+#include "lwip/apps/snmp_opts.h"
+#include "lwip/err.h"
+#include "lwip/apps/snmpv3.h"
+
+#if LWIP_SNMP && LWIP_SNMP_V3
+
+err_t snmpv3_set_user_auth_algo(const char *username, snmpv3_auth_algo_t algo);
+err_t snmpv3_set_user_priv_algo(const char *username, snmpv3_priv_algo_t algo);
+err_t snmpv3_set_user_auth_key(const char *username, const char *password);
+err_t snmpv3_set_user_priv_key(const char *username, const char *password);
+
+void snmpv3_dummy_init(void);
+
+#endif /* LWIP_SNMP && LWIP_SNMP_V3 */
+
+#endif /* LWIP_HDR_APPS_SNMP_V3_DUMMY_H */
diff --git a/contrib/examples/sntp/sntp_example.c b/contrib/examples/sntp/sntp_example.c
new file mode 100644
index 0000000..e9f6ac8
--- /dev/null
+++ b/contrib/examples/sntp/sntp_example.c
@@ -0,0 +1,66 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include <time.h>
+
+#include "lwip/opt.h"
+#include "lwip/apps/sntp.h"
+#include "sntp_example.h"
+#include "lwip/netif.h"
+
+void
+sntp_set_system_time(u32_t sec)
+{
+ char buf[32];
+ struct tm current_time_val;
+ time_t current_time = (time_t)sec;
+
+#if defined(_WIN32) || defined(WIN32)
+ localtime_s(¤t_time_val, ¤t_time);
+#else
+ localtime_r(¤t_time, ¤t_time_val);
+#endif
+
+ strftime(buf, sizeof(buf), "%d.%m.%Y %H:%M:%S", ¤t_time_val);
+ LWIP_PLATFORM_DIAG(("SNTP time: %s\n", buf));
+}
+
+void
+sntp_example_init(void)
+{
+ sntp_setoperatingmode(SNTP_OPMODE_POLL);
+#if LWIP_DHCP
+ sntp_servermode_dhcp(1); /* get SNTP server via DHCP */
+#else /* LWIP_DHCP */
+#if LWIP_IPV4
+ sntp_setserver(0, netif_ip_gw4(netif_default));
+#endif /* LWIP_IPV4 */
+#endif /* LWIP_DHCP */
+ sntp_init();
+}
diff --git a/contrib/examples/sntp/sntp_example.h b/contrib/examples/sntp/sntp_example.h
new file mode 100644
index 0000000..94fc10d
--- /dev/null
+++ b/contrib/examples/sntp/sntp_example.h
@@ -0,0 +1,45 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#ifndef SNTP_EXAMPLE_H
+#define SNTP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sntp_example_init(void);
+
+void sntp_set_system_time(u32_t sec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SNTP_EXAMPLE_H */
diff --git a/contrib/examples/tftp/tftp_example.c b/contrib/examples/tftp/tftp_example.c
new file mode 100644
index 0000000..3e14014
--- /dev/null
+++ b/contrib/examples/tftp/tftp_example.c
@@ -0,0 +1,155 @@
+/*
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Dirk Ziegelmeier <dziegel@gmx.de>
+ *
+ */
+
+#include <stdio.h>
+
+#include "lwip/apps/tftp_client.h"
+#include "lwip/apps/tftp_server.h"
+#include "tftp_example.h"
+
+#include <string.h>
+
+#if LWIP_UDP
+
+/* Define a base directory for TFTP access
+ * ATTENTION: This code does NOT check for sandboxing,
+ * i.e. '..' in paths is not checked! */
+#ifndef LWIP_TFTP_EXAMPLE_BASE_DIR
+#define LWIP_TFTP_EXAMPLE_BASE_DIR ""
+#endif
+
+/* Define this to a file to get via tftp client */
+#ifndef LWIP_TFTP_EXAMPLE_CLIENT_FILENAME
+#define LWIP_TFTP_EXAMPLE_CLIENT_FILENAME "test.bin"
+#endif
+
+/* Define this to a server IP string */
+#ifndef LWIP_TFTP_EXAMPLE_CLIENT_REMOTEIP
+#define LWIP_TFTP_EXAMPLE_CLIENT_REMOTEIP "192.168.0.1"
+#endif
+
+static char full_filename[256];
+
+static void *
+tftp_open_file(const char* fname, u8_t is_write)
+{
+ snprintf(full_filename, sizeof(full_filename), "%s%s", LWIP_TFTP_EXAMPLE_BASE_DIR, fname);
+ full_filename[sizeof(full_filename)-1] = 0;
+
+ if (is_write) {
+ return (void*)fopen(full_filename, "wb");
+ } else {
+ return (void*)fopen(full_filename, "rb");
+ }
+}
+
+static void*
+tftp_open(const char* fname, const char* mode, u8_t is_write)
+{
+ LWIP_UNUSED_ARG(mode);
+ return tftp_open_file(fname, is_write);
+}
+
+static void
+tftp_close(void* handle)
+{
+ fclose((FILE*)handle);
+}
+
+static int
+tftp_read(void* handle, void* buf, int bytes)
+{
+ int ret = fread(buf, 1, bytes, (FILE*)handle);
+ if (ret <= 0) {
+ return -1;
+ }
+ return ret;
+}
+
+static int
+tftp_write(void* handle, struct pbuf* p)
+{
+ while (p != NULL) {
+ if (fwrite(p->payload, 1, p->len, (FILE*)handle) != (size_t)p->len) {
+ return -1;
+ }
+ p = p->next;
+ }
+
+ return 0;
+}
+
+/* For TFTP client only */
+static void
+tftp_error(void* handle, int err, const char* msg, int size)
+{
+ char message[100];
+
+ LWIP_UNUSED_ARG(handle);
+
+ memset(message, 0, sizeof(message));
+ MEMCPY(message, msg, LWIP_MIN(sizeof(message)-1, (size_t)size));
+
+ printf("TFTP error: %d (%s)", err, message);
+}
+
+static const struct tftp_context tftp = {
+ tftp_open,
+ tftp_close,
+ tftp_read,
+ tftp_write,
+ tftp_error
+};
+
+void
+tftp_example_init_server(void)
+{
+ tftp_init_server(&tftp);
+}
+
+void
+tftp_example_init_client(void)
+{
+ void *f;
+ err_t err;
+ ip_addr_t srv;
+ int ret = ipaddr_aton(LWIP_TFTP_EXAMPLE_CLIENT_REMOTEIP, &srv);
+ LWIP_ASSERT("ipaddr_aton failed", ret == 1);
+
+ err = tftp_init_client(&tftp);
+ LWIP_ASSERT("tftp_init_client failed", err == ERR_OK);
+
+ f = tftp_open_file(LWIP_TFTP_EXAMPLE_CLIENT_FILENAME, 1);
+ LWIP_ASSERT("failed to create file", f != NULL);
+
+ err = tftp_get(f, &srv, TFTP_PORT, LWIP_TFTP_EXAMPLE_CLIENT_FILENAME, TFTP_MODE_OCTET);
+ LWIP_ASSERT("tftp_get failed", err == ERR_OK);
+}
+
+#endif /* LWIP_UDP */
diff --git a/contrib/examples/tftp/tftp_example.h b/contrib/examples/tftp/tftp_example.h
new file mode 100644
index 0000000..7340700
--- /dev/null
+++ b/contrib/examples/tftp/tftp_example.h
@@ -0,0 +1,29 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/*
+ * File: tftp_example.h
+ * Author: dziegel
+ *
+ * Created on February 17, 2018, 3:43 PM
+ */
+
+#ifndef TFTP_EXAMPLE_H
+#define TFTP_EXAMPLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void tftp_example_init_server(void);
+void tftp_example_init_client(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TFTP_EXAMPLE_H */
+