diff --git a/libports/include/lwip/arch/sys_arch.h b/libports/include/lwip/arch/sys_arch.h index 0849802f2..b8f17cd65 100644 --- a/libports/include/lwip/arch/sys_arch.h +++ b/libports/include/lwip/arch/sys_arch.h @@ -16,8 +16,16 @@ #include -typedef mem_ptr_t sys_sem_t; -typedef mem_ptr_t sys_mbox_t; +struct _sys_sem_t { + void* ptr; +}; +typedef struct _sys_sem_t sys_sem_t; + +struct _sys_mbox_t { + void* ptr; +}; +typedef struct _sys_mbox_t sys_mbox_t; + typedef mem_ptr_t sys_thread_t; typedef mem_ptr_t sys_prot_t; diff --git a/libports/include/lwip/genode.h b/libports/include/lwip/genode.h index e26839844..7731d61b6 100644 --- a/libports/include/lwip/genode.h +++ b/libports/include/lwip/genode.h @@ -42,9 +42,6 @@ void lwip_tcpip_init(void); int lwip_nic_init(genode_int32_t ip_addr, genode_int32_t netmask, genode_int32_t gateway); -/** Initialize lwIP for loopback only */ -struct netif *lwip_loopback_init(void); - #ifdef __cplusplus } #endif diff --git a/libports/include/lwip/lwipopts.h b/libports/include/lwip/lwipopts.h index 06b2bdaf0..d4dea2e54 100644 --- a/libports/include/lwip/lwipopts.h +++ b/libports/include/lwip/lwipopts.h @@ -27,6 +27,7 @@ #define LWIP_DHCP 1 /* DHCP support */ #define LWIP_SOCKET 1 /* LwIP socket API */ #define LWIP_COMPAT_SOCKETS 0 /* Libc compatibility layer */ +#define LWIP_COMPAT_MUTEX 1 /* use binary semaphore instead of mutex */ #define LWIP_NETIF_API 1 /* Network interface API */ #define LWIP_NETIF_LOOPBACK 1 /* Looping back to same address? */ #define LWIP_HAVE_LOOPIF 1 /* 127.0.0.1 support ? */ diff --git a/libports/lib/mk/lwip.mk b/libports/lib/mk/lwip.mk index 06dffa1db..f4d2b8b52 100644 --- a/libports/lib/mk/lwip.mk +++ b/libports/lib/mk/lwip.mk @@ -4,14 +4,16 @@ # The library implementes TCP and UDP as well as DNS and DHCP. # -LWIP_DIR = $(REP_DIR)/contrib/lwip-1.3.2 +include $(REP_DIR)/ports/lwip.inc + +LWIP_DIR = $(REP_DIR)/contrib/$(LWIP) # Genode platform files SRC_CC = nic.cc printf.cc sys_arch.cc # Core files SRC_C = init.c mem.c memp.c netif.c pbuf.c stats.c udp.c raw.c sys.c \ - tcp.c tcp_in.c tcp_out.c dhcp.c dns.c + tcp.c tcp_in.c tcp_out.c dhcp.c dns.c timers.c def.c # IPv4 files SRC_C += icmp.c inet.c ip_addr.c ip.c ip_frag.c inet_chksum.c @@ -21,7 +23,7 @@ SRC_C += err.c api_lib.c api_msg.c netbuf.c netdb.c netifapi.c sockets.c \ tcpip.c # Network interface files -SRC_C += etharp.c loopif.c +SRC_C += etharp.c LIBS = thread cxx alarm signal libc timed_semaphore diff --git a/libports/ports/lwip.inc b/libports/ports/lwip.inc new file mode 100644 index 000000000..1554482d2 --- /dev/null +++ b/libports/ports/lwip.inc @@ -0,0 +1,2 @@ +LWIP_VERSION = STABLE-1_4_1-RC1 +LWIP = lwip-$(LWIP_VERSION) diff --git a/libports/ports/lwip.mk b/libports/ports/lwip.mk index db789b82d..7824671c9 100644 --- a/libports/ports/lwip.mk +++ b/libports/ports/lwip.mk @@ -1,6 +1,7 @@ -LWIP = lwip-1.3.2 -LWIP_ZIP = $(LWIP).zip -LWIP_URL = http://mirrors.zerg.biz/nongnu/lwip/$(LWIP_ZIP) +include ports/lwip.inc + +LWIP_TGZ = $(LWIP).tar.gz +LWIP_URL = http://git.savannah.gnu.org/cgit/lwip.git/snapshot/$(LWIP_TGZ) # # Interface to top-level prepare Makefile @@ -19,14 +20,13 @@ $(CONTRIB_DIR)/$(LWIP): clean-lwip # # Port-specific local rules # -$(DOWNLOAD_DIR)/$(LWIP_ZIP): +$(DOWNLOAD_DIR)/$(LWIP_TGZ): $(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(LWIP_URL) && touch $@ -$(CONTRIB_DIR)/$(LWIP): $(DOWNLOAD_DIR)/$(LWIP_ZIP) - $(VERBOSE)unzip $< -d $(CONTRIB_DIR) && touch $@ - $(VERBOSE)patch -d $(CONTRIB_DIR) -p0 -i ../src/lib/lwip/libc_select_notify.patch - $(VERBOSE)patch -d $(CONTRIB_DIR) -p0 -i ../src/lib/lwip/errno.patch - $(VERBOSE)patch -d $(CONTRIB_DIR) -p0 -i ../src/lib/lwip/sol_socket_definition.patch +$(CONTRIB_DIR)/$(LWIP): $(DOWNLOAD_DIR)/$(LWIP_TGZ) + $(VERBOSE)tar xvzf $< -C $(CONTRIB_DIR) && touch $@ + $(VERBOSE)find ./src/lib/lwip/ -name "*.patch" |\ + xargs -ixxx sh -c "patch -p0 -r - -N -d $(CONTRIB_DIR) < xxx" || true include/lwip/lwip: $(VERBOSE)mkdir -p $@ diff --git a/libports/src/lib/lwip/errno.patch b/libports/src/lib/lwip/errno.patch index 4dca112db..4097b9a29 100644 --- a/libports/src/lib/lwip/errno.patch +++ b/libports/src/lib/lwip/errno.patch @@ -1,7 +1,6 @@ -diff -urN lwip-1.3.2.orig/src/include/lwip/arch.h lwip-1.3.2/src/include/lwip/arch.h ---- lwip-1.3.2.orig/src/include/lwip/arch.h 2009-12-24 16:38:19.000000000 +0100 -+++ lwip-1.3.2/src/include/lwip/arch.h 2010-11-01 15:43:34.000000000 +0100 -@@ -224,6 +224,12 @@ +--- lwip-STABLE-1_4_1-RC1/src/include/lwip/arch.h.orig ++++ lwip-STABLE-1_4_1-RC1/src/include/lwip/arch.h +@@ -208,6 +208,12 @@ extern "C" { extern int errno; #endif diff --git a/libports/src/lib/lwip/libc_select_notify.patch b/libports/src/lib/lwip/libc_select_notify.patch index 425367ba1..a5638368b 100644 --- a/libports/src/lib/lwip/libc_select_notify.patch +++ b/libports/src/lib/lwip/libc_select_notify.patch @@ -1,7 +1,6 @@ -diff -urN lwip-1.3.2.orig/src/api/sockets.c lwip-1.3.2/src/api/sockets.c ---- lwip-1.3.2.orig/src/api/sockets.c 2009-12-24 16:38:19.000000000 +0100 -+++ lwip-1.3.2/src/api/sockets.c 2010-02-16 11:27:00.000000000 +0100 -@@ -162,6 +162,9 @@ +--- lwip-STABLE-1_4_1-RC1/src/api/sockets.c.orig ++++ lwip-STABLE-1_4_1-RC1/src/api/sockets.c +@@ -171,6 +171,9 @@ static const int err_to_errno_table[] = { set_errno(sk->err); \ } while (0) @@ -11,7 +10,7 @@ diff -urN lwip-1.3.2.orig/src/api/sockets.c lwip-1.3.2/src/api/sockets.c /* Forward delcaration of some functions */ static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); static void lwip_getsockopt_internal(void *arg); -@@ -1034,7 +1037,7 @@ +@@ -1244,7 +1247,7 @@ return_copy_fdsets: * Processes recvevent (data available) and wakes up tasks waiting for select. */ static void @@ -19,9 +18,9 @@ diff -urN lwip-1.3.2.orig/src/api/sockets.c lwip-1.3.2/src/api/sockets.c +orig_event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) { int s; - struct lwip_socket *sock; -@@ -1123,6 +1126,17 @@ - } + struct lwip_sock *sock; +@@ -1359,6 +1362,17 @@ again: + SYS_ARCH_UNPROTECT(lev); } +/* Wrapper for the original event_callback() function that additionally calls @@ -30,9 +29,9 @@ diff -urN lwip-1.3.2.orig/src/api/sockets.c lwip-1.3.2/src/api/sockets.c +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ -+ orig_event_callback(conn, evt, len); -+ if (libc_select_notify) -+ libc_select_notify(); ++ orig_event_callback(conn, evt, len); ++ if (libc_select_notify) ++ libc_select_notify(); +} + /** diff --git a/libports/src/lib/lwip/platform/sys_arch.cc b/libports/src/lib/lwip/platform/sys_arch.cc index 8127e374d..71dc4b3f5 100644 --- a/libports/src/lib/lwip/platform/sys_arch.cc +++ b/libports/src/lib/lwip/platform/sys_arch.cc @@ -101,7 +101,6 @@ extern "C" { #include #include #include -#include #include #include #include @@ -140,7 +139,6 @@ extern "C" { { static struct netif netif; struct ip_addr ip, nm, gw; - struct netif *loopif = lwip_loopback_init(); ip.addr = ip_addr; nm.addr = netmask; gw.addr = gateway; @@ -179,7 +177,6 @@ extern "C" { dhcp_semaphore()->down(20000); } catch (Genode::Timeout_exception) { PWRN("DHCP timed out!"); - netif_set_default(loopif); return 1; } PDBG("got IP address %d.%d.%d.%d", @@ -193,30 +190,13 @@ extern "C" { #endif /* LWIP_DHCP */ } } catch (Nic_not_availble) { - PWRN("NIC not available, set loopback as default"); - netif_set_default(loopif); + PWRN("NIC not available, loopback is used as default"); return 2; } return 0; } - /* in lwip/genode.h */ - struct netif *lwip_loopback_init(void) - { - /* setup LwIP's loopback device (as default NIC) */ - static struct netif loop_netif; - struct ip_addr loop_ipaddr, loop_netmask, loop_gw; - IP4_ADDR(&loop_gw, 127,0,0,1); - IP4_ADDR(&loop_ipaddr, 127,0,0,1); - IP4_ADDR(&loop_netmask, 255,255,255,0); - netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, - loopif_init, ip_input); - netif_set_up(&loop_netif); - return &loop_netif; - } - - /*************** ** Semaphore ** ***************/ @@ -227,18 +207,21 @@ extern "C" { * \param count specifies the initial state of the semaphore. * \return the semaphore, or SYS_SEM_NULL on error. */ - sys_sem_t sys_sem_new(u8_t count) + err_t sys_sem_new(sys_sem_t* sem, u8_t count) { try { Genode::Timed_semaphore *_sem = new (Genode::env()->heap()) Genode::Timed_semaphore(count); - return (sys_sem_t) _sem; + sem->ptr = _sem; + return ERR_OK; } catch (Genode::Allocator::Out_of_memory) { PWRN("Out of memory"); - return SYS_SEM_NULL; + return ERR_MEM; } catch (...) { PERR("Unknown Exception occured!"); - return SYS_SEM_NULL; + /* we just use a arbitrary value that is + * not defined in err.h */ + return -32; } } @@ -248,11 +231,11 @@ extern "C" { * * \param sem the semaphore to free */ - void sys_sem_free(sys_sem_t sem) + void sys_sem_free(sys_sem_t* sem) { try { Genode::Timed_semaphore *_sem = - reinterpret_cast(sem); + reinterpret_cast(sem->ptr); if (_sem) destroy(Genode::env()->heap(), _sem); } catch (...) { @@ -265,13 +248,13 @@ extern "C" { * Signals (or releases) a semaphore. * */ - void sys_sem_signal(sys_sem_t sem) + void sys_sem_signal(sys_sem_t* sem) { try { Genode::Timed_semaphore *_sem = - reinterpret_cast(sem); + reinterpret_cast(sem->ptr); if (!_sem) { - PERR("Invalid semaphore pointer at: %lx", sem); + //PERR("Invalid semaphore pointer at: %lx", *sem->ptr); return; } _sem->up(); @@ -281,6 +264,37 @@ extern "C" { } + /** + * Checks if a semaphore is valid + * + * \param sem semaphore to check + * + * \return 1 if semaphore is valid, 0 otherwise. + */ + int sys_sem_valid(sys_sem_t* sem) + { + try { + Genode::Timed_semaphore *_sem = + reinterpret_cast(sem->ptr); + + if (_sem) + return 1; + } catch (...) { } + + return 0; + } + + + /** + * Sets a semaphore to invalid + * + * \param sem semaphore to set invalid + */ + void sys_sem_set_invalid(sys_sem_t* sem) + { + sem->ptr = NULL; + } + /** * Blocks the thread while waiting for the semaphore to be signaled. * @@ -291,13 +305,13 @@ extern "C" { * acquires the semaphore, it should return how many * milliseconds expired while waiting for the semaphore. */ - u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) + u32_t sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout) { using namespace Genode; try { - Timed_semaphore *_sem = reinterpret_cast(sem); + Timed_semaphore *_sem = reinterpret_cast(sem->ptr); if (!_sem) { - PERR("Invalid semaphore pointer at: %lx", sem); + //PERR("Invalid semaphore pointer at: %lx", *sem->ptr); return EINVAL; } @@ -357,17 +371,19 @@ extern "C" { * \param size size of the mailbox * \return a new mailbox, or SYS_MBOX_NULL on error. */ - sys_mbox_t sys_mbox_new(int size) { + err_t sys_mbox_new(sys_mbox_t *mbox, int size) { LWIP_UNUSED_ARG(size); try { Mailbox* _mbox = new (Genode::env()->heap()) Mailbox(); - return (sys_mbox_t) _mbox; + mbox->ptr = _mbox; + return ERR_OK; } catch (Genode::Allocator::Out_of_memory) { PWRN("Out of memory"); + return ERR_MEM; } catch (...) { PERR("Unknown Exception occured!"); + return -32; } - return SYS_MBOX_NULL; } @@ -376,10 +392,10 @@ extern "C" { * * \param mbox mailbox to free */ - void sys_mbox_free(sys_mbox_t mbox) + void sys_mbox_free(sys_mbox_t* mbox) { try { - Mailbox* _mbox = reinterpret_cast(mbox); + Mailbox* _mbox = reinterpret_cast(mbox->ptr); if (_mbox) destroy(Genode::env()->heap(), _mbox); } catch (...) { @@ -387,6 +403,40 @@ extern "C" { } } + /** + * Checks if a mailbox is valid. + * + * \param mbox mailbox to check + * + * \return 1 if mailbox is valid, 0 otherwise. + */ + int sys_mbox_valid(sys_mbox_t* mbox) + { + try { + Mailbox* _mbox = reinterpret_cast(mbox->ptr); + if (_mbox) { + return 1; + } + } catch (...) { } + + return 0; + } + + + /** + * Invalidate a mailbox + * + * Afterwards sys_mbox_valid() returns 0. + * ATTENTION: This does NOT mean that the mailbox shall be deallocated: + * sys_mbox_free() is always called before calling this function! + * + * \param mbox mailbox to set invalid + */ + void sys_mbox_set_invalid(sys_mbox_t* mbox) + { + mbox->ptr = NULL; + } + /** * Posts the "msg" to the mailbox. @@ -394,13 +444,13 @@ extern "C" { * \param mbox target mailbox * \param msg message to post */ - void sys_mbox_post(sys_mbox_t mbox, void *msg) + void sys_mbox_post(sys_mbox_t* mbox, void *msg) { while (true) { try { - Mailbox* _mbox = reinterpret_cast(mbox); + Mailbox* _mbox = reinterpret_cast(mbox->ptr); if (!_mbox) { - PERR("Invalid mailbox pointer at %lx", mbox); + //PERR("Invalid mailbox pointer at %lx", *mbox->ptr); return; } _mbox->add(msg); @@ -420,12 +470,12 @@ extern "C" { * \param mbox target mailbox * \param msg message to post */ - err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) + err_t sys_mbox_trypost(sys_mbox_t* mbox, void *msg) { try { - Mailbox* _mbox = reinterpret_cast(mbox); + Mailbox* _mbox = reinterpret_cast(mbox->ptr); if (!_mbox) { - PERR("Invalid mailbox pointer at %lx", mbox); + //PERR("Invalid mailbox pointer at %lx", *mbox->ptr); return EINVAL; } _mbox->add(msg); @@ -446,7 +496,7 @@ extern "C" { * \param msg pointer to message buffer * \param timeout how long will it block, if no message is available */ - u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) + u32_t sys_arch_mbox_fetch(sys_mbox_t* mbox, void **msg, u32_t timeout) { /* * The mailbox might be invalid to indicate, @@ -456,9 +506,9 @@ extern "C" { return 0; try { - Mailbox* _mbox = reinterpret_cast(mbox); + Mailbox* _mbox = reinterpret_cast(mbox->ptr); if (!_mbox) { - PERR("Invalid mailbox pointer at %lx", mbox); + //PERR("Invalid mailbox pointer at %lx", *mbox->ptr); return EINVAL; } return _mbox->get(msg, timeout); @@ -483,7 +533,7 @@ extern "C" { * This is similar to sys_arch_mbox_fetch, however if a message is not present * in the mailbox, it immediately returns with the code SYS_MBOX_EMPTY. */ - u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) + u32_t sys_arch_mbox_tryfetch(sys_mbox_t* mbox, void **msg) { return sys_arch_mbox_fetch(mbox, msg, Mailbox::NO_BLOCK); } @@ -502,7 +552,7 @@ extern "C" { * \param stacksize size of the thread's stack * \param prio priority of new thread */ - sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), + sys_thread_t sys_thread_new(const char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) { try @@ -523,6 +573,7 @@ extern "C" { } +#if 0 /************** ** Timeouts ** **************/ @@ -568,5 +619,6 @@ extern "C" { return 0; } } +#endif } /* extern "C" */ diff --git a/libports/src/lib/lwip/sockets_c_errno.patch b/libports/src/lib/lwip/sockets_c_errno.patch new file mode 100644 index 000000000..46c5e7b5f --- /dev/null +++ b/libports/src/lib/lwip/sockets_c_errno.patch @@ -0,0 +1,16 @@ +This patch is necessary because lwip always returns EALREADY if the +connection is established but never EISCONN. So most programs will +fail to connect because they at one point while connecting expect to +get EISCONN. + +--- lwip-STABLE-1_4_1-RC1/src/api/sockets.c.orig ++++ lwip-STABLE-1_4_1-RC1/src/api/sockets.c +@@ -142,7 +142,7 @@ static const int err_to_errno_table[] = { + EINVAL, /* ERR_VAL -6 Illegal value. */ + EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ +- EALREADY, /* ERR_ISCONN -9 Already connected. */ ++ EISCONN, /* ERR_ISCONN -9 Already connected. */ + ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + ECONNRESET, /* ERR_RST -11 Connection reset. */ + ENOTCONN, /* ERR_CLSD -12 Connection closed. */ diff --git a/libports/src/lib/lwip/sol_socket_definition.patch b/libports/src/lib/lwip/sol_socket_definition.patch index c8f71606c..a20129fa0 100644 --- a/libports/src/lib/lwip/sol_socket_definition.patch +++ b/libports/src/lib/lwip/sol_socket_definition.patch @@ -2,14 +2,14 @@ Our FreeBSD libc based libc defines SOL_SOCKET as 0xffff. We change lwip's definition from 0xfff to match ours. This prevents us from converting the level when we call {g,s}etsockopt. ---- lwip-1.3.2.orig/src/include/lwip/sockets.h -+++ lwip-1.3.2/src/include/lwip/sockets.h -@@ -113,7 +113,7 @@ struct linger { +--- lwip-STABLE-1_4_1-RC1/src/include/lwip/sockets.h.orig ++++ lwip-STABLE-1_4_1-RC1/src/include/lwip/sockets.h +@@ -115,7 +115,7 @@ struct linger { /* * Level number for (get/set)sockopt() to apply to socket itself. */ -#define SOL_SOCKET 0xfff /* options for socket level */ -+#define SOL_SOCKET 0xffff /* options for socket level */ ++#define SOL_SOCKET 0xffff /* options for socket level */ #define AF_UNSPEC 0