debuggers.hg
changeset 18114:a8603b2fb786
stubdom: use lwip 1.3.0 release + patch instead of checking out from cvs
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Thu Jul 17 15:37:09 2008 +0100 (2008-07-17) |
parents | 6f82840f173b |
children | e126614f0def 400e5d4877ca |
files | stubdom/Makefile stubdom/lwip.patch-cvs |
line diff
1.1 --- a/stubdom/Makefile Thu Jul 17 15:33:15 2008 +0100 1.2 +++ b/stubdom/Makefile Thu Jul 17 15:37:09 2008 +0100 1.3 @@ -13,7 +13,7 @@ IOEMU_OPTIONS=--disable-sdl --disable-op 1.4 ZLIB_VERSION=1.2.3 1.5 LIBPCI_VERSION=2.2.9 1.6 NEWLIB_VERSION=1.16.0 1.7 -LWIP_DATE=2008-06-01 1.8 +LWIP_VERSION=1.3.0 1.9 GRUB_VERSION=0.97 1.10 1.11 WGET=wget -c 1.12 @@ -54,8 +54,8 @@ TARGET_CPPFLAGS += -nostdinc 1.13 TARGET_CPPFLAGS += -isystem $(CURDIR)/$(MINI_OS)/include/posix 1.14 TARGET_CPPFLAGS += -isystem $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include 1.15 TARGET_CPPFLAGS += -isystem $(GCC_INSTALL)include 1.16 -TARGET_CPPFLAGS += -isystem $(CURDIR)/lwip-cvs/src/include 1.17 -TARGET_CPPFLAGS += -isystem $(CURDIR)/lwip-cvs/src/include/ipv4 1.18 +TARGET_CPPFLAGS += -isystem $(CURDIR)/lwip/src/include 1.19 +TARGET_CPPFLAGS += -isystem $(CURDIR)/lwip/src/include/ipv4 1.20 TARGET_CPPFLAGS += -I$(CURDIR)/include 1.21 1.22 TARGET_LDFLAGS += -nostdlib -L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib 1.23 @@ -139,8 +139,13 @@ cross-libpci: $(LIBPCI_STAMPFILE) 1.24 # lwIP 1.25 ###### 1.26 1.27 -lwip-cvs: 1.28 - cvs -z 9 -d :pserver:anonymous@cvs.savannah.nongnu.org:/sources/lwip co -D $(LWIP_DATE) -d $@ lwip 1.29 +lwip-$(LWIP_VERSION).tar.gz: 1.30 + $(WGET) http://download.savannah.gnu.org/releases/lwip/$@ 1.31 + 1.32 +lwip: lwip-$(LWIP_VERSION).tar.gz 1.33 + tar xzf $< 1.34 + patch -d $@ -p0 < lwip.patch-cvs 1.35 + touch $@ 1.36 1.37 ####### 1.38 # Links 1.39 @@ -213,12 +218,12 @@ ifeq ($(CONFIG_QEMU),ioemu) 1.40 [ -f ioemu/config-host.mak ] || \ 1.41 ( cd ioemu ; \ 1.42 XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) CFLAGS="$(TARGET_CFLAGS)" sh configure --prefix=/usr --enable-stubdom $(IOEMU_OPTIONS)) 1.43 - CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip-cvs TOOLS= 1.44 + CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip TOOLS= 1.45 else 1.46 [ -f ioemu/config-host.mak ] || \ 1.47 ( cd ioemu ; \ 1.48 CONFIG_STUBDOM=yes XEN_ROOT=$(abspath $(XEN_ROOT)) XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) CFLAGS="$(TARGET_CFLAGS)" sh ./xen-setup --cc=$(CC) --disable-gcc-check $(IOEMU_OPTIONS)) 1.49 - CPPFLAGS= TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip-cvs TOOLS= CONFIG_STUBDOM=yes 1.50 + CPPFLAGS= TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip TOOLS= CONFIG_STUBDOM=yes 1.51 endif 1.52 1.53 ###### 1.54 @@ -227,7 +232,7 @@ endif 1.55 1.56 .PHONY: caml 1.57 caml: cross-newlib mk-headers 1.58 - CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 1.59 + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip 1.60 1.61 ### 1.62 # C 1.63 @@ -235,7 +240,7 @@ caml: cross-newlib mk-headers 1.64 1.65 .PHONY: c 1.66 c: cross-newlib mk-headers 1.67 - CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 1.68 + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip 1.69 1.70 ###### 1.71 # Grub 1.72 @@ -265,17 +270,17 @@ ioemu-stubdom: APP_OBJS=$(CURDIR)/ioemu/ 1.73 else 1.74 ioemu-stubdom: APP_OBJS=$(CURDIR)/ioemu/i386-stubdom/qemu.a $(CURDIR)/ioemu/i386-stubdom/libqemu.a $(CURDIR)/ioemu/libqemu_common.a 1.75 endif 1.76 -ioemu-stubdom: mini-os-ioemu lwip-cvs libxc ioemu 1.77 - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_QEMU $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(APP_OBJS)" 1.78 +ioemu-stubdom: mini-os-ioemu lwip libxc ioemu 1.79 + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_QEMU $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip APP_OBJS="$(APP_OBJS)" 1.80 1.81 CAMLLIB = $(shell ocamlc -where) 1.82 .PHONY: caml-stubdom 1.83 -caml-stubdom: mini-os-caml lwip-cvs libxc caml 1.84 - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_CAML $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a" 1.85 +caml-stubdom: mini-os-caml lwip libxc caml 1.86 + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_CAML $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip APP_OBJS="$(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a" 1.87 1.88 .PHONY: c-stubdom 1.89 -c-stubdom: mini-os-c lwip-cvs libxc c 1.90 - DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_C $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a 1.91 +c-stubdom: mini-os-c lwip libxc c 1.92 + DEF_CPPFLAGS="$(TARGET_CPPFLAGS)" DEF_CFLAGS="-DCONFIG_C $(TARGET_CFLAGS)" DEF_LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip APP_OBJS=$(CURDIR)/c/main.a 1.93 1.94 .PHONY: pv-grub 1.95 pv-grub: mini-os-grub libxc grub 1.96 @@ -328,7 +333,7 @@ crossclean: clean 1.97 .PHONY: patchclean 1.98 patchclean: crossclean 1.99 rm -fr newlib-$(NEWLIB_VERSION) 1.100 - rm -fr lwip-cvs 1.101 + rm -fr lwip 1.102 rm -fr grub-upstream 1.103 1.104 # clean downloads 1.105 @@ -337,6 +342,8 @@ downloadclean: patchclean 1.106 rm -f newlib-$(NEWLIB_VERSION).tar.gz 1.107 rm -f zlib-$(ZLIB_VERSION).tar.gz 1.108 rm -f pciutils-$(LIBPCI_VERSION).tar.bz2 1.109 + rm -f grub-$(GRUB_VERSION).tar.gz 1.110 + rm -f lwip-$(LWIP_VERSION).tar.gz 1.111 1.112 .PHONY: distclean 1.113 distclean: downloadclean
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/stubdom/lwip.patch-cvs Thu Jul 17 15:37:09 2008 +0100 2.3 @@ -0,0 +1,2398 @@ 2.4 +? .ChangeLog.swp 2.5 +? ChangeLog 2.6 +Index: CHANGELOG 2.7 +=================================================================== 2.8 +RCS file: /sources/lwip/lwip/CHANGELOG,v 2.9 +retrieving revision 1.300 2.10 +retrieving revision 1.318 2.11 +diff -u -p -r1.300 -r1.318 2.12 +--- CHANGELOG 23 Mar 2008 13:49:39 -0000 1.300 2.13 ++++ CHANGELOG 14 Jul 2008 20:12:36 -0000 1.318 2.14 +@@ -19,9 +19,77 @@ HISTORY 2.15 + 2.16 + ++ New features: 2.17 + 2.18 ++ 2008-06-30 Simon Goldschmidt 2.19 ++ * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from 2.20 ++ interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows 2.21 ++ mem_free to run between mem_malloc iterations. Added illegal counter for 2.22 ++ mem stats. 2.23 ++ 2.24 ++ 2008-06-27 Simon Goldschmidt 2.25 ++ * stats.h/.c, some other files: patch #6483: stats module improvement: 2.26 ++ Added defines to display each module's statistic individually, added stats 2.27 ++ defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. 2.28 ++ 2.29 ++ 2008-06-17 Simon Goldschmidt 2.30 ++ * err.h: patch #6459: Made err_t overridable to use a more efficient type 2.31 ++ (define LWIP_ERR_T in cc.h) 2.32 ++ 2.33 ++ 2008-06-17 Simon Goldschmidt 2.34 ++ * slipif.c: patch #6480: Added a configuration option for slipif for symmetry 2.35 ++ to loopif 2.36 ++ 2.37 ++ 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) 2.38 ++ * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly 2.39 ++ modified version of patch # 6370: Moved loopif code to netif.c so that 2.40 ++ loopback traffic is supported on all netifs (all local IPs). 2.41 ++ Added option to limit loopback packets for each netifs. 2.42 ++ 2.43 + 2.44 + ++ Bugfixes: 2.45 + 2.46 ++ 2008-08-14 Simon Goldschmidt 2.47 ++ * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when 2.48 ++ tcp_close returns != ERR_OK) 2.49 ++ 2.50 ++ 2008-07-08 Frédéric Bernon 2.51 ++ * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters 2.52 ++ in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). 2.53 ++ 2.54 ++ 2008-06-24 Jonathan Larmour 2.55 ++ * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused 2.56 ++ if tcp_seg_copy fails. 2.57 ++ 2.58 ++ 2008-06-17 Simon Goldschmidt 2.59 ++ * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) 2.60 ++ and created defines for swapping bytes and folding u32 to u16. 2.61 ++ 2.62 ++ 2008-05-30 Kieran Mansley 2.63 ++ * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd 2.64 ++ rather than rcv_ann_wnd when deciding if packets are in-window. 2.65 ++ Contributed by <arasmussen@consultant.datasys.swri.edu> 2.66 ++ 2.67 ++ 2008-05-30 Kieran Mansley 2.68 ++ * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow 2.69 ++ passing as function pointers when MEM_LIBC_MALLOC is defined. 2.70 ++ 2.71 ++ 2008-05-09 Jonathan Larmour 2.72 ++ * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to 2.73 ++ stop it being treated as a fatal error. 2.74 ++ 2.75 ++ 2008-04-15 Simon Goldschmidt 2.76 ++ * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP 2.77 ++ (flag now cleared) 2.78 ++ 2.79 ++ 2008-03-27 Simon Goldschmidt 2.80 ++ * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free 2.81 ++ from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 2.82 ++ in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs 2.83 ++ or heap memory from interrupt context 2.84 ++ 2.85 ++ 2008-03-26 Simon Goldschmidt 2.86 ++ * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote 2.87 ++ host sent a zero mss as TCP option. 2.88 ++ 2.89 + 2.90 + (STABLE-1.3.0) 2.91 + 2.92 +Index: src/api/api_msg.c 2.93 +=================================================================== 2.94 +RCS file: /sources/lwip/lwip/src/api/api_msg.c,v 2.95 +retrieving revision 1.102 2.96 +retrieving revision 1.104 2.97 +diff -u -p -r1.102 -r1.104 2.98 +--- src/api/api_msg.c 21 Mar 2008 16:23:14 -0000 1.102 2.99 ++++ src/api/api_msg.c 15 Jul 2008 11:18:58 -0000 1.104 2.100 +@@ -598,11 +598,16 @@ do_close_internal(struct netconn *conn) 2.101 + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); 2.102 + 2.103 + /* Set back some callback pointers */ 2.104 ++ tcp_arg(conn->pcb.tcp, NULL); 2.105 + if (conn->pcb.tcp->state == LISTEN) { 2.106 +- tcp_arg(conn->pcb.tcp, NULL); 2.107 + tcp_accept(conn->pcb.tcp, NULL); 2.108 + } else { 2.109 + tcp_recv(conn->pcb.tcp, NULL); 2.110 ++ tcp_accept(conn->pcb.tcp, NULL); 2.111 ++ /* some callbacks have to be reset if tcp_close is not successful */ 2.112 ++ tcp_sent(conn->pcb.tcp, NULL); 2.113 ++ tcp_poll(conn->pcb.tcp, NULL, 4); 2.114 ++ tcp_err(conn->pcb.tcp, NULL); 2.115 + } 2.116 + /* Try to close the connection */ 2.117 + err = tcp_close(conn->pcb.tcp); 2.118 +@@ -610,11 +615,6 @@ do_close_internal(struct netconn *conn) 2.119 + /* Closing succeeded */ 2.120 + conn->state = NETCONN_NONE; 2.121 + /* Set back some callback pointers as conn is going away */ 2.122 +- tcp_err(conn->pcb.tcp, NULL); 2.123 +- tcp_poll(conn->pcb.tcp, NULL, 4); 2.124 +- tcp_sent(conn->pcb.tcp, NULL); 2.125 +- tcp_recv(conn->pcb.tcp, NULL); 2.126 +- tcp_arg(conn->pcb.tcp, NULL); 2.127 + conn->pcb.tcp = NULL; 2.128 + conn->err = ERR_OK; 2.129 + /* Trigger select() in socket layer. This send should something else so the 2.130 +@@ -623,6 +623,14 @@ do_close_internal(struct netconn *conn) 2.131 + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); 2.132 + /* wake up the application task */ 2.133 + sys_sem_signal(conn->op_completed); 2.134 ++ } else { 2.135 ++ /* Closing failed, restore some of the callbacks */ 2.136 ++ /* Closing of listen pcb will never fail! */ 2.137 ++ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); 2.138 ++ tcp_sent(conn->pcb.tcp, sent_tcp); 2.139 ++ tcp_poll(conn->pcb.tcp, poll_tcp, 4); 2.140 ++ tcp_err(conn->pcb.tcp, err_tcp); 2.141 ++ tcp_arg(conn->pcb.tcp, conn); 2.142 + } 2.143 + /* If closing didn't succeed, we get called again either 2.144 + from poll_tcp or from sent_tcp */ 2.145 +Index: src/api/err.c 2.146 +=================================================================== 2.147 +RCS file: /sources/lwip/lwip/src/api/err.c,v 2.148 +retrieving revision 1.11 2.149 +retrieving revision 1.12 2.150 +diff -u -p -r1.11 -r1.12 2.151 +--- src/api/err.c 13 Dec 2007 23:06:50 -0000 1.11 2.152 ++++ src/api/err.c 9 May 2008 12:14:23 -0000 1.12 2.153 +@@ -44,17 +44,17 @@ static const char *err_strerr[] = { 2.154 + "Ok.", /* ERR_OK 0 */ 2.155 + "Out of memory error.", /* ERR_MEM -1 */ 2.156 + "Buffer error.", /* ERR_BUF -2 */ 2.157 +- "Routing problem.", /* ERR_RTE -3 */ 2.158 +- "Connection aborted.", /* ERR_ABRT -4 */ 2.159 +- "Connection reset.", /* ERR_RST -5 */ 2.160 +- "Connection closed.", /* ERR_CLSD -6 */ 2.161 +- "Not connected.", /* ERR_CONN -7 */ 2.162 +- "Illegal value.", /* ERR_VAL -8 */ 2.163 +- "Illegal argument.", /* ERR_ARG -9 */ 2.164 +- "Address in use.", /* ERR_USE -10 */ 2.165 +- "Low-level netif error.", /* ERR_IF -11 */ 2.166 +- "Already connected.", /* ERR_ISCONN -12 */ 2.167 +- "Timeout.", /* ERR_TIMEOUT -13 */ 2.168 ++ "Timeout.", /* ERR_TIMEOUT -3 */ 2.169 ++ "Routing problem.", /* ERR_RTE -4 */ 2.170 ++ "Connection aborted.", /* ERR_ABRT -5 */ 2.171 ++ "Connection reset.", /* ERR_RST -6 */ 2.172 ++ "Connection closed.", /* ERR_CLSD -7 */ 2.173 ++ "Not connected.", /* ERR_CONN -8 */ 2.174 ++ "Illegal value.", /* ERR_VAL -9 */ 2.175 ++ "Illegal argument.", /* ERR_ARG -10 */ 2.176 ++ "Address in use.", /* ERR_USE -11 */ 2.177 ++ "Low-level netif error.", /* ERR_IF -12 */ 2.178 ++ "Already connected.", /* ERR_ISCONN -13 */ 2.179 + "Operation in progress." /* ERR_INPROGRESS -14 */ 2.180 + }; 2.181 + 2.182 +Index: src/api/netdb.c 2.183 +=================================================================== 2.184 +RCS file: /sources/lwip/lwip/src/api/netdb.c,v 2.185 +retrieving revision 1.4 2.186 +retrieving revision 1.5 2.187 +diff -u -p -r1.4 -r1.5 2.188 +--- src/api/netdb.c 26 Jan 2008 16:11:39 -0000 1.4 2.189 ++++ src/api/netdb.c 16 Jul 2008 20:36:12 -0000 1.5 2.190 +@@ -326,7 +326,8 @@ lwip_getaddrinfo(const char *nodename, c 2.191 + if (nodename != NULL) { 2.192 + /* copy nodename to canonname if specified */ 2.193 + size_t namelen = strlen(nodename); 2.194 +- ai->ai_canonname = mem_malloc(namelen + 1); 2.195 ++ LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); 2.196 ++ ai->ai_canonname = mem_malloc((mem_size_t)(namelen + 1)); 2.197 + if (ai->ai_canonname == NULL) { 2.198 + goto memerr; 2.199 + } 2.200 +Index: src/api/sockets.c 2.201 +=================================================================== 2.202 +RCS file: /sources/lwip/lwip/src/api/sockets.c,v 2.203 +retrieving revision 1.116 2.204 +retrieving revision 1.117 2.205 +diff -u -p -r1.116 -r1.117 2.206 +--- src/api/sockets.c 13 Mar 2008 20:03:57 -0000 1.116 2.207 ++++ src/api/sockets.c 9 May 2008 12:14:24 -0000 1.117 2.208 +@@ -128,17 +128,17 @@ static const int err_to_errno_table[] = 2.209 + 0, /* ERR_OK 0 No error, everything OK. */ 2.210 + ENOMEM, /* ERR_MEM -1 Out of memory error. */ 2.211 + ENOBUFS, /* ERR_BUF -2 Buffer error. */ 2.212 +- EHOSTUNREACH, /* ERR_RTE -3 Routing problem. */ 2.213 +- ECONNABORTED, /* ERR_ABRT -4 Connection aborted. */ 2.214 +- ECONNRESET, /* ERR_RST -5 Connection reset. */ 2.215 +- ESHUTDOWN, /* ERR_CLSD -6 Connection closed. */ 2.216 +- ENOTCONN, /* ERR_CONN -7 Not connected. */ 2.217 +- EINVAL, /* ERR_VAL -8 Illegal value. */ 2.218 +- EIO, /* ERR_ARG -9 Illegal argument. */ 2.219 +- EADDRINUSE, /* ERR_USE -10 Address in use. */ 2.220 +- -1, /* ERR_IF -11 Low-level netif error */ 2.221 +- -1, /* ERR_ISCONN -12 Already connected. */ 2.222 +- ETIMEDOUT, /* ERR_TIMEOUT -13 Timeout */ 2.223 ++ ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */ 2.224 ++ EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ 2.225 ++ ECONNABORTED, /* ERR_ABRT -5 Connection aborted. */ 2.226 ++ ECONNRESET, /* ERR_RST -6 Connection reset. */ 2.227 ++ ESHUTDOWN, /* ERR_CLSD -7 Connection closed. */ 2.228 ++ ENOTCONN, /* ERR_CONN -8 Not connected. */ 2.229 ++ EINVAL, /* ERR_VAL -9 Illegal value. */ 2.230 ++ EIO, /* ERR_ARG -10 Illegal argument. */ 2.231 ++ EADDRINUSE, /* ERR_USE -11 Address in use. */ 2.232 ++ -1, /* ERR_IF -12 Low-level netif error */ 2.233 ++ -1, /* ERR_ISCONN -13 Already connected. */ 2.234 + EINPROGRESS /* ERR_INPROGRESS -14 Operation in progress */ 2.235 + }; 2.236 + 2.237 +Index: src/api/tcpip.c 2.238 +=================================================================== 2.239 +RCS file: /sources/lwip/lwip/src/api/tcpip.c,v 2.240 +retrieving revision 1.70 2.241 +retrieving revision 1.73 2.242 +diff -u -p -r1.70 -r1.73 2.243 +--- src/api/tcpip.c 12 Jan 2008 11:52:22 -0000 1.70 2.244 ++++ src/api/tcpip.c 27 Jun 2008 20:34:51 -0000 1.73 2.245 +@@ -518,4 +518,42 @@ tcpip_init(void (* initfunc)(void *), vo 2.246 + sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); 2.247 + } 2.248 + 2.249 ++/** 2.250 ++ * Simple callback function used with tcpip_callback to free a pbuf 2.251 ++ * (pbuf_free has a wrong signature for tcpip_callback) 2.252 ++ * 2.253 ++ * @param p The pbuf (chain) to be dereferenced. 2.254 ++ */ 2.255 ++static void 2.256 ++pbuf_free_int(void *p) 2.257 ++{ 2.258 ++ struct pbuf *q = p; 2.259 ++ pbuf_free(q); 2.260 ++} 2.261 ++ 2.262 ++/** 2.263 ++ * A simple wrapper function that allows you to free a pbuf from interrupt context. 2.264 ++ * 2.265 ++ * @param p The pbuf (chain) to be dereferenced. 2.266 ++ * @return ERR_OK if callback could be enqueued, an err_t if not 2.267 ++ */ 2.268 ++err_t 2.269 ++pbuf_free_callback(struct pbuf *p) 2.270 ++{ 2.271 ++ return tcpip_callback_with_block(pbuf_free_int, p, 0); 2.272 ++} 2.273 ++ 2.274 ++/** 2.275 ++ * A simple wrapper function that allows you to free heap memory from 2.276 ++ * interrupt context. 2.277 ++ * 2.278 ++ * @param m the heap memory to free 2.279 ++ * @return ERR_OK if callback could be enqueued, an err_t if not 2.280 ++ */ 2.281 ++err_t 2.282 ++mem_free_callback(void *m) 2.283 ++{ 2.284 ++ return tcpip_callback_with_block(mem_free, m, 0); 2.285 ++} 2.286 ++ 2.287 + #endif /* !NO_SYS */ 2.288 +Index: src/core/dhcp.c 2.289 +=================================================================== 2.290 +RCS file: /sources/lwip/lwip/src/core/dhcp.c,v 2.291 +retrieving revision 1.86 2.292 +retrieving revision 1.87 2.293 +diff -u -p -r1.86 -r1.87 2.294 +--- src/core/dhcp.c 4 Mar 2008 14:25:58 -0000 1.86 2.295 ++++ src/core/dhcp.c 15 Apr 2008 17:24:55 -0000 1.87 2.296 +@@ -568,6 +568,8 @@ dhcp_start(struct netif *netif) 2.297 + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); 2.298 + dhcp = netif->dhcp; 2.299 + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); 2.300 ++ /* Remove the flag that says this netif is handled by DHCP, 2.301 ++ it is set when we succeeded starting. */ 2.302 + netif->flags &= ~NETIF_FLAG_DHCP; 2.303 + 2.304 + /* no DHCP client attached yet? */ 2.305 +@@ -609,6 +611,7 @@ dhcp_start(struct netif *netif) 2.306 + dhcp_stop(netif); 2.307 + return ERR_MEM; 2.308 + } 2.309 ++ /* Set the flag that says this netif is handled by DHCP. */ 2.310 + netif->flags |= NETIF_FLAG_DHCP; 2.311 + return result; 2.312 + } 2.313 +@@ -1063,6 +1066,8 @@ dhcp_stop(struct netif *netif) 2.314 + { 2.315 + struct dhcp *dhcp = netif->dhcp; 2.316 + LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); 2.317 ++ /* Remove the flag that says this netif is handled by DHCP. */ 2.318 ++ netif->flags &= ~NETIF_FLAG_DHCP; 2.319 + 2.320 + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 3, ("dhcp_stop()\n")); 2.321 + /* netif is DHCP configured? */ 2.322 +Index: src/core/mem.c 2.323 +=================================================================== 2.324 +RCS file: /sources/lwip/lwip/src/core/mem.c,v 2.325 +retrieving revision 1.59 2.326 +retrieving revision 1.62 2.327 +diff -u -p -r1.59 -r1.62 2.328 +--- src/core/mem.c 4 Mar 2008 16:31:32 -0000 1.59 2.329 ++++ src/core/mem.c 30 Jun 2008 18:16:51 -0000 1.62 2.330 +@@ -177,9 +177,36 @@ static u8_t *ram; 2.331 + static struct mem *ram_end; 2.332 + /** pointer to the lowest free block, this is used for faster search */ 2.333 + static struct mem *lfree; 2.334 ++ 2.335 + /** concurrent access protection */ 2.336 + static sys_sem_t mem_sem; 2.337 + 2.338 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.339 ++ 2.340 ++static volatile u8_t mem_free_count; 2.341 ++ 2.342 ++/* Allow mem_free from other (e.g. interrupt) context */ 2.343 ++#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) 2.344 ++#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) 2.345 ++#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) 2.346 ++#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) 2.347 ++#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) 2.348 ++#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) 2.349 ++ 2.350 ++#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.351 ++ 2.352 ++/* Protect the heap only by using a semaphore */ 2.353 ++#define LWIP_MEM_FREE_DECL_PROTECT() 2.354 ++#define LWIP_MEM_FREE_PROTECT() sys_arch_sem_wait(mem_sem, 0) 2.355 ++#define LWIP_MEM_FREE_UNPROTECT() sys_sem_signal(mem_sem) 2.356 ++/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ 2.357 ++#define LWIP_MEM_ALLOC_DECL_PROTECT() 2.358 ++#define LWIP_MEM_ALLOC_PROTECT() 2.359 ++#define LWIP_MEM_ALLOC_UNPROTECT() 2.360 ++ 2.361 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.362 ++ 2.363 ++ 2.364 + /** 2.365 + * "Plug holes" by combining adjacent empty struct mems. 2.366 + * After this function is through, there should not exist 2.367 +@@ -255,9 +282,7 @@ mem_init(void) 2.368 + /* initialize the lowest-free pointer to the start of the heap */ 2.369 + lfree = (struct mem *)ram; 2.370 + 2.371 +-#if MEM_STATS 2.372 +- lwip_stats.mem.avail = MEM_SIZE_ALIGNED; 2.373 +-#endif /* MEM_STATS */ 2.374 ++ MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); 2.375 + } 2.376 + 2.377 + /** 2.378 +@@ -270,6 +295,7 @@ void 2.379 + mem_free(void *rmem) 2.380 + { 2.381 + struct mem *mem; 2.382 ++ LWIP_MEM_FREE_DECL_PROTECT(); 2.383 + 2.384 + if (rmem == NULL) { 2.385 + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n")); 2.386 +@@ -277,20 +303,20 @@ mem_free(void *rmem) 2.387 + } 2.388 + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); 2.389 + 2.390 +- /* protect the heap from concurrent access */ 2.391 +- sys_arch_sem_wait(mem_sem, 0); 2.392 +- 2.393 + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && 2.394 + (u8_t *)rmem < (u8_t *)ram_end); 2.395 + 2.396 + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { 2.397 ++ SYS_ARCH_DECL_PROTECT(lev); 2.398 + LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n")); 2.399 +-#if MEM_STATS 2.400 +- ++lwip_stats.mem.err; 2.401 +-#endif /* MEM_STATS */ 2.402 +- sys_sem_signal(mem_sem); 2.403 ++ /* protect mem stats from concurrent access */ 2.404 ++ SYS_ARCH_PROTECT(lev); 2.405 ++ MEM_STATS_INC(illegal); 2.406 ++ SYS_ARCH_UNPROTECT(lev); 2.407 + return; 2.408 + } 2.409 ++ /* protect the heap from concurrent access */ 2.410 ++ LWIP_MEM_FREE_PROTECT(); 2.411 + /* Get the corresponding struct mem ... */ 2.412 + mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); 2.413 + /* ... which has to be in a used state ... */ 2.414 +@@ -303,13 +329,14 @@ mem_free(void *rmem) 2.415 + lfree = mem; 2.416 + } 2.417 + 2.418 +-#if MEM_STATS 2.419 +- lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram); 2.420 +-#endif /* MEM_STATS */ 2.421 ++ MEM_STATS_DEC_USED(used, mem->next - ((u8_t *)mem - ram)); 2.422 + 2.423 + /* finally, see if prev or next are free also */ 2.424 + plug_holes(mem); 2.425 +- sys_sem_signal(mem_sem); 2.426 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.427 ++ mem_free_count = 1; 2.428 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.429 ++ LWIP_MEM_FREE_UNPROTECT(); 2.430 + } 2.431 + 2.432 + /** 2.433 +@@ -321,6 +348,8 @@ mem_free(void *rmem) 2.434 + * @param newsize required size after shrinking (needs to be smaller than or 2.435 + * equal to the previous size) 2.436 + * @return for compatibility reasons: is always == rmem, at the moment 2.437 ++ * or NULL if newsize is > old size, in which case rmem is NOT touched 2.438 ++ * or freed! 2.439 + */ 2.440 + void * 2.441 + mem_realloc(void *rmem, mem_size_t newsize) 2.442 +@@ -328,6 +357,8 @@ mem_realloc(void *rmem, mem_size_t newsi 2.443 + mem_size_t size; 2.444 + mem_size_t ptr, ptr2; 2.445 + struct mem *mem, *mem2; 2.446 ++ /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ 2.447 ++ LWIP_MEM_FREE_DECL_PROTECT(); 2.448 + 2.449 + /* Expand the size of the allocated memory region so that we can 2.450 + adjust for alignment. */ 2.451 +@@ -346,7 +377,12 @@ mem_realloc(void *rmem, mem_size_t newsi 2.452 + (u8_t *)rmem < (u8_t *)ram_end); 2.453 + 2.454 + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { 2.455 ++ SYS_ARCH_DECL_PROTECT(lev); 2.456 + LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n")); 2.457 ++ /* protect mem stats from concurrent access */ 2.458 ++ SYS_ARCH_PROTECT(lev); 2.459 ++ MEM_STATS_INC(illegal); 2.460 ++ SYS_ARCH_UNPROTECT(lev); 2.461 + return rmem; 2.462 + } 2.463 + /* Get the corresponding struct mem ... */ 2.464 +@@ -366,11 +402,9 @@ mem_realloc(void *rmem, mem_size_t newsi 2.465 + } 2.466 + 2.467 + /* protect the heap from concurrent access */ 2.468 +- sys_arch_sem_wait(mem_sem, 0); 2.469 ++ LWIP_MEM_FREE_PROTECT(); 2.470 + 2.471 +-#if MEM_STATS 2.472 +- lwip_stats.mem.used -= (size - newsize); 2.473 +-#endif /* MEM_STATS */ 2.474 ++ MEM_STATS_DEC_USED(used, (size - newsize)); 2.475 + 2.476 + mem2 = (struct mem *)&ram[mem->next]; 2.477 + if(mem2->used == 0) { 2.478 +@@ -426,7 +460,10 @@ mem_realloc(void *rmem, mem_size_t newsi 2.479 + -> don't do anyhting. 2.480 + -> the remaining space stays unused since it is too small 2.481 + } */ 2.482 +- sys_sem_signal(mem_sem); 2.483 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.484 ++ mem_free_count = 1; 2.485 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.486 ++ LWIP_MEM_FREE_UNPROTECT(); 2.487 + return rmem; 2.488 + } 2.489 + 2.490 +@@ -444,6 +481,10 @@ mem_malloc(mem_size_t size) 2.491 + { 2.492 + mem_size_t ptr, ptr2; 2.493 + struct mem *mem, *mem2; 2.494 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.495 ++ u8_t local_mem_free_count = 0; 2.496 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.497 ++ LWIP_MEM_ALLOC_DECL_PROTECT(); 2.498 + 2.499 + if (size == 0) { 2.500 + return NULL; 2.501 +@@ -464,88 +505,101 @@ mem_malloc(mem_size_t size) 2.502 + 2.503 + /* protect the heap from concurrent access */ 2.504 + sys_arch_sem_wait(mem_sem, 0); 2.505 ++ LWIP_MEM_ALLOC_PROTECT(); 2.506 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.507 ++ /* run as long as a mem_free disturbed mem_malloc */ 2.508 ++ do { 2.509 ++ local_mem_free_count = 0; 2.510 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.511 ++ 2.512 ++ /* Scan through the heap searching for a free block that is big enough, 2.513 ++ * beginning with the lowest free block. 2.514 ++ */ 2.515 ++ for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size; 2.516 ++ ptr = ((struct mem *)&ram[ptr])->next) { 2.517 ++ mem = (struct mem *)&ram[ptr]; 2.518 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.519 ++ mem_free_count = 0; 2.520 ++ LWIP_MEM_ALLOC_UNPROTECT(); 2.521 ++ /* allow mem_free to run */ 2.522 ++ LWIP_MEM_ALLOC_PROTECT(); 2.523 ++ if (mem_free_count != 0) { 2.524 ++ local_mem_free_count = mem_free_count; 2.525 ++ } 2.526 ++ mem_free_count = 0; 2.527 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.528 + 2.529 +- /* Scan through the heap searching for a free block that is big enough, 2.530 +- * beginning with the lowest free block. 2.531 +- */ 2.532 +- for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size; 2.533 +- ptr = ((struct mem *)&ram[ptr])->next) { 2.534 +- mem = (struct mem *)&ram[ptr]; 2.535 +- 2.536 +- if ((!mem->used) && 2.537 +- (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { 2.538 +- /* mem is not used and at least perfect fit is possible: 2.539 +- * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ 2.540 +- 2.541 +- if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { 2.542 +- /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing 2.543 +- * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') 2.544 +- * -> split large block, create empty remainder, 2.545 +- * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if 2.546 +- * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, 2.547 +- * struct mem would fit in but no data between mem2 and mem2->next 2.548 +- * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty 2.549 +- * region that couldn't hold data, but when mem->next gets freed, 2.550 +- * the 2 regions would be combined, resulting in more free memory 2.551 +- */ 2.552 +- ptr2 = ptr + SIZEOF_STRUCT_MEM + size; 2.553 +- /* create mem2 struct */ 2.554 +- mem2 = (struct mem *)&ram[ptr2]; 2.555 +- mem2->used = 0; 2.556 +- mem2->next = mem->next; 2.557 +- mem2->prev = ptr; 2.558 +- /* and insert it between mem and mem->next */ 2.559 +- mem->next = ptr2; 2.560 +- mem->used = 1; 2.561 +- 2.562 +- if (mem2->next != MEM_SIZE_ALIGNED) { 2.563 +- ((struct mem *)&ram[mem2->next])->prev = ptr2; 2.564 +- } 2.565 +-#if MEM_STATS 2.566 +- lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM); 2.567 +- if (lwip_stats.mem.max < lwip_stats.mem.used) { 2.568 +- lwip_stats.mem.max = lwip_stats.mem.used; 2.569 ++ if ((!mem->used) && 2.570 ++ (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { 2.571 ++ /* mem is not used and at least perfect fit is possible: 2.572 ++ * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ 2.573 ++ 2.574 ++ if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { 2.575 ++ /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing 2.576 ++ * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') 2.577 ++ * -> split large block, create empty remainder, 2.578 ++ * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if 2.579 ++ * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, 2.580 ++ * struct mem would fit in but no data between mem2 and mem2->next 2.581 ++ * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty 2.582 ++ * region that couldn't hold data, but when mem->next gets freed, 2.583 ++ * the 2 regions would be combined, resulting in more free memory 2.584 ++ */ 2.585 ++ ptr2 = ptr + SIZEOF_STRUCT_MEM + size; 2.586 ++ /* create mem2 struct */ 2.587 ++ mem2 = (struct mem *)&ram[ptr2]; 2.588 ++ mem2->used = 0; 2.589 ++ mem2->next = mem->next; 2.590 ++ mem2->prev = ptr; 2.591 ++ /* and insert it between mem and mem->next */ 2.592 ++ mem->next = ptr2; 2.593 ++ mem->used = 1; 2.594 ++ 2.595 ++ if (mem2->next != MEM_SIZE_ALIGNED) { 2.596 ++ ((struct mem *)&ram[mem2->next])->prev = ptr2; 2.597 ++ } 2.598 ++ MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); 2.599 ++ } else { 2.600 ++ /* (a mem2 struct does no fit into the user data space of mem and mem->next will always 2.601 ++ * be used at this point: if not we have 2 unused structs in a row, plug_holes should have 2.602 ++ * take care of this). 2.603 ++ * -> near fit or excact fit: do not split, no mem2 creation 2.604 ++ * also can't move mem->next directly behind mem, since mem->next 2.605 ++ * will always be used at this point! 2.606 ++ */ 2.607 ++ mem->used = 1; 2.608 ++ MEM_STATS_INC_USED(used, mem->next - ((u8_t *)mem - ram)); 2.609 + } 2.610 +-#endif /* MEM_STATS */ 2.611 +- } else { 2.612 +- /* (a mem2 struct does no fit into the user data space of mem and mem->next will always 2.613 +- * be used at this point: if not we have 2 unused structs in a row, plug_holes should have 2.614 +- * take care of this). 2.615 +- * -> near fit or excact fit: do not split, no mem2 creation 2.616 +- * also can't move mem->next directly behind mem, since mem->next 2.617 +- * will always be used at this point! 2.618 +- */ 2.619 +- mem->used = 1; 2.620 +-#if MEM_STATS 2.621 +- lwip_stats.mem.used += mem->next - ((u8_t *)mem - ram); 2.622 +- if (lwip_stats.mem.max < lwip_stats.mem.used) { 2.623 +- lwip_stats.mem.max = lwip_stats.mem.used; 2.624 +- } 2.625 +-#endif /* MEM_STATS */ 2.626 +- } 2.627 + 2.628 +- if (mem == lfree) { 2.629 +- /* Find next free block after mem and update lowest free pointer */ 2.630 +- while (lfree->used && lfree != ram_end) { 2.631 +- lfree = (struct mem *)&ram[lfree->next]; 2.632 ++ if (mem == lfree) { 2.633 ++ /* Find next free block after mem and update lowest free pointer */ 2.634 ++ while (lfree->used && lfree != ram_end) { 2.635 ++ LWIP_MEM_ALLOC_UNPROTECT(); 2.636 ++ /* prevent high interrupt latency... */ 2.637 ++ LWIP_MEM_ALLOC_PROTECT(); 2.638 ++ lfree = (struct mem *)&ram[lfree->next]; 2.639 ++ } 2.640 ++ LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); 2.641 + } 2.642 +- LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); 2.643 +- } 2.644 +- sys_sem_signal(mem_sem); 2.645 +- LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", 2.646 +- (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); 2.647 +- LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", 2.648 +- (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); 2.649 +- LWIP_ASSERT("mem_malloc: sanity check alignment", 2.650 +- (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); 2.651 ++ LWIP_MEM_ALLOC_UNPROTECT(); 2.652 ++ sys_sem_signal(mem_sem); 2.653 ++ LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", 2.654 ++ (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); 2.655 ++ LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", 2.656 ++ (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); 2.657 ++ LWIP_ASSERT("mem_malloc: sanity check alignment", 2.658 ++ (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); 2.659 + 2.660 +- return (u8_t *)mem + SIZEOF_STRUCT_MEM; 2.661 ++ return (u8_t *)mem + SIZEOF_STRUCT_MEM; 2.662 ++ } 2.663 + } 2.664 +- } 2.665 ++#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.666 ++ /* if we got interrupted by a mem_free, try again */ 2.667 ++ } while(local_mem_free_count != 0); 2.668 ++#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ 2.669 + LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); 2.670 +-#if MEM_STATS 2.671 +- ++lwip_stats.mem.err; 2.672 +-#endif /* MEM_STATS */ 2.673 ++ MEM_STATS_INC(err); 2.674 ++ LWIP_MEM_ALLOC_UNPROTECT(); 2.675 + sys_sem_signal(mem_sem); 2.676 + return NULL; 2.677 + } 2.678 +Index: src/core/memp.c 2.679 +=================================================================== 2.680 +RCS file: /sources/lwip/lwip/src/core/memp.c,v 2.681 +retrieving revision 1.55 2.682 +retrieving revision 1.56 2.683 +diff -u -p -r1.55 -r1.56 2.684 +--- src/core/memp.c 25 Nov 2007 10:43:28 -0000 1.55 2.685 ++++ src/core/memp.c 27 Jun 2008 18:37:54 -0000 1.56 2.686 +@@ -252,13 +252,12 @@ memp_init(void) 2.687 + struct memp *memp; 2.688 + u16_t i, j; 2.689 + 2.690 +-#if MEMP_STATS 2.691 + for (i = 0; i < MEMP_MAX; ++i) { 2.692 +- lwip_stats.memp[i].used = lwip_stats.memp[i].max = 2.693 +- lwip_stats.memp[i].err = 0; 2.694 +- lwip_stats.memp[i].avail = memp_num[i]; 2.695 ++ MEMP_STATS_AVAIL(used, i, 0); 2.696 ++ MEMP_STATS_AVAIL(max, i, 0); 2.697 ++ MEMP_STATS_AVAIL(err, i, 0); 2.698 ++ MEMP_STATS_AVAIL(avail, i, memp_num[i]); 2.699 + } 2.700 +-#endif /* MEMP_STATS */ 2.701 + 2.702 + memp = LWIP_MEM_ALIGN(memp_memory); 2.703 + /* for every pool: */ 2.704 +@@ -315,20 +314,13 @@ memp_malloc_fn(memp_t type, const char* 2.705 + memp->file = file; 2.706 + memp->line = line; 2.707 + #endif /* MEMP_OVERFLOW_CHECK */ 2.708 +-#if MEMP_STATS 2.709 +- ++lwip_stats.memp[type].used; 2.710 +- if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) { 2.711 +- lwip_stats.memp[type].max = lwip_stats.memp[type].used; 2.712 +- } 2.713 +-#endif /* MEMP_STATS */ 2.714 ++ MEMP_STATS_INC_USED(used, type); 2.715 + LWIP_ASSERT("memp_malloc: memp properly aligned", 2.716 + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); 2.717 + memp = (struct memp*)((u8_t*)memp + MEMP_SIZE); 2.718 + } else { 2.719 + LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); 2.720 +-#if MEMP_STATS 2.721 +- ++lwip_stats.memp[type].err; 2.722 +-#endif /* MEMP_STATS */ 2.723 ++ MEMP_STATS_INC(err, type); 2.724 + } 2.725 + 2.726 + SYS_ARCH_UNPROTECT(old_level); 2.727 +@@ -365,9 +357,7 @@ memp_free(memp_t type, void *mem) 2.728 + #endif /* MEMP_OVERFLOW_CHECK >= 2 */ 2.729 + #endif /* MEMP_OVERFLOW_CHECK */ 2.730 + 2.731 +-#if MEMP_STATS 2.732 +- lwip_stats.memp[type].used--; 2.733 +-#endif /* MEMP_STATS */ 2.734 ++ MEMP_STATS_DEC(used, type); 2.735 + 2.736 + memp->next = memp_tab[type]; 2.737 + memp_tab[type] = memp; 2.738 +Index: src/core/netif.c 2.739 +=================================================================== 2.740 +RCS file: /sources/lwip/lwip/src/core/netif.c,v 2.741 +retrieving revision 1.65 2.742 +retrieving revision 1.68 2.743 +diff -u -p -r1.65 -r1.68 2.744 +--- src/core/netif.c 9 Oct 2007 20:00:55 -0000 1.65 2.745 ++++ src/core/netif.c 19 Jun 2008 16:27:18 -0000 1.68 2.746 +@@ -45,6 +45,12 @@ 2.747 + #include "lwip/snmp.h" 2.748 + #include "lwip/igmp.h" 2.749 + #include "netif/etharp.h" 2.750 ++#if ENABLE_LOOPBACK 2.751 ++#include "lwip/sys.h" 2.752 ++#if LWIP_NETIF_LOOPBACK_MULTITHREADING 2.753 ++#include "lwip/tcpip.h" 2.754 ++#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ 2.755 ++#endif /* ENABLE_LOOPBACK */ 2.756 + 2.757 + #if LWIP_NETIF_STATUS_CALLBACK 2.758 + #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); } 2.759 +@@ -106,6 +112,10 @@ netif_add(struct netif *netif, struct ip 2.760 + #if LWIP_IGMP 2.761 + netif->igmp_mac_filter = NULL; 2.762 + #endif /* LWIP_IGMP */ 2.763 ++#if ENABLE_LOOPBACK 2.764 ++ netif->loop_first = NULL; 2.765 ++ netif->loop_last = NULL; 2.766 ++#endif /* ENABLE_LOOPBACK */ 2.767 + 2.768 + /* remember netif specific state information data */ 2.769 + netif->state = state; 2.770 +@@ -114,6 +124,9 @@ netif_add(struct netif *netif, struct ip 2.771 + #if LWIP_NETIF_HWADDRHINT 2.772 + netif->addr_hint = NULL; 2.773 + #endif /* LWIP_NETIF_HWADDRHINT*/ 2.774 ++#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS 2.775 ++ netif->loop_cnt_current = 0; 2.776 ++#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ 2.777 + 2.778 + netif_set_addr(netif, ipaddr, netmask, gw); 2.779 + 2.780 +@@ -493,7 +506,158 @@ u8_t netif_is_link_up(struct netif *neti 2.781 + */ 2.782 + void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif )) 2.783 + { 2.784 +- if ( netif ) 2.785 +- netif->link_callback = link_callback; 2.786 ++ if (netif) { 2.787 ++ netif->link_callback = link_callback; 2.788 ++ } 2.789 + } 2.790 + #endif /* LWIP_NETIF_LINK_CALLBACK */ 2.791 ++ 2.792 ++#if ENABLE_LOOPBACK 2.793 ++/** 2.794 ++ * Send an IP packet to be received on the same netif (loopif-like). 2.795 ++ * The pbuf is simply copied and handed back to netif->input. 2.796 ++ * In multithreaded mode, this is done directly since netif->input must put 2.797 ++ * the packet on a queue. 2.798 ++ * In callback mode, the packet is put on an internal queue and is fed to 2.799 ++ * netif->input by netif_poll(). 2.800 ++ * 2.801 ++ * @param netif the lwip network interface structure 2.802 ++ * @param p the (IP) packet to 'send' 2.803 ++ * @param ipaddr the ip address to send the packet to (not used) 2.804 ++ * @return ERR_OK if the packet has been sent 2.805 ++ * ERR_MEM if the pbuf used to copy the packet couldn't be allocated 2.806 ++ */ 2.807 ++err_t 2.808 ++netif_loop_output(struct netif *netif, struct pbuf *p, 2.809 ++ struct ip_addr *ipaddr) 2.810 ++{ 2.811 ++ struct pbuf *r; 2.812 ++ err_t err; 2.813 ++ struct pbuf *last; 2.814 ++#if LWIP_LOOPBACK_MAX_PBUFS 2.815 ++ u8_t clen = 0; 2.816 ++#endif /* LWIP_LOOPBACK_MAX_PBUFS */ 2.817 ++ SYS_ARCH_DECL_PROTECT(lev); 2.818 ++ LWIP_UNUSED_ARG(ipaddr); 2.819 ++ 2.820 ++ /* Allocate a new pbuf */ 2.821 ++ r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); 2.822 ++ if (r == NULL) { 2.823 ++ return ERR_MEM; 2.824 ++ } 2.825 ++#if LWIP_LOOPBACK_MAX_PBUFS 2.826 ++ clen = pbuf_clen(r); 2.827 ++ /* check for overflow or too many pbuf on queue */ 2.828 ++ if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || 2.829 ++ ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { 2.830 ++ pbuf_free(r); 2.831 ++ r = NULL; 2.832 ++ return ERR_MEM; 2.833 ++ } 2.834 ++ netif->loop_cnt_current += clen; 2.835 ++#endif /* LWIP_LOOPBACK_MAX_PBUFS */ 2.836 ++ 2.837 ++ /* Copy the whole pbuf queue p into the single pbuf r */ 2.838 ++ if ((err = pbuf_copy(r, p)) != ERR_OK) { 2.839 ++ pbuf_free(r); 2.840 ++ r = NULL; 2.841 ++ return err; 2.842 ++ } 2.843 ++ 2.844 ++ /* Put the packet on a linked list which gets emptied through calling 2.845 ++ netif_poll(). */ 2.846 ++ 2.847 ++ /* let last point to the last pbuf in chain r */ 2.848 ++ for (last = r; last->next != NULL; last = last->next); 2.849 ++ 2.850 ++ SYS_ARCH_PROTECT(lev); 2.851 ++ if(netif->loop_first != NULL) { 2.852 ++ LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); 2.853 ++ netif->loop_last->next = r; 2.854 ++ netif->loop_last = last; 2.855 ++ } else { 2.856 ++ netif->loop_first = r; 2.857 ++ netif->loop_last = last; 2.858 ++ } 2.859 ++ SYS_ARCH_UNPROTECT(lev); 2.860 ++ 2.861 ++#if LWIP_NETIF_LOOPBACK_MULTITHREADING 2.862 ++ /* For multithreading environment, schedule a call to netif_poll */ 2.863 ++ tcpip_callback(netif_poll, netif); 2.864 ++#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ 2.865 ++ 2.866 ++ return ERR_OK; 2.867 ++} 2.868 ++ 2.869 ++/** 2.870 ++ * Call netif_poll() in the main loop of your application. This is to prevent 2.871 ++ * reentering non-reentrant functions like tcp_input(). Packets passed to 2.872 ++ * netif_loop_output() are put on a list that is passed to netif->input() by 2.873 ++ * netif_poll(). 2.874 ++ */ 2.875 ++void 2.876 ++netif_poll(struct netif *netif) 2.877 ++{ 2.878 ++ struct pbuf *in; 2.879 ++ SYS_ARCH_DECL_PROTECT(lev); 2.880 ++ 2.881 ++ do { 2.882 ++ /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ 2.883 ++ SYS_ARCH_PROTECT(lev); 2.884 ++ in = netif->loop_first; 2.885 ++ if(in != NULL) { 2.886 ++ struct pbuf *in_end = in; 2.887 ++#if LWIP_LOOPBACK_MAX_PBUFS 2.888 ++ u8_t clen = pbuf_clen(in); 2.889 ++ /* adjust the number of pbufs on queue */ 2.890 ++ LWIP_ASSERT("netif->loop_cnt_current underflow", 2.891 ++ ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); 2.892 ++ netif->loop_cnt_current -= clen; 2.893 ++#endif /* LWIP_LOOPBACK_MAX_PBUFS */ 2.894 ++ while(in_end->len != in_end->tot_len) { 2.895 ++ LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); 2.896 ++ in_end = in_end->next; 2.897 ++ } 2.898 ++ /* 'in_end' now points to the last pbuf from 'in' */ 2.899 ++ if(in_end == netif->loop_last) { 2.900 ++ /* this was the last pbuf in the list */ 2.901 ++ netif->loop_first = netif->loop_last = NULL; 2.902 ++ } else { 2.903 ++ /* pop the pbuf off the list */ 2.904 ++ netif->loop_first = in_end->next; 2.905 ++ LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); 2.906 ++ } 2.907 ++ /* De-queue the pbuf from its successors on the 'loop_' list. */ 2.908 ++ in_end->next = NULL; 2.909 ++ } 2.910 ++ SYS_ARCH_UNPROTECT(lev); 2.911 ++ 2.912 ++ if(in != NULL) { 2.913 ++ /* loopback packets are always IP packets! */ 2.914 ++ if(ip_input(in, netif) != ERR_OK) { 2.915 ++ pbuf_free(in); 2.916 ++ } 2.917 ++ /* Don't reference the packet any more! */ 2.918 ++ in = NULL; 2.919 ++ } 2.920 ++ /* go on while there is a packet on the list */ 2.921 ++ } while(netif->loop_first != NULL); 2.922 ++} 2.923 ++ 2.924 ++#if !LWIP_NETIF_LOOPBACK_MULTITHREADING 2.925 ++/** 2.926 ++ * Calls netif_poll() for every netif on the netif_list. 2.927 ++ */ 2.928 ++void 2.929 ++netif_poll_all(void) 2.930 ++{ 2.931 ++ struct netif *netif = netif_list; 2.932 ++ /* loop through netifs */ 2.933 ++ while (netif != NULL) { 2.934 ++ netif_poll(netif); 2.935 ++ /* proceed to next network interface */ 2.936 ++ netif = netif->next; 2.937 ++ } 2.938 ++} 2.939 ++#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ 2.940 ++#endif /* ENABLE_LOOPBACK */ 2.941 +Index: src/core/pbuf.c 2.942 +=================================================================== 2.943 +RCS file: /sources/lwip/lwip/src/core/pbuf.c,v 2.944 +retrieving revision 1.127 2.945 +retrieving revision 1.128 2.946 +diff -u -p -r1.127 -r1.128 2.947 +--- src/core/pbuf.c 4 Mar 2008 16:37:46 -0000 1.127 2.948 ++++ src/core/pbuf.c 1 Apr 2008 19:05:40 -0000 1.128 2.949 +@@ -667,8 +667,8 @@ pbuf_dechain(struct pbuf *p) 2.950 + * 2.951 + * @note Only one packet is copied, no packet queue! 2.952 + * 2.953 +- * @param p_to pbuf source of the copy 2.954 +- * @param p_from pbuf destination of the copy 2.955 ++ * @param p_to pbuf destination of the copy 2.956 ++ * @param p_from pbuf source of the copy 2.957 + * 2.958 + * @return ERR_OK if pbuf was copied 2.959 + * ERR_ARG if one of the pbufs is NULL or p_to is not big 2.960 +Index: src/core/stats.c 2.961 +=================================================================== 2.962 +RCS file: /sources/lwip/lwip/src/core/stats.c,v 2.963 +retrieving revision 1.27 2.964 +retrieving revision 1.28 2.965 +diff -u -p -r1.27 -r1.28 2.966 +--- src/core/stats.c 4 Mar 2008 16:31:32 -0000 1.27 2.967 ++++ src/core/stats.c 27 Jun 2008 18:37:54 -0000 1.28 2.968 +@@ -54,7 +54,6 @@ stats_display_proto(struct stats_proto * 2.969 + { 2.970 + LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); 2.971 + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); 2.972 +- LWIP_PLATFORM_DIAG(("rexmit: %"STAT_COUNTER_F"\n\t", proto->rexmit)); 2.973 + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); 2.974 + LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); 2.975 + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); 2.976 +@@ -68,6 +67,7 @@ stats_display_proto(struct stats_proto * 2.977 + LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); 2.978 + } 2.979 + 2.980 ++#if IGMP_STATS 2.981 + void 2.982 + stats_display_igmp(struct stats_igmp *igmp) 2.983 + { 2.984 +@@ -82,7 +82,9 @@ stats_display_igmp(struct stats_igmp *ig 2.985 + LWIP_PLATFORM_DIAG(("report_rxed: %"STAT_COUNTER_F"\n\t", igmp->report_rxed)); 2.986 + LWIP_PLATFORM_DIAG(("group_query_rxed: %"STAT_COUNTER_F"\n", igmp->group_query_rxed)); 2.987 + } 2.988 ++#endif /* IGMP_STATS */ 2.989 + 2.990 ++#if MEM_STATS || MEMP_STATS 2.991 + void 2.992 + stats_display_mem(struct stats_mem *mem, char *name) 2.993 + { 2.994 +@@ -93,48 +95,53 @@ stats_display_mem(struct stats_mem *mem, 2.995 + LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); 2.996 + } 2.997 + 2.998 ++#if MEMP_STATS 2.999 + void 2.1000 +-stats_display(void) 2.1001 ++stats_display_memp(struct stats_mem *mem, int index) 2.1002 + { 2.1003 +-#if MEMP_STATS 2.1004 +- s16_t i; 2.1005 + char * memp_names[] = { 2.1006 + #define LWIP_MEMPOOL(name,num,size,desc) desc, 2.1007 + #include "lwip/memp_std.h" 2.1008 + }; 2.1009 +-#endif 2.1010 +-#if LINK_STATS 2.1011 +- stats_display_proto(&lwip_stats.link, "LINK"); 2.1012 +-#endif 2.1013 +-#if ETHARP_STATS 2.1014 +- stats_display_proto(&lwip_stats.etharp, "ETHARP"); 2.1015 +-#endif 2.1016 +-#if IPFRAG_STATS 2.1017 +- stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG"); 2.1018 +-#endif 2.1019 +-#if IP_STATS 2.1020 +- stats_display_proto(&lwip_stats.ip, "IP"); 2.1021 +-#endif 2.1022 +-#if ICMP_STATS 2.1023 +- stats_display_proto(&lwip_stats.icmp, "ICMP"); 2.1024 +-#endif 2.1025 +-#if IGMP_STATS 2.1026 +- stats_display_igmp(&lwip_stats.igmp); 2.1027 +-#endif 2.1028 +-#if UDP_STATS 2.1029 +- stats_display_proto(&lwip_stats.udp, "UDP"); 2.1030 +-#endif 2.1031 +-#if TCP_STATS 2.1032 +- stats_display_proto(&lwip_stats.tcp, "TCP"); 2.1033 +-#endif 2.1034 +-#if MEM_STATS 2.1035 +- stats_display_mem(&lwip_stats.mem, "HEAP"); 2.1036 +-#endif 2.1037 +-#if MEMP_STATS 2.1038 ++ if(index < MEMP_MAX) { 2.1039 ++ stats_display_mem(mem, memp_names[index]); 2.1040 ++ } 2.1041 ++} 2.1042 ++#endif /* MEMP_STATS */ 2.1043 ++#endif /* MEM_STATS || MEMP_STATS */ 2.1044 ++ 2.1045 ++#if SYS_STATS 2.1046 ++void 2.1047 ++stats_display_sys(struct stats_sys *sys) 2.1048 ++{ 2.1049 ++ LWIP_PLATFORM_DIAG(("\nSYS\n\t")); 2.1050 ++ LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); 2.1051 ++ LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); 2.1052 ++ LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); 2.1053 ++ LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); 2.1054 ++ LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); 2.1055 ++ LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err)); 2.1056 ++} 2.1057 ++#endif /* SYS_STATS */ 2.1058 ++ 2.1059 ++void 2.1060 ++stats_display(void) 2.1061 ++{ 2.1062 ++ s16_t i; 2.1063 ++ 2.1064 ++ LINK_STATS_DISPLAY(); 2.1065 ++ ETHARP_STATS_DISPLAY(); 2.1066 ++ IPFRAG_STATS_DISPLAY(); 2.1067 ++ IP_STATS_DISPLAY(); 2.1068 ++ IGMP_STATS_DISPLAY(); 2.1069 ++ ICMP_STATS_DISPLAY(); 2.1070 ++ UDP_STATS_DISPLAY(); 2.1071 ++ TCP_STATS_DISPLAY(); 2.1072 ++ MEM_STATS_DISPLAY(); 2.1073 + for (i = 0; i < MEMP_MAX; i++) { 2.1074 +- stats_display_mem(&lwip_stats.memp[i], memp_names[i]); 2.1075 ++ MEMP_STATS_DISPLAY(i); 2.1076 + } 2.1077 +-#endif 2.1078 ++ SYS_STATS_DISPLAY(); 2.1079 + } 2.1080 + #endif /* LWIP_STATS_DISPLAY */ 2.1081 + 2.1082 +Index: src/core/sys.c 2.1083 +=================================================================== 2.1084 +RCS file: /sources/lwip/lwip/src/core/sys.c,v 2.1085 +retrieving revision 1.32 2.1086 +retrieving revision 1.33 2.1087 +diff -u -p -r1.32 -r1.33 2.1088 +--- src/core/sys.c 25 Nov 2007 13:57:05 -0000 1.32 2.1089 ++++ src/core/sys.c 16 Jul 2008 20:36:12 -0000 1.33 2.1090 +@@ -65,7 +65,7 @@ struct sswt_cb 2.1091 + void 2.1092 + sys_mbox_fetch(sys_mbox_t mbox, void **msg) 2.1093 + { 2.1094 +- u32_t time; 2.1095 ++ u32_t time_needed; 2.1096 + struct sys_timeouts *timeouts; 2.1097 + struct sys_timeo *tmptimeout; 2.1098 + sys_timeout_handler h; 2.1099 +@@ -76,18 +76,18 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m 2.1100 + 2.1101 + if (!timeouts || !timeouts->next) { 2.1102 + UNLOCK_TCPIP_CORE(); 2.1103 +- time = sys_arch_mbox_fetch(mbox, msg, 0); 2.1104 ++ time_needed = sys_arch_mbox_fetch(mbox, msg, 0); 2.1105 + LOCK_TCPIP_CORE(); 2.1106 + } else { 2.1107 + if (timeouts->next->time > 0) { 2.1108 + UNLOCK_TCPIP_CORE(); 2.1109 +- time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time); 2.1110 ++ time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time); 2.1111 + LOCK_TCPIP_CORE(); 2.1112 + } else { 2.1113 +- time = SYS_ARCH_TIMEOUT; 2.1114 ++ time_needed = SYS_ARCH_TIMEOUT; 2.1115 + } 2.1116 + 2.1117 +- if (time == SYS_ARCH_TIMEOUT) { 2.1118 ++ if (time_needed == SYS_ARCH_TIMEOUT) { 2.1119 + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message 2.1120 + could be fetched. We should now call the timeout handler and 2.1121 + deallocate the memory allocated for the timeout. */ 2.1122 +@@ -107,8 +107,8 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m 2.1123 + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout 2.1124 + occured. The time variable is set to the number of 2.1125 + milliseconds we waited for the message. */ 2.1126 +- if (time < timeouts->next->time) { 2.1127 +- timeouts->next->time -= time; 2.1128 ++ if (time_needed < timeouts->next->time) { 2.1129 ++ timeouts->next->time -= time_needed; 2.1130 + } else { 2.1131 + timeouts->next->time = 0; 2.1132 + } 2.1133 +@@ -125,7 +125,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m 2.1134 + void 2.1135 + sys_sem_wait(sys_sem_t sem) 2.1136 + { 2.1137 +- u32_t time; 2.1138 ++ u32_t time_needed; 2.1139 + struct sys_timeouts *timeouts; 2.1140 + struct sys_timeo *tmptimeout; 2.1141 + sys_timeout_handler h; 2.1142 +@@ -139,12 +139,12 @@ sys_sem_wait(sys_sem_t sem) 2.1143 + sys_arch_sem_wait(sem, 0); 2.1144 + } else { 2.1145 + if (timeouts->next->time > 0) { 2.1146 +- time = sys_arch_sem_wait(sem, timeouts->next->time); 2.1147 ++ time_needed = sys_arch_sem_wait(sem, timeouts->next->time); 2.1148 + } else { 2.1149 +- time = SYS_ARCH_TIMEOUT; 2.1150 ++ time_needed = SYS_ARCH_TIMEOUT; 2.1151 + } 2.1152 + 2.1153 +- if (time == SYS_ARCH_TIMEOUT) { 2.1154 ++ if (time_needed == SYS_ARCH_TIMEOUT) { 2.1155 + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message 2.1156 + could be fetched. We should now call the timeout handler and 2.1157 + deallocate the memory allocated for the timeout. */ 2.1158 +@@ -164,8 +164,8 @@ sys_sem_wait(sys_sem_t sem) 2.1159 + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout 2.1160 + occured. The time variable is set to the number of 2.1161 + milliseconds we waited for the message. */ 2.1162 +- if (time < timeouts->next->time) { 2.1163 +- timeouts->next->time -= time; 2.1164 ++ if (time_needed < timeouts->next->time) { 2.1165 ++ timeouts->next->time -= time_needed; 2.1166 + } else { 2.1167 + timeouts->next->time = 0; 2.1168 + } 2.1169 +Index: src/core/tcp.c 2.1170 +=================================================================== 2.1171 +RCS file: /sources/lwip/lwip/src/core/tcp.c,v 2.1172 +retrieving revision 1.85 2.1173 +retrieving revision 1.86 2.1174 +diff -u -p -r1.85 -r1.86 2.1175 +--- src/core/tcp.c 22 Jan 2008 21:15:15 -0000 1.85 2.1176 ++++ src/core/tcp.c 26 Mar 2008 11:57:13 -0000 1.86 2.1177 +@@ -509,7 +509,8 @@ tcp_connect(struct tcp_pcb *pcb, struct 2.1178 + pcb->rcv_wnd = TCP_WND; 2.1179 + pcb->rcv_ann_wnd = TCP_WND; 2.1180 + pcb->snd_wnd = TCP_WND; 2.1181 +- /* The send MSS is updated when an MSS option is received. */ 2.1182 ++ /* As initial send MSS, we use TCP_MSS but limit it to 536. 2.1183 ++ The send MSS is updated when an MSS option is received. */ 2.1184 + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 2.1185 + #if TCP_CALCULATE_EFF_SEND_MSS 2.1186 + pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); 2.1187 +@@ -991,7 +992,8 @@ tcp_alloc(u8_t prio) 2.1188 + pcb->rcv_ann_wnd = TCP_WND; 2.1189 + pcb->tos = 0; 2.1190 + pcb->ttl = TCP_TTL; 2.1191 +- /* The send MSS is updated when an MSS option is received. */ 2.1192 ++ /* As initial send MSS, we use TCP_MSS but limit it to 536. 2.1193 ++ The send MSS is updated when an MSS option is received. */ 2.1194 + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 2.1195 + pcb->rto = 3000 / TCP_SLOW_INTERVAL; 2.1196 + pcb->sa = 0; 2.1197 +Index: src/core/tcp_in.c 2.1198 +=================================================================== 2.1199 +RCS file: /sources/lwip/lwip/src/core/tcp_in.c,v 2.1200 +retrieving revision 1.97 2.1201 +retrieving revision 1.100 2.1202 +diff -u -p -r1.97 -r1.100 2.1203 +--- src/core/tcp_in.c 22 Jan 2008 21:15:15 -0000 1.97 2.1204 ++++ src/core/tcp_in.c 24 Jun 2008 15:46:39 -0000 1.100 2.1205 +@@ -511,7 +511,7 @@ tcp_process(struct tcp_pcb *pcb) 2.1206 + } 2.1207 + } else { 2.1208 + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 2.1209 +- pcb->rcv_nxt+pcb->rcv_ann_wnd)) { 2.1210 ++ pcb->rcv_nxt+pcb->rcv_wnd)) { 2.1211 + acceptable = 1; 2.1212 + } 2.1213 + } 2.1214 +@@ -1038,7 +1038,7 @@ tcp_receive(struct tcp_pcb *pcb) 2.1215 + and below rcv_nxt + rcv_wnd) in order to be further 2.1216 + processed. */ 2.1217 + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 2.1218 +- pcb->rcv_nxt + pcb->rcv_ann_wnd - 1)){ 2.1219 ++ pcb->rcv_nxt + pcb->rcv_wnd - 1)){ 2.1220 + if (pcb->rcv_nxt == seqno) { 2.1221 + accepted_inseq = 1; 2.1222 + /* The incoming segment is the next in sequence. We check if 2.1223 +@@ -1195,14 +1195,14 @@ tcp_receive(struct tcp_pcb *pcb) 2.1224 + } else { 2.1225 + pcb->ooseq = cseg; 2.1226 + } 2.1227 +- } 2.1228 +- tcp_seg_free(next); 2.1229 +- if (cseg->next != NULL) { 2.1230 +- next = cseg->next; 2.1231 +- if (TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { 2.1232 +- /* We need to trim the incoming segment. */ 2.1233 +- cseg->len = (u16_t)(next->tcphdr->seqno - seqno); 2.1234 +- pbuf_realloc(cseg->p, cseg->len); 2.1235 ++ tcp_seg_free(next); 2.1236 ++ if (cseg->next != NULL) { 2.1237 ++ next = cseg->next; 2.1238 ++ if (TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { 2.1239 ++ /* We need to trim the incoming segment. */ 2.1240 ++ cseg->len = (u16_t)(next->tcphdr->seqno - seqno); 2.1241 ++ pbuf_realloc(cseg->p, cseg->len); 2.1242 ++ } 2.1243 + } 2.1244 + } 2.1245 + break; 2.1246 +@@ -1282,10 +1282,7 @@ tcp_receive(struct tcp_pcb *pcb) 2.1247 + 2.1248 + } 2.1249 + } else { 2.1250 +- if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, 2.1251 +- pcb->rcv_nxt + pcb->rcv_ann_wnd-1)){ 2.1252 +- tcp_ack_now(pcb); 2.1253 +- } 2.1254 ++ tcp_ack_now(pcb); 2.1255 + } 2.1256 + } else { 2.1257 + /* Segments with length 0 is taken care of here. Segments that 2.1258 +@@ -1331,7 +1328,8 @@ tcp_parseopt(struct tcp_pcb *pcb) 2.1259 + opts[c + 1] == 0x04) { 2.1260 + /* An MSS option with the right option length. */ 2.1261 + mss = (opts[c + 2] << 8) | opts[c + 3]; 2.1262 +- pcb->mss = mss > TCP_MSS? TCP_MSS: mss; 2.1263 ++ /* Limit the mss to the configured TCP_MSS and prevent division by zero */ 2.1264 ++ pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; 2.1265 + 2.1266 + /* And we are done processing options. */ 2.1267 + break; 2.1268 +Index: src/core/ipv4/autoip.c 2.1269 +=================================================================== 2.1270 +RCS file: /sources/lwip/lwip/src/core/ipv4/autoip.c,v 2.1271 +retrieving revision 1.16 2.1272 +retrieving revision 1.17 2.1273 +diff -u -p -r1.16 -r1.17 2.1274 +--- src/core/ipv4/autoip.c 26 Jan 2008 16:11:40 -0000 1.16 2.1275 ++++ src/core/ipv4/autoip.c 17 Jun 2008 20:16:23 -0000 1.17 2.1276 +@@ -395,8 +395,8 @@ autoip_arp_reply(struct netif *netif, st 2.1277 + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without 2.1278 + * structure packing (not using structure copy which breaks strict-aliasing rules). 2.1279 + */ 2.1280 +- MEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr)); 2.1281 +- MEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr)); 2.1282 ++ SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr)); 2.1283 ++ SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr)); 2.1284 + 2.1285 + if ((netif->autoip->state == AUTOIP_STATE_PROBING) || 2.1286 + ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && 2.1287 +Index: src/core/ipv4/inet_chksum.c 2.1288 +=================================================================== 2.1289 +RCS file: /sources/lwip/lwip/src/core/ipv4/inet_chksum.c,v 2.1290 +retrieving revision 1.4 2.1291 +retrieving revision 1.5 2.1292 +diff -u -p -r1.4 -r1.5 2.1293 +--- src/core/ipv4/inet_chksum.c 10 Mar 2008 16:12:31 -0000 1.4 2.1294 ++++ src/core/ipv4/inet_chksum.c 17 Jun 2008 20:06:25 -0000 1.5 2.1295 +@@ -41,8 +41,6 @@ 2.1296 + #include "lwip/inet_chksum.h" 2.1297 + #include "lwip/inet.h" 2.1298 + 2.1299 +-#include <string.h> 2.1300 +- 2.1301 + /* These are some reference implementations of the checksum algorithm, with the 2.1302 + * aim of being simple, correct and fully portable. Checksumming is the 2.1303 + * first thing you would want to optimize for your platform. If you create 2.1304 +@@ -65,6 +63,11 @@ 2.1305 + # define LWIP_CHKSUM_ALGORITHM 0 2.1306 + #endif 2.1307 + 2.1308 ++/** Like the name says... */ 2.1309 ++#define SWAP_BYTES_IN_WORD(w) ((w & 0xff) << 8) | ((w & 0xff00) >> 8) 2.1310 ++/** Split an u32_t in two u16_ts and add them up */ 2.1311 ++#define FOLD_U32T(u) ((u >> 16) + (u & 0x0000ffffUL)) 2.1312 ++ 2.1313 + #if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ 2.1314 + /** 2.1315 + * lwip checksum 2.1316 +@@ -86,8 +89,7 @@ lwip_standard_chksum(void *dataptr, u16_ 2.1317 + acc = 0; 2.1318 + /* dataptr may be at odd or even addresses */ 2.1319 + octetptr = (u8_t*)dataptr; 2.1320 +- while (len > 1) 2.1321 +- { 2.1322 ++ while (len > 1) { 2.1323 + /* declare first octet as most significant 2.1324 + thus assume network order, ignoring host order */ 2.1325 + src = (*octetptr) << 8; 2.1326 +@@ -98,8 +100,7 @@ lwip_standard_chksum(void *dataptr, u16_ 2.1327 + acc += src; 2.1328 + len -= 2; 2.1329 + } 2.1330 +- if (len > 0) 2.1331 +- { 2.1332 ++ if (len > 0) { 2.1333 + /* accumulate remaining octet */ 2.1334 + src = (*octetptr) << 8; 2.1335 + acc += src; 2.1336 +@@ -154,19 +155,22 @@ lwip_standard_chksum(void *dataptr, int 2.1337 + } 2.1338 + 2.1339 + /* Consume left-over byte, if any */ 2.1340 +- if (len > 0) 2.1341 ++ if (len > 0) { 2.1342 + ((u8_t *)&t)[0] = *(u8_t *)ps;; 2.1343 ++ } 2.1344 + 2.1345 + /* Add end bytes */ 2.1346 + sum += t; 2.1347 + 2.1348 +- /* Fold 32-bit sum to 16 bits */ 2.1349 +- while ((sum >> 16) != 0) 2.1350 +- sum = (sum & 0xffff) + (sum >> 16); 2.1351 ++ /* Fold 32-bit sum to 16 bits 2.1352 ++ calling this twice is propably faster than if statements... */ 2.1353 ++ sum = FOLD_U32T(sum); 2.1354 ++ sum = FOLD_U32T(sum); 2.1355 + 2.1356 + /* Swap if alignment was odd */ 2.1357 +- if (odd) 2.1358 +- sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8); 2.1359 ++ if (odd) { 2.1360 ++ sum = SWAP_BYTES_IN_WORD(sum); 2.1361 ++ } 2.1362 + 2.1363 + return sum; 2.1364 + } 2.1365 +@@ -211,18 +215,20 @@ lwip_standard_chksum(void *dataptr, int 2.1366 + 2.1367 + while (len > 7) { 2.1368 + tmp = sum + *pl++; /* ping */ 2.1369 +- if (tmp < sum) 2.1370 ++ if (tmp < sum) { 2.1371 + tmp++; /* add back carry */ 2.1372 ++ } 2.1373 + 2.1374 + sum = tmp + *pl++; /* pong */ 2.1375 +- if (sum < tmp) 2.1376 ++ if (sum < tmp) { 2.1377 + sum++; /* add back carry */ 2.1378 ++ } 2.1379 + 2.1380 + len -= 8; 2.1381 + } 2.1382 + 2.1383 + /* make room in upper bits */ 2.1384 +- sum = (sum >> 16) + (sum & 0xffff); 2.1385 ++ sum = FOLD_U32T(sum); 2.1386 + 2.1387 + ps = (u16_t *)pl; 2.1388 + 2.1389 +@@ -233,16 +239,20 @@ lwip_standard_chksum(void *dataptr, int 2.1390 + } 2.1391 + 2.1392 + /* dangling tail byte remaining? */ 2.1393 +- if (len > 0) /* include odd byte */ 2.1394 ++ if (len > 0) { /* include odd byte */ 2.1395 + ((u8_t *)&t)[0] = *(u8_t *)ps; 2.1396 ++ } 2.1397 + 2.1398 + sum += t; /* add end bytes */ 2.1399 + 2.1400 +- while ((sum >> 16) != 0) /* combine halves */ 2.1401 +- sum = (sum >> 16) + (sum & 0xffff); 2.1402 ++ /* Fold 32-bit sum to 16 bits 2.1403 ++ calling this twice is propably faster than if statements... */ 2.1404 ++ sum = FOLD_U32T(sum); 2.1405 ++ sum = FOLD_U32T(sum); 2.1406 + 2.1407 +- if (odd) 2.1408 +- sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8); 2.1409 ++ if (odd) { 2.1410 ++ sum = SWAP_BYTES_IN_WORD(sum); 2.1411 ++ } 2.1412 + 2.1413 + return sum; 2.1414 + } 2.1415 +@@ -277,18 +287,18 @@ inet_chksum_pseudo(struct pbuf *p, 2.1416 + (void *)q, (void *)q->next)); 2.1417 + acc += LWIP_CHKSUM(q->payload, q->len); 2.1418 + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ 2.1419 +- while ((acc >> 16) != 0) { 2.1420 +- acc = (acc & 0xffffUL) + (acc >> 16); 2.1421 +- } 2.1422 ++ /* just executing this next line is probably faster that the if statement needed 2.1423 ++ to check whether we really need to execute it, and does no harm */ 2.1424 ++ acc = FOLD_U32T(acc); 2.1425 + if (q->len % 2 != 0) { 2.1426 + swapped = 1 - swapped; 2.1427 +- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8); 2.1428 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1429 + } 2.1430 + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ 2.1431 + } 2.1432 + 2.1433 + if (swapped) { 2.1434 +- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8); 2.1435 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1436 + } 2.1437 + acc += (src->addr & 0xffffUL); 2.1438 + acc += ((src->addr >> 16) & 0xffffUL); 2.1439 +@@ -297,9 +307,10 @@ inet_chksum_pseudo(struct pbuf *p, 2.1440 + acc += (u32_t)htons((u16_t)proto); 2.1441 + acc += (u32_t)htons(proto_len); 2.1442 + 2.1443 +- while ((acc >> 16) != 0) { 2.1444 +- acc = (acc & 0xffffUL) + (acc >> 16); 2.1445 +- } 2.1446 ++ /* Fold 32-bit sum to 16 bits 2.1447 ++ calling this twice is propably faster than if statements... */ 2.1448 ++ acc = FOLD_U32T(acc); 2.1449 ++ acc = FOLD_U32T(acc); 2.1450 + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); 2.1451 + return (u16_t)~(acc & 0xffffUL); 2.1452 + } 2.1453 +@@ -340,18 +351,17 @@ inet_chksum_pseudo_partial(struct pbuf * 2.1454 + chksum_len -= chklen; 2.1455 + LWIP_ASSERT("delete me", chksum_len < 0x7fff); 2.1456 + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ 2.1457 +- while ((acc >> 16) != 0) { 2.1458 +- acc = (acc & 0xffffUL) + (acc >> 16); 2.1459 +- } 2.1460 ++ /* fold the upper bit down */ 2.1461 ++ acc = FOLD_U32T(acc); 2.1462 + if (q->len % 2 != 0) { 2.1463 + swapped = 1 - swapped; 2.1464 +- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8); 2.1465 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1466 + } 2.1467 + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ 2.1468 + } 2.1469 + 2.1470 + if (swapped) { 2.1471 +- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8); 2.1472 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1473 + } 2.1474 + acc += (src->addr & 0xffffUL); 2.1475 + acc += ((src->addr >> 16) & 0xffffUL); 2.1476 +@@ -360,9 +370,10 @@ inet_chksum_pseudo_partial(struct pbuf * 2.1477 + acc += (u32_t)htons((u16_t)proto); 2.1478 + acc += (u32_t)htons(proto_len); 2.1479 + 2.1480 +- while ((acc >> 16) != 0) { 2.1481 +- acc = (acc & 0xffffUL) + (acc >> 16); 2.1482 +- } 2.1483 ++ /* Fold 32-bit sum to 16 bits 2.1484 ++ calling this twice is propably faster than if statements... */ 2.1485 ++ acc = FOLD_U32T(acc); 2.1486 ++ acc = FOLD_U32T(acc); 2.1487 + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); 2.1488 + return (u16_t)~(acc & 0xffffUL); 2.1489 + } 2.1490 +@@ -380,13 +391,7 @@ inet_chksum_pseudo_partial(struct pbuf * 2.1491 + u16_t 2.1492 + inet_chksum(void *dataptr, u16_t len) 2.1493 + { 2.1494 +- u32_t acc; 2.1495 +- 2.1496 +- acc = LWIP_CHKSUM(dataptr, len); 2.1497 +- while ((acc >> 16) != 0) { 2.1498 +- acc = (acc & 0xffff) + (acc >> 16); 2.1499 +- } 2.1500 +- return (u16_t)~(acc & 0xffff); 2.1501 ++ return ~LWIP_CHKSUM(dataptr, len); 2.1502 + } 2.1503 + 2.1504 + /** 2.1505 +@@ -407,17 +412,15 @@ inet_chksum_pbuf(struct pbuf *p) 2.1506 + swapped = 0; 2.1507 + for(q = p; q != NULL; q = q->next) { 2.1508 + acc += LWIP_CHKSUM(q->payload, q->len); 2.1509 +- while ((acc >> 16) != 0) { 2.1510 +- acc = (acc & 0xffffUL) + (acc >> 16); 2.1511 +- } 2.1512 ++ acc = FOLD_U32T(acc); 2.1513 + if (q->len % 2 != 0) { 2.1514 + swapped = 1 - swapped; 2.1515 +- acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8); 2.1516 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1517 + } 2.1518 + } 2.1519 + 2.1520 + if (swapped) { 2.1521 +- acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8); 2.1522 ++ acc = SWAP_BYTES_IN_WORD(acc); 2.1523 + } 2.1524 + return (u16_t)~(acc & 0xffffUL); 2.1525 + } 2.1526 +Index: src/core/ipv4/ip.c 2.1527 +=================================================================== 2.1528 +RCS file: /sources/lwip/lwip/src/core/ipv4/ip.c,v 2.1529 +retrieving revision 1.66 2.1530 +retrieving revision 1.68 2.1531 +diff -u -p -r1.66 -r1.68 2.1532 +--- src/core/ipv4/ip.c 14 Jan 2008 20:53:23 -0000 1.66 2.1533 ++++ src/core/ipv4/ip.c 17 Jun 2008 19:39:22 -0000 1.68 2.1534 +@@ -531,9 +531,19 @@ ip_output_if(struct pbuf *p, struct ip_a 2.1535 + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); 2.1536 + ip_debug_print(p); 2.1537 + 2.1538 +- LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); 2.1539 ++#if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) 2.1540 ++ if (ip_addr_cmp(dest, &netif->ip_addr)) { 2.1541 ++ /* Packet to self, enqueue it for loopback */ 2.1542 ++ LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); 2.1543 ++ 2.1544 ++ return netif_loop_output(netif, p, dest); 2.1545 ++ } else 2.1546 ++#endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) */ 2.1547 ++ { 2.1548 ++ LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); 2.1549 + 2.1550 +- return netif->output(netif, p, dest); 2.1551 ++ return netif->output(netif, p, dest); 2.1552 ++ } 2.1553 + } 2.1554 + 2.1555 + /** 2.1556 +Index: src/include/lwip/debug.h 2.1557 +=================================================================== 2.1558 +RCS file: /sources/lwip/lwip/src/include/lwip/debug.h,v 2.1559 +retrieving revision 1.37 2.1560 +retrieving revision 1.39 2.1561 +diff -u -p -r1.37 -r1.39 2.1562 +--- src/include/lwip/debug.h 22 Sep 2007 11:16:07 -0000 1.37 2.1563 ++++ src/include/lwip/debug.h 16 Jul 2008 20:36:22 -0000 1.39 2.1564 +@@ -61,26 +61,28 @@ 2.1565 + #define LWIP_DBG_HALT 0x08U 2.1566 + 2.1567 + #ifndef LWIP_NOASSERT 2.1568 +-#define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0) 2.1569 ++#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ 2.1570 ++ LWIP_PLATFORM_ASSERT(message); } while(0) 2.1571 + #else /* LWIP_NOASSERT */ 2.1572 +-#define LWIP_ASSERT(x,y) 2.1573 ++#define LWIP_ASSERT(message, assertion) 2.1574 + #endif /* LWIP_NOASSERT */ 2.1575 + 2.1576 +-/** print "m" message only if "e" is true, and execute "h" expression */ 2.1577 ++/** if "expression" isn't true, then print "message" and execute "handler" expression */ 2.1578 + #ifndef LWIP_ERROR 2.1579 +-#define LWIP_ERROR(m,e,h) do { if (!(e)) { LWIP_PLATFORM_ASSERT(m); h;}} while(0) 2.1580 ++#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ 2.1581 ++ LWIP_PLATFORM_ASSERT(message); handler;}} while(0) 2.1582 + #endif /* LWIP_ERROR */ 2.1583 + 2.1584 + #ifdef LWIP_DEBUG 2.1585 + /** print debug message only if debug message type is enabled... 2.1586 + * AND is of correct type AND is at least LWIP_DBG_LEVEL 2.1587 + */ 2.1588 +-#define LWIP_DEBUGF(debug,x) do { \ 2.1589 ++#define LWIP_DEBUGF(debug, message) do { \ 2.1590 + if ( \ 2.1591 + ((debug) & LWIP_DBG_ON) && \ 2.1592 + ((debug) & LWIP_DBG_TYPES_ON) && \ 2.1593 + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ 2.1594 +- LWIP_PLATFORM_DIAG(x); \ 2.1595 ++ LWIP_PLATFORM_DIAG(message); \ 2.1596 + if ((debug) & LWIP_DBG_HALT) { \ 2.1597 + while(1); \ 2.1598 + } \ 2.1599 +@@ -88,7 +90,7 @@ 2.1600 + } while(0) 2.1601 + 2.1602 + #else /* LWIP_DEBUG */ 2.1603 +-#define LWIP_DEBUGF(debug,x) 2.1604 ++#define LWIP_DEBUGF(debug, message) 2.1605 + #endif /* LWIP_DEBUG */ 2.1606 + 2.1607 + #endif /* __LWIP_DEBUG_H__ */ 2.1608 +Index: src/include/lwip/err.h 2.1609 +=================================================================== 2.1610 +RCS file: /sources/lwip/lwip/src/include/lwip/err.h,v 2.1611 +retrieving revision 1.13 2.1612 +retrieving revision 1.15 2.1613 +diff -u -p -r1.13 -r1.15 2.1614 +--- src/include/lwip/err.h 13 Dec 2007 23:06:50 -0000 1.13 2.1615 ++++ src/include/lwip/err.h 17 Jun 2008 20:27:32 -0000 1.15 2.1616 +@@ -33,37 +33,43 @@ 2.1617 + #define __LWIP_ERR_H__ 2.1618 + 2.1619 + #include "lwip/opt.h" 2.1620 ++#include "lwip/arch.h" 2.1621 + 2.1622 + #ifdef __cplusplus 2.1623 + extern "C" { 2.1624 + #endif 2.1625 + 2.1626 +-typedef s8_t err_t; 2.1627 ++/** Define LWIP_ERR_T in cc.h if you want to use 2.1628 ++ * a different type for your platform (must be signed). */ 2.1629 ++#ifdef LWIP_ERR_T 2.1630 ++typedef LWIP_ERR_T err_t; 2.1631 ++#else /* LWIP_ERR_T */ 2.1632 ++ typedef s8_t err_t; 2.1633 ++#endif /* LWIP_ERR_T*/ 2.1634 + 2.1635 + /* Definitions for error constants. */ 2.1636 + 2.1637 + #define ERR_OK 0 /* No error, everything OK. */ 2.1638 + #define ERR_MEM -1 /* Out of memory error. */ 2.1639 + #define ERR_BUF -2 /* Buffer error. */ 2.1640 +-#define ERR_RTE -3 /* Routing problem. */ 2.1641 ++#define ERR_TIMEOUT -3 /* Timeout. */ 2.1642 ++#define ERR_RTE -4 /* Routing problem. */ 2.1643 + 2.1644 + #define ERR_IS_FATAL(e) ((e) < ERR_RTE) 2.1645 + 2.1646 +-#define ERR_ABRT -4 /* Connection aborted. */ 2.1647 +-#define ERR_RST -5 /* Connection reset. */ 2.1648 +-#define ERR_CLSD -6 /* Connection closed. */ 2.1649 +-#define ERR_CONN -7 /* Not connected. */ 2.1650 ++#define ERR_ABRT -5 /* Connection aborted. */ 2.1651 ++#define ERR_RST -6 /* Connection reset. */ 2.1652 ++#define ERR_CLSD -7 /* Connection closed. */ 2.1653 ++#define ERR_CONN -8 /* Not connected. */ 2.1654 + 2.1655 +-#define ERR_VAL -8 /* Illegal value. */ 2.1656 ++#define ERR_VAL -9 /* Illegal value. */ 2.1657 + 2.1658 +-#define ERR_ARG -9 /* Illegal argument. */ 2.1659 ++#define ERR_ARG -10 /* Illegal argument. */ 2.1660 + 2.1661 +-#define ERR_USE -10 /* Address in use. */ 2.1662 ++#define ERR_USE -11 /* Address in use. */ 2.1663 + 2.1664 +-#define ERR_IF -11 /* Low-level netif error */ 2.1665 +-#define ERR_ISCONN -12 /* Already connected. */ 2.1666 +- 2.1667 +-#define ERR_TIMEOUT -13 /* Timeout. */ 2.1668 ++#define ERR_IF -12 /* Low-level netif error */ 2.1669 ++#define ERR_ISCONN -13 /* Already connected. */ 2.1670 + 2.1671 + #define ERR_INPROGRESS -14 /* Operation in progress */ 2.1672 + 2.1673 +Index: src/include/lwip/mem.h 2.1674 +=================================================================== 2.1675 +RCS file: /sources/lwip/lwip/src/include/lwip/mem.h,v 2.1676 +retrieving revision 1.21 2.1677 +retrieving revision 1.22 2.1678 +diff -u -p -r1.21 -r1.22 2.1679 +--- src/include/lwip/mem.h 4 Mar 2008 16:31:32 -0000 1.21 2.1680 ++++ src/include/lwip/mem.h 30 May 2008 11:37:15 -0000 1.22 2.1681 +@@ -50,16 +50,16 @@ typedef size_t mem_size_t; 2.1682 + * allow these defines to be overridden. 2.1683 + */ 2.1684 + #ifndef mem_free 2.1685 +-#define mem_free(x) free(x) 2.1686 ++#define mem_free free 2.1687 + #endif 2.1688 + #ifndef mem_malloc 2.1689 +-#define mem_malloc(x) malloc(x) 2.1690 ++#define mem_malloc malloc 2.1691 + #endif 2.1692 + #ifndef mem_calloc 2.1693 +-#define mem_calloc(x, y) calloc(x, y) 2.1694 ++#define mem_calloc calloc 2.1695 + #endif 2.1696 + #ifndef mem_realloc 2.1697 +-#define mem_realloc(x, size) (x) 2.1698 ++#define mem_realloc realloc 2.1699 + #endif 2.1700 + #else /* MEM_LIBC_MALLOC */ 2.1701 + 2.1702 +Index: src/include/lwip/netif.h 2.1703 +=================================================================== 2.1704 +RCS file: /sources/lwip/lwip/src/include/lwip/netif.h,v 2.1705 +retrieving revision 1.43 2.1706 +retrieving revision 1.46 2.1707 +diff -u -p -r1.43 -r1.46 2.1708 +--- src/include/lwip/netif.h 9 Oct 2007 19:59:59 -0000 1.43 2.1709 ++++ src/include/lwip/netif.h 19 Jun 2008 16:27:23 -0000 1.46 2.1710 +@@ -34,6 +34,8 @@ 2.1711 + 2.1712 + #include "lwip/opt.h" 2.1713 + 2.1714 ++#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) 2.1715 ++ 2.1716 + #include "lwip/err.h" 2.1717 + 2.1718 + #include "lwip/ip_addr.h" 2.1719 +@@ -165,6 +167,14 @@ struct netif { 2.1720 + #if LWIP_NETIF_HWADDRHINT 2.1721 + u8_t *addr_hint; 2.1722 + #endif /* LWIP_NETIF_HWADDRHINT */ 2.1723 ++#if ENABLE_LOOPBACK 2.1724 ++ /* List of packets to be queued for ourselves. */ 2.1725 ++ struct pbuf *loop_first; 2.1726 ++ struct pbuf *loop_last; 2.1727 ++#if LWIP_LOOPBACK_MAX_PBUFS 2.1728 ++ u16_t loop_cnt_current; 2.1729 ++#endif /* LWIP_LOOPBACK_MAX_PBUFS */ 2.1730 ++#endif /* ENABLE_LOOPBACK */ 2.1731 + }; 2.1732 + 2.1733 + #if LWIP_SNMP 2.1734 +@@ -242,4 +252,12 @@ void netif_set_link_callback(struct neti 2.1735 + } 2.1736 + #endif 2.1737 + 2.1738 ++#if ENABLE_LOOPBACK 2.1739 ++err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip); 2.1740 ++void netif_poll(struct netif *netif); 2.1741 ++#if !LWIP_NETIF_LOOPBACK_MULTITHREADING 2.1742 ++void netif_poll_all(void); 2.1743 ++#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ 2.1744 ++#endif /* ENABLE_LOOPBACK */ 2.1745 ++ 2.1746 + #endif /* __LWIP_NETIF_H__ */ 2.1747 +Index: src/include/lwip/opt.h 2.1748 +=================================================================== 2.1749 +RCS file: /sources/lwip/lwip/src/include/lwip/opt.h,v 2.1750 +retrieving revision 1.116 2.1751 +retrieving revision 1.122 2.1752 +diff -u -p -r1.116 -r1.122 2.1753 +--- src/include/lwip/opt.h 31 Jan 2008 18:19:29 -0000 1.116 2.1754 ++++ src/include/lwip/opt.h 30 Jun 2008 18:16:52 -0000 1.122 2.1755 +@@ -155,6 +155,27 @@ 2.1756 + #define MEMP_USE_CUSTOM_POOLS 0 2.1757 + #endif 2.1758 + 2.1759 ++/** 2.1760 ++ * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from 2.1761 ++ * interrupt context (or another context that doesn't allow waiting for a 2.1762 ++ * semaphore). 2.1763 ++ * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, 2.1764 ++ * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs 2.1765 ++ * with each loop so that mem_free can run. 2.1766 ++ * 2.1767 ++ * ATTENTION: As you can see from the above description, this leads to dis-/ 2.1768 ++ * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc 2.1769 ++ * can need longer. 2.1770 ++ * 2.1771 ++ * If you don't want that, at least for NO_SYS=0, you can still use the following 2.1772 ++ * functions to enqueue a deallocation call which then runs in the tcpip_thread 2.1773 ++ * context: 2.1774 ++ * - pbuf_free_callback(p); 2.1775 ++ * - mem_free_callback(m); 2.1776 ++ */ 2.1777 ++#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 2.1778 ++#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 2.1779 ++#endif 2.1780 + 2.1781 + /* 2.1782 + ------------------------------------------------ 2.1783 +@@ -815,6 +836,39 @@ 2.1784 + #define LWIP_NETIF_HWADDRHINT 0 2.1785 + #endif 2.1786 + 2.1787 ++/** 2.1788 ++ * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP 2.1789 ++ * address equal to the netif IP address, looping them back up the stack. 2.1790 ++ */ 2.1791 ++#ifndef LWIP_NETIF_LOOPBACK 2.1792 ++#define LWIP_NETIF_LOOPBACK 0 2.1793 ++#endif 2.1794 ++ 2.1795 ++/** 2.1796 ++ * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback 2.1797 ++ * sending for each netif (0 = disabled) 2.1798 ++ */ 2.1799 ++#ifndef LWIP_LOOPBACK_MAX_PBUFS 2.1800 ++#define LWIP_LOOPBACK_MAX_PBUFS 0 2.1801 ++#endif 2.1802 ++ 2.1803 ++/** 2.1804 ++ * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in 2.1805 ++ * the system, as netifs must change how they behave depending on this setting 2.1806 ++ * for the LWIP_NETIF_LOOPBACK option to work. 2.1807 ++ * Setting this is needed to avoid reentering non-reentrant functions like 2.1808 ++ * tcp_input(). 2.1809 ++ * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a 2.1810 ++ * multithreaded environment like tcpip.c. In this case, netif->input() 2.1811 ++ * is called directly. 2.1812 ++ * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. 2.1813 ++ * The packets are put on a list and netif_poll() must be called in 2.1814 ++ * the main application loop. 2.1815 ++ */ 2.1816 ++#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING 2.1817 ++#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) 2.1818 ++#endif 2.1819 ++ 2.1820 + /* 2.1821 + ------------------------------------ 2.1822 + ---------- LOOPIF options ---------- 2.1823 +@@ -827,20 +881,16 @@ 2.1824 + #define LWIP_HAVE_LOOPIF 0 2.1825 + #endif 2.1826 + 2.1827 ++/* 2.1828 ++ ------------------------------------ 2.1829 ++ ---------- SLIPIF options ---------- 2.1830 ++ ------------------------------------ 2.1831 ++*/ 2.1832 + /** 2.1833 +- * LWIP_LOOPIF_MULTITHREADING: Indicates whether threading is enabled in 2.1834 +- * the system, as LOOPIF must change how it behaves depending on this setting. 2.1835 +- * Setting this is needed to avoid reentering non-reentrant functions like 2.1836 +- * tcp_input(). 2.1837 +- * LWIP_LOOPIF_MULTITHREADING==1: Indicates that the user is using a 2.1838 +- * multithreaded environment like tcpip.c. In this case, netif->input() 2.1839 +- * is called directly. 2.1840 +- * LWIP_LOOPIF_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. 2.1841 +- * The packets are put on a list and loopif_poll() must be called in 2.1842 +- * the main application loop. 2.1843 ++ * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c 2.1844 + */ 2.1845 +-#ifndef LWIP_LOOPIF_MULTITHREADING 2.1846 +-#define LWIP_LOOPIF_MULTITHREADING 1 2.1847 ++#ifndef LWIP_HAVE_SLIPIF 2.1848 ++#define LWIP_HAVE_SLIPIF 0 2.1849 + #endif 2.1850 + 2.1851 + /* 2.1852 +Index: src/include/lwip/sio.h 2.1853 +=================================================================== 2.1854 +RCS file: /sources/lwip/lwip/src/include/lwip/sio.h,v 2.1855 +retrieving revision 1.7 2.1856 +retrieving revision 1.8 2.1857 +diff -u -p -r1.7 -r1.8 2.1858 +--- src/include/lwip/sio.h 6 Sep 2007 16:43:44 -0000 1.7 2.1859 ++++ src/include/lwip/sio.h 27 Mar 2008 18:06:02 -0000 1.8 2.1860 +@@ -32,16 +32,24 @@ 2.1861 + * It needs to be implemented by those platforms which need SLIP or PPP 2.1862 + */ 2.1863 + 2.1864 ++#ifndef __SIO_H__ 2.1865 ++#define __SIO_H__ 2.1866 ++ 2.1867 + #include "lwip/arch.h" 2.1868 + 2.1869 + #ifdef __cplusplus 2.1870 + extern "C" { 2.1871 + #endif 2.1872 + 2.1873 ++/* If you want to define sio_fd_t elsewhere or differently, 2.1874 ++ define this in your cc.h file. */ 2.1875 + #ifndef __sio_fd_t_defined 2.1876 + typedef void * sio_fd_t; 2.1877 + #endif 2.1878 + 2.1879 ++/* The following functions can be defined to something else in your cc.h file 2.1880 ++ or be implemented in your custom sio.c file. */ 2.1881 ++ 2.1882 + #ifndef sio_open 2.1883 + sio_fd_t sio_open(u8_t); 2.1884 + #endif 2.1885 +@@ -69,3 +77,5 @@ void sio_read_abort(sio_fd_t); 2.1886 + #ifdef __cplusplus 2.1887 + } 2.1888 + #endif 2.1889 ++ 2.1890 ++#endif /* __SIO_H__ */ 2.1891 +Index: src/include/lwip/sockets.h 2.1892 +=================================================================== 2.1893 +RCS file: /sources/lwip/lwip/src/include/lwip/sockets.h,v 2.1894 +retrieving revision 1.38 2.1895 +retrieving revision 1.39 2.1896 +diff -u -p -r1.38 -r1.39 2.1897 +--- src/include/lwip/sockets.h 2 Dec 2007 15:24:02 -0000 1.38 2.1898 ++++ src/include/lwip/sockets.h 26 Apr 2008 10:46:23 -0000 1.39 2.1899 +@@ -177,7 +177,22 @@ typedef struct ip_mreq { 2.1900 + } ip_mreq; 2.1901 + #endif /* LWIP_IGMP */ 2.1902 + 2.1903 +-/* Unimplemented for now... */ 2.1904 ++/* 2.1905 ++ * The Type of Service provides an indication of the abstract 2.1906 ++ * parameters of the quality of service desired. These parameters are 2.1907 ++ * to be used to guide the selection of the actual service parameters 2.1908 ++ * when transmitting a datagram through a particular network. Several 2.1909 ++ * networks offer service precedence, which somehow treats high 2.1910 ++ * precedence traffic as more important than other traffic (generally 2.1911 ++ * by accepting only traffic above a certain precedence at time of high 2.1912 ++ * load). The major choice is a three way tradeoff between low-delay, 2.1913 ++ * high-reliability, and high-throughput. 2.1914 ++ * The use of the Delay, Throughput, and Reliability indications may 2.1915 ++ * increase the cost (in some sense) of the service. In many networks 2.1916 ++ * better performance for one of these parameters is coupled with worse 2.1917 ++ * performance on another. Except for very unusual cases at most two 2.1918 ++ * of these three indications should be set. 2.1919 ++ */ 2.1920 + #define IPTOS_TOS_MASK 0x1E 2.1921 + #define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) 2.1922 + #define IPTOS_LOWDELAY 0x10 2.1923 +@@ -187,7 +202,13 @@ typedef struct ip_mreq { 2.1924 + #define IPTOS_MINCOST IPTOS_LOWCOST 2.1925 + 2.1926 + /* 2.1927 +- * Definitions for IP precedence (also in ip_tos) (Unimplemented) 2.1928 ++ * The Network Control precedence designation is intended to be used 2.1929 ++ * within a network only. The actual use and control of that 2.1930 ++ * designation is up to each network. The Internetwork Control 2.1931 ++ * designation is intended for use by gateway control originators only. 2.1932 ++ * If the actual use of these precedence designations is of concern to 2.1933 ++ * a particular network, it is the responsibility of that network to 2.1934 ++ * control the access to, and use of, those precedence designations. 2.1935 + */ 2.1936 + #define IPTOS_PREC_MASK 0xe0 2.1937 + #define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) 2.1938 +Index: src/include/lwip/stats.h 2.1939 +=================================================================== 2.1940 +RCS file: /sources/lwip/lwip/src/include/lwip/stats.h,v 2.1941 +retrieving revision 1.19 2.1942 +retrieving revision 1.23 2.1943 +diff -u -p -r1.19 -r1.23 2.1944 +--- src/include/lwip/stats.h 28 Nov 2007 21:25:07 -0000 1.19 2.1945 ++++ src/include/lwip/stats.h 8 Jul 2008 09:15:57 -0000 1.23 2.1946 +@@ -57,7 +57,6 @@ extern "C" { 2.1947 + 2.1948 + struct stats_proto { 2.1949 + STAT_COUNTER xmit; /* Transmitted packets. */ 2.1950 +- STAT_COUNTER rexmit; /* Retransmitted packets. */ 2.1951 + STAT_COUNTER recv; /* Received packets. */ 2.1952 + STAT_COUNTER fw; /* Forwarded packets. */ 2.1953 + STAT_COUNTER drop; /* Dropped packets. */ 2.1954 +@@ -87,7 +86,8 @@ struct stats_mem { 2.1955 + mem_size_t avail; 2.1956 + mem_size_t used; 2.1957 + mem_size_t max; 2.1958 +- mem_size_t err; 2.1959 ++ STAT_COUNTER err; 2.1960 ++ STAT_COUNTER illegal; 2.1961 + }; 2.1962 + 2.1963 + struct stats_syselem { 2.1964 +@@ -142,64 +142,138 @@ extern struct stats_ lwip_stats; 2.1965 + #define stats_init() /* Compatibility define, not init needed. */ 2.1966 + 2.1967 + #define STATS_INC(x) ++lwip_stats.x 2.1968 ++#define STATS_DEC(x) --lwip_stats.x 2.1969 + #else 2.1970 + #define stats_init() 2.1971 + #define STATS_INC(x) 2.1972 ++#define STATS_DEC(x) 2.1973 + #endif /* LWIP_STATS */ 2.1974 + 2.1975 + #if TCP_STATS 2.1976 + #define TCP_STATS_INC(x) STATS_INC(x) 2.1977 ++#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") 2.1978 + #else 2.1979 + #define TCP_STATS_INC(x) 2.1980 ++#define TCP_STATS_DISPLAY() 2.1981 + #endif 2.1982 + 2.1983 + #if UDP_STATS 2.1984 + #define UDP_STATS_INC(x) STATS_INC(x) 2.1985 ++#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") 2.1986 + #else 2.1987 + #define UDP_STATS_INC(x) 2.1988 ++#define UDP_STATS_DISPLAY() 2.1989 + #endif 2.1990 + 2.1991 + #if ICMP_STATS 2.1992 + #define ICMP_STATS_INC(x) STATS_INC(x) 2.1993 ++#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") 2.1994 + #else 2.1995 + #define ICMP_STATS_INC(x) 2.1996 ++#define ICMP_STATS_DISPLAY() 2.1997 + #endif 2.1998 + 2.1999 + #if IGMP_STATS 2.2000 + #define IGMP_STATS_INC(x) STATS_INC(x) 2.2001 ++#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp) 2.2002 + #else 2.2003 + #define IGMP_STATS_INC(x) 2.2004 ++#define IGMP_STATS_DISPLAY() 2.2005 + #endif 2.2006 + 2.2007 + #if IP_STATS 2.2008 + #define IP_STATS_INC(x) STATS_INC(x) 2.2009 ++#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") 2.2010 + #else 2.2011 + #define IP_STATS_INC(x) 2.2012 ++#define IP_STATS_DISPLAY() 2.2013 + #endif 2.2014 + 2.2015 + #if IPFRAG_STATS 2.2016 + #define IPFRAG_STATS_INC(x) STATS_INC(x) 2.2017 ++#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") 2.2018 + #else 2.2019 + #define IPFRAG_STATS_INC(x) 2.2020 ++#define IPFRAG_STATS_DISPLAY() 2.2021 + #endif 2.2022 + 2.2023 + #if ETHARP_STATS 2.2024 + #define ETHARP_STATS_INC(x) STATS_INC(x) 2.2025 ++#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") 2.2026 + #else 2.2027 + #define ETHARP_STATS_INC(x) 2.2028 ++#define ETHARP_STATS_DISPLAY() 2.2029 + #endif 2.2030 + 2.2031 + #if LINK_STATS 2.2032 + #define LINK_STATS_INC(x) STATS_INC(x) 2.2033 ++#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") 2.2034 + #else 2.2035 + #define LINK_STATS_INC(x) 2.2036 ++#define LINK_STATS_DISPLAY() 2.2037 ++#endif 2.2038 ++ 2.2039 ++#if MEM_STATS 2.2040 ++#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y 2.2041 ++#define MEM_STATS_INC(x) STATS_INC(mem.x) 2.2042 ++#define MEM_STATS_INC_USED(x, y) do { lwip_stats.mem.used += y; \ 2.2043 ++ if (lwip_stats.mem.max < lwip_stats.mem.used) { \ 2.2044 ++ lwip_stats.mem.max = lwip_stats.mem.used; \ 2.2045 ++ } \ 2.2046 ++ } while(0) 2.2047 ++#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y 2.2048 ++#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") 2.2049 ++#else 2.2050 ++#define MEM_STATS_AVAIL(x, y) 2.2051 ++#define MEM_STATS_INC(x) 2.2052 ++#define MEM_STATS_INC_USED(x, y) 2.2053 ++#define MEM_STATS_DEC_USED(x, y) 2.2054 ++#define MEM_STATS_DISPLAY() 2.2055 ++#endif 2.2056 ++ 2.2057 ++#if MEMP_STATS 2.2058 ++#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y 2.2059 ++#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) 2.2060 ++#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) 2.2061 ++#define MEMP_STATS_INC_USED(x, i) do { ++lwip_stats.memp[i].used; \ 2.2062 ++ if (lwip_stats.memp[i].max < lwip_stats.memp[i].used) { \ 2.2063 ++ lwip_stats.memp[i].max = lwip_stats.memp[i].used; \ 2.2064 ++ } \ 2.2065 ++ } while(0) 2.2066 ++#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) 2.2067 ++#else 2.2068 ++#define MEMP_STATS_AVAIL(x, i, y) 2.2069 ++#define MEMP_STATS_INC(x, i) 2.2070 ++#define MEMP_STATS_DEC(x, i) 2.2071 ++#define MEMP_STATS_INC_USED(x, i) 2.2072 ++#define MEMP_STATS_DISPLAY(i) 2.2073 ++#endif 2.2074 ++ 2.2075 ++#if SYS_STATS 2.2076 ++#define SYS_STATS_INC(x) STATS_INC(sys.x) 2.2077 ++#define SYS_STATS_DEC(x) STATS_DEC(sys.x) 2.2078 ++#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) 2.2079 ++#else 2.2080 ++#define SYS_STATS_INC(x) 2.2081 ++#define SYS_STATS_DEC(x) 2.2082 ++#define SYS_STATS_DISPLAY() 2.2083 + #endif 2.2084 + 2.2085 + /* Display of statistics */ 2.2086 + #if LWIP_STATS_DISPLAY 2.2087 + void stats_display(void); 2.2088 ++void stats_display_proto(struct stats_proto *proto, char *name); 2.2089 ++void stats_display_igmp(struct stats_igmp *igmp); 2.2090 ++void stats_display_mem(struct stats_mem *mem, char *name); 2.2091 ++void stats_display_memp(struct stats_mem *mem, int index); 2.2092 ++void stats_display_sys(struct stats_sys *sys); 2.2093 + #else 2.2094 + #define stats_display() 2.2095 ++#define stats_display_proto(proto, name) 2.2096 ++#define stats_display_igmp(igmp) 2.2097 ++#define stats_display_mem(mem, name) 2.2098 ++#define stats_display_memp(mem, index) 2.2099 ++#define stats_display_sys(sys) 2.2100 + #endif /* LWIP_STATS_DISPLAY */ 2.2101 + 2.2102 + #ifdef __cplusplus 2.2103 +Index: src/include/lwip/tcpip.h 2.2104 +=================================================================== 2.2105 +RCS file: /sources/lwip/lwip/src/include/lwip/tcpip.h,v 2.2106 +retrieving revision 1.24 2.2107 +retrieving revision 1.27 2.2108 +diff -u -p -r1.24 -r1.27 2.2109 +--- src/include/lwip/tcpip.h 12 Jan 2008 11:52:22 -0000 1.24 2.2110 ++++ src/include/lwip/tcpip.h 27 Jun 2008 20:34:55 -0000 1.27 2.2111 +@@ -83,7 +83,11 @@ err_t tcpip_netifapi_lock(struct netifap 2.2112 + #endif /* LWIP_NETIF_API */ 2.2113 + 2.2114 + err_t tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block); 2.2115 +-#define tcpip_callback(f,ctx) tcpip_callback_with_block(f,ctx,1) 2.2116 ++#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) 2.2117 ++ 2.2118 ++/* free pbufs or heap memory from another context without blocking */ 2.2119 ++err_t pbuf_free_callback(struct pbuf *p); 2.2120 ++err_t mem_free_callback(void *m); 2.2121 + 2.2122 + err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); 2.2123 + #define tcpip_untimeout(h, arg) tcpip_timeout(0xffffffff, h, arg) 2.2124 +Index: src/include/netif/loopif.h 2.2125 +=================================================================== 2.2126 +RCS file: /sources/lwip/lwip/src/include/netif/loopif.h,v 2.2127 +retrieving revision 1.7 2.2128 +retrieving revision 1.9 2.2129 +diff -u -p -r1.7 -r1.9 2.2130 +--- src/include/netif/loopif.h 10 May 2007 10:59:20 -0000 1.7 2.2131 ++++ src/include/netif/loopif.h 17 Jun 2008 20:12:22 -0000 1.9 2.2132 +@@ -32,6 +32,7 @@ 2.2133 + #ifndef __NETIF_LOOPIF_H__ 2.2134 + #define __NETIF_LOOPIF_H__ 2.2135 + 2.2136 ++#include "lwip/opt.h" 2.2137 + #include "lwip/netif.h" 2.2138 + #include "lwip/err.h" 2.2139 + 2.2140 +@@ -39,9 +40,9 @@ 2.2141 + extern "C" { 2.2142 + #endif 2.2143 + 2.2144 +-#if !LWIP_LOOPIF_MULTITHREADING 2.2145 +-void loopif_poll(struct netif *netif); 2.2146 +-#endif 2.2147 ++#if !LWIP_NETIF_LOOPBACK_MULTITHREADING 2.2148 ++#define loopif_poll netif_poll 2.2149 ++#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ 2.2150 + 2.2151 + err_t loopif_init(struct netif *netif); 2.2152 + 2.2153 +Index: src/netif/etharp.c 2.2154 +=================================================================== 2.2155 +RCS file: /sources/lwip/lwip/src/netif/etharp.c,v 2.2156 +retrieving revision 1.145 2.2157 +retrieving revision 1.148 2.2158 +diff -u -p -r1.145 -r1.148 2.2159 +--- src/netif/etharp.c 4 Mar 2008 13:41:24 -0000 1.145 2.2160 ++++ src/netif/etharp.c 19 Jun 2008 16:40:59 -0000 1.148 2.2161 +@@ -353,7 +353,7 @@ find_entry(struct ip_addr *ipaddr, u8_t 2.2162 + * 1) empty entry 2.2163 + * 2) oldest stable entry 2.2164 + * 3) oldest pending entry without queued packets 2.2165 +- * 4) oldest pending entry without queued packets 2.2166 ++ * 4) oldest pending entry with queued packets 2.2167 + * 2.2168 + * { ETHARP_TRY_HARD is set at this point } 2.2169 + */ 2.2170 +@@ -1130,7 +1130,14 @@ ethernet_input(struct pbuf *p, struct ne 2.2171 + 2.2172 + /* points to packet payload, which starts with an Ethernet header */ 2.2173 + ethhdr = p->payload; 2.2174 +- 2.2175 ++ LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, 2.2176 ++ ("ethernet_input: dest:%02x:%02x:%02x:%02x:%02x:%02x, src:%02x:%02x:%02x:%02x:%02x:%02x, type:%2hx\n", 2.2177 ++ (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], 2.2178 ++ (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], 2.2179 ++ (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], 2.2180 ++ (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], 2.2181 ++ (unsigned)htons(ethhdr->type))); 2.2182 ++ 2.2183 + switch (htons(ethhdr->type)) { 2.2184 + /* IP packet? */ 2.2185 + case ETHTYPE_IP: 2.2186 +@@ -1165,6 +1172,8 @@ ethernet_input(struct pbuf *p, struct ne 2.2187 + #endif /* PPPOE_SUPPORT */ 2.2188 + 2.2189 + default: 2.2190 ++ ETHARP_STATS_INC(etharp.proterr); 2.2191 ++ ETHARP_STATS_INC(etharp.drop); 2.2192 + pbuf_free(p); 2.2193 + p = NULL; 2.2194 + break; 2.2195 +Index: src/netif/loopif.c 2.2196 +=================================================================== 2.2197 +RCS file: /sources/lwip/lwip/src/netif/loopif.c,v 2.2198 +retrieving revision 1.26 2.2199 +retrieving revision 1.27 2.2200 +diff -u -p -r1.26 -r1.27 2.2201 +--- src/netif/loopif.c 31 Aug 2007 10:14:09 -0000 1.26 2.2202 ++++ src/netif/loopif.c 12 Jun 2008 20:10:10 -0000 1.27 2.2203 +@@ -40,149 +40,8 @@ 2.2204 + #if LWIP_HAVE_LOOPIF 2.2205 + 2.2206 + #include "netif/loopif.h" 2.2207 +-#include "lwip/pbuf.h" 2.2208 + #include "lwip/snmp.h" 2.2209 + 2.2210 +-#include <string.h> 2.2211 +- 2.2212 +-#if !LWIP_LOOPIF_MULTITHREADING 2.2213 +- 2.2214 +-#include "lwip/sys.h" 2.2215 +-#include "lwip/mem.h" 2.2216 +- 2.2217 +-/* helper struct for the linked list of pbufs */ 2.2218 +-struct loopif_private { 2.2219 +- struct pbuf *first; 2.2220 +- struct pbuf *last; 2.2221 +-}; 2.2222 +- 2.2223 +-/** 2.2224 +- * Call loopif_poll() in the main loop of your application. This is to prevent 2.2225 +- * reentering non-reentrant functions like tcp_input(). Packets passed to 2.2226 +- * loopif_output() are put on a list that is passed to netif->input() by 2.2227 +- * loopif_poll(). 2.2228 +- * 2.2229 +- * @param netif the lwip network interface structure for this loopif 2.2230 +- */ 2.2231 +-void 2.2232 +-loopif_poll(struct netif *netif) 2.2233 +-{ 2.2234 +- SYS_ARCH_DECL_PROTECT(lev); 2.2235 +- struct pbuf *in, *in_end; 2.2236 +- struct loopif_private *priv = (struct loopif_private*)netif->state; 2.2237 +- 2.2238 +- LWIP_ERROR("priv != NULL", (priv != NULL), return;); 2.2239 +- 2.2240 +- do { 2.2241 +- /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ 2.2242 +- SYS_ARCH_PROTECT(lev); 2.2243 +- in = priv->first; 2.2244 +- if(in) { 2.2245 +- in_end = in; 2.2246 +- while(in_end->len != in_end->tot_len) { 2.2247 +- LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); 2.2248 +- in_end = in_end->next; 2.2249 +- } 2.2250 +- /* 'in_end' now points to the last pbuf from 'in' */ 2.2251 +- if(in_end == priv->last) { 2.2252 +- /* this was the last pbuf in the list */ 2.2253 +- priv->first = priv->last = NULL; 2.2254 +- } else { 2.2255 +- /* pop the pbuf off the list */ 2.2256 +- priv->first = in_end->next; 2.2257 +- LWIP_ASSERT("should not be null since first != last!", priv->first != NULL); 2.2258 +- } 2.2259 +- } 2.2260 +- SYS_ARCH_UNPROTECT(lev); 2.2261 +- 2.2262 +- if(in != NULL) { 2.2263 +- if(in_end->next != NULL) { 2.2264 +- /* De-queue the pbuf from its successors on the 'priv' list. */ 2.2265 +- in_end->next = NULL; 2.2266 +- } 2.2267 +- if(netif->input(in, netif) != ERR_OK) { 2.2268 +- pbuf_free(in); 2.2269 +- } 2.2270 +- /* Don't reference the packet any more! */ 2.2271 +- in = NULL; 2.2272 +- in_end = NULL; 2.2273 +- } 2.2274 +- /* go on while there is a packet on the list */ 2.2275 +- } while(priv->first != NULL); 2.2276 +-} 2.2277 +-#endif /* LWIP_LOOPIF_MULTITHREADING */ 2.2278 +- 2.2279 +-/** 2.2280 +- * Send an IP packet over the loopback interface. 2.2281 +- * The pbuf is simply copied and handed back to netif->input. 2.2282 +- * In multithreaded mode, this is done directly since netif->input must put 2.2283 +- * the packet on a queue. 2.2284 +- * In callback mode, the packet is put on an internal queue and is fed to 2.2285 +- * netif->input by loopif_poll(). 2.2286 +- * 2.2287 +- * @param netif the lwip network interface structure for this loopif 2.2288 +- * @param p the (IP) packet to 'send' 2.2289 +- * @param ipaddr the ip address to send the packet to (not used for loopif) 2.2290 +- * @return ERR_OK if the packet has been sent 2.2291 +- * ERR_MEM if the pbuf used to copy the packet couldn't be allocated 2.2292 +- */ 2.2293 +-static err_t 2.2294 +-loopif_output(struct netif *netif, struct pbuf *p, 2.2295 +- struct ip_addr *ipaddr) 2.2296 +-{ 2.2297 +-#if !LWIP_LOOPIF_MULTITHREADING 2.2298 +- SYS_ARCH_DECL_PROTECT(lev); 2.2299 +- struct loopif_private *priv; 2.2300 +- struct pbuf *last; 2.2301 +-#endif /* LWIP_LOOPIF_MULTITHREADING */ 2.2302 +- struct pbuf *r; 2.2303 +- err_t err; 2.2304 +- 2.2305 +- LWIP_UNUSED_ARG(ipaddr); 2.2306 +- 2.2307 +- /* Allocate a new pbuf */ 2.2308 +- r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); 2.2309 +- if (r == NULL) { 2.2310 +- return ERR_MEM; 2.2311 +- } 2.2312 +- 2.2313 +- /* Copy the whole pbuf queue p into the single pbuf r */ 2.2314 +- if ((err = pbuf_copy(r, p)) != ERR_OK) { 2.2315 +- pbuf_free(r); 2.2316 +- r = NULL; 2.2317 +- return err; 2.2318 +- } 2.2319 +- 2.2320 +-#if LWIP_LOOPIF_MULTITHREADING 2.2321 +- /* Multithreading environment, netif->input() is supposed to put the packet 2.2322 +- into a mailbox, so we can safely call it here without risking to re-enter 2.2323 +- functions that are not reentrant (TCP!!!) */ 2.2324 +- if(netif->input(r, netif) != ERR_OK) { 2.2325 +- pbuf_free(r); 2.2326 +- r = NULL; 2.2327 +- } 2.2328 +-#else /* LWIP_LOOPIF_MULTITHREADING */ 2.2329 +- /* Raw API without threads: put the packet on a linked list which gets emptied 2.2330 +- through calling loopif_poll(). */ 2.2331 +- priv = (struct loopif_private*)netif->state; 2.2332 +- 2.2333 +- /* let last point to the last pbuf in chain r */ 2.2334 +- for (last = r; last->next != NULL; last = last->next); 2.2335 +- SYS_ARCH_PROTECT(lev); 2.2336 +- if(priv->first != NULL) { 2.2337 +- LWIP_ASSERT("if first != NULL, last must also be != NULL", priv->last != NULL); 2.2338 +- priv->last->next = r; 2.2339 +- priv->last = last; 2.2340 +- } else { 2.2341 +- priv->first = r; 2.2342 +- priv->last = last; 2.2343 +- } 2.2344 +- SYS_ARCH_UNPROTECT(lev); 2.2345 +-#endif /* LWIP_LOOPIF_MULTITHREADING */ 2.2346 +- 2.2347 +- return ERR_OK; 2.2348 +-} 2.2349 +- 2.2350 + /** 2.2351 + * Initialize a lwip network interface structure for a loopback interface 2.2352 + * 2.2353 +@@ -193,16 +52,6 @@ loopif_output(struct netif *netif, struc 2.2354 + err_t 2.2355 + loopif_init(struct netif *netif) 2.2356 + { 2.2357 +-#if !LWIP_LOOPIF_MULTITHREADING 2.2358 +- struct loopif_private *priv; 2.2359 +- 2.2360 +- priv = (struct loopif_private*)mem_malloc(sizeof(struct loopif_private)); 2.2361 +- if(priv == NULL) 2.2362 +- return ERR_MEM; 2.2363 +- priv->first = priv->last = NULL; 2.2364 +- netif->state = priv; 2.2365 +-#endif /* LWIP_LOOPIF_MULTITHREADING */ 2.2366 +- 2.2367 + /* initialize the snmp variables and counters inside the struct netif 2.2368 + * ifSpeed: no assumption can be made! 2.2369 + */ 2.2370 +@@ -210,7 +59,7 @@ loopif_init(struct netif *netif) 2.2371 + 2.2372 + netif->name[0] = 'l'; 2.2373 + netif->name[1] = 'o'; 2.2374 +- netif->output = loopif_output; 2.2375 ++ netif->output = netif_loop_output; 2.2376 + return ERR_OK; 2.2377 + } 2.2378 + 2.2379 +Index: src/netif/slipif.c 2.2380 +=================================================================== 2.2381 +RCS file: /sources/lwip/lwip/src/netif/slipif.c,v 2.2382 +retrieving revision 1.29 2.2383 +retrieving revision 1.30 2.2384 +diff -u -p -r1.29 -r1.30 2.2385 +--- src/netif/slipif.c 30 Nov 2007 17:22:21 -0000 1.29 2.2386 ++++ src/netif/slipif.c 17 Jun 2008 20:14:05 -0000 1.30 2.2387 +@@ -44,6 +44,9 @@ 2.2388 + 2.2389 + #include "netif/slipif.h" 2.2390 + #include "lwip/opt.h" 2.2391 ++ 2.2392 ++#if LWIP_HAVE_SLIPIF 2.2393 ++ 2.2394 + #include "lwip/def.h" 2.2395 + #include "lwip/pbuf.h" 2.2396 + #include "lwip/sys.h" 2.2397 +@@ -273,3 +276,4 @@ slipif_init(struct netif *netif) 2.2398 + sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); 2.2399 + return ERR_OK; 2.2400 + } 2.2401 ++#endif /* LWIP_HAVE_SLIPIF */