changeset 2174:d07decb23fa2

* Updated the complete lwIP source to the latest lwIP CVS version 1.1.1 * src/ecos/init.c Added call to netif_set_up(netif) in function lwip_set_addr() - this is required since lwIP version 1.0.0 * cdl/lwip_net.cdl Minor modifications for UDP configuration options. Renamed CYGNUM_LWIP_TCPIP_THREAD_PRIORITY to CYGNUM_LWIP_NETWORK_THREAD_PRIORITY and moved option outside CYGPKG_LWIP_TCPIP component because the network thread needs to run in all configurations. * tests/nc_slave.c * tests/tcpecho.c * tests/udpecho.c * tests/sockets.c * tests/httpd.c Added eCos test infrastructure to tests and made tests applicable depending on lwip configuration.
author asl
date Wed, 29 Mar 2006 10:33:28 +0000
parents 4f828d6c4183
children 55e180a14a91
files packages/net/lwip_tcpip/current/ChangeLog packages/net/lwip_tcpip/current/cdl/lwip_net.cdl packages/net/lwip_tcpip/current/include/arch/cc.h packages/net/lwip_tcpip/current/include/arch/perf.h packages/net/lwip_tcpip/current/include/arch/sys_arch.h packages/net/lwip_tcpip/current/include/lwip/api.h packages/net/lwip_tcpip/current/include/lwip/api_msg.h packages/net/lwip_tcpip/current/include/lwip/debug.h packages/net/lwip_tcpip/current/include/lwip/dhcp.h packages/net/lwip_tcpip/current/include/lwip/inet.h packages/net/lwip_tcpip/current/include/lwip/ip.h packages/net/lwip_tcpip/current/include/lwip/ip_addr.h packages/net/lwip_tcpip/current/include/lwip/ip_frag.h packages/net/lwip_tcpip/current/include/lwip/netif.h packages/net/lwip_tcpip/current/include/lwip/opt.h packages/net/lwip_tcpip/current/include/lwip/pbuf.h packages/net/lwip_tcpip/current/include/lwip/raw.h packages/net/lwip_tcpip/current/include/lwip/sockets.h packages/net/lwip_tcpip/current/include/lwip/tcp.h packages/net/lwip_tcpip/current/include/lwip/udp.h packages/net/lwip_tcpip/current/include/lwipopts.h packages/net/lwip_tcpip/current/include/network.h packages/net/lwip_tcpip/current/src/api/api_lib.c packages/net/lwip_tcpip/current/src/api/api_msg.c packages/net/lwip_tcpip/current/src/api/sockets.c packages/net/lwip_tcpip/current/src/api/tcpip.c packages/net/lwip_tcpip/current/src/core/dhcp.c packages/net/lwip_tcpip/current/src/core/inet.c packages/net/lwip_tcpip/current/src/core/ipv4/icmp.c packages/net/lwip_tcpip/current/src/core/ipv4/ip.c packages/net/lwip_tcpip/current/src/core/ipv4/ip_addr.c packages/net/lwip_tcpip/current/src/core/ipv4/ip_frag.c packages/net/lwip_tcpip/current/src/core/mem.c packages/net/lwip_tcpip/current/src/core/memp.c packages/net/lwip_tcpip/current/src/core/netif.c packages/net/lwip_tcpip/current/src/core/pbuf.c packages/net/lwip_tcpip/current/src/core/raw.c packages/net/lwip_tcpip/current/src/core/stats.c packages/net/lwip_tcpip/current/src/core/sys.c packages/net/lwip_tcpip/current/src/core/tcp.c packages/net/lwip_tcpip/current/src/core/tcp_in.c packages/net/lwip_tcpip/current/src/core/tcp_out.c packages/net/lwip_tcpip/current/src/core/udp.c packages/net/lwip_tcpip/current/src/ecos/init.c packages/net/lwip_tcpip/current/src/ecos/sys_arch.c packages/net/lwip_tcpip/current/src/netif/etharp.c packages/net/lwip_tcpip/current/src/netif/loopif.c packages/net/lwip_tcpip/current/src/netif/ppp/chap.h packages/net/lwip_tcpip/current/src/netif/ppp/chpms.h packages/net/lwip_tcpip/current/src/netif/ppp/fsm.h packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.c packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.h packages/net/lwip_tcpip/current/src/netif/ppp/lcp.c packages/net/lwip_tcpip/current/src/netif/ppp/lcp.h packages/net/lwip_tcpip/current/src/netif/ppp/magic.h packages/net/lwip_tcpip/current/src/netif/ppp/ppp.c packages/net/lwip_tcpip/current/src/netif/ppp/vj.c packages/net/lwip_tcpip/current/src/netif/ppp/vj.h packages/net/lwip_tcpip/current/src/netif/slipif.c packages/net/lwip_tcpip/current/tests/httpd.c packages/net/lwip_tcpip/current/tests/nc_test_slave.c packages/net/lwip_tcpip/current/tests/socket.c packages/net/lwip_tcpip/current/tests/tcpecho.c packages/net/lwip_tcpip/current/tests/udpecho.c
diffstat 64 files changed, 2288 insertions(+), 1699 deletions(-) [+]
line wrap: on
line diff
--- a/packages/net/lwip_tcpip/current/ChangeLog
+++ b/packages/net/lwip_tcpip/current/ChangeLog
@@ -1,3 +1,22 @@
+2006-03-26  Uwe Kindler <uwe_kindler@web.de>
+
+	* Updated the complete lwIP source to the latest lwIP
+	CVS version 1.1.1
+	* src/ecos/init.c Added call to netif_set_up(netif) in
+	function lwip_set_addr() - this is required since lwIP
+	version 1.0.0
+	* cdl/lwip_net.cdl Minor modifications for UDP configuration
+	options. Renamed CYGNUM_LWIP_TCPIP_THREAD_PRIORITY to
+	CYGNUM_LWIP_NETWORK_THREAD_PRIORITY and moved option outside
+	CYGPKG_LWIP_TCPIP component because the network thread needs to
+	run in all configurations.
+	* tests/nc_slave.c
+	* tests/tcpecho.c 
+	* tests/udpecho.c
+	* tests/sockets.c
+	* tests/httpd.c Added eCos test infrastructure to tests and 
+	made tests applicable depending on lwip configuration.
+
 2006-03-15  Andrew Lunn  <andrew.lunn@ascom.ch>
 
 	* tests/nc_test_slave.c (nc_slave): Fix some of the compiler
--- a/packages/net/lwip_tcpip/current/cdl/lwip_net.cdl
+++ b/packages/net/lwip_tcpip/current/cdl/lwip_net.cdl
@@ -327,28 +327,12 @@ cdl_package CYGPKG_NET_LWIP {
 			}		 
 	}
 	
-	cdl_component CYGPKG_LWIP_TCP_OPTIONS {
-		display		"TCP"
-		flavor 		none
-		no_define
+	cdl_component CYGPKG_LWIP_TCP {
+		display		    "TCP"
+		flavor 		    bool
+		default_value 	1
 		description   	"
-		           Tune the TCP protocol details"
-			
-		cdl_option CYGFUN_LWIP_TCP {
-			display		"Activate TCP"
-			flavor		bool
-			default_value 	1
-			description   	""
-
-		}
-		
-		cdl_option CYGNUM_LWIP_TCPIP_THREAD_PRIORITY {
-			display "TCP/IP thread priority"
-			flavor data
-			default_value	7
-			description "Pririty of the lwIP network thread.This thread handles all API messages and
-					network packets."
-		}		 
+		           Support TCP protocol."
 		
 		cdl_option CYGNUM_LWIP_TCP_TTL {
 			display		"Time To Live"
@@ -385,7 +369,7 @@ cdl_package CYGPKG_NET_LWIP {
 		cdl_option CYGNUM_LWIP_TCP_SND_QUEUELEN {
 			display		"Sender pbufs"
 			flavor		data
-			calculated 	"4 * CYGNUM_LWIP_TCP_SND_BUF/CYGNUM_LWIP_TCP_MSS"
+			calculated 	CYGPKG_LWIP_TCP ? "4 * CYGNUM_LWIP_TCP_SND_BUF/CYGNUM_LWIP_TCP_MSS" : 0
 			description   	"
 				TCP sender buffer space (pbufs). This must be at least = 2 *
 				TCP_SND_BUF/TCP_MSS for things to work."
@@ -487,12 +471,13 @@ cdl_package CYGPKG_NET_LWIP {
 	}
 
 	cdl_component CYGPKG_LWIP_DHCP {
-		display		  "Use DHCP"
+		display		  "DHCP"
 		flavor		  bool
+		requires  CYGPKG_LWIP_UDP
 		default_value 0
 		requires  { CYGNUM_LWIP_MEMP_NUM_SYS_TIMEOUT >= 6 }
 		description "
-		    Provide DHCP for initializing the IP address of network interfaces."
+		    Provide DHCP support for initializing the IP address of network interfaces."
 		compile core/dhcp.c
 
         cdl_option CYGOPT_LWIP_DHCP_MANAGEMENT {
@@ -541,6 +526,14 @@ cdl_package CYGPKG_NET_LWIP {
 		}
 		
 	}
+	
+    cdl_option CYGNUM_LWIP_NETWORK_THREAD_PRIORITY {
+			display "Network thread priority"
+			flavor data
+			default_value	7
+			description "Priority of the lwIP network thread.This thread handles all API messages and
+					network packets."
+		}	
 
 	cdl_component CYGPKG_LWIP_SLIP {
 		display "SLIP"
@@ -615,18 +608,12 @@ cdl_package CYGPKG_NET_LWIP {
 		}	
 	}
 
-	cdl_component CYGPKG_LWIP_UDP_OPTIONS {
+	cdl_component CYGPKG_LWIP_UDP {
 		display		"UDP"
-		flavor		none
-		no_define
-
-		cdl_option CYGFUN_LWIP_UDP {
-			display		"Activate UDP"
-			flavor		bool
-			default_value 	1
-			description   	""
-			compile core/udp.c
-		}
+		flavor		bool
+		default_value 	1
+		description   	"Support UDP protocol."
+		compile core/udp.c
 
 		cdl_option CYGNUM_LWIP_UDP_TTL {
 			display		"Time To Live"
@@ -643,6 +630,17 @@ cdl_package CYGPKG_NET_LWIP {
 		description   	""
 		compile core/raw.c
 	}
+	
+	cdl_option CYGFUN_LWIP_COMPAT_SOCKETS {
+	    display       "Provide compatible socket API"
+	    flavor        bool
+	    default_value 1
+	    description "
+	         The lwIP socket API uses defines to map the lwip socket functions 
+	         (lwip_accept(), lwip_bind(), lwip_listen()...) to BSD like names
+	         (accept(), bind(), listen()...). If this causes trouble or naming
+	         conficts for your application, then disable this option"
+    }
 
 	cdl_component CYGPKG_LWIP_APP_MEM_OPTIONS {
 		display		"Memory options for apps"
--- a/packages/net/lwip_tcpip/current/include/arch/cc.h
+++ b/packages/net/lwip_tcpip/current/include/arch/cc.h
@@ -1,3 +1,68 @@
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+/*
+ * Copyright (c) 2001, 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
 #ifndef __ARCH_CC_H__
 #define __ARCH_CC_H__
 
@@ -27,6 +92,12 @@ typedef unsigned   long    u32_t;
 typedef signed     long    s32_t;
 typedef unsigned long	mem_ptr_t;
 
+#define U16_F "u"
+#define S16_F "d"
+#define X16_F "x"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
 
 #define PACK_STRUCT_FIELD(x) x __attribute__((packed))
 #define PACK_STRUCT_STRUCT __attribute__((packed))
--- a/packages/net/lwip_tcpip/current/include/arch/perf.h
+++ b/packages/net/lwip_tcpip/current/include/arch/perf.h
@@ -1,3 +1,68 @@
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
+/*
+ * Copyright (c) 2001, 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
 #ifndef __PERF_H__
 #define __PERF_H__
 
--- a/packages/net/lwip_tcpip/current/include/arch/sys_arch.h
+++ b/packages/net/lwip_tcpip/current/include/arch/sys_arch.h
@@ -1,3 +1,35 @@
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+
 #ifndef __SYS_ECOS_H__
 #define __SYS_ECOS_H__
 
@@ -6,8 +38,8 @@
 #define SYS_MBOX_NULL (sys_mbox_t)NULL 
 #define SYS_SEM_NULL  (sys_sem_t)NULL
 
-typedef cyg_sem_t * sys_sem_t;
+typedef cyg_sem_t*   sys_sem_t;
 typedef cyg_handle_t sys_mbox_t;
-typedef cyg_thread * sys_thread_t;
+typedef cyg_handle_t sys_thread_t;
 #endif /* __SYS_ECOS_H__ */
 
--- a/packages/net/lwip_tcpip/current/include/lwip/api.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/api.h
@@ -48,17 +48,11 @@
 #define NETCONN_COPY   0x01
 
 enum netconn_type {
-#if LWIP_TCP
   NETCONN_TCP,
-#endif
-#if LWIP_UDP
   NETCONN_UDP,
   NETCONN_UDPLITE,
   NETCONN_UDPNOCHKSUM,
-#endif
-#if LWIP_RAW
   NETCONN_RAW
-#endif
 };
 
 enum netconn_state {
--- a/packages/net/lwip_tcpip/current/include/lwip/api_msg.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/api_msg.h
@@ -75,7 +75,7 @@ struct api_msg_msg {
     struct {
       void *dataptr;
       u16_t len;
-      unsigned char copy;
+      u8_t copy;
     } w;    
     sys_mbox_t mbox;
     u16_t len;
--- a/packages/net/lwip_tcpip/current/include/lwip/debug.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/debug.h
@@ -71,7 +71,7 @@
 /** print debug message only if debug message type is enabled...
  *  AND is of correct type AND is at least DBG_LEVEL
  */
-#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && (((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)
+#  define LWIP_DEBUGF(debug,x) do { if (((debug) & DBG_ON) && ((debug) & DBG_TYPES_ON) && ((s16_t)((debug) & DBG_MASK_LEVEL) >= DBG_MIN_LEVEL)) { LWIP_PLATFORM_DIAG(x); if ((debug) & DBG_HALT) while(1); } } while(0)
 #  define LWIP_ERROR(x)   do { LWIP_PLATFORM_DIAG(x); } while(0)  
 #else /* LWIP_DEBUG */
 #  define LWIP_DEBUGF(debug,x) 
--- a/packages/net/lwip_tcpip/current/include/lwip/dhcp.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/dhcp.h
@@ -43,6 +43,10 @@ struct dhcp
   struct ip_addr offered_sn_mask;
   struct ip_addr offered_gw_addr;
   struct ip_addr offered_bc_addr;
+#define DHCP_MAX_DNS 2
+  u32_t dns_count; /* actual number of DNS servers obtained */
+  struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */
+ 
   u32_t offered_t0_lease; /* lease period (in seconds) */
   u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
   u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period)  */
@@ -82,8 +86,12 @@ struct dhcp_msg
   PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
   PACK_STRUCT_FIELD(u32_t cookie);
 #define DHCP_MIN_OPTIONS_LEN 68U
+/** make sure user does not configure this too small */
+#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
+#  undef DHCP_OPTIONS_LEN
+#endif
 /** allow this to be configured in lwipopts.h, but not too small */
-#if ((!defined(DHCP_OPTIONS_LEN)) || (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
+#if (!defined(DHCP_OPTIONS_LEN))
 /** set this to be sufficient for your options in outgoing DHCP msgs */
 #  define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
 #endif
@@ -96,11 +104,13 @@ PACK_STRUCT_END
 
 /** start DHCP configuration */
 err_t dhcp_start(struct netif *netif);
+/** enforce early lease renewal (not needed normally)*/
+err_t dhcp_renew(struct netif *netif);
+/** release the DHCP lease, usually called before dhcp_stop()*/
+err_t dhcp_release(struct netif *netif);
 /** stop DHCP configuration */
 void dhcp_stop(struct netif *netif);
-/** enforce lease renewal */
-err_t dhcp_renew(struct netif *netif);
-/** inform server of our IP address */
+/** inform server of our manual IP address */
 void dhcp_inform(struct netif *netif);
 
 /** if enabled, check whether the offered IP address is not in use, using ARP */
@@ -174,7 +184,8 @@ void dhcp_fine_tmr(void);
 /** BootP options */
 #define DHCP_OPTION_PAD 0
 #define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */
-#define DHCP_OPTION_ROUTER 3 
+#define DHCP_OPTION_ROUTER 3
+#define DHCP_OPTION_DNS_SERVER 6 
 #define DHCP_OPTION_HOSTNAME 12
 #define DHCP_OPTION_IP_TTL 23
 #define DHCP_OPTION_MTU 26
--- a/packages/net/lwip_tcpip/current/include/lwip/inet.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/inet.h
@@ -39,13 +39,16 @@
 #include "lwip/ip_addr.h"
 
 u16_t inet_chksum(void *dataptr, u16_t len);
+#if 0 /* optimized routine */
+u16_t inet_chksum4(u8_t *dataptr, u16_t len);
+#endif
 u16_t inet_chksum_pbuf(struct pbuf *p);
 u16_t inet_chksum_pseudo(struct pbuf *p,
        struct ip_addr *src, struct ip_addr *dest,
        u8_t proto, u16_t proto_len);
 
 u32_t inet_addr(const char *cp);
-int inet_aton(const char *cp, struct in_addr *addr);
+s8_t inet_aton(const char *cp, struct in_addr *addr);
 char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
 
 #ifdef htons
--- a/packages/net/lwip_tcpip/current/include/lwip/ip.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/ip.h
@@ -40,7 +40,6 @@
 
 #include "lwip/err.h"
 
-struct netif;
 
 void ip_init(void);
 struct netif *ip_route(struct ip_addr *dest);
@@ -128,7 +127,7 @@ PACK_STRUCT_END
 
 #define IPH_V(hdr)  (ntohs((hdr)->_v_hl_tos) >> 12)
 #define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
-#define IPH_TOS(hdr) (htons((ntohs((hdr)->_v_hl_tos) & 0xff)))
+#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)
 #define IPH_LEN(hdr) ((hdr)->_len)
 #define IPH_ID(hdr) ((hdr)->_id)
 #define IPH_OFFSET(hdr) ((hdr)->_offset)
--- a/packages/net/lwip_tcpip/current/include/lwip/ip_addr.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/ip_addr.h
@@ -117,7 +117,15 @@ extern const struct ip_addr ip_addr_broa
 #define ip_addr_set(dest, src) (dest)->addr = \
                                ((src) == NULL? 0:\
                                (src)->addr)
-#define ip_addr_maskcmp(addr1, addr2, mask) (((addr1)->addr & \
+/**
+ * Determine if two address are on the same network.
+ *
+ * @arg addr1 IP address 1
+ * @arg addr2 IP address 2
+ * @arg mask network identifier mask
+ * @return !0 if the network identifiers of both address match
+ */
+#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
                                               (mask)->addr) == \
                                              ((addr2)->addr & \
                                               (mask)->addr))
@@ -130,32 +138,18 @@ u8_t ip_addr_isbroadcast(struct ip_addr 
 #define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
 
 
-#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%u.%u.%u.%u", \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \
-        ipaddr?(unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \
-        ipaddr?(unsigned int)ntohl((ipaddr)->addr) & 0xff:0U))
+#define ip_addr_debug_print(debug, ipaddr) LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff:0, \
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff:0, \
+        ipaddr?(u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff:0, \
+        ipaddr?(u16_t)ntohl((ipaddr)->addr) & 0xff:0U))
 
 /* cast to unsigned int, as it is used as argument to printf functions
- * which expect integer arguments */
-#define ip4_addr1(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 24) & 0xff)
-#define ip4_addr2(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 16) & 0xff)
-#define ip4_addr3(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr) >> 8) & 0xff)
-#define ip4_addr4(ipaddr) ((unsigned int)(ntohl((ipaddr)->addr)) & 0xff)
-
-/**
- * Determine if two address are on the same network.
- *
- * @arg addr1 IP address 1
- * @arg addr2 IP address 2
- * @arg mask network identifier mask
- * @return !0 if the network identifiers of both address match
- */
-#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
-                                              (mask)->addr) == \
-                                             ((addr2)->addr & \
-                                              (mask)->addr))
-                                              
+ * which expect integer arguments. CSi: use cc.h formatters (conversion chars)! */
+#define ip4_addr1(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff)
+#define ip4_addr2(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff)
+#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)
+#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff)
 #endif /* __LWIP_IP_ADDR_H__ */
 
 
--- a/packages/net/lwip_tcpip/current/include/lwip/ip_frag.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/ip_frag.h
@@ -38,8 +38,9 @@
 #include "lwip/netif.h"
 #include "lwip/ip_addr.h"
 
-struct pbuf * ip_reass(struct pbuf *);
-err_t ip_frag(struct pbuf *, struct netif *, struct ip_addr *);
+void ip_reass_tmr(void);
+struct pbuf * ip_reass(struct pbuf *p);
+err_t ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest);
 
 #endif /* __LWIP_IP_FRAG_H__ */
 
--- a/packages/net/lwip_tcpip/current/include/lwip/netif.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/netif.h
@@ -52,7 +52,8 @@
 
 /** whether the network interface is 'up'. this is
  * a software flag used to control whether this network
- * interface is enabled and processes traffic */
+ * interface is enabled and processes traffic.
+ */
 #define NETIF_FLAG_UP 0x1U
 /** if set, the netif has broadcast capability */
 #define NETIF_FLAG_BROADCAST 0x2U
@@ -61,52 +62,55 @@
 /** if set, the interface is configured using DHCP */
 #define NETIF_FLAG_DHCP 0x08U
 /** if set, the interface has an active link
- *  (set by the interface) */
+ *  (set by the network interface driver) */
 #define NETIF_FLAG_LINK_UP 0x10U
 
-/** generic data structure used for all lwIP network interfaces */
+/** Generic data structure used for all lwIP network interfaces.
+ *  The following fields should be filled in by the initialization
+ *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
+
 struct netif {
   /** pointer to next in linked list */
   struct netif *next;
-  /** The following fields should be filled in by the
-      initialization function for the device driver. */
-  
+
   /** IP address configuration in network byte order */
   struct ip_addr ip_addr;
   struct ip_addr netmask;
   struct ip_addr gw;
 
   /** This function is called by the network device driver
-      to pass a packet up the TCP/IP stack. */
+   *  to pass a packet up the TCP/IP stack. */
   err_t (* input)(struct pbuf *p, struct netif *inp);
   /** This function is called by the IP module when it wants
-      to send a packet on the interface. This function typically
-      first resolves the hardware address, then sends the packet. */
+   *  to send a packet on the interface. This function typically
+   *  first resolves the hardware address, then sends the packet. */
   err_t (* output)(struct netif *netif, struct pbuf *p,
        struct ip_addr *ipaddr);
   /** This function is called by the ARP module when it wants
-      to send a packet on the interface. This function outputs
-      the pbuf as-is on the link medium. */
+   *  to send a packet on the interface. This function outputs
+   *  the pbuf as-is on the link medium. */
   err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
   /** This field can be set by the device driver and could point
-      to state information for the device. */
+   *  to state information for the device. */
   void *state;
 #if LWIP_DHCP
   /** the DHCP client state information for this netif */
   struct dhcp *dhcp;
 #endif
   /** number of bytes used in hwaddr */
-  unsigned char hwaddr_len;
+  u8_t hwaddr_len;
   /** link level hardware address of this interface */
-  unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
+  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
   /** maximum transfer unit (in bytes) */
   u16_t mtu;
+  /** flags (see NETIF_FLAG_ above) */
+  u8_t flags;
+  /** link type */
+  u8_t link_type;
   /** descriptive abbreviation */
   char name[2];
   /** number of this interface */
   u8_t num;
-  /** NETIF_FLAG_* */
-  u8_t flags;
 };
 
 /** The list of network interfaces. */
@@ -139,5 +143,8 @@ void netif_set_default(struct netif *net
 void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
 void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);
 void netif_set_gw(struct netif *netif, struct ip_addr *gw);
+void netif_set_up(struct netif *netif);
+void netif_set_down(struct netif *netif);
+u8_t netif_is_up(struct netif *netif);
 
 #endif /* __LWIP_NETIF_H__ */
--- a/packages/net/lwip_tcpip/current/include/lwip/opt.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/opt.h
@@ -68,7 +68,7 @@ a lot of data that needs to be copied, t
 #endif
 
 #ifndef MEMP_SANITY_CHECK
-#define MEMP_SANITY_CHECK		0
+#define MEMP_SANITY_CHECK       0
 #endif
 
 /* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
@@ -146,10 +146,10 @@ a lot of data that needs to be copied, t
 #endif
 
 /* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
-   link level header. */
+   link level header. Defaults to 14 for Ethernet. */
 
 #ifndef PBUF_LINK_HLEN
-#define PBUF_LINK_HLEN                  0
+#define PBUF_LINK_HLEN                  14
 #endif
 
 
@@ -163,17 +163,23 @@ a lot of data that needs to be copied, t
 
 /**
  * If enabled, outgoing packets are queued during hardware address
- * resolution. The etharp.c implementation queues 1 packet only.
+ * resolution.
+ *
+ * This feature has not stabilized yet. Single-packet queueing is
+ * believed to be stable, multi-packet queueing is believed to
+ * clash with the TCP segment queueing.
+ * 
+ * As multi-packet-queueing is currently disabled, enabling this
+ * _should_ work, but we need your testing feedback on lwip-users.
+ *
  */
 #ifndef ARP_QUEUEING
 #define ARP_QUEUEING                    1
 #endif
-/** If enabled, the first packet queued will not be overwritten by
- * later packets. If disabled, later packets overwrite early packets
- * in the queue. Default is disabled, which is recommended. 
- */
-#ifndef ARP_QUEUE_FIRST
-#define ARP_QUEUE_FIRST                 0
+
+/* This option is deprecated */
+#ifdef ETHARP_QUEUE_FIRST
+#error ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h.
 #endif
 
 /* This option is removed to comply with the ARP standard */
@@ -305,7 +311,7 @@ a lot of data that needs to be copied, t
 
 /* Support loop interface (127.0.0.1) */
 #ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF		1
+#define LWIP_HAVE_LOOPIF                0
 #endif
 
 #ifndef LWIP_EVENT_API
@@ -340,8 +346,11 @@ a lot of data that needs to be copied, t
 
 /* ---------- Socket Options ---------- */
 /* Enable SO_REUSEADDR and SO_REUSEPORT options */ 
-#ifndef SO_REUSE
-# define SO_REUSE 1
+#define SO_REUSE 0
+#if SO_REUSE
+/* I removed the lot since this was an ugly hack. It broke the raw-API.
+   It also came with many ugly goto's, Christiaan Simons. */
+#error "SO_REUSE currently unavailable, this was a hack"
 #endif                                                                        
 
 
@@ -357,63 +366,63 @@ a lot of data that needs to be copied, t
 #endif
 
 #ifndef LINK_STATS
-#define LINK_STATS	1
+#define LINK_STATS  1
 #endif
 
 #ifndef IP_STATS
-#define IP_STATS	1
+#define IP_STATS    1
 #endif
 
 #ifndef IPFRAG_STATS
-#define IPFRAG_STATS	1
+#define IPFRAG_STATS    1
 #endif
 
 #ifndef ICMP_STATS
-#define ICMP_STATS	1
+#define ICMP_STATS  1
 #endif
 
 #ifndef UDP_STATS
-#define UDP_STATS	1
+#define UDP_STATS   1
 #endif
 
 #ifndef TCP_STATS
-#define TCP_STATS	1
+#define TCP_STATS   1
 #endif
 
 #ifndef MEM_STATS
-#define MEM_STATS	1
+#define MEM_STATS   1
 #endif
 
 #ifndef MEMP_STATS
-#define MEMP_STATS	1
+#define MEMP_STATS  1
 #endif
 
 #ifndef PBUF_STATS
-#define PBUF_STATS	1
+#define PBUF_STATS  1
 #endif
 
 #ifndef SYS_STATS
-#define SYS_STATS	1
+#define SYS_STATS   1
 #endif
 
 #ifndef RAW_STATS
-#define RAW_STATS	0
+#define RAW_STATS   0
 #endif
 
 #else
 
-#define LINK_STATS	0
-#define IP_STATS	0
-#define IPFRAG_STATS	0
-#define ICMP_STATS	0
-#define UDP_STATS	0
-#define TCP_STATS	0
-#define MEM_STATS	0
-#define MEMP_STATS	0
-#define PBUF_STATS	0
-#define SYS_STATS	0
-#define RAW_STATS	0
-#define LWIP_STATS_DISPLAY	0
+#define LINK_STATS  0
+#define IP_STATS    0
+#define IPFRAG_STATS    0
+#define ICMP_STATS  0
+#define UDP_STATS   0
+#define TCP_STATS   0
+#define MEM_STATS   0
+#define MEMP_STATS  0
+#define PBUF_STATS  0
+#define SYS_STATS   0
+#define RAW_STATS   0
+#define LWIP_STATS_DISPLAY  0
 
 #endif /* LWIP_STATS */
 
--- a/packages/net/lwip_tcpip/current/include/lwip/pbuf.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/pbuf.h
@@ -53,8 +53,8 @@ typedef enum {
   PBUF_POOL
 } pbuf_flag;
 
-/* Definitions for the pbuf flag field (these are not the flags that
-   are passed to pbuf_alloc()). */
+/* Definitions for the pbuf flag field. These are NOT the flags that
+ * are passed to pbuf_alloc(). */
 #define PBUF_FLAG_RAM   0x00U    /* Flags that pbuf data is stored in RAM */
 #define PBUF_FLAG_ROM   0x01U    /* Flags that pbuf data is stored in ROM */
 #define PBUF_FLAG_POOL  0x02U    /* Flags that the pbuf comes from the pbuf pool */
@@ -79,10 +79,10 @@ struct pbuf {
    */
   u16_t tot_len;
   
-  /* length of this buffer */
+  /** length of this buffer */
   u16_t len;  
 
-  /* flags telling the type of pbuf */
+  /** flags telling the type of pbuf, see PBUF_FLAG_ */
   u16_t flags;
   
   /**
@@ -94,11 +94,6 @@ struct pbuf {
   
 };
 
-/* pbuf_init():
-
-   Initializes the pbuf module. The num parameter determines how many
-   pbufs that should be allocated to the pbuf pool, and the size
-   parameter specifies the size of the data allocated to those.  */
 void pbuf_init(void);
 
 struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
--- a/packages/net/lwip_tcpip/current/include/lwip/raw.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/raw.h
@@ -46,7 +46,7 @@ struct raw_pcb {
 
   u16_t protocol;
 
-  int (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+  u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
     struct ip_addr *addr);
   void *recv_arg;
 };
@@ -59,15 +59,15 @@ err_t            raw_bind       (struct 
 err_t            raw_connect    (struct raw_pcb *pcb, struct ip_addr *ipaddr);
 
 void             raw_recv       (struct raw_pcb *pcb,
-                                 int (* recv)(void *arg, struct raw_pcb *pcb,
+                                 u8_t (* recv)(void *arg, struct raw_pcb *pcb,
                                               struct pbuf *p,
                                               struct ip_addr *addr),
                                  void *recv_arg);
-err_t            raw_send_to    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
+err_t            raw_sendto    (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
 err_t            raw_send       (struct raw_pcb *pcb, struct pbuf *p);
 
 /* The following functions are the lower layer interface to RAW. */
-int              raw_input      (struct pbuf *p, struct netif *inp);
+u8_t              raw_input      (struct pbuf *p, struct netif *inp);
 void             raw_init       (void);
 
 
--- a/packages/net/lwip_tcpip/current/include/lwip/sockets.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/sockets.h
@@ -209,7 +209,11 @@ struct linger {
  * only define this in sockets.c so it does not interfere
  * with other projects namespaces where timeval is present
  */ 
-#ifdef LWIP_TIMEVAL_PRIVATE
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 1
+#endif
+
+#if LWIP_TIMEVAL_PRIVATE
   struct timeval {
     long    tv_sec;         /* seconds */
     long    tv_usec;        /* and microseconds */
--- a/packages/net/lwip_tcpip/current/include/lwip/tcp.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/tcp.h
@@ -105,6 +105,7 @@ void             tcp_input   (struct pbu
 /* Used within the TCP code only: */
 err_t            tcp_output  (struct tcp_pcb *pcb);
 void             tcp_rexmit  (struct tcp_pcb *pcb);
+void             tcp_rexmit_rto  (struct tcp_pcb *pcb);
 
 
 
@@ -112,7 +113,11 @@ void             tcp_rexmit  (struct tcp
 #define TCP_SEQ_LEQ(a,b)    ((s32_t)((a)-(b)) <= 0)
 #define TCP_SEQ_GT(a,b)     ((s32_t)((a)-(b)) > 0)
 #define TCP_SEQ_GEQ(a,b)    ((s32_t)((a)-(b)) >= 0)
-
+/* is b<=a<=c? */
+#if 0 /* see bug #10548 */
+#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b))
+#endif
+#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
 #define TCP_FIN 0x01U
 #define TCP_SYN 0x02U
 #define TCP_RST 0x04U
@@ -208,18 +213,13 @@ enum tcp_state {
   TIME_WAIT   = 10
 };
 
-
 /* the TCP protocol control block */
 struct tcp_pcb {
-/* Common members of all PCB types */
+/** common PCB members */
   IP_PCB;
-
-/* Protocol specific PCB members */
-
-  struct tcp_pcb *next;   /* for the linked list */
-
-  enum tcp_state state;   /* TCP state */
-
+/** protocol specific PCB members */
+  struct tcp_pcb *next; /* for the linked list */
+  enum tcp_state state; /* TCP state */
   u8_t prio;
   void *callback_arg;
 
@@ -235,7 +235,7 @@ struct tcp_pcb {
 #define TF_GOT_FIN   (u8_t)0x20U   /* Connection was closed by the remote end. */
 #define TF_NODELAY   (u8_t)0x40U   /* Disable Nagle algorithm */
 
-  /* receiver varables */
+  /* receiver variables */
   u32_t rcv_nxt;   /* next seqno expected */
   u16_t rcv_wnd;   /* receiver window */
   
@@ -248,10 +248,10 @@ struct tcp_pcb {
   
   u16_t mss;   /* maximum segment size */
   
-  /* RTT estimation variables. */
-  u16_t rttest; /* RTT estimate in 500ms ticks */
+  /* RTT (round trip time) estimation variables */
+  u32_t rttest; /* RTT estimate in 500ms ticks */
   u32_t rtseq;  /* sequence number being timed */
-  s16_t sa, sv;
+  s16_t sa, sv; /* @todo document this */
 
   u16_t rto;    /* retransmission time-out */
   u8_t nrtx;    /* number of retransmissions */
@@ -375,7 +375,7 @@ err_t lwip_tcp_event(void *arg, struct t
 #define TCP_EVENT_RECV(pcb,p,err,ret) \
                         if((pcb)->recv != NULL) \
                         { ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); } else { \
-             if (p) pbuf_free(p); }
+                          if (p) pbuf_free(p); }
 #define TCP_EVENT_CONNECTED(pcb,err,ret) \
                         if((pcb)->connected != NULL) \
                         (ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
@@ -387,7 +387,7 @@ err_t lwip_tcp_event(void *arg, struct t
                         (errf)((arg),(err))
 #endif /* LWIP_EVENT_API */
 
-/* This structure is used to repressent TCP segments when queued. */
+/* This structure represents a TCP segment on the unsent and unacked queues */
 struct tcp_seg {
   struct tcp_seg *next;    /* used when putting segements on a queue */
   struct pbuf *p;          /* buffer containing data + TCP header */
@@ -439,7 +439,7 @@ void tcp_debug_print(struct tcp_hdr *tcp
 void tcp_debug_print_flags(u8_t flags);
 void tcp_debug_print_state(enum tcp_state s);
 void tcp_debug_print_pcbs(void);
-int tcp_pcbs_sane(void);
+s16_t tcp_pcbs_sane(void);
 #else
 #  define tcp_debug_print(tcphdr)
 #  define tcp_debug_print_flags(flags)
--- a/packages/net/lwip_tcpip/current/include/lwip/udp.h
+++ b/packages/net/lwip_tcpip/current/include/lwip/udp.h
@@ -95,7 +95,7 @@ void             udp_input      (struct 
 void             udp_init       (void);
 
 #if UDP_DEBUG
-int udp_debug_print(struct udp_hdr *udphdr);
+void udp_debug_print(struct udp_hdr *udphdr);
 #else
 #define udp_debug_print(udphdr)
 #endif
--- a/packages/net/lwip_tcpip/current/include/lwipopts.h
+++ b/packages/net/lwip_tcpip/current/include/lwipopts.h
@@ -93,22 +93,13 @@ a lot of data that needs to be copied, t
 #define PBUF_LINK_HLEN          CYGNUM_LWIP_PBUF_LINK_HLEN
 
 /* ---------- TCP options ---------- */
-#ifdef CYGFUN_LWIP_TCP
-#define LWIP_TCP                1
-#else
-#define LWIP_TCP                0
-#endif
-
+#define LWIP_TCP                defined(CYGPKG_LWIP_TCP)
 #define TCP_TTL                 CYGNUM_LWIP_TCP_TTL
 
 /* Controls if TCP should queue segments that arrive out of
    order. Define to 0 if your device is low on memory. */
-#ifdef CYGIMP_LWIP_TCP_QUEUE_OOSEQ
-#define TCP_QUEUE_OOSEQ        1
-#else
-#define TCP_QUEUE_OOSEQ        0
-#endif        
-
+#define TCP_QUEUE_OOSEQ         defined(CYGIMP_LWIP_TCP_QUEUE_OOSEQ)
+    
 /* TCP Maximum segment size. */
 #define TCP_MSS                 CYGNUM_LWIP_TCP_MSS
 
@@ -136,19 +127,13 @@ a lot of data that needs to be copied, t
 /* 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. */
-#ifdef CYGFUN_LWIP_IP_FORWARD
-#define IP_FORWARD              1
-#else 
-#define IP_FORWARD              0
-#endif
+#define IP_FORWARD              defined(CYGFUN_LWIP_IP_FORWARD)
+
 
 /* If defined to 1, IP options are allowed (but not parsed). If
    defined to 0, all packets with IP options are dropped. */
-#ifdef CYGFUN_LWIP_IP_OPTIONS
-#define IP_OPTIONS              1
-#else
-#define IP_OPTIONS              0
-#endif           
+#define IP_OPTIONS              defined(CYGFUN_LWIP_IP_OPTIONS)
+
 
 /* ---------- ICMP options ---------- */
 #define ICMP_TTL                CYGNUM_LWIP_ICMP_TTL
@@ -157,84 +142,45 @@ a lot of data that needs to be copied, t
 /* ---------- DHCP options ---------- */
 /* Define LWIP_DHCP to 1 if you want DHCP configuration of
    interfaces.*/
-
-#ifdef CYGPKG_LWIP_DHCP
-  #define LWIP_DHCP               1
-
-/* 1 if you want to do an ARP check on the offered address
-   (recommended). */
-  #ifdef CYGOPT_LWIP_DHCP_DOES_ARP_CHECK
-    #define DHCP_DOES_ARP_CHECK     1
-  #else
-    #define DHCP_DOES_ARP_CHECK     0
-  #endif
-#else
-  #define LWIP_DHCP               0
-  #define DHCP_DOES_ARP_CHECK     0
-#endif
+#define LWIP_DHCP               defined(CYGPKG_LWIP_DHCP)
+#define DHCP_DOES_ARP_CHECK     defined(CYGOPT_LWIP_DHCP_DOES_ARP_CHECK)
 
 
 /* ---------- UDP options ---------- */
-#ifdef CYGFUN_LWIP_UDP
-#define LWIP_UDP                1
-#else
-#define LWIP_UDP                0
-#endif
+#define LWIP_UDP                defined(CYGPKG_LWIP_UDP)
 #define UDP_TTL                 CYGNUM_LWIP_UDP_TTL
 
 /* ---------- RAW socket support ---------- */
-#ifdef CYGFUN_LWIP_RAW
-#define LWIP_RAW                1
-#else
-#define LWIP_RAW                0
-#endif
+#define LWIP_RAW                defined(CYGFUN_LWIP_RAW)
 
 /* ---------- SLIP options --------- */ 
-#ifdef CYGPKG_LWIP_SLIP
-#define LWIP_SLIP               1
-#else
-#define LWIP_SLIP               0
-#endif
+#define LWIP_SLIP               defined(CYGPKG_LWIP_SLIP)
 #define SLIP_DEV                CYGDAT_LWIP_SLIP_DEV
 
-#ifdef CYGFUN_LWIP_LOOPIF
-#define LWIP_HAVE_LOOPIF	    1
-#else
-#define LWIP_HAVE_LOOPIF	    0
-#endif
+/* ---------- LOOPIF options --------- */ 
+#define LWIP_HAVE_LOOPIF	    defined(CYGFUN_LWIP_LOOPIF)
+
 /* ---------- PPP options --------- */ 
-#ifdef CYGPKG_LWIP_PPP 
-#define PPP_SUPPORT             1
-#else
-#define PPP_SUPPORT             0
-#endif
+#define PPP_SUPPORT             defined(CYGPKG_LWIP_PPP)
 #define PPP_DEV                 CYGDAT_LWIP_PPP_DEV
 #define MD5_SUPPORT             1
+#define PAP_SUPPORT	            defined(CYGIMP_LWIP_PPP_PAP_AUTH)
+#define CHAP_SUPPORT	        defined(CYGIMP_LWIP_PPP_CHAP_AUTH)
 
-#ifdef CYGIMP_LWIP_PPP_PAP_AUTH
-#define PAP_SUPPORT	1
-#else
-#define PAP_SUPPORT	0
-#endif
-
-#ifdef CYGIMP_LWIP_PPP_CHAP_AUTH
-#define CHAP_SUPPORT	1
-#else
-#define CHAP_SUPPORT	0
-#endif
 
 /* ------- Thread priorities ---------------*/
-#define TCPIP_THREAD_PRIO       CYGNUM_LWIP_TCPIP_THREAD_PRIORITY
+#define TCPIP_THREAD_PRIO       CYGNUM_LWIP_NETWORK_THREAD_PRIORITY
 #define SLIPIF_THREAD_PRIO      CYGNUM_LWIP_SLIPIF_THREAD_PRIORITY
 #define PPP_THREAD_PRIO         CYGNUM_LWIP_PPP_THREAD_PRIORITY
 
 
 /* ---------- Statistics options ---------- */
-#ifdef CYGDBG_LWIP_STATS
-#define LWIP_STATS		1
-#else
-#define LWIP_STATS		0
-#endif
+#define LWIP_STATS		        defined(CYGDBG_LWIP_STATS)
+
+
+// --------- Sockets options --------------
+#define LWIP_COMPAT_SOCKETS     defined(CYGFUN_LWIP_COMPAT_SOCKETS)
+
 
 /* ---------- Debug options ---------- */
 #if !defined(CYGDBG_LWIP_ASSERTS)
--- a/packages/net/lwip_tcpip/current/include/network.h
+++ b/packages/net/lwip_tcpip/current/include/network.h
@@ -1,6 +1,76 @@
-/* network.h for compatibility with the other eCos network stacks */
+#ifndef CYGONCE_NETWORK_H
+#define CYGONCE_NETWORK_H
+//=============================================================================
+//
+//      network.h
+//
+//      Misc network support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Nick Garnett
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Jani Monoses
+// Contributors:  Jani Monoses
+// Date:          2006-03-23
+// Purpose:       
+// Description:   
+//                
+//        
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
 
-#include <lwip/sys.h>           /* lwIP stack includes */
-#define LWIP_COMPAT_SOCKETS 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//=============================================================================
+//                                INCLUDES
+//=============================================================================
+#include <lwip/sys.h>           // lwIP stack includes
 #include <lwip/sockets.h>
 #include <lwip/inet.h>
+
+
+#ifdef __cplusplus
+}
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // #ifndef CYGONCE_NETWORK_H
--- a/packages/net/lwip_tcpip/current/src/api/api_lib.c
+++ b/packages/net/lwip_tcpip/current/src/api/api_lib.c
@@ -165,7 +165,7 @@ netbuf_copy_partial(struct netbuf *buf, 
       offset -= p->len;
     } else {    
       for(i = offset; i < p->len; ++i) {
-  ((char *)dataptr)[left] = ((char *)p->payload)[i];
+  ((u8_t *)dataptr)[left] = ((u8_t *)p->payload)[i];
   if (++left >= len) {
     return;
   }
@@ -280,9 +280,10 @@ netconn_delete(struct netconn *conn)
   if (conn->recvmbox != SYS_MBOX_NULL) {
     while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
       if (conn->type == NETCONN_TCP) {
-  pbuf_free((struct pbuf *)mem);
+        if(mem != NULL)
+          pbuf_free((struct pbuf *)mem);
       } else {
-  netbuf_delete((struct netbuf *)mem);
+        netbuf_delete((struct netbuf *)mem);
       }
     }
     sys_mbox_free(conn->recvmbox);
@@ -321,30 +322,29 @@ netconn_peer(struct netconn *conn, struc
        u16_t *port)
 {
   switch (conn->type) {
-#if LWIP_RAW
   case NETCONN_RAW:
     /* return an error as connecting is only a helper for upper layers */
     return ERR_CONN;
-#endif
-#if LWIP_UDP
   case NETCONN_UDPLITE:
   case NETCONN_UDPNOCHKSUM:
   case NETCONN_UDP:
+#if LWIP_UDP
     if (conn->pcb.udp == NULL ||
   ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))
      return ERR_CONN;
     *addr = (conn->pcb.udp->remote_ip);
     *port = conn->pcb.udp->remote_port;
+#endif
     break;
-#endif
+    
+  case NETCONN_TCP:
 #if LWIP_TCP
-  case NETCONN_TCP:
     if (conn->pcb.tcp == NULL)
       return ERR_CONN;
     *addr = (conn->pcb.tcp->remote_ip);
     *port = conn->pcb.tcp->remote_port;
+#endif
     break;
-#endif
   }
   return (conn->err = ERR_OK);
 }
@@ -354,26 +354,27 @@ netconn_addr(struct netconn *conn, struc
        u16_t *port)
 {
   switch (conn->type) {
+  case NETCONN_RAW:
 #if LWIP_RAW
-  case NETCONN_RAW:
     *addr = &(conn->pcb.raw->local_ip);
     *port = conn->pcb.raw->protocol;
+#endif
     break;
-#endif
-#if LWIP_UDP
   case NETCONN_UDPLITE:
   case NETCONN_UDPNOCHKSUM:
   case NETCONN_UDP:
+#if LWIP_UDP
     *addr = &(conn->pcb.udp->local_ip);
     *port = conn->pcb.udp->local_port;
+#endif
     break;
-#endif
+    
+  case NETCONN_TCP:
 #if LWIP_TCP
-  case NETCONN_TCP:
     *addr = &(conn->pcb.tcp->local_ip);
     *port = conn->pcb.tcp->local_port;
+#endif
     break;
-#endif
   }
   return (conn->err = ERR_OK);
 }
@@ -684,7 +685,7 @@ netconn_write(struct netconn *conn, void
     api_msg_post(msg);
     sys_mbox_fetch(conn->mbox, NULL);    
     if (conn->err == ERR_OK) {
-      dataptr = (void *)((char *)dataptr + len);
+      dataptr = (void *)((u8_t *)dataptr + len);
       size -= len;
     } else if (conn->err == ERR_MEM) {
       conn->err = ERR_OK;
--- a/packages/net/lwip_tcpip/current/src/api/api_msg.c
+++ b/packages/net/lwip_tcpip/current/src/api/api_msg.c
@@ -38,7 +38,7 @@
 #include "lwip/tcpip.h"
 
 #if LWIP_RAW
-static int
+static u8_t
 recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
     struct ip_addr *addr)
 {
@@ -281,14 +281,16 @@ do_newconn(struct api_msg_msg *msg)
 
    /* Allocate a PCB for this connection */
    switch(msg->conn->type) {
-#if LWIP_RAW
    case NETCONN_RAW:
+#if LWIP_RAW   
       msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field */
       raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
+#endif
      break;
-#endif
+
+
+   case NETCONN_UDPLITE:
 #if LWIP_UDP
-   case NETCONN_UDPLITE:
       msg->conn->pcb.udp = udp_new();
       if(msg->conn->pcb.udp == NULL) {
          msg->conn->err = ERR_MEM;
@@ -297,7 +299,9 @@ do_newconn(struct api_msg_msg *msg)
       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
       break;
+#endif /* LWIP_UDP */
    case NETCONN_UDPNOCHKSUM:
+#if LWIP_UDP
       msg->conn->pcb.udp = udp_new();
       if(msg->conn->pcb.udp == NULL) {
          msg->conn->err = ERR_MEM;
@@ -306,25 +310,28 @@ do_newconn(struct api_msg_msg *msg)
       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
       break;
+#endif /* LWIP_UDP */
    case NETCONN_UDP:
+#if LWIP_UDP
       msg->conn->pcb.udp = udp_new();
       if(msg->conn->pcb.udp == NULL) {
          msg->conn->err = ERR_MEM;
          break;
       }
       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
+#endif /* LWIP_UDP */
       break;
-#endif /* LWIP_UDP */
+
+   case NETCONN_TCP:
 #if LWIP_TCP
-   case NETCONN_TCP:
       msg->conn->pcb.tcp = tcp_new();
       if(msg->conn->pcb.tcp == NULL) {
          msg->conn->err = ERR_MEM;
          break;
       }
       setup_tcp(msg->conn);
+#endif
       break;
-#endif
    }
    
   
@@ -559,20 +566,19 @@ do_disconnect(struct api_msg_msg *msg)
 {
 
   switch (msg->conn->type) {
-#if LWIP_RAW
   case NETCONN_RAW:
     /* Do nothing as connecting is only a helper for upper lwip layers */
     break;
-#endif
-#if LWIP_UDP
+
   case NETCONN_UDPLITE:
     /* FALLTHROUGH */
   case NETCONN_UDPNOCHKSUM:
     /* FALLTHROUGH */
   case NETCONN_UDP:
+#if LWIP_UDP
     udp_disconnect(msg->conn->pcb.udp);
+#endif
     break;
-#endif 
   case NETCONN_TCP:
     break;
   }
@@ -585,37 +591,48 @@ do_listen(struct api_msg_msg *msg)
 {
   if (msg->conn->pcb.tcp != NULL) {
     switch (msg->conn->type) {
+
+    case NETCONN_RAW:
 #if LWIP_RAW
-    case NETCONN_RAW:
       LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen RAW: cannot listen for RAW.\n"));
+#endif
       break;
-#endif
-#if LWIP_UDP
+
     case NETCONN_UDPLITE:
       /* FALLTHROUGH */
     case NETCONN_UDPNOCHKSUM:
       /* FALLTHROUGH */
     case NETCONN_UDP:
+#if LWIP_UDP
       LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
-      break;
 #endif /* LWIP_UDP */
-#if LWIP_TCP      
+      break;
+
+    
     case NETCONN_TCP:
+#if LWIP_TCP  
       msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
-      if (msg->conn->pcb.tcp == NULL) {
-  msg->conn->err = ERR_MEM;
-      } else {
-  if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
-    msg->conn->acceptmbox = sys_mbox_new();
-    if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
-      msg->conn->err = ERR_MEM;
-      break;
-    }
-  }
-  tcp_arg(msg->conn->pcb.tcp, msg->conn);
-  tcp_accept(msg->conn->pcb.tcp, accept_function);
+      if (msg->conn->pcb.tcp == NULL) 
+      {
+          msg->conn->err = ERR_MEM;
+      } 
+      else 
+      {
+          if (msg->conn->acceptmbox == SYS_MBOX_NULL) 
+          {
+              msg->conn->acceptmbox = sys_mbox_new();
+              if (msg->conn->acceptmbox == SYS_MBOX_NULL) 
+              {
+                  msg->conn->err = ERR_MEM;
+                  break;
+              }
+          }
+          tcp_arg(msg->conn->pcb.tcp, msg->conn);
+          tcp_accept(msg->conn->pcb.tcp, accept_function);
       }
 #endif
+      break;
+
     default:
       break;
     }
@@ -628,20 +645,22 @@ do_accept(struct api_msg_msg *msg)
 {
   if (msg->conn->pcb.tcp != NULL) {
     switch (msg->conn->type) {
+
+    case NETCONN_RAW:
 #if LWIP_RAW
-    case NETCONN_RAW:
       LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept RAW: cannot accept for RAW.\n"));
+#endif
       break;
-#endif
-#if LWIP_UDP
+
     case NETCONN_UDPLITE:
       /* FALLTHROUGH */
     case NETCONN_UDPNOCHKSUM:
       /* FALLTHROUGH */
-    case NETCONN_UDP:    
+    case NETCONN_UDP:  
+#if LWIP_UDP  
       LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
+#endif /* LWIP_UDP */
       break;
-#endif /* LWIP_UDP */
     case NETCONN_TCP:
       break;
     }
@@ -653,20 +672,23 @@ do_send(struct api_msg_msg *msg)
 {
   if (msg->conn->pcb.tcp != NULL) {
     switch (msg->conn->type) {
+
+    case NETCONN_RAW:
 #if LWIP_RAW
-    case NETCONN_RAW:
       raw_send(msg->conn->pcb.raw, msg->msg.p);
+#endif
       break;
-#endif
-#if LWIP_UDP
+
     case NETCONN_UDPLITE:
       /* FALLTHROUGH */
     case NETCONN_UDPNOCHKSUM:
       /* FALLTHROUGH */
     case NETCONN_UDP:
+#if LWIP_UDP
       udp_send(msg->conn->pcb.udp, msg->msg.p);
+#endif /* LWIP_UDP */
       break;
-#endif /* LWIP_UDP */
+      
     case NETCONN_TCP:
       break;
     }
@@ -695,22 +717,26 @@ do_write(struct api_msg_msg *msg)
 #endif  
   if (msg->conn->pcb.tcp != NULL) {
     switch (msg->conn->type) {
+
+    case NETCONN_RAW:
 #if LWIP_RAW
-    case NETCONN_RAW:
       msg->conn->err = ERR_VAL;
+#endif
       break;
-#endif
-#if LWIP_UDP 
+
+
     case NETCONN_UDPLITE:
       /* FALLTHROUGH */
     case NETCONN_UDPNOCHKSUM:
       /* FALLTHROUGH */
     case NETCONN_UDP:
+#if LWIP_UDP 
       msg->conn->err = ERR_VAL;
-      break;
 #endif /* LWIP_UDP */
-#if LWIP_TCP 
-    case NETCONN_TCP:      
+      break;
+
+    case NETCONN_TCP: 
+#if LWIP_TCP      
       err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
                       msg->msg.w.len, msg->msg.w.copy);
       /* This is the Nagle algorithm: inhibit the sending of new TCP
@@ -728,6 +754,9 @@ do_write(struct api_msg_msg *msg)
                   (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
           }
 #endif
+    break;
+    
+    
     default:
       break;
     }
@@ -744,25 +773,28 @@ do_close(struct api_msg_msg *msg)
 
   if (msg->conn->pcb.tcp != NULL) {
     switch (msg->conn->type) {
-#if LWIP_RAW
+
     case NETCONN_RAW:
       break;
-#endif
-#if LWIP_UDP
+
+
     case NETCONN_UDPLITE:
       /* FALLTHROUGH */
     case NETCONN_UDPNOCHKSUM:
       /* FALLTHROUGH */
     case NETCONN_UDP:
       break;
-#endif /* LWIP_UDP */
+
+
+    case NETCONN_TCP:
 #if LWIP_TCP
-    case NETCONN_TCP:
       if (msg->conn->pcb.tcp->state == LISTEN) {
   err = tcp_close(msg->conn->pcb.tcp);
       }
       msg->conn->err = err;      
 #endif
+    break;
+    
     default:      
       break;
     }
--- a/packages/net/lwip_tcpip/current/src/api/sockets.c
+++ b/packages/net/lwip_tcpip/current/src/api/sockets.c
@@ -32,12 +32,14 @@
  *
  */
 
+#include <string.h>
+#include <errno.h>
+
 #include "lwip/opt.h"
 #include "lwip/api.h"
 #include "lwip/arch.h"
 #include "lwip/sys.h"
 
-#define LWIP_TIMEVAL_PRIVATE
 #include "lwip/sockets.h"
 
 #define NUM_SOCKETS MEMP_NUM_NETCONN
@@ -85,9 +87,12 @@ static int err_to_errno_table[11] = {
     EADDRINUSE    /* ERR_USE  -10     Address in use.          */
 };
 
+#define ERR_TO_ERRNO_TABLE_SIZE \
+  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
+
 #define err_to_errno(err) \
-  ((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \
-    err_to_errno_table[-(err)] : EIO
+  (-(err) >= 0 && -(err) < ERR_TO_ERRNO_TABLE_SIZE ? \
+    err_to_errno_table[-(err)] : EIO)
 
 #ifdef ERRNO
 #define set_errno(err) errno = (err)
@@ -416,7 +421,7 @@ lwip_recvfrom(int s, void *mem, int len,
     ip_addr_debug_print(SOCKETS_DEBUG, addr);
     LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
   } else {
-#if SOCKETS_DEBUG > 0
+#if SOCKETS_DEBUG
     addr = netbuf_fromaddr(buf);
     port = netbuf_fromport(buf);
 
@@ -1159,7 +1164,7 @@ int lwip_getsockopt (int s, int level, i
       LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int*)optval)?"on":"off") );
       break;
     case TCP_KEEPALIVE:
-      *(int*)optval = sock->conn->pcb.tcp->keepalive;
+      *(int*)optval = (int)sock->conn->pcb.tcp->keepalive;
       LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval));
       break;
     }  /* switch */
@@ -1327,7 +1332,7 @@ int lwip_setsockopt (int s, int level, i
       break;
     case TCP_KEEPALIVE:
       sock->conn->pcb.tcp->keepalive = (u32_t)(*(int*)optval);
-      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %u\n", s, sock->conn->pcb.tcp->keepalive));
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", s, sock->conn->pcb.tcp->keepalive));
       break;
     }  /* switch */
     break;
--- a/packages/net/lwip_tcpip/current/src/api/tcpip.c
+++ b/packages/net/lwip_tcpip/current/src/api/tcpip.c
@@ -38,6 +38,7 @@
 #include "lwip/pbuf.h"
 
 #include "lwip/ip.h"
+#include "lwip/ip_frag.h"
 #include "lwip/udp.h"
 #include "lwip/tcp.h"
 
@@ -46,34 +47,51 @@
 static void (* tcpip_init_done)(void *arg) = NULL;
 static void *tcpip_init_done_arg;
 static sys_mbox_t mbox;
+
 #if LWIP_TCP
 static int tcpip_tcp_timer_active = 0;
 
-
-
 static void
 tcpip_tcp_timer(void *arg)
 {
   (void)arg;
 
+  /* call TCP timer handler */
   tcp_tmr();
+  /* timer still needed? */
   if (tcp_active_pcbs || tcp_tw_pcbs) {
+    /* restart timer */
     sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
   } else {
-  tcpip_tcp_timer_active = 0;
+    /* disable timer */
+    tcpip_tcp_timer_active = 0;
   }
 }
 
+#if !NO_SYS
 void
 tcp_timer_needed(void)
 {
+  /* timer is off but needed again? */
   if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
-  tcpip_tcp_timer_active = 1;
+    /* enable and start timer */
+    tcpip_tcp_timer_active = 1;
     sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
   }
 }
+#endif /* !NO_SYS */
 #endif /* LWIP_TCP */
 
+#if IP_REASSEMBLY
+static void
+ip_timer(void *data)
+{
+  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: ip_reass_tmr()\n"));
+  ip_reass_tmr();
+  sys_timeout(1000, ip_timer, NULL);
+}
+#endif
+
 static void
 tcpip_thread(void *arg)
 {
@@ -88,6 +106,9 @@ tcpip_thread(void *arg)
 #if LWIP_TCP
   tcp_init();
 #endif
+#if IP_REASSEMBLY
+  sys_timeout(1000, ip_timer, NULL);
+#endif
   if (tcpip_init_done != NULL) {
     tcpip_init_done(tcpip_init_done_arg);
   }
--- a/packages/net/lwip_tcpip/current/src/core/dhcp.c
+++ b/packages/net/lwip_tcpip/current/src/core/dhcp.c
@@ -67,6 +67,9 @@
  * to remove the DHCP client.
  *
  */
+ 
+#include <string.h>
+ 
 #include "lwip/stats.h"
 #include "lwip/mem.h"
 #include "lwip/udp.h"
@@ -82,7 +85,8 @@
 #if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */
 
 /** global transaction identifier, must be
- *  unique for each DHCP request. */
+ *  unique for each DHCP request. We simply increment, starting
+ *  with this value (easy to match with a packet analyzer) */
 static u32_t xid = 0xABCD0000;
 
 /** DHCP client state machine functions */
@@ -96,8 +100,7 @@ static void dhcp_check(struct netif *net
 static void dhcp_bind(struct netif *netif);
 static err_t dhcp_decline(struct netif *netif);
 static err_t dhcp_rebind(struct netif *netif);
-static err_t dhcp_release(struct netif *netif);
-static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state);
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
 
 /** receive, unfold, parse and free incoming messages */
 static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
@@ -141,10 +144,10 @@ static void dhcp_option_trailer(struct d
 static void dhcp_handle_nak(struct netif *netif) {
   struct dhcp *dhcp = netif->dhcp;
   u16_t msecs = 10 * 1000;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif,
-    netif->name[0], netif->name[1], (unsigned int)netif->num));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", 
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %"U16_F" msecs\n", msecs));
   dhcp_set_state(dhcp, DHCP_BACKING_OFF);
 }
 
@@ -160,8 +163,8 @@ static void dhcp_check(struct netif *net
   struct dhcp *dhcp = netif->dhcp;
   err_t result;
   u16_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (unsigned int)netif->name[0],
-    (unsigned int)netif->name[1]));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
+    (s16_t)netif->name[1]));
   /* create an ARP query for the offered IP address, expecting that no host
      responds, as the IP address should not be in use. */
   result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
@@ -171,7 +174,7 @@ static void dhcp_check(struct netif *net
   dhcp->tries++;
   msecs = 500;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %u msecs\n", msecs));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
   dhcp_set_state(dhcp, DHCP_CHECKING);
 }
 
@@ -185,15 +188,15 @@ static void dhcp_handle_offer(struct net
   struct dhcp *dhcp = netif->dhcp;
   /* obtain the server address */
   u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif,
-    netif->name[0], netif->name[1], netif->num));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
+    (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
   if (option_ptr != NULL)
   {
     dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08lx\n", dhcp->server_ip_addr.addr));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr));
     /* remember offered address */
     ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
 
     dhcp_select(netif);
   }
@@ -212,7 +215,7 @@ static err_t dhcp_select(struct netif *n
   struct dhcp *dhcp = netif->dhcp;
   err_t result;
   u32_t msecs;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
 
   /* create and initialize the DHCP message header */
   result = dhcp_create_request(netif);
@@ -231,10 +234,11 @@ static err_t dhcp_select(struct netif *n
     dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4);
     dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr));
 
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 3);
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
     dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
     dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
     dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
 
     dhcp_option_trailer(dhcp);
     /* shrink the pbuf to the actual content length */
@@ -257,7 +261,7 @@ static err_t dhcp_select(struct netif *n
   dhcp->tries++;
   msecs = dhcp->tries < 4 ? dhcp->tries * 1000 : 4 * 1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %u msecs\n", msecs));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_select(): set request timeout %"U32_F" msecs\n", msecs));
   return result;
 }
 
@@ -293,18 +297,20 @@ void dhcp_coarse_tmr()
 /**
  * DHCP transaction timeout handling
  *
- * A DHCP server is expected to respond within a
- * short period of time.
+ * A DHCP server is expected to respond within a short period of time.
+ * This timer checks whether an outstanding DHCP request is timed out.
+ * 
  */
 void dhcp_fine_tmr()
 {
   struct netif *netif = netif_list;
-  /* loop through clients */
+  /* loop through netif's */
   while (netif != NULL) {
     /* only act on DHCP configured interfaces */
     if (netif->dhcp != NULL) {
-      /* timer is active (non zero), and triggers (zeroes) now */
+      /* timer is active (non zero), and is about to trigger now */
       if (netif->dhcp->request_timeout-- == 1) {
+        /* { netif->dhcp->request_timeout == 0 } */
         LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_fine_tmr(): request timeout\n"));
         /* this clients' request timeout triggered */
         dhcp_timeout(netif);
@@ -383,8 +389,8 @@ static void dhcp_t1_timeout(struct netif
   struct dhcp *dhcp = netif->dhcp;
   LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_t1_timeout()\n"));
   if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) {
-    /* just retry to renew */
-    /* note that the rebind timer will eventually time-out if renew does not work */
+    /* just retry to renew - note that the rebind timer (t2) will
+     * eventually time-out if renew tries fail. */
     LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
     dhcp_renew(netif);
   }
@@ -479,6 +485,19 @@ static void dhcp_handle_ack(struct netif
   if (option_ptr != NULL) {
     dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
   }
+  
+  /* DNS servers */
+  option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER);
+  if (option_ptr != NULL) {
+    u8_t n;
+    dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]);
+    /* limit to at most DHCP_MAX_DNS DNS servers */
+    if (dhcp->dns_count > DHCP_MAX_DNS) dhcp->dns_count = DHCP_MAX_DNS;
+    for (n = 0; n < dhcp->dns_count; n++)
+    {
+      dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2+(n<<2)]));
+    }
+  }
 }
 
 /**
@@ -500,40 +519,44 @@ err_t dhcp_start(struct netif *netif)
   err_t result = ERR_OK;
 
   LWIP_ASSERT("netif != NULL", netif != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
+  netif->flags &= ~NETIF_FLAG_DHCP;
 
+  /* no DHCP client attached yet? */
   if (dhcp == NULL) {
     LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
     dhcp = mem_malloc(sizeof(struct dhcp));
     if (dhcp == NULL) {
       LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
-      netif->flags &= ~NETIF_FLAG_DHCP;
-      return ERR_MEM;
-    }
-    /* clear data structure */
-    memset(dhcp, 0, sizeof(struct dhcp));
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));
-    dhcp->pcb = udp_new();
-    if (dhcp->pcb == NULL) {
-      LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
-      mem_free((void *)dhcp);
-      dhcp = NULL;
-      netif->flags &= ~NETIF_FLAG_DHCP;
       return ERR_MEM;
     }
     /* store this dhcp client in the netif */
     netif->dhcp = dhcp;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): created new udp pcb\n"));
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): allocated dhcp"));
+  /* already has DHCP client attached */
   } else {
     LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE | 3, ("dhcp_start(): restarting DHCP configuration\n"));
   }
+  	
+	/* clear data structure */
+	memset(dhcp, 0, sizeof(struct dhcp));
+  /* allocate UDP PCB */
+	dhcp->pcb = udp_new();
+	if (dhcp->pcb == NULL) {
+	  LWIP_DEBUGF(DHCP_DEBUG  | DBG_TRACE, ("dhcp_start(): could not obtain pcb\n"));
+	  mem_free((void *)dhcp);
+	  netif->dhcp = dhcp = NULL;
+	  return ERR_MEM;
+	}
+	LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
   /* (re)start the DHCP negotiation */
   result = dhcp_discover(netif);
   if (result != ERR_OK) {
     /* free resources allocated above */
     dhcp_stop(netif);
+    return ERR_MEM;
   }
+  netif->flags |= NETIF_FLAG_DHCP;
   return result;
 }
 
@@ -610,10 +633,11 @@ void dhcp_inform(struct netif *netif)
  */
 void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
 {
+  LWIP_ASSERT("netif != NULL", netif != NULL);
   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_arp_reply()\n"));
-  /* is this DHCP client doing an ARP check? */
+  /* is a DHCP client doing an ARP check? */
   if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08lx\n", addr->addr));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr));
     /* did a host respond with the address we
        were offered by the DHCP server? */
     if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) {
@@ -656,8 +680,10 @@ static err_t dhcp_decline(struct netif *
     pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
 
     udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
-    udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
-    udp_send(dhcp->pcb, dhcp->p_out);
+    /* @todo: should we really connect here? we are performing sendto() */
+    udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
+    /* per section 4.4.4, broadcast DECLINE messages */
+    udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
     dhcp_delete_request(netif);
     LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
   } else {
@@ -666,7 +692,7 @@ static err_t dhcp_decline(struct netif *
   dhcp->tries++;
   msecs = 10*1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %u msecs\n", msecs));
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
 }
 #endif
@@ -694,10 +720,11 @@ static err_t dhcp_discover(struct netif 
     dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
     dhcp_option_short(dhcp, 576);
 
-    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 3);
+    dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/);
     dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK);
     dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER);
     dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST);
+    dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER);
 
     dhcp_option_trailer(dhcp);
 
@@ -720,7 +747,7 @@ static err_t dhcp_discover(struct netif 
   dhcp->tries++;
   msecs = dhcp->tries < 4 ? (dhcp->tries + 1) * 1000 : 10 * 1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %u msecs\n", msecs));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
 }
 
@@ -736,22 +763,22 @@ static void dhcp_bind(struct netif *neti
   struct ip_addr sn_mask, gw_addr;
   LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);
   LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
 
   /* temporary DHCP lease? */
   if (dhcp->offered_t1_renew != 0xffffffffUL) {
     /* set renewal period timer */
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %lu secs\n", dhcp->offered_t1_renew));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
     dhcp->t1_timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
     if (dhcp->t1_timeout == 0) dhcp->t1_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t1_renew*1000));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
   }
   /* set renewal period timer */
   if (dhcp->offered_t2_rebind != 0xffffffffUL) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %lu secs\n", dhcp->offered_t2_rebind));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
     dhcp->t2_timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
     if (dhcp->t2_timeout == 0) dhcp->t2_timeout = 1;
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %u msecs\n", dhcp->offered_t2_rebind*1000));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
   }
   /* copy offered network mask */
   ip_addr_set(&sn_mask, &dhcp->offered_sn_mask);
@@ -775,12 +802,14 @@ static void dhcp_bind(struct netif *neti
     gw_addr.addr |= htonl(0x00000001);
   }
 
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08lx\n", dhcp->offered_ip_addr.addr));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr));
   netif_set_ipaddr(netif, &dhcp->offered_ip_addr);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08lx\n", sn_mask.addr));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr));
   netif_set_netmask(netif, &sn_mask);
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08lx\n", gw_addr.addr));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr));
   netif_set_gw(netif, &gw_addr);
+  /* bring the interface up */
+  netif_set_up(netif);
   /* netif is now bound to DHCP leased address */
   dhcp_set_state(dhcp, DHCP_BOUND);
 }
@@ -836,7 +865,7 @@ err_t dhcp_renew(struct netif *netif)
   /* back-off on retries, but to a maximum of 20 seconds */
   msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %u msecs\n", msecs));
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
 }
 
@@ -889,7 +918,7 @@ static err_t dhcp_rebind(struct netif *n
   dhcp->tries++;
   msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %u msecs\n", msecs));
+   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
 }
 
@@ -898,7 +927,7 @@ static err_t dhcp_rebind(struct netif *n
  *
  * @param netif network interface which must release its lease
  */
-static err_t dhcp_release(struct netif *netif)
+err_t dhcp_release(struct netif *netif)
 {
   struct dhcp *dhcp = netif->dhcp;
   err_t result;
@@ -907,8 +936,13 @@ static err_t dhcp_release(struct netif *
 
   /* idle DHCP client */
   dhcp_set_state(dhcp, DHCP_OFF);
-
-
+  /* clean old DHCP offer */
+  dhcp->server_ip_addr.addr = 0;
+  dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0;
+  dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0;
+  dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0;
+  dhcp->dns_count = 0;
+  
   /* create and initialize the DHCP message header */
   result = dhcp_create_request(netif);
   if (result == ERR_OK) {
@@ -930,11 +964,14 @@ static err_t dhcp_release(struct netif *
   dhcp->tries++;
   msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
   dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
-   LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %u msecs\n", msecs));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs));
+  /* bring the interface down */
+  netif_set_down(netif);
   /* remove IP address from interface */
   netif_set_ipaddr(netif, IP_ADDR_ANY);
   netif_set_gw(netif, IP_ADDR_ANY);
   netif_set_netmask(netif, IP_ADDR_ANY);
+  
   /* TODO: netif_down(netif); */
   return result;
 }
@@ -976,7 +1013,7 @@ void dhcp_stop(struct netif *netif)
  *
  * TODO: we might also want to reset the timeout here?
  */
-static void dhcp_set_state(struct dhcp *dhcp, unsigned char new_state)
+static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
 {
   if (new_state != dhcp->state)
   {
@@ -1072,7 +1109,7 @@ static err_t dhcp_unfold_reply(struct dh
       j = 0;
     }
   }
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n", i));
   if (dhcp->options_in != NULL) {
     ptr = (u8_t *)dhcp->options_in;
     /* proceed through options */
@@ -1085,7 +1122,7 @@ static err_t dhcp_unfold_reply(struct dh
         j = 0;
       }
     }
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n", i));
   }
   return ERR_OK;
 }
@@ -1121,17 +1158,17 @@ static void dhcp_recv(void *arg, struct 
   u8_t *options_ptr;
   u8_t msg_type;
   u8_t i;
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %u.%u.%u.%u port %u\n", p,
-    (unsigned int)(ntohl(addr->addr) >> 24 & 0xff), (unsigned int)(ntohl(addr->addr) >> 16 & 0xff),
-    (unsigned int)(ntohl(addr->addr) >>  8 & 0xff), (unsigned int)(ntohl(addr->addr) & 0xff), port));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %u\n", p->len));
-  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %u\n", p->tot_len));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p,
+    (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff),
+    (u16_t)(ntohl(addr->addr) >>  8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
+  LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
   /* prevent warnings about unused arguments */
   (void)pcb; (void)addr; (void)port;
   dhcp->p = p;
   /* TODO: check packet length before reading them */
   if (reply_msg->op != DHCP_BOOTREPLY) {
-    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %u\n", reply_msg->op));
+    LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
     pbuf_free(p);
     dhcp->p = NULL;
     return;
@@ -1139,8 +1176,8 @@ static void dhcp_recv(void *arg, struct 
   /* iterate through hardware address and match against DHCP message */
   for (i = 0; i < netif->hwaddr_len; i++) {
     if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
-      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n",
-        i, netif->hwaddr[i], i, reply_msg->chaddr[i]));
+      LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
+        (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
       pbuf_free(p);
       dhcp->p = NULL;
       return;
@@ -1280,7 +1317,7 @@ static void dhcp_option_trailer(struct d
   dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END;
   /* packet is too small, or not 4 byte aligned? */
   while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) {
-    /* LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_option_trailer: dhcp->options_out_len=%u, DHCP_OPTIONS_LEN=%u", dhcp->options_out_len, DHCP_OPTIONS_LEN)); */
+    /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */
     LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN);
     /* add a fill/padding byte */
     dhcp->msg_out->options[dhcp->options_out_len++] = 0;
@@ -1307,7 +1344,7 @@ static u8_t *dhcp_get_option_ptr(struct 
     u16_t offset = 0;
     /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
     while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) {
-      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%u, q->len=%u", msg_offset, q->len)); */
+      /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */
       /* are the sname and/or file field overloaded with options? */
       if (options[offset] == DHCP_OPTION_OVERLOAD) {
         LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("overloaded message detected\n"));
@@ -1317,11 +1354,11 @@ static u8_t *dhcp_get_option_ptr(struct 
       }
       /* requested option found */
       else if (options[offset] == option_type) {
-        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %u in options\n", offset));
+        LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset));
         return &options[offset];
       /* skip option */
       } else {
-         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %u in options\n", options[offset]));
+         LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset]));
         /* skip option type */
         offset++;
         /* skip option length, and then length bytes */
@@ -1350,11 +1387,11 @@ static u8_t *dhcp_get_option_ptr(struct 
       /* at least 1 byte to read and no end marker */
       while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) {
         if (options[offset] == option_type) {
-           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%u\n", offset));
+           LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("option found at offset=%"U16_F"\n", offset));
           return &options[offset];
         /* skip option */
         } else {
-          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %u\n", options[offset]));
+          LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("skipping option %"U16_F"\n", options[offset]));
           /* skip option type */
           offset++;
           offset += 1 + options[offset];
@@ -1375,7 +1412,7 @@ static u8_t *dhcp_get_option_ptr(struct 
  */
 static u8_t dhcp_get_option_byte(u8_t *ptr)
 {
-  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr));
+  LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr)));
   return *ptr;
 }
 
@@ -1392,7 +1429,7 @@ static u16_t dhcp_get_option_short(u8_t 
   u16_t value;
   value = *ptr++ << 8;
   value |= *ptr;
-  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value));
+  LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value));
   return value;
 }
 
@@ -1411,7 +1448,7 @@ static u32_t dhcp_get_option_long(u8_t *
   value |= (u32_t)(*ptr++) << 16;
   value |= (u32_t)(*ptr++) << 8;
   value |= (u32_t)(*ptr++);
-  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
+  LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value));
   return value;
 }
 
--- a/packages/net/lwip_tcpip/current/src/core/inet.c
+++ b/packages/net/lwip_tcpip/current/src/core/inet.c
@@ -46,36 +46,195 @@
 #include "lwip/def.h"
 #include "lwip/inet.h"
 
+#include "lwip/sys.h"
 
+/* This is a reference implementation of the checksum algorithm, with the
+ * aim of being simple, correct and fully portable. Checksumming is the
+ * first thing you would want to optimize for your platform. You will
+ * need to port it to your architecture and in your sys_arch.h:
+ * 
+ * #define LWIP_CHKSUM <your_checksum_routine> 
+*/
+#ifndef LWIP_CHKSUM
+#define LWIP_CHKSUM lwip_standard_chksum
 
+/**
+ * lwip checksum
+ *
+ * @param dataptr points to start of data to be summed at any boundary
+ * @param len length of data to be summed
+ * @return host order (!) lwip checksum (non-inverted Internet sum) 
+ *
+ * @note accumulator size limits summable lenght to 64k
+ * @note host endianess is irrelevant (p3 RFC1071)
+ */
 static u16_t
-lwip_chksum(void *dataptr, int len)
+lwip_standard_chksum(void *dataptr, u16_t len)
 {
   u32_t acc;
+  u16_t src;
+  u8_t *octetptr;
 
-  LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));
-  for(acc = 0; len > 1; len -= 2) {
-      /*    acc = acc + *((u16_t *)dataptr)++;*/
-    acc += *(u16_t *)dataptr;
-    dataptr = (void *)((u16_t *)dataptr + 1);
+  acc = 0;
+  /* dataptr may be at odd or even addresses */
+  octetptr = (u8_t*)dataptr;
+  while (len > 1)
+  {
+    /* declare first octet as most significant
+       thus assume network order, ignoring host order */
+    src = (*octetptr) << 8;
+    octetptr++;
+    /* declare second octet as least significant */
+    src |= (*octetptr);
+    octetptr++;
+    acc += src;
+    len -= 2;
+  }
+  if (len > 0)
+  {
+    /* accumulate remaining octet */
+    src = (*octetptr) << 8;
+    acc += src;
+  }
+  /* add deferred carry bits */
+  acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  if ((acc & 0xffff0000) != 0) {
+    acc = (acc >> 16) + (acc & 0x0000ffffUL);
+  }
+  /* This maybe a little confusing: reorder sum using htons()
+     instead of ntohs() since it has a little less call overhead.
+     The caller must invert bits for Internet sum ! */
+  return htons((u16_t)acc);
+}
+
+#endif
+
+#if 0
+/*
+ * Curt McDowell
+ * Broadcom Corp.
+ * csm@broadcom.com
+ *
+ * IP checksum two bytes at a time with support for
+ * unaligned buffer.
+ * Works for len up to and including 0x20000.
+ * by Curt McDowell, Broadcom Corp. 12/08/2005
+ */
+
+static u16_t
+lwip_standard_chksum2(void *dataptr, int len)
+{
+  u8_t *pb = dataptr;
+  u16_t *ps, t = 0;
+  u32_t sum = 0;
+  int odd = ((u32_t)pb & 1);
+
+  /* Get aligned to u16_t */
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
   }
 
-  /* add up any odd byte */
-  if (len == 1) {
-    acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
-    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));
-  } else {
-    LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
-  }
-  acc = (acc >> 16) + (acc & 0xffffUL);
-
-  if ((acc & 0xffff0000) != 0) {
-    acc = (acc >> 16) + (acc & 0xffffUL);
+  /* Add the bulk of the data */
+  ps = (u16_t *)pb;
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
   }
 
-  return (u16_t)acc;
+  /* Consume left-over byte, if any */
+  if (len > 0)
+    ((u8_t *)&t)[0] = *(u8_t *)ps;;
+
+  /* Add end bytes */
+  sum += t;
+
+  /*  Fold 32-bit sum to 16 bits */
+  while (sum >> 16)
+    sum = (sum & 0xffff) + (sum >> 16);
+
+  /* Swap if alignment was odd */
+  if (odd)
+    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
+
+  return sum;
 }
 
+/**
+ * An optimized checksum routine. Basically, it uses loop-unrolling on
+ * the checksum loop, treating the head and tail bytes specially, whereas
+ * the inner loop acts on 8 bytes at a time. 
+ *
+ * @arg start of buffer to be checksummed. May be an odd byte address.
+ * @len number of bytes in the buffer to be checksummed.
+ * 
+ * @todo First argument type conflicts with generic checksum routine.
+ * 
+ * by Curt McDowell, Broadcom Corp. December 8th, 2005
+ */
+
+static u16_t
+lwip_standard_chksum4(u8_t *pb, int len)
+{
+  u16_t *ps, t = 0;
+  u32_t *pl;
+  u32_t sum = 0, tmp;
+  /* starts at odd byte address? */
+  int odd = ((u32_t)pb & 1);
+
+  if (odd && len > 0) {
+    ((u8_t *)&t)[1] = *pb++;
+    len--;
+  }
+
+  ps = (u16_t *)pb;
+
+  if (((u32_t)ps & 3) && len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  pl = (u32_t *)ps;
+
+  while (len > 7)  {
+    tmp = sum + *pl++;          /* ping */
+    if (tmp < sum)
+      tmp++;                    /* add back carry */
+
+    sum = tmp + *pl++;          /* pong */
+    if (sum < tmp)
+      sum++;                    /* add back carry */
+
+    len -= 8;
+  }
+
+  /* make room in upper bits */
+  sum = (sum >> 16) + (sum & 0xffff);
+
+  ps = (u16_t *)pl;
+
+  /* 16-bit aligned word remaining? */
+  while (len > 1) {
+    sum += *ps++;
+    len -= 2;
+  }
+
+  /* dangling tail byte remaining? */
+  if (len > 0)                  /* include odd byte */
+    ((u8_t *)&t)[0] = *(u8_t *)ps;
+
+  sum += t;                     /* add end bytes */
+
+  while (sum >> 16)             /* combine halves */
+    sum = (sum >> 16) + (sum & 0xffff);
+
+  if (odd)
+    sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
+
+  return sum;
+}
+#endif
+
 /* inet_chksum_pseudo:
  *
  * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
@@ -96,8 +255,8 @@ inet_chksum_pseudo(struct pbuf *p,
   for(q = p; q != NULL; q = q->next) {
     LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
       (void *)q, (void *)q->next));
-    acc += lwip_chksum(q->payload, q->len);
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/
+    acc += LWIP_CHKSUM(q->payload, q->len);
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
     while (acc >> 16) {
       acc = (acc & 0xffffUL) + (acc >> 16);
     }
@@ -105,7 +264,7 @@ inet_chksum_pseudo(struct pbuf *p,
       swapped = 1 - swapped;
       acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
     }
-    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%lx \n", acc));*/
+    /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
   }
 
   if (swapped) {
@@ -121,8 +280,8 @@ inet_chksum_pseudo(struct pbuf *p,
   while (acc >> 16) {
     acc = (acc & 0xffffUL) + (acc >> 16);
   }
-  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));
-  return ~(acc & 0xffffUL);
+  LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
+  return (u16_t)~(acc & 0xffffUL);
 }
 
 /* inet_chksum:
@@ -136,11 +295,11 @@ inet_chksum(void *dataptr, u16_t len)
 {
   u32_t acc;
 
-  acc = lwip_chksum(dataptr, len);
+  acc = LWIP_CHKSUM(dataptr, len);
   while (acc >> 16) {
     acc = (acc & 0xffff) + (acc >> 16);
   }
-  return ~(acc & 0xffff);
+  return (u16_t)~(acc & 0xffff);
 }
 
 u16_t
@@ -153,7 +312,7 @@ inet_chksum_pbuf(struct pbuf *p)
   acc = 0;
   swapped = 0;
   for(q = p; q != NULL; q = q->next) {
-    acc += lwip_chksum(q->payload, q->len);
+    acc += LWIP_CHKSUM(q->payload, q->len);
     while (acc >> 16) {
       acc = (acc & 0xffffUL) + (acc >> 16);
     }
@@ -166,7 +325,7 @@ inet_chksum_pbuf(struct pbuf *p)
   if (swapped) {
     acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
   }
-  return ~(acc & 0xffffUL);
+  return (u16_t)~(acc & 0xffffUL);
 }
 
 /* Here for now until needed in other places in lwIP */
@@ -206,10 +365,11 @@ inet_chksum_pbuf(struct pbuf *p)
   */
  /*  */
  /* inet_aton */
- int inet_aton(const char *cp, struct in_addr *addr)
+ s8_t
+ inet_aton(const char *cp, struct in_addr *addr)
  {
      u32_t val;
-     int base, n;
+     s32_t base, n;
      char c;
      u32_t parts[4];
      u32_t* pp = parts;
@@ -232,12 +392,12 @@ inet_chksum_pbuf(struct pbuf *p)
                  base = 8;
          }
          for (;;) {
-             if (isascii(c) && isdigit(c)) {
-                 val = (val * base) + (c - '0');
+             if (isdigit(c)) {
+                 val = (val * base) + (s16_t)(c - '0');
                  c = *++cp;
-             } else if (base == 16 && isascii(c) && isxdigit(c)) {
+             } else if (base == 16 && isxdigit(c)) {
                  val = (val << 4) |
-                     (c + 10 - (islower(c) ? 'a' : 'A'));
+                     (s16_t)(c + 10 - (islower(c) ? 'a' : 'A'));
                  c = *++cp;
              } else
              break;
@@ -302,17 +462,17 @@ inet_chksum_pbuf(struct pbuf *p)
  */
 char *inet_ntoa(struct in_addr addr)
 {
-  static u8_t str[16];
+  static char str[16];
   u32_t s_addr = addr.s_addr;
-  u8_t inv[3];
-  u8_t *rp;
+  char inv[3];
+  char *rp;
   u8_t *ap;
   u8_t rem;
   u8_t n;
   u8_t i;
 
   rp = str;
-  ap = (char *)&s_addr;
+  ap = (u8_t *)&s_addr;
   for(n = 0; n < 4; n++) {
     i = 0;
     do {
--- a/packages/net/lwip_tcpip/current/src/core/ipv4/icmp.c
+++ b/packages/net/lwip_tcpip/current/src/core/ipv4/icmp.c
@@ -33,22 +33,21 @@
 /* Some ICMP messages should be passed to the transport protocols. This
    is not implemented. */
 
+#include <string.h>
+
 #include "lwip/opt.h"
-
 #include "lwip/icmp.h"
 #include "lwip/inet.h"
 #include "lwip/ip.h"
 #include "lwip/def.h"
-
 #include "lwip/stats.h"
-
 #include "lwip/snmp.h"
 
 void
 icmp_input(struct pbuf *p, struct netif *inp)
 {
-  unsigned char type;
-  unsigned char code;
+  u8_t type;
+  u8_t code;
   struct icmp_echo_hdr *iecho;
   struct ip_hdr *iphdr;
   struct ip_addr tmpaddr;
@@ -61,7 +60,7 @@ icmp_input(struct pbuf *p, struct netif 
   iphdr = p->payload;
   hlen = IPH_HL(iphdr) * 4;
   if (pbuf_header(p, -((s16_t)hlen)) || (p->tot_len < sizeof(u16_t)*2)) {
-    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%u bytes) received\n", p->tot_len));
+    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
     pbuf_free(p);
     ICMP_STATS_INC(icmp.lenerr);
     snmp_inc_icmpinerrors();
@@ -74,7 +73,7 @@ icmp_input(struct pbuf *p, struct netif 
   case ICMP_ECHO:
     /* broadcast or multicast destination address? */
     if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) {
-      LWIP_DEBUGF(ICMP_DEBUG, ("Smurf.\n"));
+      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n"));
       ICMP_STATS_INC(icmp.err);
       pbuf_free(p);
       return;
@@ -117,7 +116,7 @@ icmp_input(struct pbuf *p, struct netif 
 		 IPH_TTL(iphdr), 0, IP_PROTO_ICMP, inp);
     break;
   default:
-  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code));
+  LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", (s16_t)type, (s16_t)code));
     ICMP_STATS_INC(icmp.proterr);
     ICMP_STATS_INC(icmp.drop);
   }
@@ -140,7 +139,7 @@ icmp_dest_unreach(struct pbuf *p, enum i
   ICMPH_TYPE_SET(idur, ICMP_DUR);
   ICMPH_CODE_SET(idur, t);
 
-  memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);
+  memcpy((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8);
 
   /* calculate checksum */
   idur->chksum = 0;
@@ -178,7 +177,7 @@ icmp_time_exceeded(struct pbuf *p, enum 
   ICMPH_CODE_SET(tehdr, t);
 
   /* copy fields from original packet */
-  memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);
+  memcpy((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8);
 
   /* calculate checksum */
   tehdr->chksum = 0;
--- a/packages/net/lwip_tcpip/current/src/core/ipv4/ip.c
+++ b/packages/net/lwip_tcpip/current/src/core/ipv4/ip.c
@@ -1,3 +1,10 @@
+/* @file
+ *
+ * This is the IP layer implementation for incoming and outgoing IP traffic.
+ * 
+ * @see ip_frag.c
+ *
+ */
 /*
  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  * All rights reserved.
@@ -30,18 +37,8 @@
  *
  */
 
-
-
-/* ip.c
- *
- * This is the code for the IP layer.
- *
- */
-
-
 #include "lwip/opt.h"
 
-
 #include "lwip/def.h"
 #include "lwip/mem.h"
 #include "lwip/ip.h"
@@ -63,18 +60,17 @@
 #endif /* LWIP_DHCP */
 
 
-/* ip_init:
- *
+/**
  * Initializes the IP layer.
  */
 
 void
 ip_init(void)
 {
+  /* no initializations as of yet */
 }
 
-/* ip_route:
- *
+/**
  * Finds the appropriate network interface for a given IP address. It
  * searches the list of network interfaces linearly. A match is found
  * if the masked IP address of the network interface equals the masked
@@ -89,7 +85,7 @@ ip_route(struct ip_addr *dest)
   /* iterate through netifs */
   for(netif = netif_list; netif != NULL; netif = netif->next) {
     /* network mask matches? */
-    if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
+    if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
       /* return netif on which to forward IP packet */
       return netif;
     }
@@ -99,14 +95,13 @@ ip_route(struct ip_addr *dest)
 }
 #if IP_FORWARD
 
-/* ip_forward:
- *
+/**
  * Forwards an IP packet. It finds an appropriate route for the
  * packet, decrements the TTL value of the packet, adjusts the
  * checksum and outputs the packet on the appropriate interface.
  */
 
-static void
+static struct netif *
 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
 {
   struct netif *netif;
@@ -115,17 +110,17 @@ ip_forward(struct pbuf *p, struct ip_hdr
   /* Find network interface where to forward this IP packet to. */
   netif = ip_route((struct ip_addr *)&(iphdr->dest));
   if (netif == NULL) {
-    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
+    LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n",
                       iphdr->dest.addr));
     snmp_inc_ipnoroutes();
-    return;
+    return (struct netif *)NULL;
   }
   /* Do not forward packets onto the same network interface on which
-     they arrived. */
+   * they arrived. */
   if (netif == inp) {
     LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
     snmp_inc_ipnoroutes();
-    return;
+    return (struct netif *)NULL;
   }
 
   /* decrement TTL */
@@ -137,7 +132,7 @@ ip_forward(struct pbuf *p, struct ip_hdr
       icmp_time_exceeded(p, ICMP_TE_TTL);
       snmp_inc_icmpouttimeexcds();
     }
-    return;
+    return (struct netif *)NULL;
   }
 
   /* Incrementally update the IP checksum. */
@@ -147,7 +142,7 @@ ip_forward(struct pbuf *p, struct ip_hdr
     IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
   }
 
-  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
+  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n",
                     iphdr->dest.addr));
 
   IP_STATS_INC(ip.fw);
@@ -157,11 +152,11 @@ ip_forward(struct pbuf *p, struct ip_hdr
   PERF_STOP("ip_forward");
   /* transmit pbuf on chosen interface */
   netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
+  return netif;
 }
 #endif /* IP_FORWARD */
 
-/* ip_input:
- *
+/**
  * This function is called by the network interface device driver when
  * an IP packet is received. The function does the basic checks of the
  * IP header such as packet size being at least larger than the header
@@ -169,13 +164,16 @@ ip_forward(struct pbuf *p, struct ip_hdr
  * forwarded (using ip_forward). The IP checksum is always checked.
  *
  * Finally, the packet is sent to the upper layer protocol input function.
+ * 
+ * 
+ * 
  */
 
 err_t
 ip_input(struct pbuf *p, struct netif *inp) {
-  static struct ip_hdr *iphdr;
-  static struct netif *netif;
-  static u16_t iphdrlen;
+  struct ip_hdr *iphdr;
+  struct netif *netif;
+  u16_t iphdrlen;
 
   IP_STATS_INC(ip.recv);
   snmp_inc_ipinreceives();
@@ -183,7 +181,7 @@ ip_input(struct pbuf *p, struct netif *i
   /* identify the IP header */
   iphdr = p->payload;
   if (IPH_V(iphdr) != 4) {
-    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));
+    LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
     ip_debug_print(p);
     pbuf_free(p);
     IP_STATS_INC(ip.err);
@@ -198,7 +196,7 @@ ip_input(struct pbuf *p, struct netif *i
 
   /* header length exceeds first pbuf length? */
   if (iphdrlen > p->len) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet droppped.\n",
       iphdrlen, p->len));
     /* free (drop) packet pbufs */
     pbuf_free(p);
@@ -212,7 +210,7 @@ ip_input(struct pbuf *p, struct netif *i
 #if CHECKSUM_CHECK_IP
   if (inet_chksum(iphdr, iphdrlen) != 0) {
 
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
     ip_debug_print(p);
     pbuf_free(p);
     IP_STATS_INC(ip.chkerr);
@@ -223,43 +221,41 @@ ip_input(struct pbuf *p, struct netif *i
 #endif
 
   /* Trim pbuf. This should have been done at the netif layer,
-     but we'll do it anyway just to be sure that its done. */
+   * but we'll do it anyway just to be sure that its done. */
   pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
 
-  /* is this packet for us? */
-  for(netif = netif_list; netif != NULL; netif = netif->next) {
+  /* match packet against an interface, i.e. is this packet for us? */
+  for (netif = netif_list; netif != NULL; netif = netif->next) {
 
-    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
-                      iphdr->dest.addr, netif->ip_addr.addr,
-                      iphdr->dest.addr & netif->netmask.addr,
-                      netif->ip_addr.addr & netif->netmask.addr,
-                      iphdr->dest.addr & ~(netif->netmask.addr)));
+    LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
+      iphdr->dest.addr, netif->ip_addr.addr,
+      iphdr->dest.addr & netif->netmask.addr,
+      netif->ip_addr.addr & netif->netmask.addr,
+      iphdr->dest.addr & ~(netif->netmask.addr)));
 
-    /* interface configured? */
-    if (!ip_addr_isany(&(netif->ip_addr)))
+    /* interface is up and configured? */
+    if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr))))
     {
       /* unicast to this interface address? */
       if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
-        /* or broadcast matching this interface network address? */
-        (ip_addr_isbroadcast(&(iphdr->dest), netif) &&
-         ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
-         /* or restricted broadcast? */
-         ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
-         LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
-                       netif->name[0], netif->name[1]));
-         /* break out of for loop */
-         break;
+         /* or broadcast on this interface network address? */
+         ip_addr_isbroadcast(&(iphdr->dest), netif)) {
+        LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
+          netif->name[0], netif->name[1]));
+        /* break out of for loop */
+        break;
       }
     }
   }
 #if LWIP_DHCP
   /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
-     using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
-     According to RFC 1542 section 3.1.1, referred by RFC 2131). */
+   * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
+   * According to RFC 1542 section 3.1.1, referred by RFC 2131).
+   */
   if (netif == NULL) {
     /* remote port is DHCP server? */
     if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
-      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
+      LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
         ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
       if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
         LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
@@ -268,7 +264,7 @@ ip_input(struct pbuf *p, struct netif *i
     }
   }
 #endif /* LWIP_DHCP */
-        /* packet not for us? */
+  /* packet not for us? */
   if (netif == NULL) {
     /* packet not for us, route or discard */
     LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
@@ -286,30 +282,30 @@ ip_input(struct pbuf *p, struct netif *i
     pbuf_free(p);
     return ERR_OK;
   }
-
-#if IP_REASSEMBLY
+  /* packet consists of multiple fragments? */
   if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
-    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",
+#if IP_REASSEMBLY /* packet fragment reassembly code present? */
+    LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
       ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
+    /* reassemble the packet*/
     p = ip_reass(p);
+    /* packet not fully reassembled yet? */
     if (p == NULL) {
       return ERR_OK;
     }
     iphdr = p->payload;
-  }
-#else /* IP_REASSEMBLY */
-  if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
+#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
     pbuf_free(p);
-    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
-                  ntohs(IPH_OFFSET(iphdr))));
+    LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
+      ntohs(IPH_OFFSET(iphdr))));
     IP_STATS_INC(ip.opterr);
     IP_STATS_INC(ip.drop);
     snmp_inc_ipunknownprotos();
     return ERR_OK;
+#endif /* IP_REASSEMBLY */
   }
-#endif /* IP_REASSEMBLY */
 
-#if IP_OPTIONS == 0
+#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
   if (iphdrlen > IP_HLEN) {
     LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
     pbuf_free(p);
@@ -323,10 +319,11 @@ ip_input(struct pbuf *p, struct netif *i
   /* send to upper layers */
   LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
   ip_debug_print(p);
-  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
+  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
 
 #if LWIP_RAW
-  if (!raw_input(p, inp)) {
+  /* raw input did not eat the packet? */
+  if (raw_input(p, inp) == 0) {
 #endif /* LWIP_RAW */
 
   switch (IPH_PROTO(iphdr)) {
@@ -356,12 +353,11 @@ ip_input(struct pbuf *p, struct netif *i
     }
     pbuf_free(p);
 
-    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
+    LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
 
     IP_STATS_INC(ip.proterr);
     IP_STATS_INC(ip.drop);
     snmp_inc_ipunknownprotos();
-
   }
 #if LWIP_RAW
   } /* LWIP_RAW */
@@ -369,9 +365,7 @@ ip_input(struct pbuf *p, struct netif *i
   return ERR_OK;
 }
 
-
-/* ip_output_if:
- *
+/**
  * Sends an IP packet on a network interface. This function constructs
  * the IP header and calculates the IP header checksum. If the source
  * IP address is NULL, the IP address of the outgoing network
@@ -383,8 +377,8 @@ ip_output_if(struct pbuf *p, struct ip_a
              u8_t ttl, u8_t tos,
              u8_t proto, struct netif *netif)
 {
-  static struct ip_hdr *iphdr;
-  static u16_t ip_id = 0;
+  struct ip_hdr *iphdr;
+  u16_t ip_id = 0;
 
   snmp_inc_ipoutrequests();
 
@@ -433,7 +427,7 @@ ip_output_if(struct pbuf *p, struct ip_a
 
   IP_STATS_INC(ip.xmit);
 
-  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
+  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
   ip_debug_print(p);
 
   LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
@@ -441,8 +435,7 @@ ip_output_if(struct pbuf *p, struct ip_a
   return netif->output(netif, p, dest);
 }
 
-/* ip_output:
- *
+/**
  * Simple interface to ip_output_if. It finds the outgoing network
  * interface and calls upon ip_output_if to do the actual work.
  */
@@ -454,7 +447,7 @@ ip_output(struct pbuf *p, struct ip_addr
   struct netif *netif;
 
   if ((netif = ip_route(dest)) == NULL) {
-    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
+    LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
 
     IP_STATS_INC(ip.rterr);
     snmp_inc_ipoutdiscards();
@@ -475,35 +468,35 @@ ip_debug_print(struct pbuf *p)
 
   LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d |  0x%02x |     %5u     | (v, hl, tos, len)\n",
+  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",
                     IPH_V(iphdr),
                     IPH_HL(iphdr),
                     IPH_TOS(iphdr),
                     ntohs(IPH_LEN(iphdr))));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|    %5u      |%u%u%u|    %4u   | (id, flags, offset)\n",
+  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",
                     ntohs(IPH_ID(iphdr)),
                     ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
                     ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
                     ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
                     ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3u  |  %3u  |    0x%04x     | (ttl, proto, chksum)\n",
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",
                     IPH_TTL(iphdr),
                     IPH_PROTO(iphdr),
                     ntohs(IPH_CHKSUM(iphdr))));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3ld  |  %3ld  |  %3ld  |  %3ld  | (src)\n",
-                    ntohl(iphdr->src.addr) >> 24 & 0xff,
-                    ntohl(iphdr->src.addr) >> 16 & 0xff,
-                    ntohl(iphdr->src.addr) >> 8 & 0xff,
-                    ntohl(iphdr->src.addr) & 0xff));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",
+                    ip4_addr1(&iphdr->src),
+                    ip4_addr2(&iphdr->src),
+                    ip4_addr3(&iphdr->src),
+                    ip4_addr4(&iphdr->src)));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(IP_DEBUG, ("|  %3ld  |  %3ld  |  %3ld  |  %3ld  | (dest)\n",
-                    ntohl(iphdr->dest.addr) >> 24 & 0xff,
-                    ntohl(iphdr->dest.addr) >> 16 & 0xff,
-                    ntohl(iphdr->dest.addr) >> 8 & 0xff,
-                    ntohl(iphdr->dest.addr) & 0xff));
+  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",
+                    ip4_addr1(&iphdr->dest),
+                    ip4_addr2(&iphdr->dest),
+                    ip4_addr3(&iphdr->dest),
+                    ip4_addr4(&iphdr->dest)));
   LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
 }
 #endif /* IP_DEBUG */
--- a/packages/net/lwip_tcpip/current/src/core/ipv4/ip_addr.c
+++ b/packages/net/lwip_tcpip/current/src/core/ipv4/ip_addr.c
@@ -60,9 +60,12 @@ u8_t ip_addr_isbroadcast(struct ip_addr 
   /* address matches network interface address exactly? => no broadcast */
   else if (addr->addr == netif->ip_addr.addr)
     return 0;
-  /* host identifier bits are all ones? => network broadcast address */
-  else if ((addr->addr & ~netif->netmask.addr) ==
-           (ip_addr_broadcast.addr & ~netif->netmask.addr))
+  /*  on the same (sub) network... */
+  else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
+         /* ...and host identifier bits are all ones? =>... */
+          && ((addr->addr & ~netif->netmask.addr) ==
+           (ip_addr_broadcast.addr & ~netif->netmask.addr)))
+    /* => network broadcast address */
     return 1;
   else
     return 0;
--- a/packages/net/lwip_tcpip/current/src/core/ipv4/ip_frag.c
+++ b/packages/net/lwip_tcpip/current/src/core/ipv4/ip_frag.c
@@ -1,3 +1,9 @@
+/* @file
+ * 
+ * This is the IP packet segmentation and reassembly implementation.
+ *
+ */
+
 /*
  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  * All rights reserved. 
@@ -31,20 +37,13 @@
  * 
  */
 
-
-/* ip_frag.c
- *
- * This is the code for IP segmentation and reassembly
- *
- */
-
+#include <string.h>
 
 #include "lwip/opt.h"
-#include "lwip/sys.h"
+/* #include "lwip/sys.h" */
 #include "lwip/ip.h"
 #include "lwip/ip_frag.h"
 #include "lwip/netif.h"
-
 #include "lwip/stats.h"
 
 
@@ -79,7 +78,7 @@ copy_from_pbuf(struct pbuf *p, u16_t * o
 #define IP_REASS_TMO 1000
 
 static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE];
-static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8)];
+static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8) + 1];
 static const u8_t bitmap_bits[8] = { 0xff, 0x7f, 0x3f, 0x1f,
   0x0f, 0x07, 0x03, 0x01
 };
@@ -89,18 +88,26 @@ static u8_t ip_reassflags;
 
 static u8_t ip_reasstmr;
 
-/* Reassembly timer */ 
-static void 
-ip_reass_timer(void *arg)
+/**
+ * Reassembly timer base function
+ * for both NO_SYS == 0 and 1 (!).
+ *
+ * Should be called every 1000 msec.
+ */
+void
+ip_reass_tmr(void)
 {
-  (void)arg;
-  if (ip_reasstmr > 1) {
+  if (ip_reasstmr > 0) {
     ip_reasstmr--;
-    sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);
-  } else if (ip_reasstmr == 1)
-  ip_reasstmr = 0;
+  }
 }
 
+/**
+ * Reassembles incoming IP fragments into an IP datagram.
+ *
+ * @param p points to a pbuf chain of the fragment
+ * @return NULL if reassembly is incomplete, ? otherwise
+ */
 struct pbuf *
 ip_reass(struct pbuf *p)
 {
@@ -120,7 +127,6 @@ ip_reass(struct pbuf *p)
     LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: new packet\n"));
     memcpy(iphdr, fraghdr, IP_HLEN);
     ip_reasstmr = IP_REASS_MAXAGE;
-    sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);
     ip_reassflags = 0;
     /* Clear the bitmap. */
     memset(ip_reassbitmap, 0, sizeof(ip_reassbitmap));
@@ -132,7 +138,8 @@ ip_reass(struct pbuf *p)
   if (ip_addr_cmp(&iphdr->src, &fraghdr->src) &&
       ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&
       IPH_ID(iphdr) == IPH_ID(fraghdr)) {
-    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n"));
+    LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n",
+      ntohs(IPH_ID(fraghdr))));
     IPFRAG_STATS_INC(ip_frag.cachehit);
     /* Find out the offset in the reassembly buffer where we should
        copy the fragment. */
@@ -143,9 +150,8 @@ ip_reass(struct pbuf *p)
        reassembly buffer, we discard the entire packet. */
     if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {
       LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
+       ("ip_reass: fragment outside of buffer (%"S16_F":%"S16_F"/%"S16_F").\n", offset,
         offset + len, IP_REASS_BUFSIZE));
-      sys_untimeout(ip_reass_timer, NULL);
       ip_reasstmr = 0;
       goto nullreturn;
     }
@@ -153,7 +159,7 @@ ip_reass(struct pbuf *p)
     /* Copy the fragment into the reassembly buffer, at the right
        offset. */
     LWIP_DEBUGF(IP_REASS_DEBUG,
-     ("ip_reass: copying with offset %d into %d:%d\n", offset,
+     ("ip_reass: copying with offset %"S16_F" into %"S16_F":%"S16_F"\n", offset,
       IP_HLEN + offset, IP_HLEN + offset + len));
     i = IPH_HL(fraghdr) * 4;
     copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);
@@ -162,24 +168,29 @@ ip_reass(struct pbuf *p)
     if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
       LWIP_DEBUGF(IP_REASS_DEBUG,
        ("ip_reass: updating single byte in bitmap.\n"));
-      /* If the two endpoints are in the same byte, we only update
-         that byte. */
+      /* If the two endpoints are in the same byte, we only update that byte. */
+      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",
+                   offset / (8 * 8) < sizeof(ip_reassbitmap));
       ip_reassbitmap[offset / (8 * 8)] |=
-    bitmap_bits[(offset / 8) & 7] &
-    ~bitmap_bits[((offset + len) / 8) & 7];
+        bitmap_bits[(offset / 8) & 7] &
+        ~bitmap_bits[((offset + len) / 8) & 7];
     } else {
       /* If the two endpoints are in different bytes, we update the
          bytes in the endpoints and fill the stuff inbetween with
          0xff. */
+      LWIP_ASSERT("offset / (8 * 8) < sizeof(ip_reassbitmap)",
+                   offset / (8 * 8) < sizeof(ip_reassbitmap));
       ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
       LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: updating many bytes in bitmap (%d:%d).\n",
+       ("ip_reass: updating many bytes in bitmap (%"S16_F":%"S16_F").\n",
         1 + offset / (8 * 8), (offset + len) / (8 * 8)));
       for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
-  ip_reassbitmap[i] = 0xff;
+        ip_reassbitmap[i] = 0xff;
       }
+      LWIP_ASSERT("(offset + len) / (8 * 8) < sizeof(ip_reassbitmap)",
+                   (offset + len) / (8 * 8) < sizeof(ip_reassbitmap));
       ip_reassbitmap[(offset + len) / (8 * 8)] |=
-    ~bitmap_bits[((offset + len) / 8) & 7];
+        ~bitmap_bits[((offset + len) / 8) & 7];
     }
 
     /* If this fragment has the More Fragments flag set to zero, we
@@ -192,7 +203,7 @@ ip_reass(struct pbuf *p)
       ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
       ip_reasslen = offset + len;
       LWIP_DEBUGF(IP_REASS_DEBUG,
-       ("ip_reass: last fragment seen, total len %d\n",
+       ("ip_reass: last fragment seen, total len %"S16_F"\n",
         ip_reasslen));
     }
 
@@ -202,23 +213,27 @@ ip_reass(struct pbuf *p)
     if (ip_reassflags & IP_REASS_FLAG_LASTFRAG) {
       /* Check all bytes up to and including all but the last byte in
          the bitmap. */
+      LWIP_ASSERT("ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap)",
+                   ip_reasslen / (8 * 8) - 1 < sizeof(ip_reassbitmap));
       for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
-  if (ip_reassbitmap[i] != 0xff) {
-    LWIP_DEBUGF(IP_REASS_DEBUG,
-     ("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",
-      i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
-    goto nullreturn;
-  }
+        if (ip_reassbitmap[i] != 0xff) {
+          LWIP_DEBUGF(IP_REASS_DEBUG,
+           ("ip_reass: last fragment seen, bitmap %"S16_F"/%"S16_F" failed (%"X16_F")\n",
+            i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
+          goto nullreturn;
+        }
       }
       /* Check the last byte in the bitmap. It should contain just the
          right amount of bits. */
+      LWIP_ASSERT("ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap)",
+                   ip_reasslen / (8 * 8) < sizeof(ip_reassbitmap));
       if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=
-    (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
-  LWIP_DEBUGF(IP_REASS_DEBUG,
-         ("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
-    ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
-    ip_reassbitmap[ip_reasslen / (8 * 8)]));
-  goto nullreturn;
+        (u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
+         LWIP_DEBUGF(IP_REASS_DEBUG,
+          ("ip_reass: last fragment seen, bitmap %"S16_F" didn't contain %"X16_F" (%"X16_F")\n",
+        ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
+        ip_reassbitmap[ip_reasslen / (8 * 8)]));
+        goto nullreturn;
       }
 
       /* Pretend to be a "normal" (i.e., not fragmented) IP packet
@@ -233,27 +248,25 @@ ip_reass(struct pbuf *p)
       /* If we have come this far, we have a full packet in the
          buffer, so we allocate a pbuf and copy the packet into it. We
          also reset the timer. */
-      sys_untimeout(ip_reass_timer, NULL);
       ip_reasstmr = 0;
       pbuf_free(p);
       p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
       if (p != NULL) {
-  i = 0;
-  for (q = p; q != NULL; q = q->next) {
-    /* Copy enough bytes to fill this pbuf in the chain. The
-       available data in the pbuf is given by the q->len
-       variable. */
-    LWIP_DEBUGF(IP_REASS_DEBUG,
-     ("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",
-      &ip_reassbuf[i], i, q->payload,
-      q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
-    memcpy(q->payload, &ip_reassbuf[i],
-    q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
-    i += q->len;
-  }
-  IPFRAG_STATS_INC(ip_frag.fw);
+        i = 0;
+        for (q = p; q != NULL; q = q->next) {
+          /* Copy enough bytes to fill this pbuf in the chain. The
+             available data in the pbuf is given by the q->len variable. */
+          LWIP_DEBUGF(IP_REASS_DEBUG,
+           ("ip_reass: memcpy from %p (%"S16_F") to %p, %"S16_F" bytes\n",
+            (void *)&ip_reassbuf[i], i, q->payload,
+            q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
+          memcpy(q->payload, &ip_reassbuf[i],
+            q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
+          i += q->len;
+        }
+        IPFRAG_STATS_INC(ip_frag.fw);
       } else {
-  IPFRAG_STATS_INC(ip_frag.memerr);
+        IPFRAG_STATS_INC(ip_frag.memerr);
       }
       LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));
       return p;
@@ -270,9 +283,9 @@ nullreturn:
 static u8_t buf[MEM_ALIGN_SIZE(MAX_MTU)];
 
 /**
- * Fragment an IP packet if too large
+ * Fragment an IP datagram if too large for the netif.
  *
- * Chop the packet in mtu sized chunks and send them in order
+ * Chop the datagram in MTU sized chunks and send them in order
  * by using a fixed size static memory buffer (PBUF_ROM)
  */
 err_t 
@@ -291,10 +304,12 @@ ip_frag(struct pbuf *p, struct netif *ne
 
   /* Get a RAM based MTU sized pbuf */
   rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF);
+  if (rambuf == NULL) {
+    return ERR_MEM;
+  }
   rambuf->tot_len = rambuf->len = mtu;
   rambuf->payload = MEM_ALIGN((void *)buf);
 
-
   /* Copy the IP header in it */
   iphdr = rambuf->payload;
   memcpy(iphdr, p->payload, IP_HLEN);
@@ -335,11 +350,15 @@ ip_frag(struct pbuf *p, struct netif *ne
      * worked would make things simpler.
      */
     header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
-    pbuf_chain(header, rambuf);
-    netif->output(netif, header, dest);
-    IPFRAG_STATS_INC(ip_frag.xmit);
-    pbuf_free(header);
-
+    if (header != NULL) {
+      pbuf_chain(header, rambuf);
+      netif->output(netif, header, dest);
+      IPFRAG_STATS_INC(ip_frag.xmit);
+      pbuf_free(header);
+    } else {
+      pbuf_free(rambuf);      
+      return ERR_MEM;    
+    }
     left -= cop;
   }
   pbuf_free(rambuf);
--- a/packages/net/lwip_tcpip/current/src/core/mem.c
+++ b/packages/net/lwip_tcpip/current/src/core/mem.c
@@ -36,6 +36,7 @@
  *
  */
 
+#include <string.h>
 
 #include "lwip/arch.h"
 #include "lwip/opt.h"
@@ -300,7 +301,7 @@ mem_malloc(mem_size_t size)
       return (u8_t *)mem + SIZEOF_STRUCT_MEM;
     }    
   }
-  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %d bytes\n", (int)size));
+  LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
 #if MEM_STATS
   ++lwip_stats.mem.err;
 #endif /* MEM_STATS */  
--- a/packages/net/lwip_tcpip/current/src/core/memp.c
+++ b/packages/net/lwip_tcpip/current/src/core/memp.c
@@ -124,7 +124,7 @@ static sys_sem_t mutex;
 static int
 memp_sanity(void)
 {
-  int i, c;
+  s16_t i, c;
   struct memp *m, *n;
 
   for(i = 0; i < MEMP_MAX; i++) {
@@ -222,7 +222,7 @@ memp_malloc(memp_t type)
     mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
     return mem;
   } else {
-    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
+    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %"S16_F"\n", type));
 #if MEMP_STATS
     ++lwip_stats.memp[type].err;
 #endif /* MEMP_STATS */
--- a/packages/net/lwip_tcpip/current/src/core/netif.c
+++ b/packages/net/lwip_tcpip/current/src/core/netif.c
@@ -67,8 +67,7 @@ netif_add(struct netif *netif, struct ip
   err_t (* init)(struct netif *netif),
   err_t (* input)(struct pbuf *p, struct netif *netif))
 {
-  static int netifnum = 0;
-
+  static s16_t netifnum = 0;
   
 #if LWIP_DHCP
   /* netif not under DHCP control by default */
@@ -198,36 +197,44 @@ netif_set_ipaddr(struct netif *netif, st
   }
 #endif
   ip_addr_set(&(netif->ip_addr), ipaddr);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",
+#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
+  /** For Ethernet network interfaces, we would like to send a
+   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
+   *  to spontaneously cause other nodes to update an entry in their
+   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
+   */ 
+  etharp_query(netif, ipaddr, NULL);
+#endif
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
     netif->name[0], netif->name[1],
-    (unsigned int)(ntohl(netif->ip_addr.addr) >> 24 & 0xff),
-    (unsigned int)(ntohl(netif->ip_addr.addr) >> 16 & 0xff),
-    (unsigned int)(ntohl(netif->ip_addr.addr) >> 8 & 0xff),
-    (unsigned int)(ntohl(netif->ip_addr.addr) & 0xff)));
+    ip4_addr1(&netif->ip_addr),
+    ip4_addr2(&netif->ip_addr),
+    ip4_addr3(&netif->ip_addr),
+    ip4_addr4(&netif->ip_addr)));
 }
 
 void
 netif_set_gw(struct netif *netif, struct ip_addr *gw)
 {
   ip_addr_set(&(netif->gw), gw);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %u.%u.%u.%u\n",
-           netif->name[0], netif->name[1],
-           (unsigned int)(ntohl(netif->gw.addr) >> 24 & 0xff),
-           (unsigned int)(ntohl(netif->gw.addr) >> 16 & 0xff),
-           (unsigned int)(ntohl(netif->gw.addr) >> 8 & 0xff),
-           (unsigned int)(ntohl(netif->gw.addr) & 0xff)));
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    netif->name[0], netif->name[1],
+    ip4_addr1(&netif->gw),
+    ip4_addr2(&netif->gw),
+    ip4_addr3(&netif->gw),
+    ip4_addr4(&netif->gw)));
 }
 
 void
 netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
 {
   ip_addr_set(&(netif->netmask), netmask);
-  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %u.%u.%u.%u\n",
-           netif->name[0], netif->name[1],
-           (unsigned int)(ntohl(netif->netmask.addr) >> 24 & 0xff),
-           (unsigned int)(ntohl(netif->netmask.addr) >> 16 & 0xff),
-           (unsigned int)(ntohl(netif->netmask.addr) >> 8 & 0xff),
-           (unsigned int)(ntohl(netif->netmask.addr) & 0xff)));
+  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
+    netif->name[0], netif->name[1],
+    ip4_addr1(&netif->netmask),
+    ip4_addr2(&netif->netmask),
+    ip4_addr3(&netif->netmask),
+    ip4_addr4(&netif->netmask)));
 }
 
 void
@@ -238,6 +245,41 @@ netif_set_default(struct netif *netif)
            netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
 }
 
+/**
+ * Bring an interface up, available for processing
+ * traffic.
+ * 
+ * @note: Enabling DHCP on a down interface will make it come
+ * up once configured.
+ * 
+ * @see dhcp_start()
+ */ 
+void netif_set_up(struct netif *netif)
+{
+  netif->flags |= NETIF_FLAG_UP;
+}
+
+/**
+ * Ask if an interface is up
+ */ 
+u8_t netif_is_up(struct netif *netif)
+{
+  return (netif->flags & NETIF_FLAG_UP)?1:0;
+}
+
+/**
+ * Bring an interface down, disabling any traffic processing.
+ *
+ * @note: Enabling DHCP on a down interface will make it come
+ * up once configured.
+ * 
+ * @see dhcp_start()
+ */ 
+void netif_set_down(struct netif *netif)
+{
+  netif->flags &= ~NETIF_FLAG_UP;
+}
+
 void
 netif_init(void)
 {
--- a/packages/net/lwip_tcpip/current/src/core/pbuf.c
+++ b/packages/net/lwip_tcpip/current/src/core/pbuf.c
@@ -62,20 +62,18 @@
  *
  */
 
-#include "lwip/opt.h"
+#include <string.h>
 
+#include "lwip/opt.h"
 #include "lwip/stats.h"
-
 #include "lwip/def.h"
 #include "lwip/mem.h"
 #include "lwip/memp.h"
 #include "lwip/pbuf.h"
-
 #include "lwip/sys.h"
-
 #include "arch/perf.h"
 
-static u8_t pbuf_pool_memory[(PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf)))];
+static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))];
 
 #if !SYS_LIGHTWEIGHT_PROT
 static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;
@@ -102,8 +100,7 @@ pbuf_init(void)
   struct pbuf *p, *q = NULL;
   u16_t i;
 
-  pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
-  LWIP_ASSERT("pbuf_init: pool aligned", (mem_ptr_t)pbuf_pool % MEM_ALIGNMENT == 0);
+  pbuf_pool = (struct pbuf *)MEM_ALIGN(pbuf_pool_memory);
 
 #if PBUF_STATS
   lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
@@ -183,7 +180,7 @@ pbuf_pool_alloc(void)
 
 
 /**
- * Allocates a pbuf.
+ * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
  *
  * The actual memory allocated for the pbuf is determined by the
  * layer at which the pbuf is allocated and the requested size
@@ -217,7 +214,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, p
   struct pbuf *p, *q, *r;
   u16_t offset;
   s32_t rem_len; /* remaining length */
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u)\n", length));
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F")\n", length));
 
   /* determine header offset */
   offset = 0;
@@ -306,7 +303,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, p
     break;
   case PBUF_RAM:
     /* If pbuf is to be allocated in RAM, allocate memory for it. */
-    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + length + offset));
+    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + offset) + MEM_ALIGN_SIZE(length));
     if (p == NULL) {
       return NULL;
     }
@@ -319,7 +316,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, p
     LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
            ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
     break;
-  /* pbuf references existing (static constant) ROM payload? */
+  /* pbuf references existing (non-volatile static constant) ROM payload? */
   case PBUF_ROM:
   /* pbuf references existing (externally allocated) RAM payload? */
   case PBUF_REF:
@@ -341,7 +338,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, p
   }
   /* set reference count */
   p->ref = 1;
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u) == %p\n", length, (void *)p));
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
   return p;
 }
 
@@ -453,55 +450,60 @@ pbuf_realloc(struct pbuf *p, u16_t new_l
  *
  * The ->payload, ->tot_len and ->len fields are adjusted.
  *
- * @param hdr_size Number of bytes to increment header size which
+ * @param hdr_size_inc Number of bytes to increment header size which
  * increases the size of the pbuf. New space is on the front.
  * (Using a negative value decreases the header size.)
+ * If hdr_size_inc is 0, this function does nothing and returns succesful.
  *
  * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
  * the call will fail. A check is made that the increase in header size does
  * not move the payload pointer in front of the start of the buffer.
- * @return 1 on failure, 0 on success.
+ * @return non-zero on failure, zero on success.
  *
- * @note May not be called on a packet queue.
  */
 u8_t
-pbuf_header(struct pbuf *p, s16_t header_size)
+pbuf_header(struct pbuf *p, s16_t header_size_increment)
 {
   void *payload;
 
+  LWIP_ASSERT("p != NULL", p != NULL);
+  if ((header_size_increment == 0) || (p == NULL)) return 0;
+ 
   /* remember current payload pointer */
   payload = p->payload;
 
   /* pbuf types containing payloads? */
   if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {
     /* set new payload pointer */
-    p->payload = (u8_t *)p->payload - header_size;
+    p->payload = (u8_t *)p->payload - header_size_increment;
     /* boundary check fails? */
     if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
-      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p\n",
-        (u8_t *)p->payload,
-        (u8_t *)p + sizeof(struct pbuf)) );\
+      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
+        (void *)p->payload,
+        (void *)(p + 1)));\
       /* restore old payload pointer */
       p->payload = payload;
       /* bail out unsuccesfully */
       return 1;
     }
-  /* pbuf types refering to payloads? */
+  /* pbuf types refering to external payloads? */
   } else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {
     /* hide a header in the payload? */
-    if ((header_size < 0) && (header_size - p->len <= 0)) {
+    if ((header_size_increment < 0) && (header_size_increment - p->len <= 0)) {
       /* increase payload pointer */
-      p->payload = (u8_t *)p->payload - header_size;
+      p->payload = (u8_t *)p->payload - header_size_increment;
     } else {
       /* cannot expand payload to front (yet!)
        * bail out unsuccesfully */
       return 1;
     }
   }
-  LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", (void *)payload, (void *)p->payload, header_size) );
   /* modify pbuf length fields */
-  p->len += header_size;
-  p->tot_len += header_size;
+  p->len += header_size_increment;
+  p->tot_len += header_size_increment;
+
+  LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%"S16_F")\n",
+    (void *)payload, (void *)p->payload, header_size_increment));
 
   return 0;
 }
@@ -510,19 +512,20 @@ pbuf_header(struct pbuf *p, s16_t header
  * Dereference a pbuf chain or queue and deallocate any no-longer-used
  * pbufs at the head of this chain or queue.
  *
- * Decrements the pbuf reference count. If it reaches
- * zero, the pbuf is deallocated.
+ * Decrements the pbuf reference count. If it reaches zero, the pbuf is
+ * deallocated.
  *
  * For a pbuf chain, this is repeated for each pbuf in the chain,
  * up to the first pbuf which has a non-zero reference count after
- * decrementing. (This might de-allocate the whole chain.)
+ * decrementing. So, when all reference counts are one, the whole
+ * chain is free'd.
  *
  * @param pbuf The pbuf (chain) to be dereferenced.
  *
  * @return the number of pbufs that were de-allocated
  * from the head of the chain.
  *
- * @note MUST NOT be called on a packet queue.
+ * @note MUST NOT be called on a packet queue (Not verified to work yet).
  * @note the reference counter of a pbuf equals the number of pointers
  * that refer to the pbuf (or into the pbuf).
  *
@@ -581,7 +584,7 @@ pbuf_free(struct pbuf *p)
         p->len = p->tot_len = PBUF_POOL_BUFSIZE;
         p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
         PBUF_POOL_FREE(p);
-      /* a ROM or RAM referencing pbuf */
+      /* is this a ROM or RAM referencing pbuf? */
       } else if (p->flags == PBUF_FLAG_ROM || p->flags == PBUF_FLAG_REF) {
         memp_free(MEMP_PBUF, p);
       /* p->flags == PBUF_FLAG_RAM */
@@ -594,8 +597,8 @@ pbuf_free(struct pbuf *p)
     /* p->ref > 0, this pbuf is still referenced to */
     /* (and so the remaining pbufs in chain as well) */
     } else {
-      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.\n", (void *)p, (unsigned int)p->ref));
-      /* stop walking through chain */
+      LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, (u16_t)p->ref));
+      /* stop walking through the chain */
       p = NULL;
     }
   }
@@ -658,8 +661,8 @@ pbuf_cat(struct pbuf *h, struct pbuf *t)
 {
   struct pbuf *p;
 
-  LWIP_ASSERT("h != NULL", h != NULL);
-  LWIP_ASSERT("t != NULL", t != NULL);
+  LWIP_ASSERT("h != NULL (programmer violates API)", h != NULL);
+  LWIP_ASSERT("t != NULL (programmer violates API)", t != NULL);
   if ((h == NULL) || (t == NULL)) return;
 
   /* proceed to last pbuf of chain */
@@ -669,10 +672,14 @@ pbuf_cat(struct pbuf *h, struct pbuf *t)
   }
   /* { p is last pbuf of first h chain, p->next == NULL } */
   LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
+  LWIP_ASSERT("p->next == NULL", p->next == NULL);
   /* add total length of second chain to last pbuf total of first chain */
   p->tot_len += t->tot_len;
   /* chain last pbuf of head (p) with first of tail (t) */
   p->next = t;
+  /* p->next now references t, but the caller will drop its reference to t,
+   * so netto there is no change to the reference count of t.
+   */
 }
 
 /**
@@ -700,8 +707,8 @@ pbuf_chain(struct pbuf *h, struct pbuf *
   LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
 }
 
-/* For packet queueing. Note that queued packets must be dequeued first
- * before calling any pbuf functions. */
+/* For packet queueing. Note that queued packets MUST be dequeued first
+ * using pbuf_dequeue() before calling other pbuf_() functions. */
 #if ARP_QUEUEING
 /**
  * Add a packet to the end of a queue.
@@ -709,13 +716,22 @@ pbuf_chain(struct pbuf *h, struct pbuf *
  * @param q pointer to first packet on the queue
  * @param n packet to be queued
  *
+ * Both packets MUST be given, and must be different.
  */
 void
 pbuf_queue(struct pbuf *p, struct pbuf *n)
 {
-  LWIP_ASSERT("p != NULL", p != NULL);
-  LWIP_ASSERT("n != NULL", n != NULL);
-  if ((p == NULL) || (n == NULL)) return;
+#if PBUF_DEBUG /* remember head of queue */
+  struct pbuf *q = p;
+#endif
+  /* programmer stupidity checks */
+  LWIP_ASSERT("p == NULL in pbuf_queue: this indicates a programmer error\n", p != NULL);
+  LWIP_ASSERT("n == NULL in pbuf_queue: this indicates a programmer error\n", n != NULL);
+  LWIP_ASSERT("p == n in pbuf_queue: this indicates a programmer error\n", p != n);
+  if ((p == NULL) || (n == NULL) || (p == n)){
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_HALT | 3, ("pbuf_queue: programmer argument error\n"));
+    return;
+  }
 
   /* iterate through all packets on queue */
   while (p->next != NULL) {
@@ -728,26 +744,33 @@ pbuf_queue(struct pbuf *p, struct pbuf *
       /* make sure each packet is complete */
       LWIP_ASSERT("p->next != NULL", p->next != NULL);
       p = p->next;
-      /* { p->tot_len == p->len } => p is last pbuf of a packet */
+      /* { p->tot_len == p->len => p is last pbuf of a packet } */
     }
+    /* { p is last pbuf of a packet } */
+    /* proceed to next packet on queue */
 #endif
-    /* { p->tot_len == p->len } => p is last pbuf of a packet */
-    /* proceed to next packet on queue */
+    /* proceed to next pbuf */
     if (p->next != NULL) p = p->next;
   }
   /* { p->tot_len == p->len and p->next == NULL } ==>
    * { p is last pbuf of last packet on queue } */
   /* chain last pbuf of queue with n */
   p->next = n;
-  /* n is now referenced to one more time */
+  /* n is now referenced to by the (packet p in the) queue */
   pbuf_ref(n);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_queue: referencing queued packet %p\n", (void *)n));
+#if PBUF_DEBUG
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2,
+    ("pbuf_queue: newly queued packet %p sits after packet %p in queue %p\n",
+    (void *)n, (void *)p, (void *)q));
+#endif
 }
 
 /**
  * Remove a packet from the head of a queue.
  *
- * The caller MUST reference the remainder of the queue (as returned).
+ * The caller MUST reference the remainder of the queue (as returned). The
+ * caller MUST NOT call pbuf_ref() as it implicitly takes over the reference
+ * from p.
  * 
  * @param p pointer to first packet on the queue which will be dequeued.
  * @return first packet on the remaining queue (NULL if no further packets).
@@ -759,7 +782,7 @@ pbuf_dequeue(struct pbuf *p)
   struct pbuf *q;
   LWIP_ASSERT("p != NULL", p != NULL);
 
-  /* iterate through all pbufs in packet */
+  /* iterate through all pbufs in packet p */
   while (p->tot_len != p->len) {
     /* make sure invariant condition holds */
     LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
@@ -768,15 +791,16 @@ pbuf_dequeue(struct pbuf *p)
     p = p->next;
   }
   /* { p->tot_len == p->len } => p is the last pbuf of the first packet */
-  /* remember next packet on queue */
+  /* remember next packet on queue in q */
   q = p->next;
-  /* dequeue p from queue */
+  /* dequeue packet p from queue */
   p->next = NULL;
   /* any next packet on queue? */
   if (q != NULL) {
     /* although q is no longer referenced by p, it MUST be referenced by
-     * the caller, who is maintaining this packet queue */
-    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: at least one packet on queue, first %p\n", (void *)q));
+     * the caller, who is maintaining this packet queue. So, we do not call
+     * pbuf_free(q) here, resulting in an implicit pbuf_ref(q) for the caller. */
+    LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: first remaining packet on queue is %p\n", (void *)q));
   } else {
     LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: no further packets on queue\n"));
   }
@@ -797,7 +821,7 @@ pbuf_dequeue(struct pbuf *p)
  *
  * @note You MUST explicitly use p = pbuf_take(p);
  * The pbuf you give as argument, may have been replaced
- * by pbuf_take()!
+ * by a (differently located) copy through pbuf_take()!
  *
  * @note Any replaced pbufs will be freed through pbuf_free().
  * This may deallocate them if they become no longer referenced.
@@ -825,7 +849,9 @@ pbuf_take(struct pbuf *p)
       /* PBUF_POOL buffers are faster if we can use them */
       if (p->len <= PBUF_POOL_BUFSIZE) {
         q = pbuf_alloc(PBUF_RAW, p->len, PBUF_POOL);
-        if (q == NULL) LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOL\n"));
+        if (q == NULL) {
+          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOL\n"));
+        }
       } else {
         /* no replacement pbuf yet */
         q = NULL;
@@ -834,7 +860,9 @@ pbuf_take(struct pbuf *p)
       /* no (large enough) PBUF_POOL was available? retry with PBUF_RAM */
       if (q == NULL) {
         q = pbuf_alloc(PBUF_RAW, p->len, PBUF_RAM);
-        if (q == NULL) LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAM\n"));
+        if (q == NULL) {
+          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAM\n"));
+        }
       }
       /* replacement pbuf could be allocated? */
       if (q != NULL)
@@ -917,8 +945,10 @@ pbuf_dechain(struct pbuf *p)
     /* q is no longer referenced by p, free it */
     LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
     tail_gone = pbuf_free(q);
-    if (tail_gone > 0) LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,
-      ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
+    if (tail_gone > 0) {
+      LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,
+                  ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
+    }
     /* return remaining tail or NULL if deallocated */
   }
   /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
--- a/packages/net/lwip_tcpip/current/src/core/raw.c
+++ b/packages/net/lwip_tcpip/current/src/core/raw.c
@@ -1,6 +1,9 @@
 /**
  * @file
- * Raw Access module
+ * 
+ * Implementation of raw protocol PCBs for low-level handling of
+ * different types of protocols besides (or overriding) those
+ * already available in lwIP.
  *
  */
 /*
@@ -35,12 +38,7 @@
  *
  */
 
-
-/* raw.c
- *
- * The code for the Raw Access to the IP
- *
- */
+#include <string.h>
 
 #include "lwip/opt.h"
 
@@ -57,11 +55,10 @@
 #include "lwip/snmp.h"
 
 #if LWIP_RAW
-/* The list of RAW PCBs */
 
+/** The list of RAW PCBs */
 static struct raw_pcb *raw_pcbs = NULL;
 
-
 void
 raw_init(void)
 {
@@ -69,42 +66,54 @@ raw_init(void)
 }
 
 /**
- * Determine if in incoming IP packet is covered by a RAW pcb and
- * and process it if possible
+ * Determine if in incoming IP packet is covered by a RAW PCB
+ * and if so, pass it to a user-provided receive callback function.
  *
  * Given an incoming IP datagram (as a chain of pbufs) this function
- * finds a corresponding RAW PCB and
+ * finds a corresponding RAW PCB and calls the corresponding receive
+ * callback function.
  *
  * @param pbuf pbuf to be demultiplexed to a RAW PCB.
  * @param netif network interface on which the datagram was received.
- * @return 0 if packet is not eated (pbuf needs to be freed then)
- *         or 1 if the packet has been eaten (pbuf needs not to be freed
- *         then)
+ * @Return - 1 if the packet has been eaten by a RAW PCB receive
+ *           callback function. The caller MAY NOT not reference the
+ *           packet any longer, and MAY NOT call pbuf_free().
+ * @return - 0 if packet is not eaten (pbuf is still referenced by the
+ *           caller).
  *
  */
-int
+u8_t
 raw_input(struct pbuf *p, struct netif *inp)
 {
   struct raw_pcb *pcb;
   struct ip_hdr *iphdr;
-  int proto;
-  int rc = 0;
+  s16_t proto;
+  u8_t eaten = 0;
 
   iphdr = p->payload;
   proto = IPH_PROTO(iphdr);
 
-  for(pcb = raw_pcbs; pcb != NULL; pcb = pcb->next) {
+  pcb = raw_pcbs;
+  /* loop through all raw pcbs until the packet is eaten by one */
+  /* this allows multiple pcbs to match against the packet by design */
+  while ((eaten == 0) && (pcb != NULL)) {
     if (pcb->protocol == proto) {
-      if (pcb->recv) {
-        if (!pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)))
-          return 0;
+      /* receive callback function available? */
+      if (pcb->recv != NULL) {
+        /* the receive callback function did not eat the packet? */
+        if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0)
+        {
+          /* receive function ate the packet */
+          p = NULL;
+          eaten = 1;
+        }
       }
-      pbuf_free(p);
-      rc = 1;
-      break;
+      /* no receive callback function was set for this raw PCB */
+      /* drop the packet */
     }
+    pcb = pcb->next;
   }
-  return rc;
+  return eaten;
 }
 
 /**
@@ -116,7 +125,7 @@ raw_input(struct pbuf *p, struct netif *
  *
  * @return lwIP error code.
  * - ERR_OK. Successful. No error occured.
- * - ERR_USE. The specified ipaddr is already bound to by
+ * - ERR_USE. The specified IP address is already bound to by
  * another RAW PCB.
  *
  * @see raw_disconnect()
@@ -130,7 +139,7 @@ raw_bind(struct raw_pcb *pcb, struct ip_
 
 /**
  * Connect an RAW PCB. This function is required by upper layers
- * of lwip. Using the raw api you could use raw_send_to() instead
+ * of lwip. Using the raw api you could use raw_sendto() instead
  *
  * This will associate the RAW PCB with the remote address.
  *
@@ -139,7 +148,7 @@ raw_bind(struct raw_pcb *pcb, struct ip_
  *
  * @return lwIP error code
  *
- * @see raw_disconnect() and raw_send_to()
+ * @see raw_disconnect() and raw_sendto()
  */
 err_t
 raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)
@@ -150,14 +159,21 @@ raw_connect(struct raw_pcb *pcb, struct 
 
 
 /**
- * Set the callback function if a RAW packet with the pcb's protocol
- * is received. If the callback function returns a value unequal 0
- * the raw packet is "eaten" and not forwarded to any other raw pcb
- * including lwip itself
+ * Set the callback function for received packets that match the
+ * raw PCB's protocol and binding. 
+ * 
+ * The callback function MUST either
+ * - eat the packet by calling pbuf_free() and returning non-zero. The
+ *   packet will not be passed to other raw PCBs or other protocol layers.
+ * - not free the packet, and return zero. The packet will be matched
+ *   against further PCBs and/or forwarded to another protocol layers.
+ * 
+ * @return non-zero if the packet was free()d, zero if the packet remains
+ * available for others.
  */
 void
 raw_recv(struct raw_pcb *pcb,
-         int (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,
+         u8_t (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,
                       struct ip_addr *addr),
          void *recv_arg)
 {
@@ -168,25 +184,25 @@ raw_recv(struct raw_pcb *pcb,
 
 /**
  * Send the raw IP packet to the given address. Note that actually you cannot
- * modify the IP headers (this is inconsitent with the receive callback where
- * you actually get the IP headers), you can only specifiy the ip payload here.
- * It requires some more changes in LWIP. (there will be a raw_send() function
- * then)
+ * modify the IP headers (this is inconsistent with the receive callback where
+ * you actually get the IP headers), you can only specify the IP payload here.
+ * It requires some more changes in lwIP. (there will be a raw_send() function
+ * then.)
  *
  * @param pcb the raw pcb which to send
- * @param p the ip payload to send
- * @param ipaddr the destination address of the whole IP packet
+ * @param p the IP payload to send
+ * @param ipaddr the destination address of the IP packet
  *
  */
 err_t
-raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
+raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
 {
   err_t err;
   struct netif *netif;
   struct ip_addr *src_ip;
   struct pbuf *q; /* q will be sent down the stack */
   
-  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_send_to\n"));
+  LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_sendto\n"));
   
   /* not enough space to add an IP header to first pbuf in given p chain? */
   if (pbuf_header(p, IP_HLEN)) {
@@ -194,13 +210,13 @@ raw_send_to(struct raw_pcb *pcb, struct 
     q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
     /* new header pbuf could not be allocated? */
     if (q == NULL) {
-      LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_send_to: could not allocate header\n"));
+      LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_sendto: could not allocate header\n"));
       return ERR_MEM;
     }
     /* chain header q in front of given pbuf p */
     pbuf_chain(q, p);
     /* { first pbuf q points to header pbuf } */
-    LWIP_DEBUGF(RAW_DEBUG, ("raw_send_to: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
+    LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
   }  else {
     /* first pbuf q equals given pbuf */
     q = p;
@@ -208,10 +224,11 @@ raw_send_to(struct raw_pcb *pcb, struct 
   }
   
   if ((netif = ip_route(ipaddr)) == NULL) {
-    LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_send_to: No route to 0x%lx\n", ipaddr->addr));
+    LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr));
 #if RAW_STATS
     /*    ++lwip_stats.raw.rterr;*/
 #endif /* RAW_STATS */
+    /* free any temporary header pbuf allocated by pbuf_header() */
     if (q != p) {
       pbuf_free(q);
     }
@@ -240,14 +257,14 @@ raw_send_to(struct raw_pcb *pcb, struct 
  * Send the raw IP packet to the address given by raw_connect()
  *
  * @param pcb the raw pcb which to send
- * @param p the ip payload to send
- * @param ipaddr the destination address of the whole IP packet
+ * @param p the IP payload to send
+ * @param ipaddr the destination address of the IP packet
  *
  */
 err_t
 raw_send(struct raw_pcb *pcb, struct pbuf *p)
 {
-  return raw_send_to(pcb,p,&pcb->remote_ip);
+  return raw_sendto(pcb, p, &pcb->remote_ip);
 }
 
 /**
@@ -266,7 +283,7 @@ raw_remove(struct raw_pcb *pcb)
   if (raw_pcbs == pcb) {
     /* make list start at 2nd pcb */
     raw_pcbs = raw_pcbs->next;
-  /* pcb not 1st in list */
+    /* pcb not 1st in list */
   } else for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
     /* find pcb in raw_pcbs list */
     if (pcb2->next != NULL && pcb2->next == pcb) {
@@ -303,7 +320,6 @@ raw_new(u16_t proto) {
     pcb->next = raw_pcbs;
     raw_pcbs = pcb;
   }
-
   return pcb;
 }
 
--- a/packages/net/lwip_tcpip/current/src/core/stats.c
+++ b/packages/net/lwip_tcpip/current/src/core/stats.c
@@ -30,6 +30,7 @@
  *
  */
 
+#include <string.h>
 
 #include "lwip/opt.h"
 
@@ -52,48 +53,48 @@ void
 stats_display_proto(struct stats_proto *proto, char *name)
 {
   LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
-  LWIP_PLATFORM_DIAG(("xmit: %d\n\t", proto->xmit)); 
-  LWIP_PLATFORM_DIAG(("rexmit: %d\n\t", proto->rexmit)); 
-  LWIP_PLATFORM_DIAG(("recv: %d\n\t", proto->recv)); 
-  LWIP_PLATFORM_DIAG(("fw: %d\n\t", proto->fw)); 
-  LWIP_PLATFORM_DIAG(("drop: %d\n\t", proto->drop)); 
-  LWIP_PLATFORM_DIAG(("chkerr: %d\n\t", proto->chkerr)); 
-  LWIP_PLATFORM_DIAG(("lenerr: %d\n\t", proto->lenerr)); 
-  LWIP_PLATFORM_DIAG(("memerr: %d\n\t", proto->memerr)); 
-  LWIP_PLATFORM_DIAG(("rterr: %d\n\t", proto->rterr)); 
-  LWIP_PLATFORM_DIAG(("proterr: %d\n\t", proto->proterr)); 
-  LWIP_PLATFORM_DIAG(("opterr: %d\n\t", proto->opterr)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n\t", proto->err)); 
-  LWIP_PLATFORM_DIAG(("cachehit: %d\n", proto->cachehit)); 
+  LWIP_PLATFORM_DIAG(("xmit: %"S16_F"\n\t", proto->xmit)); 
+  LWIP_PLATFORM_DIAG(("rexmit: %"S16_F"\n\t", proto->rexmit)); 
+  LWIP_PLATFORM_DIAG(("recv: %"S16_F"\n\t", proto->recv)); 
+  LWIP_PLATFORM_DIAG(("fw: %"S16_F"\n\t", proto->fw)); 
+  LWIP_PLATFORM_DIAG(("drop: %"S16_F"\n\t", proto->drop)); 
+  LWIP_PLATFORM_DIAG(("chkerr: %"S16_F"\n\t", proto->chkerr)); 
+  LWIP_PLATFORM_DIAG(("lenerr: %"S16_F"\n\t", proto->lenerr)); 
+  LWIP_PLATFORM_DIAG(("memerr: %"S16_F"\n\t", proto->memerr)); 
+  LWIP_PLATFORM_DIAG(("rterr: %"S16_F"\n\t", proto->rterr)); 
+  LWIP_PLATFORM_DIAG(("proterr: %"S16_F"\n\t", proto->proterr)); 
+  LWIP_PLATFORM_DIAG(("opterr: %"S16_F"\n\t", proto->opterr)); 
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", proto->err)); 
+  LWIP_PLATFORM_DIAG(("cachehit: %"S16_F"\n", proto->cachehit)); 
 }
 
 void
 stats_display_pbuf(struct stats_pbuf *pbuf)
 {
   LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));
-  LWIP_PLATFORM_DIAG(("avail: %d\n\t", pbuf->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %d\n\t", pbuf->used)); 
-  LWIP_PLATFORM_DIAG(("max: %d\n\t", pbuf->max)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n\t", pbuf->err)); 
-  LWIP_PLATFORM_DIAG(("alloc_locked: %d\n\t", pbuf->alloc_locked)); 
-  LWIP_PLATFORM_DIAG(("refresh_locked: %d\n", pbuf->refresh_locked)); 
+  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", pbuf->avail)); 
+  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", pbuf->used)); 
+  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", pbuf->max)); 
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n\t", pbuf->err)); 
+  LWIP_PLATFORM_DIAG(("alloc_locked: %"S16_F"\n\t", pbuf->alloc_locked)); 
+  LWIP_PLATFORM_DIAG(("refresh_locked: %"S16_F"\n", pbuf->refresh_locked)); 
 }
 
 void
 stats_display_mem(struct stats_mem *mem, char *name)
 {
   LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));
-  LWIP_PLATFORM_DIAG(("avail: %d\n\t", mem->avail)); 
-  LWIP_PLATFORM_DIAG(("used: %d\n\t", mem->used)); 
-  LWIP_PLATFORM_DIAG(("max: %d\n\t", mem->max)); 
-  LWIP_PLATFORM_DIAG(("err: %d\n", mem->err));
+  LWIP_PLATFORM_DIAG(("avail: %"S16_F"\n\t", mem->avail)); 
+  LWIP_PLATFORM_DIAG(("used: %"S16_F"\n\t", mem->used)); 
+  LWIP_PLATFORM_DIAG(("max: %"S16_F"\n\t", mem->max)); 
+  LWIP_PLATFORM_DIAG(("err: %"S16_F"\n", mem->err));
   
 }
 
 void
 stats_display(void)
 {
-  int i;
+  s16_t i;
   char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",
 	  		"TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};
   stats_display_proto(&lwip_stats.link, "LINK");
--- a/packages/net/lwip_tcpip/current/src/core/sys.c
+++ b/packages/net/lwip_tcpip/current/src/core/sys.c
@@ -39,7 +39,7 @@
 
 struct sswt_cb
 {
-    int timeflag;
+    s16_t timeflag;
     sys_sem_t *psem;
 };
 
@@ -170,7 +170,7 @@ sys_timeout(u32_t msecs, sys_timeout_han
 
   timeouts = sys_arch_timeouts();
 
-  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n",
+  LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n",
     (void *)timeout, msecs, (void *)h, (void *)arg));
 
   LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
--- a/packages/net/lwip_tcpip/current/src/core/tcp.c
+++ b/packages/net/lwip_tcpip/current/src/core/tcp.c
@@ -41,6 +41,8 @@
  *
  */
 
+#include <string.h>
+
 #include "lwip/opt.h"
 #include "lwip/def.h"
 #include "lwip/mem.h"
@@ -120,6 +122,18 @@ tcp_close(struct tcp_pcb *pcb)
   LWIP_DEBUGF(TCP_DEBUG, ("\n"));
 #endif /* TCP_DEBUG */
   switch (pcb->state) {
+  case CLOSED:
+    /* Closing a pcb in the CLOSED state might seem erroneous,
+     * however, it is in this state once allocated and as yet unused
+     * and the user needs some way to free it should the need arise.
+     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
+     * or for a pcb that has been used and then entered the CLOSED state 
+     * is erroneous, but this should never happen as the pcb has in those cases
+     * been freed, and so any remaining handles are bogus. */
+    err = ERR_OK;
+    memp_free(MEMP_TCP_PCB, pcb);
+    pcb = NULL;
+    break;
   case LISTEN:
     err = ERR_OK;
     tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
@@ -223,14 +237,10 @@ err_t
 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
 {
   struct tcp_pcb *cpcb;
-#if SO_REUSE
-  int reuse_port_all_set = 1;
-#endif /* SO_REUSE */
 
   if (port == 0) {
     port = tcp_new_port();
   }
-#if SO_REUSE == 0
   /* Check if the address already is in use. */
   for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
       cpcb != NULL; cpcb = cpcb->next) {
@@ -252,107 +262,12 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_
       }
     }
   }
-#else /* SO_REUSE */
-  /* Search through list of PCB's in LISTEN state. 
-     
-  If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
-  or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to 
-  the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
-  But no two PCB's bound to same local port and same local address is valid.
-  
-  If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then 
-  all PCB's must have the SOF_REUSEPORT option set.
-  
-  When the two options aren't set and specified port is already bound, ERR_USE is returned saying that 
-  address is already in use. */
-  for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; cpcb != NULL; cpcb = cpcb->next) {
-    if(cpcb->local_port == port) {
-      if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
-        if(pcb->so_options & SOF_REUSEPORT) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in listening PCB's: SO_REUSEPORT set and same address.\n"));
-          reuse_port_all_set = (reuse_port_all_set && (cpcb->so_options & SOF_REUSEPORT));
-        }
-        else {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in listening PCB's: SO_REUSEPORT not set and same address.\n"));
-          return ERR_USE;
-        }
-      }
-      else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(cpcb->local_ip))) ||
-              (!ip_addr_isany(ipaddr) && ip_addr_isany(&(cpcb->local_ip)))) {
-        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in listening PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
-          return ERR_USE;
-        }      
-        else {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in listening PCB's SO_REUSEPORT or SO_REUSEADDR set and not the same address.\n"));
-        }     
-      }
-    }
-  }
-
-  /* Search through list of PCB's in a state in which they can accept or send data. Same decription as for 
-     PCB's in state LISTEN applies to this PCB's regarding the options SOF_REUSEADDR and SOF_REUSEPORT. */
-  for(cpcb = tcp_active_pcbs; cpcb != NULL; cpcb = cpcb->next) {
-    if(cpcb->local_port == port) {
-      if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
-        if(pcb->so_options & SOF_REUSEPORT) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in active PCB's SO_REUSEPORT set and same address.\n"));
-          reuse_port_all_set = (reuse_port_all_set && (cpcb->so_options & SOF_REUSEPORT));
-        }
-        else {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in active PCB's SO_REUSEPORT not set and same address.\n"));
-          return ERR_USE;
-        }
-      }
-      else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(cpcb->local_ip))) ||
-              (!ip_addr_isany(ipaddr) && ip_addr_isany(&(cpcb->local_ip)))) {
-        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in active PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
-          return ERR_USE;
-        }   
-        else {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in active PCB's SO_REUSEPORT or SO_REUSEADDR set and not the same address.\n"));
-        }        
-      }
-    }
-  }
-
-  /* Search through list of PCB's in TIME_WAIT state. If SO_REUSEADDR is set a bound combination [IP, port} 
-     can be rebound. The same applies when SOF_REUSEPORT is set. 
-     
-     If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then 
-     all PCB's must have the SOF_REUSEPORT option set.
-     
-     When the two options aren't set and specified port is already bound, ERR_USE is returned saying that 
-     address is already in use. */
-  for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) {
-    if(cpcb->local_port == port) {
-      if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
-        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in TIME_WAIT PCB's SO_REUSEPORT or SO_REUSEADDR not set and same address.\n"));
-          return ERR_USE;
-        }
-        else if(pcb->so_options & SOF_REUSEPORT) {
-          LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: in TIME_WAIT PCB's SO_REUSEPORT set and same address.\n"));
-          reuse_port_all_set = (reuse_port_all_set && (cpcb->so_options & SOF_REUSEPORT));
-        }
-      }
-    }
-  }
-
-  /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then 
-     {IP, port} can't be reused. */
-  if(!reuse_port_all_set) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: not all sockets have SO_REUSEPORT set.\n"));
-    return ERR_USE;
-  }
-#endif /* SO_REUSE */
 
   if (!ip_addr_isany(ipaddr)) {
     pcb->local_ip = *ipaddr;
   }
   pcb->local_port = port;
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %u\n", port));
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
   return ERR_OK;
 }
 #if LWIP_CALLBACK_API
@@ -430,9 +345,19 @@ tcp_recved(struct tcp_pcb *pcb, u16_t le
      * continue to transmit.
      */
     tcp_ack(pcb);
+  } 
+  else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) {
+    /* If we can send a window update such that there is a full
+     * segment available in the window, do so now.  This is sort of
+     * nagle-like in its goals, and tries to hit a compromise between
+     * sending acks each time the window is updated, and only sending
+     * window updates when a timer expires.  The "threshold" used
+     * above (currently TCP_WND/2) can be tuned to be more or less
+     * aggressive  */
+    tcp_ack_now(pcb);
   }
 
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %u bytes, wnd %u (%u).\n",
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
          len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
 }
 
@@ -486,7 +411,7 @@ tcp_connect(struct tcp_pcb *pcb, struct 
   err_t ret;
   u32_t iss;
 
-  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\n", port));
+  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
   if (ipaddr != NULL) {
     pcb->remote_ip = *ipaddr;
   } else {
@@ -545,7 +470,9 @@ tcp_slowtmr(void)
   /* Steps through all of the active PCBs. */
   prev = NULL;
   pcb = tcp_active_pcbs;
-  if (pcb == NULL) LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
+  if (pcb == NULL) {
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
+  }
   while (pcb != NULL) {
     LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
     LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
@@ -566,7 +493,7 @@ tcp_slowtmr(void)
       if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
 
         /* Time for a retransmission. */
-        LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n",
+        LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"U16_F" pcb->rto %"U16_F"\n",
           pcb->rtime, pcb->rto));
 
         /* Double retransmission time-out unless we are trying to
@@ -574,7 +501,6 @@ tcp_slowtmr(void)
         if (pcb->state != SYN_SENT) {
           pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
         }
-        tcp_rexmit(pcb);
         /* Reduce congestion window and ssthresh. */
         eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
         pcb->ssthresh = eff_wnd >> 1;
@@ -582,9 +508,12 @@ tcp_slowtmr(void)
           pcb->ssthresh = pcb->mss * 2;
         }
         pcb->cwnd = pcb->mss;
-        LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %u ssthresh %u\n",
+        LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F" ssthresh %"U16_F"\n",
                                 pcb->cwnd, pcb->ssthresh));
-      }
+ 
+        /* The following needs to be called AFTER cwnd is set to one mss - STJ */
+        tcp_rexmit_rto(pcb);
+     }
     }
     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
     if (pcb->state == FIN_WAIT_2) {
@@ -598,7 +527,7 @@ tcp_slowtmr(void)
    /* Check if KEEPALIVE should be sent */
    if((pcb->so_options & SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
       if((u32_t)(tcp_ticks - pcb->tmr) > (pcb->keepalive + TCP_MAXIDLE) / TCP_SLOW_INTERVAL)  {
-         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %u.%u.%u.%u.\n",
+         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
                                  ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
                                  ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
 
@@ -626,12 +555,19 @@ tcp_slowtmr(void)
     /* Check if this PCB has stayed too long in SYN-RCVD */
     if (pcb->state == SYN_RCVD) {
       if ((u32_t)(tcp_ticks - pcb->tmr) >
-   TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
+        TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
         ++pcb_remove;
         LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
       }
     }
 
+    /* Check if this PCB has stayed too long in LAST-ACK */
+    if (pcb->state == LAST_ACK) {
+      if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
+        ++pcb_remove;
+        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
+      }
+    }
 
     /* If the PCB should be removed, do it. */
     if (pcb_remove) {
@@ -786,7 +722,7 @@ tcp_seg_copy(struct tcp_seg *seg)
   if (cseg == NULL) {
     return NULL;
   }
-  memcpy((char *)cseg, (const char *)seg, sizeof(struct tcp_seg)); 
+  memcpy((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 
   pbuf_ref(cseg->p);
   return cseg;
 }
@@ -830,7 +766,7 @@ tcp_kill_prio(u8_t prio)
     }
   }
   if (inactive != NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n",
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
            (void *)inactive, inactivity));
     tcp_abort(inactive);
   }      
@@ -852,7 +788,7 @@ tcp_kill_timewait(void)
     }
   }
   if (inactive != NULL) {
-    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n",
+    LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
            (void *)inactive, inactivity));
     tcp_abort(inactive);
   }      
@@ -1084,16 +1020,16 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
 {
   LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|    %5u      |    %5u      | (src port, dest port)\n",
+  LWIP_DEBUGF(TCP_DEBUG, ("|    %5"U16_F"      |    %5"U16_F"      | (src port, dest port)\n",
          ntohs(tcphdr->src), ntohs(tcphdr->dest)));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|           %010lu          | (seq no)\n",
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (seq no)\n",
           ntohl(tcphdr->seqno)));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|           %010lu          | (ack no)\n",
+  LWIP_DEBUGF(TCP_DEBUG, ("|           %010"U32_F"          | (ack no)\n",
          ntohl(tcphdr->ackno)));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("| %2u |   |%u%u%u%u%u%u|     %5u     | (hdrlen, flags (",
+  LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" |   |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"|     %5"U16_F"     | (hdrlen, flags (",
        TCPH_HDRLEN(tcphdr),
          TCPH_FLAGS(tcphdr) >> 5 & 1,
          TCPH_FLAGS(tcphdr) >> 4 & 1,
@@ -1105,7 +1041,7 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
   tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
   LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04x     |     %5u     | (chksum, urgp)\n",
+  LWIP_DEBUGF(TCP_DEBUG, ("|    0x%04"X16_F"     |     %5"U16_F"     | (chksum, urgp)\n",
          ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
   LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
 }
@@ -1186,28 +1122,28 @@ tcp_debug_print_pcbs(void)
   struct tcp_pcb *pcb;
   LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
                        pcb->local_port, pcb->remote_port,
                        pcb->snd_nxt, pcb->rcv_nxt));
     tcp_debug_print_state(pcb->state);
   }    
   LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
   for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
                        pcb->local_port, pcb->remote_port,
                        pcb->snd_nxt, pcb->rcv_nxt));
     tcp_debug_print_state(pcb->state);
   }    
   LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
   for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
-    LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
+    LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
                        pcb->local_port, pcb->remote_port,
                        pcb->snd_nxt, pcb->rcv_nxt));
     tcp_debug_print_state(pcb->state);
   }    
 }
 
-int
+s16_t
 tcp_pcbs_sane(void)
 {
   struct tcp_pcb *pcb;
--- a/packages/net/lwip_tcpip/current/src/core/tcp_in.c
+++ b/packages/net/lwip_tcpip/current/src/core/tcp_in.c
@@ -97,12 +97,6 @@ tcp_input(struct pbuf *p, struct netif *
   u8_t hdrlen;
   err_t err;
 
-#if SO_REUSE
-  struct tcp_pcb *pcb_temp;
-  int reuse = 0;
-  int reuse_port = 0;
-#endif /* SO_REUSE */
-
   PERF_START;
 
   TCP_STATS_INC(tcp.recv);
@@ -117,7 +111,7 @@ tcp_input(struct pbuf *p, struct netif *
   /* remove header from payload */
   if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
     /* drop short packets */
-    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
     TCP_STATS_INC(tcp.lenerr);
     TCP_STATS_INC(tcp.drop);
     pbuf_free(p);
@@ -136,7 +130,7 @@ tcp_input(struct pbuf *p, struct netif *
   if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
       (struct ip_addr *)&(iphdr->dest),
       IP_PROTO_TCP, p->tot_len) != 0) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n",
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
         inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),
       IP_PROTO_TCP, p->tot_len)));
 #if TCP_DEBUG
@@ -169,16 +163,8 @@ tcp_input(struct pbuf *p, struct netif *
      for an active connection. */
   prev = NULL;
 
-#if SO_REUSE
-  pcb_temp = tcp_active_pcbs;
   
- again_1:
-  
-  /* Iterate through the TCP pcb list for a fully matching pcb */
-  for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */
   for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */
     LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
     LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
     LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
@@ -187,32 +173,6 @@ tcp_input(struct pbuf *p, struct netif *
        ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
 
-#if SO_REUSE
-      if(pcb->so_options & SOF_REUSEPORT) {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-        } else {
-          /* First PCB with this address */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n"));
-          reuse = 1;
-        }
-        
-        reuse_port = 1; 
-        p->ref++;
-        
-        /* We want to search on next socket after receiving */
-        pcb_temp = pcb->next;
-        
-        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref));
-      } else  {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-        }
-      }
-#endif /* SO_REUSE */
-
       /* Move this PCB to the front of the list so that subsequent
    lookups will be faster (we exploit locality in TCP segment
    arrivals). */
@@ -357,25 +317,9 @@ tcp_input(struct pbuf *p, struct netif *
     tcp_debug_print_state(pcb->state);
 #endif /* TCP_DEBUG */
 #endif /* TCP_INPUT_DEBUG */
-#if SO_REUSE
-    /* First socket should receive now */
-    if(reuse_port) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
-      reuse_port = 0;
       
-      /* We are searching connected sockets */
-      goto again_1;
-    }
-#endif /* SO_REUSE */
+  } else {
 
-  } else {
-#if SO_REUSE
-    if(reuse) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
-      pbuf_free(p);
-      goto end;
-    }
-#endif /* SO_REUSE */
     /* If no matching PCB was found, send a TCP RST (reset) to the
        sender. */
     LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
@@ -388,9 +332,7 @@ tcp_input(struct pbuf *p, struct netif *
     }
     pbuf_free(p);
   }
-#if SO_REUSE
- end:
-#endif /* SO_REUSE */
+
   LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
   PERF_STOP("tcp_input");
 }
@@ -417,7 +359,7 @@ tcp_listen_input(struct tcp_pcb_listen *
       &(iphdr->dest), &(iphdr->src),
       tcphdr->dest, tcphdr->src);
   } else if (flags & TCP_SYN) {
-    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
+    LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
     npcb = tcp_alloc(pcb->prio);
     /* If a new PCB could not be created (probably due to lack of memory),
        we don't do anything, but rely on the sender will retransmit the
@@ -503,12 +445,14 @@ tcp_process(struct tcp_pcb *pcb)
     /* First, determine if the reset is acceptable. */
     if (pcb->state == SYN_SENT) {
       if (ackno == pcb->snd_nxt) {
-  acceptable = 1;
+        acceptable = 1;
       }
     } else {
-      if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
-   TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
-  acceptable = 1;
+      /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
+          TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
+      */
+      if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
+        acceptable = 1;
       }
     }
 
@@ -519,9 +463,9 @@ tcp_process(struct tcp_pcb *pcb)
       pcb->flags &= ~TF_ACK_DELAY;
       return ERR_RST;
     } else {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
        seqno, pcb->rcv_nxt));
-      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
+      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
        seqno, pcb->rcv_nxt));
       return ERR_OK;
     }
@@ -534,10 +478,12 @@ tcp_process(struct tcp_pcb *pcb)
   /* Do different things depending on the TCP state. */
   switch (pcb->state) {
   case SYN_SENT:
-    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
+    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
      pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
+    /* received SYN ACK with expected sequence number? */
     if ((flags & TCP_ACK) && (flags & TCP_SYN)
         && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
+      pcb->snd_buf++;
       pcb->rcv_nxt = seqno + 1;
       pcb->lastack = ackno;
       pcb->snd_wnd = tcphdr->wnd;
@@ -545,7 +491,7 @@ tcp_process(struct tcp_pcb *pcb)
       pcb->state = ESTABLISHED;
       pcb->cwnd = pcb->mss;
       --pcb->snd_queuelen;
-      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
       rseg = pcb->unacked;
       pcb->unacked = rseg->next;
       tcp_seg_free(rseg);
@@ -558,14 +504,20 @@ tcp_process(struct tcp_pcb *pcb)
       TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
       tcp_ack(pcb);
     }
+    /* received ACK? possibly a half-open connection */
+    else if (flags & TCP_ACK) {
+      /* send a RST to bring the other side in a non-synchronized state. */
+      tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
+        tcphdr->dest, tcphdr->src);
+    }
     break;
   case SYN_RCVD:
     if (flags & TCP_ACK &&
        !(flags & TCP_RST)) {
-      if (TCP_SEQ_LT(pcb->lastack, ackno) &&
-          TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
+      /* expected ACK number? */
+      if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
         pcb->state = ESTABLISHED;
-        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
 #if LWIP_CALLBACK_API
         LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
 #endif
@@ -582,6 +534,12 @@ tcp_process(struct tcp_pcb *pcb)
         tcp_receive(pcb);
         pcb->cwnd = pcb->mss;
       }
+      /* incorrect ACK number */
+      else {
+        /* send RST */
+        tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
+          tcphdr->dest, tcphdr->src);
+      }
     }
     break;
   case CLOSE_WAIT:
@@ -598,15 +556,15 @@ tcp_process(struct tcp_pcb *pcb)
     if (flags & TCP_FIN) {
       if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
         LWIP_DEBUGF(TCP_DEBUG,
-         ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
-  tcp_ack_now(pcb);
-  tcp_pcb_purge(pcb);
-  TCP_RMV(&tcp_active_pcbs, pcb);
-  pcb->state = TIME_WAIT;
-  TCP_REG(&tcp_tw_pcbs, pcb);
+          ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+        tcp_ack_now(pcb);
+        tcp_pcb_purge(pcb);
+        TCP_RMV(&tcp_active_pcbs, pcb);
+        pcb->state = TIME_WAIT;
+        TCP_REG(&tcp_tw_pcbs, pcb);
       } else {
-  tcp_ack_now(pcb);
-  pcb->state = CLOSING;
+        tcp_ack_now(pcb);
+        pcb->state = CLOSING;
       }
     } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
       pcb->state = FIN_WAIT_2;
@@ -615,7 +573,7 @@ tcp_process(struct tcp_pcb *pcb)
   case FIN_WAIT_2:
     tcp_receive(pcb);
     if (flags & TCP_FIN) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
       tcp_ack_now(pcb);
       tcp_pcb_purge(pcb);
       TCP_RMV(&tcp_active_pcbs, pcb);
@@ -626,7 +584,7 @@ tcp_process(struct tcp_pcb *pcb)
   case CLOSING:
     tcp_receive(pcb);
     if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
       tcp_ack_now(pcb);
       tcp_pcb_purge(pcb);
       TCP_RMV(&tcp_active_pcbs, pcb);
@@ -637,7 +595,7 @@ tcp_process(struct tcp_pcb *pcb)
   case LAST_ACK:
     tcp_receive(pcb);
     if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
-      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
+      LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
       pcb->state = CLOSED;
       recv_flags = TF_CLOSED;
     }
@@ -645,7 +603,6 @@ tcp_process(struct tcp_pcb *pcb)
   default:
     break;
   }
-
   return ERR_OK;
 }
 
@@ -670,8 +627,9 @@ tcp_receive(struct tcp_pcb *pcb)
 #endif
   struct pbuf *p;
   s32_t off;
-  int m;
+  s16_t m;
   u32_t right_wnd_edge;
+  u16_t new_tot_len;
 
 
   if (flags & TCP_ACK) {
@@ -684,11 +642,11 @@ tcp_receive(struct tcp_pcb *pcb)
       pcb->snd_wnd = tcphdr->wnd;
       pcb->snd_wl1 = seqno;
       pcb->snd_wl2 = ackno;
-      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd));
+      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U32_F"\n", pcb->snd_wnd));
 #if TCP_WND_DEBUG
     } else {
       if (pcb->snd_wnd != tcphdr->wnd) {
-        LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",
+        LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %"U32_F" snd_max %"U32_F" ackno %"U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
                                pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
       }
 #endif /* TCP_WND_DEBUG */
@@ -699,43 +657,50 @@ tcp_receive(struct tcp_pcb *pcb)
       pcb->acked = 0;
 
       if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
-  ++pcb->dupacks;
-  if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
-    if (!(pcb->flags & TF_INFR)) {
-      /* This is fast retransmit. Retransmit the first unacked segment. */
-      LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n",
-          (unsigned int)pcb->dupacks, pcb->lastack,
-          ntohl(pcb->unacked->tcphdr->seqno)));
-      tcp_rexmit(pcb);
-      /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
-      pcb->ssthresh = LWIP_MAX((pcb->snd_max -
-          pcb->lastack) / 2,
-         2 * pcb->mss);
+        ++pcb->dupacks;
+        if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
+          if (!(pcb->flags & TF_INFR)) {
+            /* This is fast retransmit. Retransmit the first unacked segment. */
+            LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n",
+                                       (u16_t)pcb->dupacks, pcb->lastack,
+                                       ntohl(pcb->unacked->tcphdr->seqno)));
+            tcp_rexmit(pcb);
+            /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
+            /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
+                                      pcb->lastack) / 2,
+                                      2 * pcb->mss);*/
+            /* Set ssthresh to half of the minimum of the currenct cwnd and the advertised window */
+            if(pcb->cwnd > pcb->snd_wnd)
+              pcb->ssthresh = pcb->snd_wnd / 2;
+            else
+              pcb->ssthresh = pcb->cwnd / 2;
 
-      pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
-      pcb->flags |= TF_INFR;
-    } else {
-      /* Inflate the congestion window, but not if it means that
-         the value overflows. */
-      if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
-        pcb->cwnd += pcb->mss;
+            pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
+            pcb->flags |= TF_INFR;
+          } else {
+            /* Inflate the congestion window, but not if it means that
+               the value overflows. */
+            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+              pcb->cwnd += pcb->mss;
+            }
+          }
+        }
+      } else {
+        LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",
+                                   pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
       }
-    }
-  }
-      } else {
-  LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
-            pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
-      }
-    } else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
-              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
+    } else
+      /*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
+        TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */
+      if(TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
       /* We come here when the ACK acknowledges new data. */
-
+      
       /* Reset the "IN Fast Retransmit" flag, since we are no longer
          in fast retransmit. Also reset the congestion window to the
          slow start threshold. */
       if (pcb->flags & TF_INFR) {
-  pcb->flags &= ~TF_INFR;
-  pcb->cwnd = pcb->ssthresh;
+        pcb->flags &= ~TF_INFR;
+        pcb->cwnd = pcb->ssthresh;
       }
 
       /* Reset the number of retransmissions. */
@@ -746,6 +711,7 @@ tcp_receive(struct tcp_pcb *pcb)
 
       /* Update the send buffer space. */
       pcb->acked = ackno - pcb->lastack;
+
       pcb->snd_buf += pcb->acked;
 
       /* Reset the fast retransmit variables. */
@@ -756,86 +722,85 @@ tcp_receive(struct tcp_pcb *pcb)
          ssthresh). */
       if (pcb->state >= ESTABLISHED) {
         if (pcb->cwnd < pcb->ssthresh) {
-    if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
-      pcb->cwnd += pcb->mss;
-    }
-          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd));
+          if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+            pcb->cwnd += pcb->mss;
+          }
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
         } else {
-    u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
-    if (new_cwnd > pcb->cwnd) {
-      pcb->cwnd = new_cwnd;
-    }
-          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));
+          u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
+          if (new_cwnd > pcb->cwnd) {
+            pcb->cwnd = new_cwnd;
+          }
+          LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
         }
       }
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n",
-                               ackno,
-                               pcb->unacked != NULL?
-                               ntohl(pcb->unacked->tcphdr->seqno): 0,
-                               pcb->unacked != NULL?
-                               ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
+                                    ackno,
+                                    pcb->unacked != NULL?
+                                    ntohl(pcb->unacked->tcphdr->seqno): 0,
+                                    pcb->unacked != NULL?
+                                    ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
 
       /* Remove segment from the unacknowledged list if the incoming
-   ACK acknowlegdes them. */
+         ACK acknowlegdes them. */
       while (pcb->unacked != NULL &&
-      TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
-      TCP_TCPLEN(pcb->unacked), ackno)) {
-  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
-         ntohl(pcb->unacked->tcphdr->seqno),
-         ntohl(pcb->unacked->tcphdr->seqno) +
-         TCP_TCPLEN(pcb->unacked)));
+             TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
+                         TCP_TCPLEN(pcb->unacked), ackno)) {
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
+                                      ntohl(pcb->unacked->tcphdr->seqno),
+                                      ntohl(pcb->unacked->tcphdr->seqno) +
+                                      TCP_TCPLEN(pcb->unacked)));
 
-  next = pcb->unacked;
-  pcb->unacked = pcb->unacked->next;
+        next = pcb->unacked;
+        pcb->unacked = pcb->unacked->next;
 
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
-  pcb->snd_queuelen -= pbuf_clen(next->p);
-  tcp_seg_free(next);
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
+        pcb->snd_queuelen -= pbuf_clen(next->p);
+        tcp_seg_free(next);
 
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen));
-  if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
-     pcb->unsent != NULL);
-  }
+        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
+        if (pcb->snd_queuelen != 0) {
+          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
+                      pcb->unsent != NULL);
+        }
       }
       pcb->polltmr = 0;
     }
 
-      /* We go through the ->unsent list to see if any of the segments
-         on the list are acknowledged by the ACK. This may seem
-         strange since an "unsent" segment shouldn't be acked. The
-         rationale is that lwIP puts all outstanding segments on the
-         ->unsent list after a retransmission, so these segments may
-         in fact have been sent once. */
-      while (pcb->unsent != NULL &&
-      TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
-                        ackno) &&
-      TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
-  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",
-         ntohl(pcb->unsent->tcphdr->seqno),
-         ntohl(pcb->unsent->tcphdr->seqno) +
-         TCP_TCPLEN(pcb->unsent)));
+    /* We go through the ->unsent list to see if any of the segments
+       on the list are acknowledged by the ACK. This may seem
+       strange since an "unsent" segment shouldn't be acked. The
+       rationale is that lwIP puts all outstanding segments on the
+       ->unsent list after a retransmission, so these segments may
+       in fact have been sent once. */
+    while (pcb->unsent != NULL &&
+           /*TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&
+             TCP_SEQ_LEQ(ackno, pcb->snd_max)*/
+           TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)
+           ) {
+      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
+                                    ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
+                                    TCP_TCPLEN(pcb->unsent)));
 
-  next = pcb->unsent;
-  pcb->unsent = pcb->unsent->next;
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
-  pcb->snd_queuelen -= pbuf_clen(next->p);
-  tcp_seg_free(next);
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen));
-  if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
-     pcb->unsent != NULL);
-  }
-
-        if (pcb->unsent != NULL) {
-          pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
-        }
+      next = pcb->unsent;
+      pcb->unsent = pcb->unsent->next;
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
+      pcb->snd_queuelen -= pbuf_clen(next->p);
+      tcp_seg_free(next);
+      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
+      if (pcb->snd_queuelen != 0) {
+        LWIP_ASSERT("tcp_receive: valid queue length",
+          pcb->unacked != NULL || pcb->unsent != NULL);
       }
 
+      if (pcb->unsent != NULL) {
+        pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
+      }
+    }
     /* End of ACK for new data processing. */
 
-    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\n",
-     pcb->rttest, pcb->rtseq, ackno));
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
+                                pcb->rttest, pcb->rtseq, ackno));
 
     /* RTT estimation calculations. This is done by checking if the
        incoming segment acknowledges the segment we use to take a
@@ -843,21 +808,21 @@ tcp_receive(struct tcp_pcb *pcb)
     if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
       m = tcp_ticks - pcb->rttest;
 
-      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u msec).\n",
-       m, m * TCP_SLOW_INTERVAL));
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
+                                  m, m * TCP_SLOW_INTERVAL));
 
       /* This is taken directly from VJs original code in his paper */
       m = m - (pcb->sa >> 3);
       pcb->sa += m;
       if (m < 0) {
-  m = -m;
+        m = -m;
       }
       m = m - (pcb->sv >> 2);
       pcb->sv += m;
       pcb->rto = (pcb->sa >> 3) + pcb->sv;
 
-      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %u (%u miliseconds)\n",
-           pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
+      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" miliseconds)\n",
+                                  pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
 
       pcb->rttest = 0;
     }
@@ -868,290 +833,314 @@ tcp_receive(struct tcp_pcb *pcb)
   if (tcplen > 0) {
     /* This code basically does three things:
 
-     +) If the incoming segment contains data that is the next
-        in-sequence data, this data is passed to the application. This
-        might involve trimming the first edge of the data. The rcv_nxt
-        variable and the advertised window are adjusted.
+    +) If the incoming segment contains data that is the next
+    in-sequence data, this data is passed to the application. This
+    might involve trimming the first edge of the data. The rcv_nxt
+    variable and the advertised window are adjusted.
 
-     +) If the incoming segment has data that is above the next
-        sequence number expected (->rcv_nxt), the segment is placed on
-        the ->ooseq queue. This is done by finding the appropriate
-        place in the ->ooseq queue (which is ordered by sequence
-        number) and trim the segment in both ends if needed. An
-        immediate ACK is sent to indicate that we received an
-        out-of-sequence segment.
+    +) If the incoming segment has data that is above the next
+    sequence number expected (->rcv_nxt), the segment is placed on
+    the ->ooseq queue. This is done by finding the appropriate
+    place in the ->ooseq queue (which is ordered by sequence
+    number) and trim the segment in both ends if needed. An
+    immediate ACK is sent to indicate that we received an
+    out-of-sequence segment.
 
-     +) Finally, we check if the first segment on the ->ooseq queue
-        now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
-        rcv_nxt > ooseq->seqno, we must trim the first edge of the
-        segment on ->ooseq before we adjust rcv_nxt. The data in the
-        segments that are now on sequence are chained onto the
-        incoming segment so that we only need to call the application
-        once.
+    +) Finally, we check if the first segment on the ->ooseq queue
+    now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
+    rcv_nxt > ooseq->seqno, we must trim the first edge of the
+    segment on ->ooseq before we adjust rcv_nxt. The data in the
+    segments that are now on sequence are chained onto the
+    incoming segment so that we only need to call the application
+    once.
     */
 
     /* First, we check if we must trim the first edge. We have to do
        this if the sequence number of the incoming segment is less
        than rcv_nxt, and the sequence number plus the length of the
        segment is larger than rcv_nxt. */
-    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
-      if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
-  /* Trimming the first edge is done by pushing the payload
-     pointer in the pbuf downwards. This is somewhat tricky since
-     we do not want to discard the full contents of the pbuf up to
-     the new starting point of the data since we have to keep the
-     TCP header which is present in the first pbuf in the chain.
-
-     What is done is really quite a nasty hack: the first pbuf in
-     the pbuf chain is pointed to by inseg.p. Since we need to be
-     able to deallocate the whole pbuf, we cannot change this
-     inseg.p pointer to point to any of the later pbufs in the
-     chain. Instead, we point the ->payload pointer in the first
-     pbuf to data in one of the later pbufs. We also set the
-     inseg.data pointer to point to the right place. This way, the
-     ->p pointer will still point to the first pbuf, but the
-     ->p->payload pointer will point to data in another pbuf.
-
-     After we are done with adjusting the pbuf pointers we must
-     adjust the ->data pointer in the seg and the segment
-     length.*/
-  off = pcb->rcv_nxt - seqno;
-  if (inseg.p->len < off) {
-    p = inseg.p;
-    while (p->len < off) {
-      off -= p->len;
-      inseg.p->tot_len -= p->len;
-      p->len = 0;
-      p = p->next;
+    /*    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
+          if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
+    if(TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno+1, seqno+tcplen-1)){
+      /* Trimming the first edge is done by pushing the payload
+         pointer in the pbuf downwards. This is somewhat tricky since
+         we do not want to discard the full contents of the pbuf up to
+         the new starting point of the data since we have to keep the
+         TCP header which is present in the first pbuf in the chain.
+         
+         What is done is really quite a nasty hack: the first pbuf in
+         the pbuf chain is pointed to by inseg.p. Since we need to be
+         able to deallocate the whole pbuf, we cannot change this
+         inseg.p pointer to point to any of the later pbufs in the
+         chain. Instead, we point the ->payload pointer in the first
+         pbuf to data in one of the later pbufs. We also set the
+         inseg.data pointer to point to the right place. This way, the
+         ->p pointer will still point to the first pbuf, but the
+         ->p->payload pointer will point to data in another pbuf.
+         
+         After we are done with adjusting the pbuf pointers we must
+         adjust the ->data pointer in the seg and the segment
+         length.*/
+      
+      off = pcb->rcv_nxt - seqno;
+      p = inseg.p;
+      if (inseg.p->len < off) {
+        new_tot_len = inseg.p->tot_len - off;
+        while (p->len < off) {
+          off -= p->len;
+          /* KJM following line changed (with addition of new_tot_len var)
+             to fix bug #9076
+             inseg.p->tot_len -= p->len; */
+          p->tot_len = new_tot_len;
+          p->len = 0;
+          p = p->next;
+        }
+        pbuf_header(p, -off);
+      } else {
+        pbuf_header(inseg.p, -off);
+      }
+      /* KJM following line changed to use p->payload rather than inseg->p->payload
+         to fix bug #9076 */
+      inseg.dataptr = p->payload;
+      inseg.len -= pcb->rcv_nxt - seqno;
+      inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
     }
-    pbuf_header(p, -off);
-  } else {
-    pbuf_header(inseg.p, -off);
-  }
-  inseg.dataptr = inseg.p->payload;
-  inseg.len -= pcb->rcv_nxt - seqno;
-  inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
-      }
-      else{
-  /* the whole segment is < rcv_nxt */
-  /* must be a duplicate of a packet that has already been correctly handled */
-
-  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
-  tcp_ack_now(pcb);
+    else{
+      if(TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
+        /* the whole segment is < rcv_nxt */
+        /* must be a duplicate of a packet that has already been correctly handled */
+        
+        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
+        tcp_ack_now(pcb);
       }
     }
 
     /* The sequence number must be within the window (above rcv_nxt
        and below rcv_nxt + rcv_wnd) in order to be further
        processed. */
-    if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
-       TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
+    /*if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
+      TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
+    if(TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)){
       if (pcb->rcv_nxt == seqno) {
-  /* The incoming segment is the next in sequence. We check if
+        /* The incoming segment is the next in sequence. We check if
            we have to trim the end of the segment and update rcv_nxt
            and pass the data to the application. */
 #if TCP_QUEUE_OOSEQ
-  if (pcb->ooseq != NULL &&
-     TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
-    /* We have to trim the second edge of the incoming
+        if (pcb->ooseq != NULL &&
+            TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
+          /* We have to trim the second edge of the incoming
              segment. */
-    inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
-    pbuf_realloc(inseg.p, inseg.len);
-  }
+          inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
+          pbuf_realloc(inseg.p, inseg.len);
+        }
 #endif /* TCP_QUEUE_OOSEQ */
 
-  tcplen = TCP_TCPLEN(&inseg);
-
-  pcb->rcv_nxt += tcplen;
+        tcplen = TCP_TCPLEN(&inseg);
 
-  /* Update the receiver's (our) window. */
-  if (pcb->rcv_wnd < tcplen) {
-    pcb->rcv_wnd = 0;
-  } else {
-    pcb->rcv_wnd -= tcplen;
-  }
+        /* First received FIN will be ACKed +1, on any successive (duplicate)
+         * FINs we are already in CLOSE_WAIT and have already done +1.
+         */
+        if (pcb->state != CLOSE_WAIT) {
+          pcb->rcv_nxt += tcplen;
+        }
+
+        /* Update the receiver's (our) window. */
+        if (pcb->rcv_wnd < tcplen) {
+          pcb->rcv_wnd = 0;
+        } else {
+          pcb->rcv_wnd -= tcplen;
+        }
 
-  /* If there is data in the segment, we make preparations to
-     pass this up to the application. The ->recv_data variable
-     is used for holding the pbuf that goes to the
-     application. The code for reassembling out-of-sequence data
-     chains its data on this pbuf as well.
+        /* If there is data in the segment, we make preparations to
+           pass this up to the application. The ->recv_data variable
+           is used for holding the pbuf that goes to the
+           application. The code for reassembling out-of-sequence data
+           chains its data on this pbuf as well.
 
-     If the segment was a FIN, we set the TF_GOT_FIN flag that will
-     be used to indicate to the application that the remote side has
-     closed its end of the connection. */
-  if (inseg.p->tot_len > 0) {
-    recv_data = inseg.p;
-    /* Since this pbuf now is the responsibility of the
-       application, we delete our reference to it so that we won't
-       (mistakingly) deallocate it. */
-    inseg.p = NULL;
-  }
-  if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
-    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
-    recv_flags = TF_GOT_FIN;
-  }
+           If the segment was a FIN, we set the TF_GOT_FIN flag that will
+           be used to indicate to the application that the remote side has
+           closed its end of the connection. */
+        if (inseg.p->tot_len > 0) {
+          recv_data = inseg.p;
+          /* Since this pbuf now is the responsibility of the
+             application, we delete our reference to it so that we won't
+             (mistakingly) deallocate it. */
+          inseg.p = NULL;
+        }
+        if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
+          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
+          recv_flags = TF_GOT_FIN;
+        }
 
 #if TCP_QUEUE_OOSEQ
-  /* We now check if we have segments on the ->ooseq queue that
+        /* We now check if we have segments on the ->ooseq queue that
            is now in sequence. */
-  while (pcb->ooseq != NULL &&
-        pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
+        while (pcb->ooseq != NULL &&
+               pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
 
-    cseg = pcb->ooseq;
-    seqno = pcb->ooseq->tcphdr->seqno;
+          cseg = pcb->ooseq;
+          seqno = pcb->ooseq->tcphdr->seqno;
 
-    pcb->rcv_nxt += TCP_TCPLEN(cseg);
-    if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
-      pcb->rcv_wnd = 0;
-    } else {
-      pcb->rcv_wnd -= TCP_TCPLEN(cseg);
-    }
-    if (cseg->p->tot_len > 0) {
-      /* Chain this pbuf onto the pbuf that we will pass to
-         the application. */
-      if (recv_data) {
+          pcb->rcv_nxt += TCP_TCPLEN(cseg);
+          if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
+            pcb->rcv_wnd = 0;
+          } else {
+            pcb->rcv_wnd -= TCP_TCPLEN(cseg);
+          }
+          if (cseg->p->tot_len > 0) {
+            /* Chain this pbuf onto the pbuf that we will pass to
+               the application. */
+            if (recv_data) {
               pbuf_cat(recv_data, cseg->p);
             } else {
-        recv_data = cseg->p;
-      }
-      cseg->p = NULL;
-    }
-    if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
-      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
-      recv_flags = TF_GOT_FIN;
-    }
+              recv_data = cseg->p;
+            }
+            cseg->p = NULL;
+          }
+          if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
+            LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
+            recv_flags = TF_GOT_FIN;
+          }
 
 
-    pcb->ooseq = cseg->next;
-    tcp_seg_free(cseg);
-  }
+          pcb->ooseq = cseg->next;
+          tcp_seg_free(cseg);
+        }
 #endif /* TCP_QUEUE_OOSEQ */
 
 
-  /* Acknowledge the segment(s). */
-  tcp_ack(pcb);
+        /* Acknowledge the segment(s). */
+        tcp_ack(pcb);
 
       } else {
-  /* We get here if the incoming segment is out-of-sequence. */
-  tcp_ack_now(pcb);
+        /* We get here if the incoming segment is out-of-sequence. */
+        tcp_ack_now(pcb);
 #if TCP_QUEUE_OOSEQ
-  /* We queue the segment on the ->ooseq queue. */
-  if (pcb->ooseq == NULL) {
-    pcb->ooseq = tcp_seg_copy(&inseg);
-  } else {
-    /* If the queue is not empty, we walk through the queue and
-    try to find a place where the sequence number of the
-    incoming segment is between the sequence numbers of the
-    previous and the next segment on the ->ooseq queue. That is
-    the place where we put the incoming segment. If needed, we
-    trim the second edges of the previous and the incoming
-    segment so that it will fit into the sequence.
+        /* We queue the segment on the ->ooseq queue. */
+        if (pcb->ooseq == NULL) {
+          pcb->ooseq = tcp_seg_copy(&inseg);
+        } else {
+          /* If the queue is not empty, we walk through the queue and
+             try to find a place where the sequence number of the
+             incoming segment is between the sequence numbers of the
+             previous and the next segment on the ->ooseq queue. That is
+             the place where we put the incoming segment. If needed, we
+             trim the second edges of the previous and the incoming
+             segment so that it will fit into the sequence.
 
-    If the incoming segment has the same sequence number as a
-    segment on the ->ooseq queue, we discard the segment that
-    contains less data. */
+             If the incoming segment has the same sequence number as a
+             segment on the ->ooseq queue, we discard the segment that
+             contains less data. */
 
-    prev = NULL;
-    for(next = pcb->ooseq; next != NULL; next = next->next) {
-      if (seqno == next->tcphdr->seqno) {
-        /* The sequence number of the incoming segment is the
+          prev = NULL;
+          for(next = pcb->ooseq; next != NULL; next = next->next) {
+            if (seqno == next->tcphdr->seqno) {
+              /* The sequence number of the incoming segment is the
                  same as the sequence number of the segment on
                  ->ooseq. We check the lengths to see which one to
                  discard. */
-        if (inseg.len > next->len) {
-    /* The incoming segment is larger than the old
+              if (inseg.len > next->len) {
+                /* The incoming segment is larger than the old
                    segment. We replace the old segment with the new
                    one. */
-    cseg = tcp_seg_copy(&inseg);
-    if (cseg != NULL) {
-      cseg->next = next->next;
-      if (prev != NULL) {
-        prev->next = cseg;
-      } else {
-        pcb->ooseq = cseg;
-      }
-    }
-    break;
-        } else {
-    /* Either the lenghts are the same or the incoming
+                cseg = tcp_seg_copy(&inseg);
+                if (cseg != NULL) {
+                  cseg->next = next->next;
+                  if (prev != NULL) {
+                    prev->next = cseg;
+                  } else {
+                    pcb->ooseq = cseg;
+                  }
+                }
+                break;
+              } else {
+                /* Either the lenghts are the same or the incoming
                    segment was smaller than the old one; in either
                    case, we ditch the incoming segment. */
-    break;
-        }
-      } else {
-        if (prev == NULL) {
-    if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
-      /* The sequence number of the incoming segment is lower
-         than the sequence number of the first segment on the
-         queue. We put the incoming segment first on the
-         queue. */
+                break;
+              }
+            } else {
+              if (prev == NULL) {
+                if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
+                  /* The sequence number of the incoming segment is lower
+                     than the sequence number of the first segment on the
+                     queue. We put the incoming segment first on the
+                     queue. */
 
-      if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-        /* We need to trim the incoming segment. */
-        inseg.len = next->tcphdr->seqno - seqno;
-        pbuf_realloc(inseg.p, inseg.len);
-      }
-      cseg = tcp_seg_copy(&inseg);
-      if (cseg != NULL) {
-        cseg->next = next;
-        pcb->ooseq = cseg;
-      }
-      break;
-    }
-        } else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
-     TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
-    /* The sequence number of the incoming segment is in
+                  if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
+                    /* We need to trim the incoming segment. */
+                    inseg.len = next->tcphdr->seqno - seqno;
+                    pbuf_realloc(inseg.p, inseg.len);
+                  }
+                  cseg = tcp_seg_copy(&inseg);
+                  if (cseg != NULL) {
+                    cseg->next = next;
+                    pcb->ooseq = cseg;
+                  }
+                  break;
+                }
+              } else 
+                /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
+                  TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/
+                if(TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)){
+                /* The sequence number of the incoming segment is in
                    between the sequence numbers of the previous and
                    the next segment on ->ooseq. We trim and insert the
                    incoming segment and trim the previous segment, if
                    needed. */
-    if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
-      /* We need to trim the incoming segment. */
-      inseg.len = next->tcphdr->seqno - seqno;
-      pbuf_realloc(inseg.p, inseg.len);
-    }
+                if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
+                  /* We need to trim the incoming segment. */
+                  inseg.len = next->tcphdr->seqno - seqno;
+                  pbuf_realloc(inseg.p, inseg.len);
+                }
 
-    cseg = tcp_seg_copy(&inseg);
-    if (cseg != NULL) {
-      cseg->next = next;
-      prev->next = cseg;
-      if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
-        /* We need to trim the prev segment. */
-        prev->len = seqno - prev->tcphdr->seqno;
-        pbuf_realloc(prev->p, prev->len);
-      }
-    }
-    break;
-    }
-        /* If the "next" segment is the last segment on the
+                cseg = tcp_seg_copy(&inseg);
+                if (cseg != NULL) {
+                  cseg->next = next;
+                  prev->next = cseg;
+                  if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
+                    /* We need to trim the prev segment. */
+                    prev->len = seqno - prev->tcphdr->seqno;
+                    pbuf_realloc(prev->p, prev->len);
+                  }
+                }
+                break;
+              }
+              /* If the "next" segment is the last segment on the
                  ooseq queue, we add the incoming segment to the end
                  of the list. */
-        if (next->next == NULL &&
-     TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
-    next->next = tcp_seg_copy(&inseg);
-    if (next->next != NULL) {
-      if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
-        /* We need to trim the last segment. */
-        next->len = seqno - next->tcphdr->seqno;
-        pbuf_realloc(next->p, next->len);
-      }
-    }
-    break;
+              if (next->next == NULL &&
+                  TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
+                next->next = tcp_seg_copy(&inseg);
+                if (next->next != NULL) {
+                  if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
+                    /* We need to trim the last segment. */
+                    next->len = seqno - next->tcphdr->seqno;
+                    pbuf_realloc(next->p, next->len);
+                  }
+                }
+                break;
+              }
+            }
+            prev = next;
+          }
         }
-      }
-      prev = next;
-    }
-  }
 #endif /* TCP_QUEUE_OOSEQ */
 
       }
+    } else {
+      /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
+        TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
+      if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
+        tcp_ack_now(pcb);
+      }
     }
   } else {
     /* Segments with length 0 is taken care of here. Segments that
        fall out of the window are ACKed. */
-    if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
-       TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
+    /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
+      TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
+    if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
       tcp_ack_now(pcb);
     }
   }
@@ -1185,7 +1174,7 @@ tcp_parseopt(struct tcp_pcb *pcb)
         ++c;
         /* NOP option. */
       } else if (opt == 0x02 &&
-                opts[c + 1] == 0x04) {
+        opts[c + 1] == 0x04) {
         /* An MSS option with the right option length. */
         mss = (opts[c + 2] << 8) | opts[c + 3];
         pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
--- a/packages/net/lwip_tcpip/current/src/core/tcp_out.c
+++ b/packages/net/lwip_tcpip/current/src/core/tcp_out.c
@@ -39,19 +39,17 @@
  *
  */
 
+#include <string.h>
+
 #include "lwip/def.h"
 #include "lwip/opt.h"
-
 #include "lwip/mem.h"
 #include "lwip/memp.h"
 #include "lwip/sys.h"
-
 #include "lwip/ip_addr.h"
 #include "lwip/netif.h"
-
 #include "lwip/inet.h"
 #include "lwip/tcp.h"
-
 #include "lwip/stats.h"
 
 #if LWIP_TCP
@@ -62,27 +60,33 @@ static void tcp_output_segment(struct tc
 err_t
 tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
 {
+  /* no data, no length, flags, copy=1, no optdata, no optdatalen */
   return tcp_enqueue(pcb, NULL, 0, flags, 1, NULL, 0);
-
 }
 
-/*
- * NB. tcp_write() enqueues data for sending, but does not send it
- * straight away.  It waits in the expectation of more data being sent
- * soon (as it can send them more efficiently by combining them
- * together).  To prompt the system to send data now, call
- * tcp_output() after calling tcp_write().
+/**
+ * Write data for sending (but does not send it immediately).
+ *
+ * It waits in the expectation of more data being sent soon (as
+ * it can send them more efficiently by combining them together).
+ * To prompt the system to send data now, call tcp_output() after
+ * calling tcp_write().
+ * 
+ * @arg pcb Protocol control block of the TCP connection to enqueue data for. 
+ * 
+ * @see tcp_write()
  */
 
 err_t
 tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
 {
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%u, copy=%d)\n", (void *)pcb,
-    arg, len, (unsigned int)copy));
-  if (pcb->state == SYN_SENT ||
-     pcb->state == SYN_RCVD ||
-     pcb->state == ESTABLISHED ||
-     pcb->state == CLOSE_WAIT) {
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb,
+    arg, len, (u16_t)copy));
+  /* connection is in valid state for data transmission? */
+  if (pcb->state == ESTABLISHED ||
+     pcb->state == CLOSE_WAIT ||
+     pcb->state == SYN_SENT ||
+     pcb->state == SYN_RCVD) {
     if (len > 0) {
       return tcp_enqueue(pcb, (void *)arg, len, 0, copy, NULL, 0);
     }
@@ -93,10 +97,24 @@ tcp_write(struct tcp_pcb *pcb, const voi
   }
 }
 
+/**
+ * Enqueue either data or TCP options (but not both) for tranmission
+ * 
+ * 
+ * 
+ * @arg pcb Protocol control block for the TCP connection to enqueue data for.
+ * @arg arg Pointer to the data to be enqueued for sending.
+ * @arg len Data length in bytes
+ * @arg flags
+ * @arg copy 1 if data must be copied, 0 if data is non-volatile and can be
+ * referenced.
+ * @arg optdata
+ * @arg optlen
+ */
 err_t
 tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
-      u8_t flags, u8_t copy,
-            u8_t *optdata, u8_t optlen)
+  u8_t flags, u8_t copy,
+  u8_t *optdata, u8_t optlen)
 {
   struct pbuf *p;
   struct tcp_seg *seg, *useg, *queue;
@@ -105,41 +123,46 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
   void *ptr;
   u8_t queuelen;
 
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%u, flags=%x, copy=%u)\n",
-    (void *)pcb, arg, len, (unsigned int)flags, (unsigned int)copy));
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n",
+    (void *)pcb, arg, len, (u16_t)flags, (u16_t)copy));
+  LWIP_ASSERT("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)",
+      len == 0 || optlen == 0);
+  LWIP_ASSERT("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)",
+      arg == NULL || optdata == NULL);
+  /* fail on too much data */
+  if (len > pcb->snd_buf) {
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
+    return ERR_MEM;
+  }
   left = len;
   ptr = arg;
-  /* fail on too much data */
-  if (len > pcb->snd_buf) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%u > snd_buf=%u)\n", len, pcb->snd_buf));
-    return ERR_MEM;
-  }
 
   /* seqno will be the sequence number of the first segment enqueued
    * by the call to this function. */
   seqno = pcb->snd_lbb;
 
-  queue = NULL;
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %u\n", (unsigned int)pcb->snd_queuelen));
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
 
-  /* Check if the queue length exceeds the configured maximum queue
-   * length. If so, we return an error. */
+  /* If total number of pbufs on the unsent/unacked queues exceeds the
+   * configured maximum, return an error */
   queuelen = pcb->snd_queuelen;
   if (queuelen >= TCP_SND_QUEUELEN) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %u (max %u)\n", queuelen, TCP_SND_QUEUELEN));
-    goto memerr;
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
+    TCP_STATS_INC(tcp.memerr);
+    return ERR_MEM;
   }
-
-  if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
-    pcb->unsent != NULL);
+  if (queuelen != 0) {
+    LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty",
+      pcb->unacked != NULL || pcb->unsent != NULL);
+  } else {
+    LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty",
+      pcb->unacked == NULL && pcb->unsent == NULL);
   }
 
-  seg = useg = NULL;
-  seglen = 0;
-
   /* First, break up the data into segments and tuck them together in
    * the local "queue" variable. */
+  useg = queue = seg = NULL;
+  seglen = 0;
   while (queue == NULL || left > 0) {
 
     /* The segment length should be the MSS if the data to be enqueued
@@ -155,20 +178,25 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
     seg->next = NULL;
     seg->p = NULL;
 
+    /* first segment of to-be-queued data? */
     if (queue == NULL) {
-      useg = queue = seg;
+      queue = seg;
     }
+    /* subsequent segments of to-be-queued data */
     else {
-      /* Attach the segment to the end of the queued segments. */
+      /* Attach the segment to the end of the queued segments */
       LWIP_ASSERT("useg != NULL", useg != NULL);
       useg->next = seg;
-      useg = seg;
     }
+    /* remember last segment of to-be-queued data for next iteration */
+    useg = seg;
 
     /* If copy is set, memory should be allocated
      * and data copied into pbuf, otherwise data comes from
      * ROM or other static memory, and need not be copied. If
      * optdata is != NULL, we have options instead of data. */
+     
+    /* options? */
     if (optdata != NULL) {
       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
         goto memerr;
@@ -176,9 +204,10 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
       ++queuelen;
       seg->dataptr = seg->p->payload;
     }
+    /* copy from volatile memory? */
     else if (copy) {
       if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
-        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %u\n", seglen));
+        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
         goto memerr;
       }
       ++queuelen;
@@ -189,8 +218,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
     }
     /* do not copy data */
     else {
-
-      /* first, allocate a pbuf for holding the data.
+      /* First, allocate a pbuf for holding the data.
        * since the referenced data is available at least until it is sent out on the
        * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM
        * instead of PBUF_REF here.
@@ -200,6 +228,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
         goto memerr;
       }
       ++queuelen;
+      /* reference the non-volatile payload data */
       p->payload = ptr;
       seg->dataptr = ptr;
 
@@ -214,28 +243,22 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
       ++queuelen;
 
       /* Concatenate the headers and data pbufs together. */
-      pbuf_cat(seg->p, p);
+      pbuf_cat(seg->p/*header*/, p/*data*/);
       p = NULL;
     }
 
     /* Now that there are more segments queued, we check again if the
     length of the queue exceeds the configured maximum. */
     if (queuelen > TCP_SND_QUEUELEN) {
-      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %u (%u)\n", queuelen, TCP_SND_QUEUELEN));
+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
       goto memerr;
     }
 
     seg->len = seglen;
-#if 0 /* Was commented out. TODO: can someone say why this is here? */
-    if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
-      ++seg->len;
-    }
-#endif
-    /* Build TCP header. */
+
+    /* build TCP header */
     if (pbuf_header(seg->p, TCP_HLEN)) {
-
       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
-
       TCP_STATS_INC(tcp.err);
       goto memerr;
     }
@@ -258,17 +281,16 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
        segments such as SYN|ACK. */
       memcpy(seg->dataptr, optdata, optlen);
     }
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE, ("tcp_enqueue: queueing %lu:%lu (0x%x)\n",
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n",
       ntohl(seg->tcphdr->seqno),
       ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
-      flags));
+      (u16_t)flags));
 
     left -= seglen;
     seqno += seglen;
-    ptr = (void *)((char *)ptr + seglen);
+    ptr = (void *)((u8_t *)ptr + seglen);
   }
 
-
   /* Now that the data to be enqueued has been broken up into TCP
   segments in the queue variable, we add them to the end of the
   pcb->unsent queue. */
@@ -278,6 +300,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
   else {
     for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
   }
+  /* { useg is last segment on the unsent queue, NULL if list is empty } */
 
   /* If there is room in the last pbuf on the unsent queue,
   chain the first pbuf on the queue together with that. */
@@ -285,24 +308,27 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
     TCP_TCPLEN(useg) != 0 &&
     !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
     !(flags & (TCP_SYN | TCP_FIN)) &&
+    /* fit within max seg size */
     useg->len + queue->len <= pcb->mss) {
-    /* Remove TCP header from first segment. */
+    /* Remove TCP header from first segment of our to-be-queued list */
     pbuf_header(queue->p, -TCP_HLEN);
     pbuf_cat(useg->p, queue->p);
     useg->len += queue->len;
     useg->next = queue->next;
 
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE | DBG_STATE, ("tcp_enqueue: chaining, new len %u\n", useg->len));
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | DBG_TRACE | DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
     if (seg == queue) {
       seg = NULL;
     }
     memp_free(MEMP_TCP_SEG, queue);
   }
   else {
+    /* empty list */
     if (useg == NULL) {
+      /* initialize list with this segment */
       pcb->unsent = queue;
-
     }
+    /* enqueue segment */
     else {
       useg->next = queue;
     }
@@ -311,13 +337,15 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
     ++len;
   }
   pcb->snd_lbb += len;
+
   pcb->snd_buf -= len;
+
+  /* update number of segments on the queues */
   pcb->snd_queuelen = queuelen;
-  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d (after enqueued)\n", pcb->snd_queuelen));
+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
   if (pcb->snd_queuelen != 0) {
-    LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
-      pcb->unsent != NULL);
-
+    LWIP_ASSERT("tcp_enqueue: valid queue length",
+      pcb->unacked != NULL || pcb->unsent != NULL);
   }
 
   /* Set the PSH flag in the last segment that we enqueued, but only
@@ -327,7 +355,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
   }
 
   return ERR_OK;
-  memerr:
+memerr:
   TCP_STATS_INC(tcp.memerr);
 
   if (queue != NULL) {
@@ -336,9 +364,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *a
   if (pcb->snd_queuelen != 0) {
     LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
       pcb->unsent != NULL);
-
   }
-  LWIP_DEBUGF(TCP_QLEN_DEBUG | DBG_STATE, ("tcp_enqueue: %d (with mem err)\n", pcb->snd_queuelen));
+  LWIP_DEBUGF(TCP_QLEN_DEBUG | DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
   return ERR_MEM;
 }
 
@@ -351,7 +378,7 @@ tcp_output(struct tcp_pcb *pcb)
   struct tcp_seg *seg, *useg;
   u32_t wnd;
 #if TCP_CWND_DEBUG
-  int i = 0;
+  s16_t i = 0;
 #endif /* TCP_CWND_DEBUG */
 
   /* First, check if we are invoked by the TCP input processing
@@ -364,7 +391,6 @@ tcp_output(struct tcp_pcb *pcb)
 
   wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
 
-
   seg = pcb->unsent;
 
   /* useg should point to last segment on unacked queue */
@@ -372,24 +398,24 @@ tcp_output(struct tcp_pcb *pcb)
   if (useg != NULL) {
     for (; useg->next != NULL; useg = useg->next);
   }                                                                             
-
    
-  /* If the TF_ACK_NOW flag is set, we check if there is data that is
-     to be sent. If data is to be sent out, we'll just piggyback our
-     acknowledgement with the outgoing segment. If no data will be
-     sent (either because the ->unsent queue is empty or because the
-     window doesn't allow it) we'll have to construct an empty ACK
-     segment and send it. */
+  /* If the TF_ACK_NOW flag is set and no data will be sent (either
+   * because the ->unsent queue is empty or because the window does
+   * not allow it), construct an empty ACK segment and send it.
+   *
+   * If data is to be sent, we will just piggyback the ACK (see below).
+   */
   if (pcb->flags & TF_ACK_NOW &&
      (seg == NULL ||
       ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
-    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
     p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
     if (p == NULL) {
       LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
       return ERR_BUF;
     }
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %lu\n", pcb->rcv_nxt));
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
+    /* remove ACK flags from the PCB, as we send an empty ACK now */
+    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
 
     tcphdr = p->payload;
     tcphdr->src = htons(pcb->local_port);
@@ -406,7 +432,6 @@ tcp_output(struct tcp_pcb *pcb)
     tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
           IP_PROTO_TCP, p->tot_len);
 #endif
-
     ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
         IP_PROTO_TCP);
     pbuf_free(p);
@@ -416,26 +441,26 @@ tcp_output(struct tcp_pcb *pcb)
 
 #if TCP_OUTPUT_DEBUG
   if (seg == NULL) {
-    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", pcb->unsent));
+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", (void*)pcb->unsent));
   }
 #endif /* TCP_OUTPUT_DEBUG */
 #if TCP_CWND_DEBUG
   if (seg == NULL) {
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, seg == NULL, ack %lu\n",
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", seg == NULL, ack %"U32_F"\n",
                             pcb->snd_wnd, pcb->cwnd, wnd,
                             pcb->lastack));
   } else {
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu\n",
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
                             pcb->snd_wnd, pcb->cwnd, wnd,
                             ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
                             ntohl(seg->tcphdr->seqno), pcb->lastack));
   }
 #endif /* TCP_CWND_DEBUG */
-
+  /* data available and window allows it to be sent? */
   while (seg != NULL &&
   ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
 #if TCP_CWND_DEBUG
-    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu, i%d\n",
+    LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
                             pcb->snd_wnd, pcb->cwnd, wnd,
                             ntohl(seg->tcphdr->seqno) + seg->len -
                             pcb->lastack,
@@ -458,13 +483,26 @@ tcp_output(struct tcp_pcb *pcb)
     /* put segment on unacknowledged list if length > 0 */
     if (TCP_TCPLEN(seg) > 0) {
       seg->next = NULL;
+      /* unacked list is empty? */
       if (pcb->unacked == NULL) {
         pcb->unacked = seg;
         useg = seg;
+      /* unacked list is not empty? */
       } else {
-        useg->next = seg;
-        useg = useg->next;
+        /* In the case of fast retransmit, the packet should not go to the tail
+         * of the unacked queue, but rather at the head. We need to check for
+         * this case. -STJ Jul 27, 2004 */
+        if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
+          /* add segment to head of unacked list */
+          seg->next = pcb->unacked;
+          pcb->unacked = seg;
+        } else {
+          /* add segment to tail of unacked list */
+          useg->next = seg;
+          useg = useg->next;
+        }
       }
+    /* do not queue empty segments on the unacked list */
     } else {
       tcp_seg_free(seg);
     }
@@ -473,6 +511,9 @@ tcp_output(struct tcp_pcb *pcb)
   return ERR_OK;
 }
 
+/**
+ * Actually send a TCP segment over IP
+ */
 static void
 tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
 {
@@ -507,9 +548,9 @@ tcp_output_segment(struct tcp_seg *seg, 
     pcb->rttest = tcp_ticks;
     pcb->rtseq = ntohl(seg->tcphdr->seqno);
 
-    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq));
+    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq));
   }
-  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n",
+  LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n",
           htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
           seg->len));
 
@@ -565,7 +606,37 @@ tcp_rst(u32_t seqno, u32_t ackno,
    /* Send output with hardcoded TTL since we have no access to the pcb */
   ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
   pbuf_free(p);
-  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %lu ackno %lu.\n", seqno, ackno));
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
+}
+
+/* requeue all unacked segments for retransmission */
+void
+tcp_rexmit_rto(struct tcp_pcb *pcb)
+{
+  struct tcp_seg *seg;
+
+  if (pcb->unacked == NULL) {
+    return;
+  }
+
+  /* Move all unacked segments to the head of the unsent queue */
+  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
+  /* concatenate unsent queue after unacked queue */
+  seg->next = pcb->unsent;
+  /* unsent queue is the concatenated queue (of unacked, unsent) */
+  pcb->unsent = pcb->unacked;
+  /* unacked queue is now empty */
+  pcb->unacked = NULL;
+
+  pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
+  /* increment number of retransmissions */
+  ++pcb->nrtx;
+
+  /* Don't take any RTT measurements after retransmitting. */
+  pcb->rttest = 0;
+
+  /* Do the actual retransmission */
+  tcp_output(pcb);
 }
 
 void
@@ -577,14 +648,11 @@ tcp_rexmit(struct tcp_pcb *pcb)
     return;
   }
 
-  /* Move all unacked segments to the unsent queue. */
-  for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
-
-  seg->next = pcb->unsent;
+  /* Move the first unacked segment to the unsent queue */
+  seg = pcb->unacked->next;
+  pcb->unacked->next = pcb->unsent;
   pcb->unsent = pcb->unacked;
-
-  pcb->unacked = NULL;
-
+  pcb->unacked = seg;
 
   pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
 
@@ -598,17 +666,18 @@ tcp_rexmit(struct tcp_pcb *pcb)
 
 }
 
+
 void
 tcp_keepalive(struct tcp_pcb *pcb)
 {
    struct pbuf *p;
    struct tcp_hdr *tcphdr;
 
-   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %u.%u.%u.%u\n",
+   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
                            ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
                            ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
 
-   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %ld   pcb->tmr %ld  pcb->keep_cnt %ld\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
+   LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F"   pcb->tmr %"U32_F"  pcb->keep_cnt %"U16_F"\n", tcp_ticks, pcb->tmr, pcb->keep_cnt));
    
    p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
 
@@ -637,7 +706,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
 
   pbuf_free(p);
 
-  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %lu ackno %lu.\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
+  LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", pcb->snd_nxt - 1, pcb->rcv_nxt));
 }
 
 #endif /* LWIP_TCP */
--- a/packages/net/lwip_tcpip/current/src/core/udp.c
+++ b/packages/net/lwip_tcpip/current/src/core/udp.c
@@ -42,6 +42,8 @@
  *
  */
 
+#include <string.h>
+
 #include "lwip/opt.h"
 
 #include "lwip/def.h"
@@ -64,7 +66,6 @@ struct udp_pcb *udp_pcbs = NULL;
 
 static struct udp_pcb *pcb_cache = NULL;
 
-
 void
 udp_init(void)
 {
@@ -86,16 +87,11 @@ udp_input(struct pbuf *p, struct netif *
 {
   struct udp_hdr *udphdr;
   struct udp_pcb *pcb;
+  struct udp_pcb *uncon_pcb;
   struct ip_hdr *iphdr;
   u16_t src, dest;
+  u8_t local_match;
 
-#if SO_REUSE
-  struct udp_pcb *pcb_temp;
-  int reuse = 0;
-  int reuse_port_1 = 0;
-  int reuse_port_2 = 0;
-#endif /* SO_REUSE */
-  
   PERF_START;
 
   UDP_STATS_INC(udp.recv);
@@ -104,7 +100,7 @@ udp_input(struct pbuf *p, struct netif *
 
   if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
     /* drop short packets */
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
     UDP_STATS_INC(udp.lenerr);
     UDP_STATS_INC(udp.drop);
     snmp_inc_udpinerrors();
@@ -114,7 +110,7 @@ udp_input(struct pbuf *p, struct netif *
 
   udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
 
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
 
   src = ntohs(udphdr->src);
   dest = ntohs(udphdr->dest);
@@ -122,117 +118,46 @@ udp_input(struct pbuf *p, struct netif *
   udp_debug_print(udphdr);
 
   /* print the UDP source and destination */
-  LWIP_DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
+  LWIP_DEBUGF(UDP_DEBUG, ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
     ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
     ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
     ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
     ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
 
-#if SO_REUSE
-  pcb_temp = udp_pcbs;
-  
- again_1:
-  
-  /* Iterate through the UDP pcb list for a fully matching pcb */
-  for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */ 
-  /* Iterate through the UDP pcb list for a fully matching pcb */
-  for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */ 
+  local_match = 0;
+  uncon_pcb = NULL;
+  /* Iterate through the UDP pcb list for a matching pcb */
+  for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
     /* print the PCB local and remote address */
-    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
+    LWIP_DEBUGF(UDP_DEBUG, ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
       ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
       ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
       ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
       ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
 
-       /* PCB remote port matches UDP source port? */
-    if ((pcb->remote_port == src) &&
-       /* PCB local port matches UDP destination port? */
-       (pcb->local_port == dest) &&
-       /* accepting from any remote (source) IP address? or... */
-       (ip_addr_isany(&pcb->remote_ip) ||
-       /* PCB remote IP address matches UDP source IP address? */
-        ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
-       /* accepting on any local (netif) IP address? or... */
+    /* compare PCB local addr+port to UDP destination addr+port */
+    if ((pcb->local_port == dest) &&
        (ip_addr_isany(&pcb->local_ip) ||
-       /* PCB local IP address matches UDP destination IP address? */
         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
-#if SO_REUSE
-      if(pcb->so_options & SOF_REUSEPORT) {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-        } else {
-          /* First PCB with this address */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
-          reuse = 1;
-        }
-        
-        reuse_port_1 = 1; 
-        p->ref++;
-        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
-      } else {
-        if(reuse) {
-          /* We processed one PCB already */
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-        }
-      }
-#endif /* SO_REUSE */
+       local_match = 1;
+       if ((uncon_pcb == NULL) && 
+           ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
+         /* the first unconnected matching PCB */     
+         uncon_pcb = pcb;
+       }
+    }
+    /* compare PCB remote addr+port to UDP source addr+port */
+    if ((local_match != 0) &&
+       (pcb->remote_port == src) &&
+       (ip_addr_isany(&pcb->remote_ip) ||
+       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) {
+       /* the first fully matching PCB */
       break;
     }
   }
   /* no fully matching pcb found? then look for an unconnected pcb */
   if (pcb == NULL) {
-    /* Iterate through the UDP PCB list for a pcb that matches
-       the local address. */
-
-#if SO_REUSE
-    pcb_temp = udp_pcbs;
-    
-  again_2:
-
-    for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
-#else  /* SO_REUSE */ 
-    for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
-#endif  /* SO_REUSE */ 
-      LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
-        ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
-        ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
-        ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
-        ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
-      /* unconnected? */
-      if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
-         /* destination port matches? */
-        (pcb->local_port == dest) &&
-        /* not bound to a specific (local) interface address? or... */
-        (ip_addr_isany(&pcb->local_ip) ||
-        /* ...matching interface address? */
-        ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
-#if SO_REUSE
-        if(pcb->so_options & SOF_REUSEPORT) {
-          if(reuse) {
-            /* We processed one PCB already */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
-          } else {
-            /* First PCB with this address */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
-            reuse = 1;
-          }
-          
-          reuse_port_2 = 1; 
-          p->ref++;
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
-        } else {
-          if(reuse) {
-            /* We processed one PCB already */
-            LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
-          }
-        }
-#endif /* SO_REUSE */
-        break;
-      }
-    }
+    pcb = uncon_pcb;
   }
 
   /* Check checksum if this is a match or if it was directed at us. */
@@ -278,34 +203,12 @@ udp_input(struct pbuf *p, struct netif *
     pbuf_header(p, -UDP_HLEN);
     if (pcb != NULL) {
       snmp_inc_udpindatagrams();
-      pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
-#if SO_REUSE
-      /* First socket should receive now */
-      if(reuse_port_1 || reuse_port_2) {
-        /* We want to search on next socket after receiving */
-        pcb_temp = pcb->next;
-        
-        if(reuse_port_1) {
-          /* We are searching connected sockets */
-          reuse_port_1 = 0;
-          reuse_port_2 = 0;
-          goto again_1;
+      /* callback */
+      if (pcb->recv != NULL)
+      {
+        pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
+      }
         } else {
-          /* We are searching unconnected sockets */
-          reuse_port_1 = 0;
-          reuse_port_2 = 0;
-          goto again_2;
-        }
-      }
-#endif /* SO_REUSE */ 
-    } else {
-#if SO_REUSE
-      if(reuse) {
-        LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
-        pbuf_free(p);
-        goto end;
-      }
-#endif /* SO_REUSE */
       LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
 
       /* No match was found, send ICMP destination port unreachable unless
@@ -354,9 +257,10 @@ udp_sendto(struct udp_pcb *pcb, struct p
   struct ip_addr *dst_ip, u16_t dst_port)
 {
   err_t err;
+  /* temporary space for current PCB remote address */
   struct ip_addr pcb_remote_ip;
   u16_t pcb_remote_port;
-  /* remember remote peer address of PCB */
+  /* remember current remote peer address of PCB */
   pcb_remote_ip.addr = pcb->remote_ip.addr;
   pcb_remote_port = pcb->remote_port;
   /* copy packet destination address to PCB remote peer address */
@@ -364,7 +268,7 @@ udp_sendto(struct udp_pcb *pcb, struct p
   pcb->remote_port = dst_port;
   /* send to the packet destination address */
   err = udp_send(pcb, p);
-  /* reset PCB remote peer address */
+  /* restore PCB remote peer address */
   pcb->remote_ip.addr = pcb_remote_ip.addr;
   pcb->remote_port = pcb_remote_port;
   return err;
@@ -403,6 +307,14 @@ udp_send(struct udp_pcb *pcb, struct pbu
       return err;
     }
   }
+  /* find the outgoing network interface for this packet */
+  netif = ip_route(&(pcb->remote_ip));
+  /* no outgoing network interface could be found? */
+  if (netif == NULL) {
+    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", pcb->remote_ip.addr));
+    UDP_STATS_INC(udp.rterr);
+    return ERR_RTE;
+  }
 
   /* not enough space to add an UDP header to first pbuf in given p chain? */
   if (pbuf_header(p, UDP_HLEN)) {
@@ -430,12 +342,6 @@ udp_send(struct udp_pcb *pcb, struct pbu
   /* in UDP, 0 checksum means 'no checksum' */
   udphdr->chksum = 0x0000; 
 
-  /* find the outgoing network interface for this packet */
-  if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
-    LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
-    UDP_STATS_INC(udp.rterr);
-    return ERR_RTE;
-  }
   /* PCB local address is IP_ANY_ADDR? */
   if (ip_addr_isany(&pcb->local_ip)) {
     /* use outgoing network interface IP address as source address */
@@ -445,11 +351,11 @@ udp_send(struct udp_pcb *pcb, struct pbu
     src_ip = &(pcb->local_ip);
   }
 
-  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
+  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
 
   /* UDP Lite protocol? */
   if (pcb->flags & UDP_FLAGS_UDPLITE) {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
     /* set UDP message length in UDP header */
     udphdr->len = htons(pcb->chksum_len);
     /* calculate checksum */
@@ -466,7 +372,7 @@ udp_send(struct udp_pcb *pcb, struct pbu
     err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);    
   /* UDP */
   } else {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
     udphdr->len = htons(q->tot_len);
     /* calculate checksum */
 #if CHECKSUM_GEN_UDP
@@ -478,7 +384,7 @@ udp_send(struct udp_pcb *pcb, struct pbu
 #else
     udphdr->chksum = 0x0000;
 #endif
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
+    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
     /* output to IP */
     err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    
@@ -517,12 +423,10 @@ udp_bind(struct udp_pcb *pcb, struct ip_
 {
   struct udp_pcb *ipcb;
   u8_t rebind;
-#if SO_REUSE
-  int reuse_port_all_set = 1;
-#endif /* SO_REUSE */
+
   LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
   ip_addr_debug_print(UDP_DEBUG, ipaddr);
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %u)\n", port));
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %"U16_F")\n", port));
 
   rebind = 0;
   /* Check for double bind and rebind of the same pcb */
@@ -535,7 +439,6 @@ udp_bind(struct udp_pcb *pcb, struct ip_
       rebind = 1;
     }
 
-#if SO_REUSE == 0
 /* this code does not allow upper layer to share a UDP port for
    listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
    SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
@@ -548,56 +451,13 @@ udp_bind(struct udp_pcb *pcb, struct ip_
        ip_addr_isany(ipaddr) ||
        ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
       /* other PCB already binds to this local IP and port */
-      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
+      LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
       return ERR_USE;
     }
 #endif
 
-#else /* SO_REUSE */
-      /* Search through list of PCB's. 
-         
-      If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
-      or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to 
-      the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
-      But no two PCB's bound to same local port and same local address is valid.
-      
-      If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then 
-      all PCB's must have the SOF_REUSEPORT option set.
-      
-      When the two options aren't set and specified port is already bound, ERR_USE is returned saying that 
-      address is already in use. */
-    else if (ipcb->local_port == port) {
-      if(ip_addr_cmp(&(ipcb->local_ip), ipaddr)) {
-        if(pcb->so_options & SOF_REUSEPORT) {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));
-          reuse_port_all_set = (reuse_port_all_set && (ipcb->so_options & SOF_REUSEPORT));
-        }
-        else {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
-          return ERR_USE;
-        }
-      }
-      else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(ipcb->local_ip))) ||
-              (!ip_addr_isany(ipaddr) && ip_addr_isany(&(ipcb->local_ip)))) {
-        if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
-          LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
-          return ERR_USE;
-        }           
-      }
-    }
-#endif /* SO_REUSE */
-
   }
 
-#if SO_REUSE
-  /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then 
-     {IP, port} can't be reused. */
-  if(!reuse_port_all_set) {
-    LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));
-    return ERR_USE;
-  }
-#endif /* SO_REUSE */
-
   ip_addr_set(&pcb->local_ip, ipaddr);
   /* no port specified? */
   if (port == 0) {
@@ -627,11 +487,11 @@ udp_bind(struct udp_pcb *pcb, struct ip_
     pcb->next = udp_pcbs;
     udp_pcbs = pcb;
   }
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
-   (unsigned int)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
+   (u16_t)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
+   (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
   return ERR_OK;
 }
 /**
@@ -680,11 +540,11 @@ udp_connect(struct udp_pcb *pcb, struct 
     pcb->local_ip.addr = 0;
   }
 #endif
-  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
-   (unsigned int)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
+  LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
+   (u16_t)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
+   (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
 
   /* Insert UDP PCB into the list of active UDP PCBs. */
   for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
@@ -769,18 +629,17 @@ udp_new(void) {
 }
 
 #if UDP_DEBUG
-int
+void
 udp_debug_print(struct udp_hdr *udphdr)
 {
   LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     %5u     | (src port, dest port)\n",
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",
          ntohs(udphdr->src), ntohs(udphdr->dest)));
   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  LWIP_DEBUGF(UDP_DEBUG, ("|     %5u     |     0x%04x    | (len, chksum)\n",
+  LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",
          ntohs(udphdr->len), ntohs(udphdr->chksum)));
   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
-  return 0;
 }
 #endif /* UDP_DEBUG */
 
--- a/packages/net/lwip_tcpip/current/src/ecos/init.c
+++ b/packages/net/lwip_tcpip/current/src/ecos/init.c
@@ -225,6 +225,7 @@ lwip_set_addr(struct netif *netif)
 
     netif_add(netif, &ipaddr, &netmask, &gw, netif->state, lwip_dummy_netif_init, tcpip_input);
     netif_set_default(netif);
+    netif_set_up(netif);        // new step from lwip 1.0.0
 #else
 	IP_ADDR(&gw, CYGDAT_LWIP_SERV_ADDR);
 	IP_ADDR(&ipaddr, CYGDAT_LWIP_MY_ADDR);
@@ -232,6 +233,7 @@ lwip_set_addr(struct netif *netif)
 
 	netif_add(netif, &ipaddr, &netmask, &gw, netif->state, lwip_dummy_netif_init, tcpip_input);
     netif_set_default(netif); 
+    netif_set_up(netif);        // new step from lwip 1.0.0
 #endif 
 }
 
@@ -306,8 +308,13 @@ ecosglue_init(void)
 {
     etharp_init();
     cyg_semaphore_init(&delivery, 0);
+    //
+    // start input thread before hardware drivers are initialized because
+    // init_hw_drivers() calls dhcp_init() if DHCP support is configured 
+    // and dhcp_init() requires a running input thread
+    //
+    sys_thread_new(input_thread, (void*)0, CYGNUM_LWIP_ETH_THREAD_PRIORITY);
     init_hw_drivers();
-    sys_thread_new(input_thread, (void*)0, CYGNUM_LWIP_ETH_THREAD_PRIORITY);
 }
 
 #endif //CYGPKG_LWIP_ETH
--- a/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c
+++ b/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c
@@ -255,7 +255,7 @@ sys_thread_t sys_thread_new(void (*funct
 			(char *)arg , stack, CYGNUM_LWIP_THREAD_STACK_SIZE, &(nt->th), &(nt->t) );
 
 	cyg_thread_resume(nt->th);
-	return NULL;
+	return nt->th;
 }
 
 /* 
--- a/packages/net/lwip_tcpip/current/src/netif/etharp.c
+++ b/packages/net/lwip_tcpip/current/src/netif/etharp.c
@@ -39,7 +39,7 @@
  * 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.
  *
  */
--- a/packages/net/lwip_tcpip/current/src/netif/loopif.c
+++ b/packages/net/lwip_tcpip/current/src/netif/loopif.c
@@ -58,7 +58,7 @@ loopif_output(struct netif *netif, struc
        struct ip_addr *ipaddr)
 {
   struct pbuf *q, *r;
-  char *ptr;
+  u8_t *ptr;
   void **arg;
 
 #if defined(LWIP_DEBUG) && defined(LWIP_TCPDUMP)
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/chap.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/chap.h
@@ -62,7 +62,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: chap.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: chap.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef CHAP_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/chpms.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/chpms.h
@@ -51,7 +51,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: chpms.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: chpms.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef CHPMS_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/fsm.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/fsm.h
@@ -48,7 +48,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: fsm.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: fsm.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef FSM_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.c
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.c
@@ -49,6 +49,8 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include <string.h>
+
 #include "ppp.h"
 #if PPP_SUPPORT > 0
 #include "auth.h"
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/ipcp.h
@@ -48,7 +48,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: ipcp.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: ipcp.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef IPCP_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/lcp.c
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/lcp.c
@@ -49,6 +49,9 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
+ 
+#include <string.h>
+ 
 #include "ppp.h"
 #if PPP_SUPPORT > 0
 #include "fsm.h"
@@ -1232,7 +1235,7 @@ static int lcp_reqci(fsm *f,
 			ho->neg_mru = 1;		/* Remember he sent MRU */
 			ho->mru = cishort;		/* And remember value */
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " MRU %d", cishort);
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort);
 			traceNdx = strlen(traceBuf);
 #endif
 			break;
@@ -1265,7 +1268,7 @@ static int lcp_reqci(fsm *f,
 			ho->neg_asyncmap = 1;
 			ho->asyncmap = cilong;
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " ASYNCMAP=%lX", cilong);
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong);
 			traceNdx = strlen(traceBuf);
 #endif
 			break;
@@ -1317,7 +1320,7 @@ static int lcp_reqci(fsm *f,
 				}
 				ho->neg_upap = 1;
 #if TRACELCP > 0
-				sprintf(&traceBuf[traceNdx], " PAP (%X)", cishort);
+				snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort);
 				traceNdx = strlen(traceBuf);
 #endif
 				break;
@@ -1355,7 +1358,7 @@ static int lcp_reqci(fsm *f,
 					break;
 				}
 #if TRACELCP > 0
-				sprintf(&traceBuf[traceNdx], " CHAP %X,%d", cishort, cichar);
+				snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, cichar);
 				traceNdx = strlen(traceBuf);
 #endif
 				ho->chap_mdtype = cichar; /* save md type */
@@ -1387,7 +1390,7 @@ static int lcp_reqci(fsm *f,
 			GETSHORT(cishort, p);
 			GETLONG(cilong, p);
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " QUALITY (%x %x)", cishort, (unsigned int) cilong);
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong);
 			traceNdx = strlen(traceBuf);
 #endif
 
@@ -1419,7 +1422,7 @@ static int lcp_reqci(fsm *f,
 			}
 			GETLONG(cilong, p);
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " MAGICNUMBER (%lX)", cilong);
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong);
 			traceNdx = strlen(traceBuf);
 #endif
 
@@ -1442,7 +1445,7 @@ static int lcp_reqci(fsm *f,
 		
 		case CI_PCOMPRESSION:
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " PCOMPRESSION");
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION");
 			traceNdx = strlen(traceBuf);
 #endif
 			if (!ao->neg_pcompression ||
@@ -1455,7 +1458,7 @@ static int lcp_reqci(fsm *f,
 		
 		case CI_ACCOMPRESSION:
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " ACCOMPRESSION");
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION");
 			traceNdx = strlen(traceBuf);
 #endif
 			if (!ao->neg_accompression ||
@@ -1468,7 +1471,7 @@ static int lcp_reqci(fsm *f,
 		
 		case CI_MRRU:
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " CI_MRRU");
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU");
 			traceNdx = strlen(traceBuf);
 #endif
 			orc = CONFREJ;
@@ -1476,7 +1479,7 @@ static int lcp_reqci(fsm *f,
 		
 		case CI_SSNHF:
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " CI_SSNHF");
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF");
 			traceNdx = strlen(traceBuf);
 #endif
 			orc = CONFREJ;
@@ -1484,7 +1487,7 @@ static int lcp_reqci(fsm *f,
 		
 		case CI_EPDISC:
 #if TRACELCP > 0
-			sprintf(&traceBuf[traceNdx], " CI_EPDISC");
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC");
 			traceNdx = strlen(traceBuf);
 #endif
 			orc = CONFREJ;
@@ -1492,7 +1495,7 @@ static int lcp_reqci(fsm *f,
 		
 		default:
 #if TRACELCP
-			sprintf(&traceBuf[traceNdx], " unknown %d", citype);
+			snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype);
 			traceNdx = strlen(traceBuf);
 #endif
 			orc = CONFREJ;
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/lcp.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/lcp.h
@@ -48,7 +48,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: lcp.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: lcp.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef LCP_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/magic.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/magic.h
@@ -48,7 +48,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: magic.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: magic.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  */
 
 #ifndef MAGIC_H
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/ppp.c
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/ppp.c
@@ -78,6 +78,9 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
+ 
+#include <string.h>
+ 
 #include "ppp.h"
 #if PPP_SUPPORT > 0
 #include "randm.h"
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/vj.c
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/vj.c
@@ -28,11 +28,12 @@
  * for a 16 bit processor.
  */
 
+#include <string.h>
+
 #include "ppp.h"
 #include "vj.h"
 #include "pppdebug.h"
 
-
 #if VJ_SUPPORT > 0
 
 #if LINK_STATS
--- a/packages/net/lwip_tcpip/current/src/netif/ppp/vj.h
+++ b/packages/net/lwip_tcpip/current/src/netif/ppp/vj.h
@@ -1,7 +1,7 @@
 /*
  * Definitions for tcp compression routines.
  *
- * $Id: vj.h,v 1.1 2004/05/04 12:32:33 jani Exp $
+ * $Id: vj.h,v 1.2 2006/03/29 10:33:28 asl Exp $
  *
  * Copyright (c) 1989 Regents of the University of California.
  * All rights reserved.
--- a/packages/net/lwip_tcpip/current/src/netif/slipif.c
+++ b/packages/net/lwip_tcpip/current/src/netif/slipif.c
@@ -32,9 +32,9 @@
  */
 
 /* 
- * This is an arch independent SLIP netif. The specific serial hooks must be provided 
- * by another file.They are sio_open, sio_recv and sio_send
- */ 
+ * This is an arch independent SLIP netif. The specific serial hooks must be
+ * provided by another file. They are sio_open, sio_recv and sio_send
+ */
 
 #include "netif/slipif.h"
 #include "lwip/opt.h"
@@ -55,32 +55,32 @@
  * Send a pbuf doing the necessary SLIP encapsulation
  *
  * Uses the serial layer's sio_send() 
- */ 
+ */
 err_t
 slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
 {
   struct pbuf *q;
-  int i;
+  u16_t i;
   u8_t c;
 
   /* Send pbuf out on the serial I/O device. */
   sio_send(SLIP_END, netif->state);
 
-  for(q = p; q != NULL; q = q->next) {
-    for(i = 0; i < q->len; i++) {
+  for (q = p; q != NULL; q = q->next) {
+    for (i = 0; i < q->len; i++) {
       c = ((u8_t *)q->payload)[i];
       switch (c) {
       case SLIP_END:
-  sio_send(SLIP_ESC, netif->state);
-  sio_send(SLIP_ESC_END, netif->state);
-  break;
+        sio_send(SLIP_ESC, netif->state);
+        sio_send(SLIP_ESC_END, netif->state);
+        break;
       case SLIP_ESC:
-  sio_send(SLIP_ESC, netif->state);
-  sio_send(SLIP_ESC_ESC, netif->state);
-  break;
+        sio_send(SLIP_ESC, netif->state);
+        sio_send(SLIP_ESC_ESC, netif->state);
+        break;
       default:
-  sio_send(c, netif->state);
-  break;
+        sio_send(c, netif->state);
+        break;
       }
     }
   }
@@ -94,14 +94,14 @@ slipif_output(struct netif *netif, struc
  * Poll the serial layer by calling sio_recv()
  * 
  * @return The IP packet when SLIP_END is received 
- */ 
+ */
 static struct pbuf *
-slipif_input( struct netif * netif )
+slipif_input(struct netif *netif)
 {
   u8_t c;
   struct pbuf *p, *q;
-  int recved;
-  int i;
+  u16_t recved;
+  u16_t i;
 
   q = p = NULL;
   recved = i = 0;
@@ -112,13 +112,13 @@ slipif_input( struct netif * netif )
     switch (c) {
     case SLIP_END:
       if (recved > 0) {
-  /* Received whole packet. */
-  pbuf_realloc(q, recved);
-  
-  LINK_STATS_INC(link.recv);
-  
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
-  return q;
+        /* Received whole packet. */
+        pbuf_realloc(q, recved);
+        
+        LINK_STATS_INC(link.recv);
+        
+        LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
+        return q;
       }
       break;
 
@@ -126,51 +126,54 @@ slipif_input( struct netif * netif )
       c = sio_recv(netif->state);
       switch (c) {
       case SLIP_ESC_END:
-  c = SLIP_END;
-  break;
+        c = SLIP_END;
+        break;
       case SLIP_ESC_ESC:
-  c = SLIP_ESC;
-  break;
+        c = SLIP_ESC;
+        break;
       }
       /* FALLTHROUGH */
-      
+
     default:
       if (p == NULL) {
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
-  p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
+        LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
+        p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
 
-  if (p == NULL) {
-    LINK_STATS_INC(link.drop);
-    LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
-  }
-  
-  if (q != NULL) {
-    pbuf_cat(q, p);
-  } else {
-    q = p;
-  }
+        if (p == NULL) {
+          LINK_STATS_INC(link.drop);
+          LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
+        }
+
+        if (q != NULL) {
+          pbuf_cat(q, p);
+        } else {
+          q = p;
+        }
       }
       if (p != NULL && recved < MAX_SIZE) {
-  ((u8_t *)p->payload)[i] = c;
-  recved++;
-  i++;
-  if (i >= p->len) {
-    i = 0;
-    p = NULL;
-  }
+        ((u8_t *)p->payload)[i] = c;
+        recved++;
+        i++;
+        if (i >= p->len) {
+          i = 0;
+          if (p->next != NULL && p->next->len > 0)
+            p = p->next;
+          else
+            p = NULL;
+        }
       }
       break;
     }
-    
+
   }
   return NULL;
 }
 
 /**
- * The SLIP input thread 
+ * The SLIP input thread.
  *
  * Feed the IP layer with incoming packets
- */ 
+ */
 static void
 slipif_loop(void *nf)
 {
@@ -188,22 +191,22 @@ slipif_loop(void *nf)
  *
  * Call the arch specific sio_open and remember
  * the opened device in the state field of the netif.
- */ 
+ */
 err_t
 slipif_init(struct netif *netif)
 {
-  
-  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num));
+
+  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
 
   netif->name[0] = 's';
   netif->name[1] = 'l';
   netif->output = slipif_output;
-  netif->mtu = 1500;  
+  netif->mtu = 1500;
   netif->flags = NETIF_FLAG_POINTTOPOINT;
 
   netif->state = sio_open(netif->num);
   if (!netif->state)
-      return ERR_IF;
+    return ERR_IF;
 
   sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);
   return ERR_OK;
--- a/packages/net/lwip_tcpip/current/tests/httpd.c
+++ b/packages/net/lwip_tcpip/current/tests/httpd.c
@@ -33,10 +33,11 @@
  */
 
 #include "lwip/debug.h"
+#include "lwip/stats.h"
+#include "lwip/tcp.h"
+#include <cyg/infra/testcase.h>
 
-#include "lwip/stats.h"
-
-#include "lwip/tcp.h"
+#ifdef CYGPKG_LWIP_TCP
 
 struct http_state {
   const char *file;
@@ -256,8 +257,9 @@ static cyg_thread thread_data;
 static cyg_handle_t thread_handle;
 
 void
-cyg_user_start(void)
+httpd_main(void)
 {
+    CYG_TEST_INIT();
     // Create a main thread, so we can run the scheduler and have time 'pass'
     cyg_thread_create(10,                // Priority - just a number
                       tmain,          // entry
@@ -269,5 +271,26 @@ cyg_user_start(void)
                       &thread_data       // Thread data structure
             );
     cyg_thread_resume(thread_handle);  // Start it
+    cyg_scheduler_start();
+    CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+    httpd_main();
 }
 
+#else // def CYGPKG_LWIP_TCP
+#define N_A_MSG "TCP support disabled"
+#endif // def CYGFUN_KERNEL_API_C
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
--- a/packages/net/lwip_tcpip/current/tests/nc_test_slave.c
+++ b/packages/net/lwip_tcpip/current/tests/nc_test_slave.c
@@ -35,19 +35,20 @@
 
 #include "nc_test_framework.h"
 
-#include <cyg/error/errno.h>
-#include <cyg/error/codes.h>
-#include <cyg/error/strerror.h>
 #include <cyg/infra/diag.h>
 
 #include <lwip/inet.h>
 #include <lwip/arch.h>
 #include <lwip/sys.h>
-#define LWIP_TIMEVAL_PRIVATE 
+#define LWIP_TIMEVAL_PRIVATE 1
 #include <lwip/sockets.h>
+#include <cyg/infra/testcase.h>
 
 #ifndef CYGPKG_LIBC_STDIO
+#include <cyg/error/errno.h>
 #define perror(s) diag_printf(#s ": %s\n", strerror(errno))
+#else
+#include <stdio.h>
 #endif
 #define STACK_SIZE               (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
 #define MAX_LOAD_THREAD_LEVEL    20
@@ -60,6 +61,11 @@
 #define DESIRED_BACKGROUND_LOAD  20
 #define CYGHWR_NET_DRIVERS 1
 
+#if SO_REUSE
+#ifdef CYGPKG_LWIP_TCP
+#ifdef CYGPKG_LWIP_UDP
+
+
 #if 0
 static char         main_thread_stack[CYGHWR_NET_DRIVERS][STACK_SIZE];
 static cyg_thread   main_thread_data[CYGHWR_NET_DRIVERS];
@@ -185,13 +191,13 @@ do_udp_test(int s1, struct nc_request *r
                 if ((ntohl(tdp->key1) == NC_TEST_DATA_KEY1) &&
                     (ntohl(tdp->key2) == NC_TEST_DATA_KEY2)) {
                     if (ntohl(tdp->seq) != seq) {
-                        test_printf("Packets out of sequence - recvd: %ld, expected: %d\n",
+                        test_printf("Packets out of sequence - recvd: %d, expected: %d\n",
                                     ntohl(tdp->seq), seq);
                         seq = ntohl(tdp->seq);
                         seq_errors++;
                     }
                 } else {
-                    test_printf("Bad data packet - key: %lx/%lx, seq: %ld\n",
+                    test_printf("Bad data packet - key: %lx/%lx, seq: %d\n",
                                 ntohl(tdp->key1), ntohl(tdp->key2),
                                 ntohl(tdp->seq));
                 }
@@ -358,13 +364,13 @@ do_tcp_test(int s1, struct nc_request *r
                 if ((ntohl(tdp->key1) == NC_TEST_DATA_KEY1) &&
                     (ntohl(tdp->key2) == NC_TEST_DATA_KEY2)) {
                     if (ntohl(tdp->seq) != seq) {
-                        test_printf("Packets out of sequence - recvd: %ld, expected: %d\n",
+                        test_printf("Packets out of sequence - recvd: %d, expected: %d\n",
                                     ntohl(tdp->seq), seq);
                         seq = ntohl(tdp->seq);
                         seq_errors++;
                     }
                 } else {
-                    test_printf("Bad data packet - key: %lx/%lx, seq: %ld\n",
+                    test_printf("Bad data packet - key: %lx/%lx, seq: %d\n",
                                 ntohl(tdp->key1), ntohl(tdp->key2),
                                 ntohl(tdp->seq));
                 }
@@ -452,22 +458,22 @@ nc_slave(test_param_t param)
             done = true;
             break;
         case NC_REQUEST_UDP_SEND:
-            test_printf("UDP send - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("UDP send - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_UDP_RECV:
-            test_printf("UDP recv - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("UDP recv - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_UDP_ECHO:
-            test_printf("UDP echo - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("UDP echo - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_TCP_SEND:
-            test_printf("TCP send - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("TCP send - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_TCP_RECV:
-            test_printf("TCP recv - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("TCP recv - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_TCP_ECHO:
-            test_printf("TCP echo - %ld buffers, %ld bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
+            test_printf("TCP echo - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen));
             break;
         case NC_REQUEST_SET_LOAD:
             start_load(ntohl(req.nbufs));
@@ -487,7 +493,7 @@ nc_slave(test_param_t param)
             reply.misc.idle_results.count[1] = htonl((long)idle_thread_count);
             break;
         default:
-            test_printf("Unrecognized request: %ld\n", ntohl(req.type));
+            test_printf("Unrecognized request: %d\n", ntohl(req.type));
             reply.response = htonl(NC_REPLY_NAK);
             reply.reason = htonl(NC_REPLY_NAK_UNKNOWN_REQUEST);
             break;
@@ -757,9 +763,11 @@ static cyg_thread thread_data;
 static cyg_handle_t thread_handle;
 
 void
-cyg_user_start(void)
+nc_slave_main(void)
 {
 	int i;	
+	
+	CYG_TEST_INIT();
    // Create the idle thread environment
     cyg_semaphore_init(&idle_thread_sem, 0);
     cyg_thread_create(IDLE_THREAD_PRIORITY,     // Priority
@@ -797,4 +805,32 @@ cyg_user_start(void)
                       &thread_data       // Thread data structure
             );
     cyg_thread_resume(thread_handle);  // Start it
+    cyg_scheduler_start();
+    CYG_TEST_FAIL_FINISH("Not reached");
 }
+
+
+externC void
+cyg_start( void )
+{
+    nc_slave_main();
+}
+
+#else // def CYGPKG_LWIP_UDP
+#define N_A_MSG "UDP support disabled"
+#endif // def CYGPKG_LWIP_UDP
+#else // def CYGPKG_LWIP_TCP
+#define N_A_MSG "TCP support disabled"
+#endif // def CYGPKG_LWIP_TCP
+#else // SO_REUSE
+#define N_A_MSG "SO_REUSE currently unavailable"
+#endif // SO_REUSE
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
--- a/packages/net/lwip_tcpip/current/tests/socket.c
+++ b/packages/net/lwip_tcpip/current/tests/socket.c
@@ -33,9 +33,13 @@
 /* Simple test-case for the BSD socket API  : echo on TCP port 7 */
 
 #include <lwip/sys.h>
+#undef LWIP_COMPAT_SOCKETS
 #define LWIP_COMPAT_SOCKETS 1
 #include <lwip/sockets.h>
 #include <lwip/inet.h>
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGPKG_LWIP_TCP
 
 char buf[400];
 static void
@@ -74,8 +78,9 @@ static cyg_thread thread_data;
 static cyg_handle_t thread_handle;
 
 void
-cyg_user_start(void)
+socket_main(void)
 {
+    CYG_TEST_INIT();
     // Create a main thread, so we can run the scheduler and have time 'pass'
     cyg_thread_create(10,                // Priority - just a number
                       tmain,          // entry
@@ -87,5 +92,26 @@ cyg_user_start(void)
                       &thread_data       // Thread data structure
             );
     cyg_thread_resume(thread_handle);  // Start it
+    cyg_scheduler_start();
+    CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+    socket_main();
 }
 
+#else // def CYGPKG_LWIP_TCP
+#define N_A_MSG "TCP support disabled"
+#endif // def CYGFUN_KERNEL_API_C
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
--- a/packages/net/lwip_tcpip/current/tests/tcpecho.c
+++ b/packages/net/lwip_tcpip/current/tests/tcpecho.c
@@ -34,6 +34,9 @@
 
 #include "lwip/sys.h"
 #include "lwip/api.h"
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGPKG_LWIP_TCP
 
 static void 
 tcpecho_thread(void *arg)
@@ -88,8 +91,10 @@ static cyg_thread thread_data;
 static cyg_handle_t thread_handle;
 
 void
-cyg_user_start(void)
+tcpecho_main(void)
 {
+    CYG_TEST_INIT();
+    
     // Create a main thread, so we can run the scheduler and have time 'pass'
     cyg_thread_create(10,                // Priority - just a number
                       tmain,          // entry
@@ -100,6 +105,27 @@ cyg_user_start(void)
                       &thread_handle,    // Handle
                       &thread_data       // Thread data structure
             );
-    cyg_thread_resume(thread_handle);  // Start it
+            
+    cyg_thread_resume(thread_handle);  // Start it   
+    cyg_scheduler_start();
+    CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+    tcpecho_main();
 }
 
+#else // def CYGPKG_LWIP_TCP
+#define N_A_MSG "TCP support disabled"
+#endif // def CYGFUN_KERNEL_API_C
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
--- a/packages/net/lwip_tcpip/current/tests/udpecho.c
+++ b/packages/net/lwip_tcpip/current/tests/udpecho.c
@@ -34,6 +34,9 @@
 
 #include "lwip/api.h"
 #include "lwip/sys.h"
+#include <cyg/infra/testcase.h>
+
+#ifdef CYGPKG_LWIP_UDP
 
 /*-----------------------------------------------------------------------------------*/
 char buffer[100];
@@ -71,8 +74,9 @@ static cyg_thread thread_data;
 static cyg_handle_t thread_handle;
 
 void
-cyg_user_start(void)
+udpecho_main(void)
 {
+    CYG_TEST_INIT();
     // Create a main thread, so we can run the scheduler and have time 'pass'
     cyg_thread_create(10,                // Priority - just a number
                       tmain,          // entry
@@ -84,5 +88,29 @@ cyg_user_start(void)
                       &thread_data       // Thread data structure
             );
     cyg_thread_resume(thread_handle);  // Start it
+    
+    cyg_scheduler_start();
+
+    CYG_TEST_FAIL_FINISH("Not reached");
+}
+
+externC void
+cyg_start( void )
+{
+    udpecho_main();
 }
 
+#else // def CYGPKG_LWIP_UDP
+#define N_A_MSG "UDP support disabled"
+#endif // def CYGFUN_KERNEL_API_C
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(N_A_MSG);
+}
+#endif // N_A_MSG
+
+