bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Update patches


From: Samuel Thibault
Subject: Re: [PATCH] Update patches
Date: Tue, 28 Aug 2018 20:50:08 +0200
User-agent: NeoMutt/20170113 (1.7.2)

Hello,

Unfortunately your mailer dropped all ^M characters so the patch can't
be applied. Could you re-send it as a compressed file to make sure that
it doesn't get mangled?

Thanks,
Samuel

Joan Lledó, le mar. 07 août 2018 18:09:55 +0200, a ecrit:
>       PORT:           Use always interruptible functions for waiting
>                       Return SYS_ARCH_INTR when a waiting thread is cancelled
>       POLL:           Use always interruptible functions for waiting
>                       Fix some debug messages
>       MAX_SOCKETS:    Protect the socket list every time it's read
>       All but AUTOCONF: Converted to DOS format to mach lwip sources
>       All: Remove fuzziness
> 
> ---
>  debian/patches/bug-36167   |    8 +-
>  debian/patches/errno       |   20 +-
>  debian/patches/max_sockets |   75 +-
>  debian/patches/poll        |  146 ++--
>  debian/patches/port        | 1943 
> +++++++++++++++++++++-----------------------
>  debian/patches/posix       | 1733 ++++++++++++++++++++-------------------
>  6 files changed, 1917 insertions(+), 2008 deletions(-)
> 
> diff --git a/debian/patches/bug-36167 b/debian/patches/bug-36167
> index 4220301..e0a6d92 100644
> --- a/debian/patches/bug-36167
> +++ b/debian/patches/bug-36167
> @@ -1,10 +1,8 @@
>  Already upstream
>  
> -diff --git a/src/core/tcp.c b/src/core/tcp.c
> -index 7103a52..ccfa3c1 100644
>  --- a/src/core/tcp.c
>  +++ b/src/core/tcp.c
> -@@ -804,7 +804,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
> +@@ -804,7 +804,7 @@
>       pcb->rcv_wnd = TCP_WND_MAX(pcb);
>     } else if (pcb->rcv_wnd == 0) {
>       /* rcv_wnd overflowed */
> @@ -13,11 +11,9 @@ index 7103a52..ccfa3c1 100644
>         /* In passive close, we allow this, since the FIN bit is added to 
> rcv_wnd
>            by the stack itself, since it is not mandatory for an application
>            to call tcp_recved() for the FIN bit, but e.g. the netconn API 
> does so. */
> -diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
> -index 3845b9f..fb7fa17 100644
>  --- a/src/include/lwip/tcp.h
>  +++ b/src/include/lwip/tcp.h
> -@@ -424,6 +424,9 @@ const char* tcp_debug_state_str(enum tcp_state s);
> +@@ -424,6 +424,9 @@
>   /* for compatibility with older implementation */
>   #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
>   
> diff --git a/debian/patches/errno b/debian/patches/errno
> index 1cf5d42..9aed02a 100644
> --- a/debian/patches/errno
> +++ b/debian/patches/errno
> @@ -1,10 +1,8 @@
>  Already upstream
>  
> -Index: lwip/src/api/sockets.c
> -===================================================================
> ---- lwip.orig/src/api/sockets.c
> -+++ lwip/src/api/sockets.c
> -@@ -213,7 +213,7 @@ struct lwip_sock {
> +--- a/src/api/sockets.c
> ++++ b/src/api/sockets.c
> +@@ -223,7 +223,7 @@
>     /** error happened for this socket, set by event_callback(), tested by 
> select */
>     u16_t errevent;
>     /** last error that occurred on this socket (in fact, all our errnos fit 
> into an u8_t) */
> @@ -13,7 +11,7 @@ Index: lwip/src/api/sockets.c
>     /** counter of how many threads are waiting for this socket using select 
> */
>     SELWAIT_T select_waiting;
>   };
> -@@ -299,7 +299,7 @@ static volatile int select_cb_ctr;
> +@@ -309,7 +309,7 @@
>   
>   #define sock_set_errno(sk, e) do { \
>     const int sockerr = (e); \
> @@ -22,7 +20,7 @@ Index: lwip/src/api/sockets.c
>     set_errno(sockerr); \
>   } while (0)
>   
> -@@ -309,8 +309,8 @@ static void event_callback(struct netcon
> +@@ -319,8 +319,8 @@
>   static void lwip_getsockopt_callback(void *arg);
>   static void lwip_setsockopt_callback(void *arg);
>   #endif
> @@ -33,7 +31,7 @@ Index: lwip/src/api/sockets.c
>   
>   #if LWIP_IPV4 && LWIP_IPV6
>   static void
> -@@ -1792,7 +1792,7 @@ lwip_getsockname(int s, struct sockaddr
> +@@ -1804,7 +1804,7 @@
>   int
>   lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t 
> *optlen)
>   {
> @@ -42,7 +40,7 @@ Index: lwip/src/api/sockets.c
>     struct lwip_sock *sock = get_socket(s);
>   #if !LWIP_TCPIP_CORE_LOCKING
>     LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
> -@@ -1887,10 +1887,10 @@ lwip_getsockopt_callback(void *arg)
> +@@ -1899,10 +1899,10 @@
>   /** lwip_getsockopt_impl: the actual implementation of getsockopt:
>    * same argument as lwip_getsockopt, either called directly or through 
> callback
>    */
> @@ -55,7 +53,7 @@ Index: lwip/src/api/sockets.c
>     struct lwip_sock *sock = tryget_socket(s);
>     if (!sock) {
>       return EBADF;
> -@@ -2198,7 +2198,7 @@ lwip_getsockopt_impl(int s, int level, i
> +@@ -2210,7 +2210,7 @@
>   int
>   lwip_setsockopt(int s, int level, int optname, const void *optval, 
> socklen_t optlen)
>   {
> @@ -64,7 +62,7 @@ Index: lwip/src/api/sockets.c
>     struct lwip_sock *sock = get_socket(s);
>   #if !LWIP_TCPIP_CORE_LOCKING
>     LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
> -@@ -2288,10 +2288,10 @@ lwip_setsockopt_callback(void *arg)
> +@@ -2300,10 +2300,10 @@
>   /** lwip_setsockopt_impl: the actual implementation of setsockopt:
>    * same argument as lwip_setsockopt, either called directly or through 
> callback
>    */
> diff --git a/debian/patches/max_sockets b/debian/patches/max_sockets
> index 53b4555..1862444 100644
> --- a/debian/patches/max_sockets
> +++ b/debian/patches/max_sockets
> @@ -33,7 +33,7 @@ Won't get to upstream
>    * in seconds. (does not require sockets.c, and will affect tcp.c)
>  --- a/src/api/sockets.c
>  +++ b/src/api/sockets.c
> -@@ -198,6 +198,12 @@
> +@@ -208,6 +208,12 @@
>   
>   /** Contains all internal pointers and states used for a socket */
>   struct lwip_sock {
> @@ -46,7 +46,7 @@ Won't get to upstream
>     /** sockets currently are built on netconns, each socket has one netconn 
> */
>     struct netconn *conn;
>     /** data that was left from the previous read */
> -@@ -287,8 +293,13 @@
> +@@ -297,8 +303,13 @@
>   static void lwip_socket_drop_registered_memberships(int s);
>   #endif /* LWIP_IGMP */
>   
> @@ -60,7 +60,7 @@ Won't get to upstream
>   /** The global list of tasks waiting for select */
>   static struct lwip_select_cb *select_cb_list;
>   /** This counter is increased from lwip_select when the list is changed
> -@@ -359,15 +370,26 @@
> +@@ -369,15 +380,29 @@
>   
>     s -= LWIP_SOCKET_OFFSET;
>   
> @@ -76,10 +76,13 @@ Won't get to upstream
>     }
>   
>  +#if LWIP_SOCKET_OPEN_COUNT
> ++  SYS_ARCH_DECL_PROTECT(lev);
> ++  SYS_ARCH_PROTECT(lev);
>  +  for(sock = sockets; sock != NULL; sock = sock->next) {
>  +    if(sock->count == s)
>  +      break;
>  +  }
> ++  SYS_ARCH_UNPROTECT(lev);
>  +#else /* LWIP_SOCKET_OPEN_COUNT */
>     sock = &sockets[s];
>  +#endif /* LWIP_SOCKET_OPEN_COUNT */
> @@ -89,9 +92,14 @@ Won't get to upstream
>       LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s + 
> LWIP_SOCKET_OFFSET));
>       set_errno(EBADF);
>       return NULL;
> -@@ -386,13 +408,26 @@
> +@@ -395,14 +420,33 @@
> + static struct lwip_sock *
>   tryget_socket(int s)
>   {
> ++#if LWIP_SOCKET_OPEN_COUNT
> ++  struct lwip_sock *sock;
> ++#endif /* LWIP_SOCKET_OPEN_COUNT */
> ++
>     s -= LWIP_SOCKET_OFFSET;
>  -  if ((s < 0) || (s >= NUM_SOCKETS)) {
>  +  if ((s < 0)
> @@ -102,11 +110,13 @@ Won't get to upstream
>       return NULL;
>     }
>  +#if LWIP_SOCKET_OPEN_COUNT
> -+  struct lwip_sock *sock;
> ++  SYS_ARCH_DECL_PROTECT(lev);
> ++  SYS_ARCH_PROTECT(lev);
>  +  for(sock = sockets; sock != NULL; sock = sock->next) {
>  +    if(sock->count == s)
>  +      break;
>  +  }
> ++  SYS_ARCH_UNPROTECT(lev);
>  +  return sock;
>  +#else /* LWIP_SOCKET_OPEN_COUNT */
>     if (!sockets[s].conn) {
> @@ -117,7 +127,7 @@ Won't get to upstream
>   }
>   
>   /**
> -@@ -407,30 +442,70 @@
> +@@ -417,30 +461,70 @@
>   alloc_socket(struct netconn *newconn, int accepted)
>   {
>     int i;
> @@ -199,33 +209,34 @@ Won't get to upstream
>   }
>   
>   /** Free a socket. The socket's netconn must have been
> -@@ -442,9 +517,14 @@
> - static void
> +@@ -453,6 +537,9 @@
>   free_socket(struct lwip_sock *sock, int is_tcp)
>   {
> --  void *lastdata;
> --
> --  lastdata         = sock->lastdata;
> -+  void *lastdata = sock->lastdata;
> +   void *lastdata;
>  +#if LWIP_SOCKET_OPEN_COUNT
>  +  struct lwip_sock **it = &sockets;
> -+
> -+  while(*it != sock) it = &(*it)->next;
> -+  *it = (*it)->next;
> -+  mem_free(sock);
> -+#else /* LWIP_SOCKET_OPEN_COUNT */
> ++#endif /* LWIP_SOCKET_OPEN_COUNT */
> + 
> +   lastdata         = sock->lastdata;
>     sock->lastdata   = NULL;
> -   sock->lastoffset = 0;
> +@@ -460,7 +547,15 @@
>     sock->err        = 0;
> -@@ -452,6 +532,7 @@
> + 
>     /* Protect socket array */
> -   SYS_ARCH_SET(sock->conn, NULL);
> -   /* don't use 'sock' after this line, as another task might have allocated 
> it */
> +-  SYS_ARCH_SET(sock->conn, NULL);
> ++  SYS_ARCH_DECL_PROTECT(lev);
> ++  SYS_ARCH_PROTECT(lev);
> ++  sock->conn       = NULL;
> ++#if LWIP_SOCKET_OPEN_COUNT
> ++  while(*it != sock) it = &(*it)->next;
> ++  *it = (*it)->next;
> ++  mem_free(sock);
>  +#endif /* LWIP_SOCKET_OPEN_COUNT */
> ++  SYS_ARCH_UNPROTECT(lev);
> +   /* don't use 'sock' after this line, as another task might have allocated 
> it */
>   
>     if (lastdata != NULL) {
> -     if (is_tcp) {
> -@@ -512,7 +593,9 @@
> +@@ -522,7 +617,9 @@
>       sock_set_errno(sock, ENFILE);
>       return -1;
>     }
> @@ -238,12 +249,12 @@ Won't get to upstream
>  --- a/port/include/lwipopts.h
>  +++ b/port/include/lwipopts.h
>  @@ -26,6 +26,9 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS   0
> - 
> -+/* Don't limit the number of sockets */
> -+#define LWIP_SOCKET_OPEN_COUNT  1
> -+
> - /* We're using lwip_poll() */
> - #define LWIP_POLL               1
> - 
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS   0
> + 
> ++/* Don't limit the number of sockets */
> ++#define LWIP_SOCKET_OPEN_COUNT  1
> ++
> + /* We're using lwip_poll() */
> + #define LWIP_POLL               1
> + 
> diff --git a/debian/patches/poll b/debian/patches/poll
> index c060cf3..198e258 100644
> --- a/debian/patches/poll
> +++ b/debian/patches/poll
> @@ -2,7 +2,7 @@ Already upstream
>  
>  --- a/src/api/sockets.c
>  +++ b/src/api/sockets.c
> -@@ -238,6 +238,12 @@
> +@@ -248,6 +248,12 @@
>     fd_set *writeset;
>     /** unimplemented: exceptset passed to select */
>     fd_set *exceptset;
> @@ -15,7 +15,7 @@ Already upstream
>     /** don't signal the same semaphore twice: set to 1 when signalled */
>     int sem_signalled;
>     /** semaphore to wake up a task waiting for select */
> -@@ -1288,6 +1294,51 @@
> +@@ -1302,6 +1308,51 @@
>     return lwip_sendmsg(s, &msg, 0);
>   }
>   
> @@ -67,7 +67,7 @@ Already upstream
>   /**
>    * Go through the readset and writeset lists and see which socket of the 
> sockets
>    * set in the sets has events. On return, readset, writeset and exceptset 
> have
> -@@ -1411,6 +1462,10 @@
> +@@ -1425,6 +1476,10 @@
>       select_cb.readset = readset;
>       select_cb.writeset = writeset;
>       select_cb.exceptset = exceptset;
> @@ -78,7 +78,7 @@ Already upstream
>       select_cb.sem_signalled = 0;
>   #if LWIP_NETCONN_SEM_PER_THREAD
>       select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET();
> -@@ -1422,20 +1477,7 @@
> +@@ -1436,20 +1491,7 @@
>       }
>   #endif /* LWIP_NETCONN_SEM_PER_THREAD */
>   
> @@ -100,7 +100,7 @@ Already upstream
>   
>       /* Increase select_waiting for each socket we are interested in */
>       maxfdp2 = maxfdp1;
> -@@ -1505,21 +1547,7 @@
> +@@ -1519,21 +1561,7 @@
>           SYS_ARCH_UNPROTECT(lev);
>         }
>       }
> @@ -123,7 +123,7 @@ Already upstream
>   
>   #if LWIP_NETCONN_SEM_PER_THREAD
>       if (select_cb.sem_signalled && (!waited || (waitres == 
> SYS_ARCH_TIMEOUT))) {
> -@@ -1563,6 +1591,253 @@
> +@@ -1577,6 +1605,253 @@
>     return nready;
>   }
>   
> @@ -304,7 +304,7 @@ Already upstream
>  +        LWIP_ASSERT("timeout > 0", timeout > 0);
>  +        msectimeout = timeout;
>  +      }
> -+      waitres = sys_arch_sem_wait_intr(SELECT_SEM_PTR(select_cb.sem), 
> msectimeout);
> ++      waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem), 
> msectimeout);
>  +#if LWIP_NETCONN_SEM_PER_THREAD
>  +      waited = 1;
>  +#endif
> @@ -332,12 +332,12 @@ Already upstream
>  +
>  +    if (waitres == SYS_ARCH_TIMEOUT) {
>  +      /* Timeout */
> -+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
> ++      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n"));
>  +      goto return_success;
>  +    }
>  +  }
>  +
> -+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
> ++  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready));
>  +return_success:
>  +  set_errno(0);
>  +  return nready;
> @@ -377,7 +377,7 @@ Already upstream
>   /**
>    * Callback registered in the netconn layer for each socket-netconn.
>    * Processes recvevent (data available) and wakes up tasks waiting for 
> select.
> -@@ -1649,20 +1924,27 @@
> +@@ -1663,20 +1938,27 @@
>       if (scb->sem_signalled == 0) {
>         /* semaphore not signalled yet */
>         int do_signal = 0;
> @@ -419,7 +419,7 @@ Already upstream
>         if (do_signal) {
>  --- a/src/include/lwip/opt.h
>  +++ b/src/include/lwip/opt.h
> -@@ -1751,6 +1751,17 @@
> +@@ -1751,6 +1751,17 @@
>   #endif
>   
>   /**
> @@ -439,49 +439,49 @@ Already upstream
>    * names (read, write & close). (only used if you use sockets.c)
>  --- a/src/include/lwip/lwip_sockets.h
>  +++ b/src/include/lwip/lwip_sockets.h
> -@@ -430,6 +430,21 @@
> - #error "external FD_SETSIZE too small for number of sockets"
> - #endif /* FD_SET */
> - 
> -+#if LWIP_POLL == 2
> -+#define POLLIN   0x01
> -+#define POLLOUT  0x02
> -+#define POLLERR  0x04
> -+#define POLLNVAL 0x08
> -+/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
> -+typedef int nfds_t;
> -+struct pollfd
> -+{
> -+  int fd;
> -+  short events;
> -+  short revents;
> -+};
> -+#endif
> -+
> - /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> -  * by your system, set this to 0 and include <sys/time.h> in cc.h */
> - #ifndef LWIP_TIMEVAL_PRIVATE
> -@@ -466,6 +481,9 @@
> - #define lwip_sendto       sendto
> - #define lwip_socket       socket
> - #define lwip_select       select
> -+#if LWIP_POLL
> -+#define lwip_poll         poll
> -+#endif
> - #define lwip_ioctlsocket  ioctl
> - 
> - #if LWIP_POSIX_SOCKETS_IO_NAMES
> -@@ -516,6 +534,10 @@
> - #define socket(domain,type,protocol)              
> lwip_socket(domain,type,protocol)
> - /** @ingroup socket */
> - #define select(maxfdp1,readset,writeset,exceptset,timeout)     
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> -+#if LWIP_POLL
> -+/** @ingroup socket */
> -+#define poll(fds,nfds,timeout)                    
> lwip_poll(fds,nfds,timeout)
> -+#endif
> - /** @ingroup socket */
> - #define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
> - 
> +@@ -432,6 +432,21 @@
> + #error "external FD_SETSIZE too small for number of sockets"
> + #endif /* FD_SET */
> + 
> ++#if LWIP_POLL == 2
> ++#define POLLIN   0x01
> ++#define POLLOUT  0x02
> ++#define POLLERR  0x04
> ++#define POLLNVAL 0x08
> ++/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
> ++typedef int nfds_t;
> ++struct pollfd
> ++{
> ++  int fd;
> ++  short events;
> ++  short revents;
> ++};
> ++#endif
> ++
> + /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> +  * by your system, set this to 0 and include <sys/time.h> in cc.h */
> + #ifndef LWIP_TIMEVAL_PRIVATE
> +@@ -468,6 +483,9 @@
> + #define lwip_sendto       sendto
> + #define lwip_socket       socket
> + #define lwip_select       select
> ++#if LWIP_POLL
> ++#define lwip_poll         poll
> ++#endif
> + #define lwip_ioctlsocket  ioctl
> + 
> + #if LWIP_POSIX_SOCKETS_IO_NAMES
> +@@ -518,6 +536,10 @@
> + #define socket(domain,type,protocol)              
> lwip_socket(domain,type,protocol)
> + /** @ingroup socket */
> + #define select(maxfdp1,readset,writeset,exceptset,timeout)     
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> ++#if LWIP_POLL
> ++/** @ingroup socket */
> ++#define poll(fds,nfds,timeout)                    
> lwip_poll(fds,nfds,timeout)
> ++#endif
> + /** @ingroup socket */
> + #define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
> + 
>  --- a/src/include/lwip/sockets.h
>  +++ b/src/include/lwip/sockets.h
>  @@ -75,6 +75,9 @@
> @@ -497,24 +497,24 @@ Already upstream
>  --- a/port/include/lwipopts.h
>  +++ b/port/include/lwipopts.h
>  @@ -26,6 +26,9 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS   0
> - 
> -+/* We're using lwip_poll() */
> -+#define LWIP_POLL               1
> -+
> - /* Use Glibc's sockets headers */
> - #define LWIP_STD_SOCKETS  1
> - #define LWIP_INCLUDE_STD_SOCKETS  "posix/socket.h"
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS   0
> + 
> ++/* We're using lwip_poll() */
> ++#define LWIP_POLL               1
> ++
> + /* Use Glibc's sockets headers */
> + #define LWIP_STD_SOCKETS  1
> + #define LWIP_INCLUDE_STD_SOCKETS  "posix/socket.h"
>  --- a/port/include/arch/cc.h
>  +++ b/port/include/arch/cc.h
> -@@ -46,6 +46,9 @@
> - #include <netinet/tcp.h>
> - #include <netinet/udp.h>
> - 
> -+/* We use poll() instead of select()*/
> -+#include <poll.h>
> -+
> - /* Use our own htons() and pals */
> - #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> - 
> +@@ -40,6 +40,9 @@
> + /* Use our own ioctls */
> + #include <sys/ioctl.h>
> + 
> ++/* We use poll() instead of select()*/
> ++#include <poll.h>
> ++
> + /* Use our own htons() and pals */
> + #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> + 
> diff --git a/debian/patches/port b/debian/patches/port
> index c6c9d82..b0ab392 100644
> --- a/debian/patches/port
> +++ b/debian/patches/port
> @@ -3,1022 +3,941 @@ Not intended to be upstream
>  --- /dev/null
>  +++ b/port/include/arch/cc.h
>  @@ -0,0 +1,68 @@
> -+/*
> -+   Copyright (C) 2017 Free Software Foundation, Inc.
> -+   Written by Joan Lledó.
> -+
> -+   This file is part of the GNU Hurd.
> -+
> -+   The GNU Hurd is free software; you can redistribute it and/or
> -+   modify it under the terms of the GNU General Public License as
> -+   published by the Free Software Foundation; either version 2, or (at
> -+   your option) any later version.
> -+
> -+   The GNU Hurd is distributed in the hope that it will be useful, but
> -+   WITHOUT ANY WARRANTY; without even the implied warranty of
> -+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -+   General Public License for more details.
> -+
> -+   You should have received a copy of the GNU General Public License
> -+   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> -+
> -+#ifndef LWIP_ARCH_CC_H
> -+#define LWIP_ARCH_CC_H
> -+
> -+#include <stdlib.h> /* rand() */
> -+#include <stdio.h> /* printf() */
> -+
> -+/* Use Glibc's fcntl() macros */
> -+#include <fcntl.h>
> -+
> -+/* Use Glibc's <errno.h> */
> -+#include <errno.h>
> -+#define LWIP_ERR_T  int
> -+
> -+/* System provides its own struct timeval */
> -+#define LWIP_TIMEVAL_PRIVATE  0
> -+#include <sys/time.h>
> -+
> -+/* We need INT_MAX */
> -+#include <limits.h>
> -+
> -+/* Use our own ioctls */
> -+#include <sys/ioctl.h>
> -+
> -+/* Use our own htons() and pals */
> -+#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> -+
> -+/* printf() codes */
> -+#define S16_F "d"
> -+#define U16_F "u"
> -+#define X16_F "x"
> -+
> -+#define S32_F "d"
> -+#define U32_F "u"
> -+#define X32_F "x"
> -+
> -+#ifdef LWIP_DEBUG
> -+#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
> -+#endif
> -+
> -+/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
> -+#define LWIP_ERROR(message, expression, handler) \
> -+  do { \
> -+    if (!(expression)) { \
> -+      printf("Assertion \"%s\" failed at line %d in %s\n", \
> -+        message, __LINE__, __FILE__); fflush(NULL); \
> -+      handler;} \
> -+  } while(0)
> -+
> -+#endif /* LWIP_ARCH_CC_H */
> ++/*
> ++   Copyright (C) 2017 Free Software Foundation, Inc.
> ++   Written by Joan Lledó.
> ++
> ++   This file is part of the GNU Hurd.
> ++
> ++   The GNU Hurd is free software; you can redistribute it and/or
> ++   modify it under the terms of the GNU General Public License as
> ++   published by the Free Software Foundation; either version 2, or (at
> ++   your option) any later version.
> ++
> ++   The GNU Hurd is distributed in the hope that it will be useful, but
> ++   WITHOUT ANY WARRANTY; without even the implied warranty of
> ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++   General Public License for more details.
> ++
> ++   You should have received a copy of the GNU General Public License
> ++   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> ++
> ++#ifndef LWIP_ARCH_CC_H
> ++#define LWIP_ARCH_CC_H
> ++
> ++#include <stdlib.h> /* rand() */
> ++#include <stdio.h> /* printf() */
> ++
> ++/* Use Glibc's fcntl() macros */
> ++#include <fcntl.h>
> ++
> ++/* Use Glibc's <errno.h> */
> ++#include <errno.h>
> ++#define LWIP_ERR_T  int
> ++
> ++/* System provides its own struct timeval */
> ++#define LWIP_TIMEVAL_PRIVATE  0
> ++#include <sys/time.h>
> ++
> ++/* We need INT_MAX */
> ++#include <limits.h>
> ++
> ++/* Use our own ioctls */
> ++#include <sys/ioctl.h>
> ++
> ++/* Use our own htons() and pals */
> ++#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> ++
> ++/* printf() codes */
> ++#define S16_F "d"
> ++#define U16_F "u"
> ++#define X16_F "x"
> ++
> ++#define S32_F "d"
> ++#define U32_F "u"
> ++#define X32_F "x"
> ++
> ++#ifdef LWIP_DEBUG
> ++#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
> ++#endif
> ++
> ++/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
> ++#define LWIP_ERROR(message, expression, handler) \
> ++  do { \
> ++    if (!(expression)) { \
> ++      printf("Assertion \"%s\" failed at line %d in %s\n", \
> ++        message, __LINE__, __FILE__); fflush(NULL); \
> ++      handler;} \
> ++  } while(0)
> ++
> ++#endif /* LWIP_ARCH_CC_H */
>  --- /dev/null
>  +++ b/port/include/arch/sys_arch.h
> -@@ -0,0 +1,64 @@
> -+/*
> -+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> -+ * All rights reserved. 
> -+ * 
> -+ * Redistribution and use in source and binary forms, with or without 
> modification, 
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ *    this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> -+ *    this list of conditions and the following disclaimer in the 
> documentation
> -+ *    and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ *    derived from this software without specific prior written permission. 
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED 
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT 
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
> SPECIAL, 
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT 
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS 
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING 
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY 
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ * 
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+#ifndef LWIP_ARCH_SYS_ARCH_H
> -+#define LWIP_ARCH_SYS_ARCH_H
> -+
> -+#define SYS_MBOX_NULL NULL
> -+#define SYS_SEM_NULL  NULL
> -+
> -+/* Return code for an interrupted timed wait */
> -+#define SYS_ARCH_INTR 0xfffffffeUL
> -+
> -+typedef u32_t sys_prot_t;
> -+
> -+struct sys_sem;
> -+typedef struct sys_sem * sys_sem_t;
> -+#define sys_sem_valid(sem)       (*(sem) != NULL)
> -+#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; 
> }}while(0)
> -+
> -+struct sys_mutex;
> -+typedef struct sys_mutex * sys_mutex_t;
> -+#define sys_mutex_valid(mutex)       sys_sem_valid(mutex)
> -+#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
> -+
> -+struct sys_mbox;
> -+typedef struct sys_mbox * sys_mbox_t;
> -+#define sys_mbox_valid(mbox)       sys_sem_valid(mbox)
> -+#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
> -+
> -+struct sys_thread;
> -+typedef struct sys_thread * sys_thread_t;
> -+
> -+u32_t sys_arch_sem_wait_intr(sys_sem_t *sem, u32_t timeout);
> -+
> -+#endif /* LWIP_ARCH_SYS_ARCH_H */
> -+
> +@@ -0,0 +1,62 @@
> ++/*
> ++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> ++ * All rights reserved. 
> ++ * 
> ++ * Redistribution and use in source and binary forms, with or without 
> modification, 
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ *    this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> ++ *    this list of conditions and the following disclaimer in the 
> documentation
> ++ *    and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ *    derived from this software without specific prior written permission. 
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED 
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT 
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
> SPECIAL, 
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT 
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS 
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING 
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY 
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ * 
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++#ifndef LWIP_ARCH_SYS_ARCH_H
> ++#define LWIP_ARCH_SYS_ARCH_H
> ++
> ++#define SYS_MBOX_NULL NULL
> ++#define SYS_SEM_NULL  NULL
> ++
> ++/* Return code for an interrupted timed wait */
> ++#define SYS_ARCH_INTR 0xfffffffeUL
> ++
> ++typedef u32_t sys_prot_t;
> ++
> ++struct sys_sem;
> ++typedef struct sys_sem * sys_sem_t;
> ++#define sys_sem_valid(sem)       (*(sem) != NULL)
> ++#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; 
> }}while(0)
> ++
> ++struct sys_mutex;
> ++typedef struct sys_mutex * sys_mutex_t;
> ++#define sys_mutex_valid(mutex)       sys_sem_valid(mutex)
> ++#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
> ++
> ++struct sys_mbox;
> ++typedef struct sys_mbox * sys_mbox_t;
> ++#define sys_mbox_valid(mbox)       sys_sem_valid(mbox)
> ++#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
> ++
> ++struct sys_thread;
> ++typedef struct sys_thread * sys_thread_t;
> ++
> ++#endif /* LWIP_ARCH_SYS_ARCH_H */
> ++
>  --- /dev/null
>  +++ b/port/include/lwipopts.h
>  @@ -0,0 +1,131 @@
> -+/*
> -+   Copyright (C) 2017 Free Software Foundation, Inc.
> -+   Written by Joan Lledó.
> -+
> -+   This file is part of the GNU Hurd.
> -+
> -+   The GNU Hurd is free software; you can redistribute it and/or
> -+   modify it under the terms of the GNU General Public License as
> -+   published by the Free Software Foundation; either version 2, or (at
> -+   your option) any later version.
> -+
> -+   The GNU Hurd is distributed in the hope that it will be useful, but
> -+   WITHOUT ANY WARRANTY; without even the implied warranty of
> -+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -+   General Public License for more details.
> -+
> -+   You should have received a copy of the GNU General Public License
> -+   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> -+
> -+#ifndef HURD_LWIP_LWIPOPTS_H
> -+#define HURD_LWIP_LWIPOPTS_H
> -+
> -+/* An OS is present */
> -+#define NO_SYS    0
> -+
> -+/* Don't rename Sockets API functions */
> -+#define LWIP_COMPAT_SOCKETS   0
> -+
> -+/* Use Glibc malloc()/free() */
> -+#define MEM_LIBC_MALLOC   1
> -+#define MEMP_MEM_MALLOC   1
> -+#define MEM_USE_POOLS     0
> -+#define MEM_ALIGNMENT     4
> -+
> -+/* Only send complete packets to the device */
> -+#define LWIP_NETIF_TX_SINGLE_PBUF 1
> -+
> -+/* Randomize local ports */
> -+#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS  1
> -+
> -+/* Glibc sends more than one packet in a row during an ARP resolution */
> -+#define ARP_QUEUEING    1
> -+#define ARP_QUEUE_LEN   10
> -+
> -+/* Netif API is needed to add or remove interfaces on run time */
> -+#define LWIP_NETIF_API  1
> -+
> -+/* IPv4 stuff */
> -+#define IP_FORWARD  1
> -+
> -+/* SLAAC support and other IPv6 stuff */
> -+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
> -+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
> -+#define LWIP_IPV6_AUTOCONFIG          1
> -+#define LWIP_IPV6_FORWARD             1
> -+#define MEMP_NUM_MLD6_GROUP           16
> -+#define LWIP_IPV6_NUM_ADDRESSES       6
> -+
> -+/* TCP tuning */
> -+#define TCP_MSS                 1460
> -+#define TCP_WND                 0xFFFF
> -+#define TCP_SND_BUF             TCP_WND
> -+
> -+/* Throughput settings */
> -+#define LWIP_CHECKSUM_ON_COPY   1
> -+
> -+/* Disable stats */
> -+#define LWIP_STATS          0
> -+#define LWIP_STATS_DISPLAY  0
> -+
> -+/* Enable all socket operations */
> -+#define LWIP_TCP_KEEPALIVE          1
> -+#define LWIP_SO_SNDTIMEO            1
> -+#define LWIP_SO_RCVTIMEO            1
> -+#define LWIP_SO_RCVBUF              1
> -+#define LWIP_SO_LINGER              1
> -+#define SO_REUSE                    1
> -+#define LWIP_MULTICAST_TX_OPTIONS   1
> -+
> -+/* Enable modules */
> -+#define LWIP_ARP              1
> -+#define LWIP_ETHERNET         1
> -+#define LWIP_IPV4             1
> -+#define LWIP_ICMP             1
> -+#define LWIP_IGMP             1
> -+#define LWIP_RAW              1
> -+#define LWIP_UDP              1
> -+#define LWIP_UDPLITE          1
> -+#define LWIP_TCP              1
> -+#define LWIP_IPV6             1
> -+#define LWIP_ICMP6            1
> -+#define LWIP_IPV6_MLD         1
> -+#define LWIP_NETIF_LOOPBACK   1
> -+
> -+/* Debug mode */
> -+#ifdef LWIP_DEBUG
> -+#define ETHARP_DEBUG      LWIP_DBG_OFF
> -+#define NETIF_DEBUG       LWIP_DBG_OFF
> -+#define PBUF_DEBUG        LWIP_DBG_OFF
> -+#define API_LIB_DEBUG     LWIP_DBG_OFF
> -+#define API_MSG_DEBUG     LWIP_DBG_OFF
> -+#define SOCKETS_DEBUG     LWIP_DBG_OFF
> -+#define ICMP_DEBUG        LWIP_DBG_OFF
> -+#define IGMP_DEBUG        LWIP_DBG_OFF
> -+#define INET_DEBUG        LWIP_DBG_OFF
> -+#define IP_DEBUG          LWIP_DBG_OFF
> -+#define IP_REASS_DEBUG    LWIP_DBG_OFF
> -+#define RAW_DEBUG         LWIP_DBG_OFF
> -+#define MEM_DEBUG         LWIP_DBG_OFF
> -+#define MEMP_DEBUG        LWIP_DBG_OFF
> -+#define SYS_DEBUG         LWIP_DBG_OFF
> -+#define TIMERS_DEBUG      LWIP_DBG_OFF
> -+#define TCP_DEBUG         LWIP_DBG_OFF
> -+#define TCP_INPUT_DEBUG   LWIP_DBG_OFF
> -+#define TCP_FR_DEBUG      LWIP_DBG_OFF
> -+#define TCP_RTO_DEBUG     LWIP_DBG_OFF
> -+#define TCP_CWND_DEBUG    LWIP_DBG_OFF
> -+#define TCP_WND_DEBUG     LWIP_DBG_OFF
> -+#define TCP_OUTPUT_DEBUG  LWIP_DBG_OFF
> -+#define TCP_RST_DEBUG     LWIP_DBG_OFF
> -+#define TCP_QLEN_DEBUG    LWIP_DBG_OFF
> -+#define UDP_DEBUG         LWIP_DBG_OFF
> -+#define TCPIP_DEBUG       LWIP_DBG_OFF
> -+#define SLIP_DEBUG        LWIP_DBG_OFF
> -+#define DHCP_DEBUG        LWIP_DBG_OFF
> -+#define AUTOIP_DEBUG      LWIP_DBG_OFF
> -+#define DNS_DEBUG         LWIP_DBG_OFF
> -+#define IP6_DEBUG         LWIP_DBG_OFF
> -+#endif
> -+
> -+#endif
> ++/*
> ++   Copyright (C) 2017 Free Software Foundation, Inc.
> ++   Written by Joan Lledó.
> ++
> ++   This file is part of the GNU Hurd.
> ++
> ++   The GNU Hurd is free software; you can redistribute it and/or
> ++   modify it under the terms of the GNU General Public License as
> ++   published by the Free Software Foundation; either version 2, or (at
> ++   your option) any later version.
> ++
> ++   The GNU Hurd is distributed in the hope that it will be useful, but
> ++   WITHOUT ANY WARRANTY; without even the implied warranty of
> ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++   General Public License for more details.
> ++
> ++   You should have received a copy of the GNU General Public License
> ++   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> ++
> ++#ifndef HURD_LWIP_LWIPOPTS_H
> ++#define HURD_LWIP_LWIPOPTS_H
> ++
> ++/* An OS is present */
> ++#define NO_SYS    0
> ++
> ++/* Don't rename Sockets API functions */
> ++#define LWIP_COMPAT_SOCKETS   0
> ++
> ++/* Use Glibc malloc()/free() */
> ++#define MEM_LIBC_MALLOC   1
> ++#define MEMP_MEM_MALLOC   1
> ++#define MEM_USE_POOLS     0
> ++#define MEM_ALIGNMENT     4
> ++
> ++/* Only send complete packets to the device */
> ++#define LWIP_NETIF_TX_SINGLE_PBUF 1
> ++
> ++/* Randomize local ports */
> ++#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS  1
> ++
> ++/* Glibc sends more than one packet in a row during an ARP resolution */
> ++#define ARP_QUEUEING    1
> ++#define ARP_QUEUE_LEN   10
> ++
> ++/* Netif API is needed to add or remove interfaces on run time */
> ++#define LWIP_NETIF_API  1
> ++
> ++/* IPv4 stuff */
> ++#define IP_FORWARD  1
> ++
> ++/* SLAAC support and other IPv6 stuff */
> ++#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
> ++#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
> ++#define LWIP_IPV6_AUTOCONFIG          1
> ++#define LWIP_IPV6_FORWARD             1
> ++#define MEMP_NUM_MLD6_GROUP           16
> ++#define LWIP_IPV6_NUM_ADDRESSES       6
> ++
> ++/* TCP tuning */
> ++#define TCP_MSS                 1460
> ++#define TCP_WND                 0xFFFF
> ++#define TCP_SND_BUF             TCP_WND
> ++
> ++/* Throughput settings */
> ++#define LWIP_CHECKSUM_ON_COPY   1
> ++
> ++/* Disable stats */
> ++#define LWIP_STATS          0
> ++#define LWIP_STATS_DISPLAY  0
> ++
> ++/* Enable all socket operations */
> ++#define LWIP_TCP_KEEPALIVE          1
> ++#define LWIP_SO_SNDTIMEO            1
> ++#define LWIP_SO_RCVTIMEO            1
> ++#define LWIP_SO_RCVBUF              1
> ++#define LWIP_SO_LINGER              1
> ++#define SO_REUSE                    1
> ++#define LWIP_MULTICAST_TX_OPTIONS   1
> ++
> ++/* Enable modules */
> ++#define LWIP_ARP              1
> ++#define LWIP_ETHERNET         1
> ++#define LWIP_IPV4             1
> ++#define LWIP_ICMP             1
> ++#define LWIP_IGMP             1
> ++#define LWIP_RAW              1
> ++#define LWIP_UDP              1
> ++#define LWIP_UDPLITE          1
> ++#define LWIP_TCP              1
> ++#define LWIP_IPV6             1
> ++#define LWIP_ICMP6            1
> ++#define LWIP_IPV6_MLD         1
> ++#define LWIP_NETIF_LOOPBACK   1
> ++
> ++/* Debug mode */
> ++#ifdef LWIP_DEBUG
> ++#define ETHARP_DEBUG      LWIP_DBG_OFF
> ++#define NETIF_DEBUG       LWIP_DBG_OFF
> ++#define PBUF_DEBUG        LWIP_DBG_OFF
> ++#define API_LIB_DEBUG     LWIP_DBG_OFF
> ++#define API_MSG_DEBUG     LWIP_DBG_OFF
> ++#define SOCKETS_DEBUG     LWIP_DBG_OFF
> ++#define ICMP_DEBUG        LWIP_DBG_OFF
> ++#define IGMP_DEBUG        LWIP_DBG_OFF
> ++#define INET_DEBUG        LWIP_DBG_OFF
> ++#define IP_DEBUG          LWIP_DBG_OFF
> ++#define IP_REASS_DEBUG    LWIP_DBG_OFF
> ++#define RAW_DEBUG         LWIP_DBG_OFF
> ++#define MEM_DEBUG         LWIP_DBG_OFF
> ++#define MEMP_DEBUG        LWIP_DBG_OFF
> ++#define SYS_DEBUG         LWIP_DBG_OFF
> ++#define TIMERS_DEBUG      LWIP_DBG_OFF
> ++#define TCP_DEBUG         LWIP_DBG_OFF
> ++#define TCP_INPUT_DEBUG   LWIP_DBG_OFF
> ++#define TCP_FR_DEBUG      LWIP_DBG_OFF
> ++#define TCP_RTO_DEBUG     LWIP_DBG_OFF
> ++#define TCP_CWND_DEBUG    LWIP_DBG_OFF
> ++#define TCP_WND_DEBUG     LWIP_DBG_OFF
> ++#define TCP_OUTPUT_DEBUG  LWIP_DBG_OFF
> ++#define TCP_RST_DEBUG     LWIP_DBG_OFF
> ++#define TCP_QLEN_DEBUG    LWIP_DBG_OFF
> ++#define UDP_DEBUG         LWIP_DBG_OFF
> ++#define TCPIP_DEBUG       LWIP_DBG_OFF
> ++#define SLIP_DEBUG        LWIP_DBG_OFF
> ++#define DHCP_DEBUG        LWIP_DBG_OFF
> ++#define AUTOIP_DEBUG      LWIP_DBG_OFF
> ++#define DNS_DEBUG         LWIP_DBG_OFF
> ++#define IP6_DEBUG         LWIP_DBG_OFF
> ++#endif
> ++
> ++#endif
>  --- /dev/null
>  +++ b/port/sys_arch.c
> -@@ -0,0 +1,747 @@
> -+/*
> -+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> -+ * All rights reserved. 
> -+ * 
> -+ * Redistribution and use in source and binary forms, with or without 
> modification, 
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ *    this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> -+ *    this list of conditions and the following disclaimer in the 
> documentation
> -+ *    and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ *    derived from this software without specific prior written permission. 
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED 
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT 
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
> SPECIAL, 
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT 
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS 
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING 
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY 
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ * 
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+
> -+/*
> -+ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
> -+ *
> -+ *  - Fixed an unlikely sys_thread_new() race condition.
> -+ *
> -+ *  - Made current_thread() work with threads which where
> -+ *    not created with sys_thread_new().  This includes
> -+ *    the main thread and threads made with pthread_create().
> -+ *
> -+ *  - Catch overflows where more than SYS_MBOX_SIZE messages
> -+ *    are waiting to be read.  The sys_mbox_post() routine
> -+ *    will block until there is more room instead of just
> -+ *    leaking messages.
> -+ */
> -+#include "lwip/debug.h"
> -+
> -+#include <string.h>
> -+#include <sys/time.h>
> -+#include <sys/types.h>
> -+#include <stdlib.h>
> -+#include <unistd.h>
> -+#include <pthread.h>
> -+
> -+#include "lwip/def.h"
> -+
> -+#ifdef LWIP_UNIX_MACH
> -+#include <mach/mach.h>
> -+#include <mach/mach_time.h>
> -+#endif
> -+
> -+#include "lwip/sys.h"
> -+#include "lwip/opt.h"
> -+#include "lwip/stats.h"
> -+
> -+static void
> -+get_monotonic_time(struct timespec *ts)
> -+{
> -+#ifdef LWIP_UNIX_MACH
> -+  /* darwin impl (no CLOCK_MONOTONIC) */
> -+  uint64_t t = mach_absolute_time();
> -+  mach_timebase_info_data_t timebase_info = {0, 0};
> -+  mach_timebase_info(&timebase_info);
> -+  uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
> -+  uint64_t sec = nano/1000000000L;
> -+  nano -= sec * 1000000000L;
> -+  ts->tv_sec = sec;
> -+  ts->tv_nsec = nano;
> -+#else
> -+  clock_gettime(CLOCK_MONOTONIC, ts);
> -+#endif
> -+}
> -+
> -+#if !NO_SYS
> -+
> -+static struct sys_thread *threads = NULL;
> -+static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
> -+
> -+struct sys_mbox_msg {
> -+  struct sys_mbox_msg *next;
> -+  void *msg;
> -+};
> -+
> -+#define SYS_MBOX_SIZE 128
> -+
> -+struct sys_mbox {
> -+  int first, last;
> -+  void *msgs[SYS_MBOX_SIZE];
> -+  struct sys_sem *not_empty;
> -+  struct sys_sem *not_full;
> -+  struct sys_sem *mutex;
> -+  int wait_send;
> -+};
> -+
> -+struct sys_sem {
> -+  unsigned int c;
> -+  pthread_condattr_t condattr;
> -+  pthread_cond_t cond;
> -+  pthread_mutex_t mutex;
> -+};
> -+
> -+struct sys_mutex {
> -+  pthread_mutex_t mutex;
> -+};
> -+
> -+struct sys_thread {
> -+  struct sys_thread *next;
> -+  pthread_t pthread;
> -+};
> -+
> -+#if SYS_LIGHTWEIGHT_PROT
> -+static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
> -+static pthread_t lwprot_thread = (pthread_t)0xDEAD;
> -+static int lwprot_count = 0;
> -+#endif /* SYS_LIGHTWEIGHT_PROT */
> -+
> -+static struct sys_sem *sys_sem_new_internal(u8_t count);
> -+static void sys_sem_free_internal(struct sys_sem *sem);
> -+
> -+static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
> -+                       u32_t timeout);
> -+
> -+static u32_t cond_wait_intr(pthread_cond_t * cond, pthread_mutex_t * mutex,
> -+                       u32_t timeout);
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Threads */
> -+static struct sys_thread * 
> -+introduce_thread(pthread_t id)
> -+{
> -+  struct sys_thread *thread;
> -+
> -+  thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
> -+
> -+  if (thread != NULL) {
> -+    pthread_mutex_lock(&threads_mutex);
> -+    thread->next = threads;
> -+    thread->pthread = id;
> -+    threads = thread;
> -+    pthread_mutex_unlock(&threads_mutex);
> -+  }
> -+
> -+  return thread;
> -+}
> -+
> -+sys_thread_t
> -+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int 
> stacksize, int prio)
> -+{
> -+  int code;
> -+  pthread_t tmp;
> -+  struct sys_thread *st = NULL;
> -+  LWIP_UNUSED_ARG(name);
> -+  LWIP_UNUSED_ARG(stacksize);
> -+  LWIP_UNUSED_ARG(prio);
> -+
> -+  code = pthread_create(&tmp,
> -+                        NULL, 
> -+                        (void *(*)(void *)) 
> -+                        function, 
> -+                        arg);
> -+  
> -+  if (0 == code) {
> -+    st = introduce_thread(tmp);
> -+  }
> -+  
> -+  if (NULL == st) {
> -+    LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
> -+                       code, (unsigned long)st));
> -+    abort();
> -+  }
> -+  return st;
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Mailbox */
> -+err_t
> -+sys_mbox_new(struct sys_mbox **mb, int size)
> -+{
> -+  struct sys_mbox *mbox;
> -+  LWIP_UNUSED_ARG(size);
> -+
> -+  mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
> -+  if (mbox == NULL) {
> -+    return ERR_MEM;
> -+  }
> -+  mbox->first = mbox->last = 0;
> -+  mbox->not_empty = sys_sem_new_internal(0);
> -+  mbox->not_full = sys_sem_new_internal(0);
> -+  mbox->mutex = sys_sem_new_internal(1);
> -+  mbox->wait_send = 0;
> -+
> -+  SYS_STATS_INC_USED(mbox);
> -+  *mb = mbox;
> -+  return ERR_OK;
> -+}
> -+
> -+void
> -+sys_mbox_free(struct sys_mbox **mb)
> -+{
> -+  if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
> -+    struct sys_mbox *mbox = *mb;
> -+    SYS_STATS_DEC(mbox.used);
> -+    sys_arch_sem_wait(&mbox->mutex, 0);
> -+    
> -+    sys_sem_free_internal(mbox->not_empty);
> -+    sys_sem_free_internal(mbox->not_full);
> -+    sys_sem_free_internal(mbox->mutex);
> -+    mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
> -+    /*  LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
> -+    free(mbox);
> -+  }
> -+}
> -+
> -+err_t
> -+sys_mbox_trypost(struct sys_mbox **mb, void *msg)
> -+{
> -+  u8_t first;
> -+  struct sys_mbox *mbox;
> -+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+  mbox = *mb;
> -+
> -+  sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
> -+                          (void *)mbox, (void *)msg));
> -+
> -+  if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> -+    sys_sem_signal(&mbox->mutex);
> -+    return ERR_MEM;
> -+  }
> -+
> -+  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> -+
> -+  if (mbox->last == mbox->first) {
> -+    first = 1;
> -+  } else {
> -+    first = 0;
> -+  }
> -+
> -+  mbox->last++;
> -+
> -+  if (first) {
> -+    sys_sem_signal(&mbox->not_empty);
> -+  }
> -+
> -+  sys_sem_signal(&mbox->mutex);
> -+
> -+  return ERR_OK;
> -+}
> -+
> -+void
> -+sys_mbox_post(struct sys_mbox **mb, void *msg)
> -+{
> -+  u8_t first;
> -+  struct sys_mbox *mbox;
> -+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+  mbox = *mb;
> -+
> -+  sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, 
> (void *)msg));
> -+
> -+  while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> -+    mbox->wait_send++;
> -+    sys_sem_signal(&mbox->mutex);
> -+    sys_arch_sem_wait(&mbox->not_full, 0);
> -+    sys_arch_sem_wait(&mbox->mutex, 0);
> -+    mbox->wait_send--;
> -+  }
> -+
> -+  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> -+
> -+  if (mbox->last == mbox->first) {
> -+    first = 1;
> -+  } else {
> -+    first = 0;
> -+  }
> -+
> -+  mbox->last++;
> -+
> -+  if (first) {
> -+    sys_sem_signal(&mbox->not_empty);
> -+  }
> -+
> -+  sys_sem_signal(&mbox->mutex);
> -+}
> -+
> -+u32_t
> -+sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
> -+{
> -+  struct sys_mbox *mbox;
> -+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+  mbox = *mb;
> -+
> -+  sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+  if (mbox->first == mbox->last) {
> -+    sys_sem_signal(&mbox->mutex);
> -+    return SYS_MBOX_EMPTY;
> -+  }
> -+
> -+  if (msg != NULL) {
> -+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void 
> *)mbox, *msg));
> -+    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> -+  }
> -+  else{
> -+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void 
> *)mbox));
> -+  }
> -+
> -+  mbox->first++;
> -+
> -+  if (mbox->wait_send) {
> -+    sys_sem_signal(&mbox->not_full);
> -+  }
> -+
> -+  sys_sem_signal(&mbox->mutex);
> -+
> -+  return 0;
> -+}
> -+
> -+u32_t
> -+sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
> -+{
> -+  u32_t time_needed = 0;
> -+  struct sys_mbox *mbox;
> -+  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+  mbox = *mb;
> -+
> -+  /* The mutex lock is quick so we don't bother with the timeout
> -+     stuff here. */
> -+  sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+  while (mbox->first == mbox->last) {
> -+    sys_sem_signal(&mbox->mutex);
> -+
> -+    /* We block while waiting for a mail to arrive in the mailbox. We
> -+       must be prepared to timeout. */
> -+    if (timeout != 0) {
> -+      time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
> -+
> -+      if (time_needed == SYS_ARCH_TIMEOUT) {
> -+        return SYS_ARCH_TIMEOUT;
> -+      }
> -+    } else {
> -+      sys_arch_sem_wait(&mbox->not_empty, 0);
> -+    }
> -+
> -+    sys_arch_sem_wait(&mbox->mutex, 0);
> -+  }
> -+
> -+  if (msg != NULL) {
> -+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void 
> *)mbox, *msg));
> -+    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> -+  }
> -+  else{
> -+    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void 
> *)mbox));
> -+  }
> -+
> -+  mbox->first++;
> -+
> -+  if (mbox->wait_send) {
> -+    sys_sem_signal(&mbox->not_full);
> -+  }
> -+
> -+  sys_sem_signal(&mbox->mutex);
> -+
> -+  return time_needed;
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Semaphore */
> -+static struct sys_sem *
> -+sys_sem_new_internal(u8_t count)
> -+{
> -+  struct sys_sem *sem;
> -+
> -+  sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
> -+  if (sem != NULL) {
> -+    sem->c = count;
> -+    pthread_condattr_init(&(sem->condattr));
> -+#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && 
> __ANDROID_API__ < 21))
> -+    pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
> -+#endif
> -+    pthread_cond_init(&(sem->cond), &(sem->condattr));
> -+    pthread_mutex_init(&(sem->mutex), NULL);
> -+  }
> -+  return sem;
> -+}
> -+
> -+err_t
> -+sys_sem_new(struct sys_sem **sem, u8_t count)
> -+{
> -+  SYS_STATS_INC_USED(sem);
> -+  *sem = sys_sem_new_internal(count);
> -+  if (*sem == NULL) {
> -+    return ERR_MEM;
> -+  }
> -+  return ERR_OK;
> -+}
> -+
> -+static u32_t
> -+cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> -+{
> -+  struct timespec rtime1, rtime2, ts;
> -+  int ret;
> -+
> -+  if (timeout == 0) {
> -+    pthread_cond_wait(cond, mutex);
> -+    return 0;
> -+  }
> -+
> -+  /* Get a timestamp and add the timeout value. */
> -+  get_monotonic_time(&rtime1);
> -+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && 
> __ANDROID_API__ < 21)
> -+  ts.tv_sec = timeout / 1000L;
> -+  ts.tv_nsec = (timeout % 1000L) * 1000000L;
> -+  ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> -+#else
> -+  ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> -+  ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> -+  if (ts.tv_nsec >= 1000000000L) {
> -+    ts.tv_sec++;
> -+    ts.tv_nsec -= 1000000000L;
> -+  }
> -+
> -+  ret = pthread_cond_timedwait(cond, mutex, &ts);
> -+#endif
> -+  if (ret == ETIMEDOUT) {
> -+    return SYS_ARCH_TIMEOUT;
> -+  }
> -+
> -+  /* Calculate for how long we waited for the cond. */
> -+  get_monotonic_time(&rtime2);
> -+  ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> -+  ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> -+  if (ts.tv_nsec < 0) {
> -+    ts.tv_sec--;
> -+    ts.tv_nsec += 1000000000L;
> -+  }
> -+  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+u32_t
> -+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
> -+{
> -+  u32_t time_needed = 0;
> -+  struct sys_sem *sem;
> -+  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+  sem = *s;
> -+
> -+  pthread_mutex_lock(&(sem->mutex));
> -+  while (sem->c <= 0) {
> -+    if (timeout > 0) {
> -+      time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
> -+
> -+      if (time_needed == SYS_ARCH_TIMEOUT) {
> -+        pthread_mutex_unlock(&(sem->mutex));
> -+        return SYS_ARCH_TIMEOUT;
> -+      }
> -+      /*      pthread_mutex_unlock(&(sem->mutex));
> -+              return time_needed; */
> -+    } else {
> -+      cond_wait(&(sem->cond), &(sem->mutex), 0);
> -+    }
> -+  }
> -+  sem->c--;
> -+  pthread_mutex_unlock(&(sem->mutex));
> -+  return (u32_t)time_needed;
> -+}
> -+
> -+/*
> -+ * Like cond_wait(), but it calls Hurd's non portable
> -+ * functions to receive cancellation requests
> -+ */
> -+static u32_t
> -+cond_wait_intr(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> -+{
> -+  struct timespec rtime1, rtime2, ts;
> -+  int ret;
> -+
> -+#ifdef __GNU__
> -+  #define pthread_cond_wait pthread_hurd_cond_wait_np
> -+  #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
> -+#endif
> -+
> -+  if (timeout == 0) {
> -+    ret = pthread_cond_wait(cond, mutex);
> -+    return ret;
> -+  }
> -+
> -+  /* Get a timestamp and add the timeout value. */
> -+  get_monotonic_time(&rtime1);
> -+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && 
> __ANDROID_API__ < 21)
> -+  ts.tv_sec = timeout / 1000L;
> -+  ts.tv_nsec = (timeout % 1000L) * 1000000L;
> -+  ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> -+#else
> -+  ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> -+  ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> -+  if (ts.tv_nsec >= 1000000000L) {
> -+    ts.tv_sec++;
> -+    ts.tv_nsec -= 1000000000L;
> -+  }
> -+
> -+  ret = pthread_cond_timedwait(cond, mutex, &ts);
> -+#endif
> -+  if (ret == ETIMEDOUT) {
> -+    return SYS_ARCH_TIMEOUT;
> -+  } else if (ret == EINTR) {
> -+    return SYS_ARCH_INTR;
> -+  }
> -+
> -+  /* Calculate for how long we waited for the cond. */
> -+  get_monotonic_time(&rtime2);
> -+  ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> -+  ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> -+  if (ts.tv_nsec < 0) {
> -+    ts.tv_sec--;
> -+    ts.tv_nsec += 1000000000L;
> -+  }
> -+  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+/*
> -+ * Like sys_arch_sem_wait(), but it handles thread cancellations.
> -+ */
> -+u32_t
> -+sys_arch_sem_wait_intr(struct sys_sem **s, u32_t timeout)
> -+{
> -+  u32_t time_needed = 0;
> -+  struct sys_sem *sem;
> -+  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+  sem = *s;
> -+
> -+  pthread_mutex_lock(&(sem->mutex));
> -+  while (sem->c <= 0) {
> -+    if (timeout > 0) {
> -+      time_needed = cond_wait_intr(&(sem->cond), &(sem->mutex), timeout);
> -+
> -+      if (time_needed == SYS_ARCH_TIMEOUT) {
> -+        pthread_mutex_unlock(&(sem->mutex));
> -+        return SYS_ARCH_TIMEOUT;
> -+      } else if(time_needed == SYS_ARCH_INTR) {
> -+         /* This means we were interrupted, so don't wait again */
> -+        sem->c++;
> -+
> -+        if (sem->c > 1) {
> -+          sem->c = 1;
> -+        }
> -+      }
> -+    } else {
> -+      if(cond_wait_intr(&(sem->cond), &(sem->mutex), 0)) {
> -+        /* This means we were interrupted, so don't wait again */
> -+        sem->c++;
> -+
> -+        if (sem->c > 1) {
> -+          sem->c = 1;
> -+        }
> -+      }
> -+    }
> -+  }
> -+  sem->c--;
> -+  pthread_mutex_unlock(&(sem->mutex));
> -+  return (u32_t)time_needed;
> -+}
> -+
> -+void
> -+sys_sem_signal(struct sys_sem **s)
> -+{
> -+  struct sys_sem *sem;
> -+  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+  sem = *s;
> -+
> -+  pthread_mutex_lock(&(sem->mutex));
> -+  sem->c++;
> -+
> -+  if (sem->c > 1) {
> -+    sem->c = 1;
> -+  }
> -+
> -+  pthread_cond_broadcast(&(sem->cond));
> -+  pthread_mutex_unlock(&(sem->mutex));
> -+}
> -+
> -+static void
> -+sys_sem_free_internal(struct sys_sem *sem)
> -+{
> -+  pthread_cond_destroy(&(sem->cond));
> -+  pthread_condattr_destroy(&(sem->condattr));
> -+  pthread_mutex_destroy(&(sem->mutex));
> -+  free(sem);
> -+}
> -+
> -+void
> -+sys_sem_free(struct sys_sem **sem)
> -+{
> -+  if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
> -+    SYS_STATS_DEC(sem.used);
> -+    sys_sem_free_internal(*sem);
> -+  }
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Mutex */
> -+/** Create a new mutex
> -+ * @param mutex pointer to the mutex to create
> -+ * @return a new mutex */
> -+err_t
> -+sys_mutex_new(struct sys_mutex **mutex)
> -+{
> -+  struct sys_mutex *mtx;
> -+
> -+  mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
> -+  if (mtx != NULL) {
> -+    pthread_mutex_init(&(mtx->mutex), NULL);
> -+    *mutex = mtx;
> -+    return ERR_OK;
> -+  }
> -+  else {
> -+    return ERR_MEM;
> -+  }
> -+}
> -+
> -+/** Lock a mutex
> -+ * @param mutex the mutex to lock */
> -+void
> -+sys_mutex_lock(struct sys_mutex **mutex)
> -+{
> -+  pthread_mutex_lock(&((*mutex)->mutex));
> -+}
> -+
> -+/** Unlock a mutex
> -+ * @param mutex the mutex to unlock */
> -+void
> -+sys_mutex_unlock(struct sys_mutex **mutex)
> -+{
> -+  pthread_mutex_unlock(&((*mutex)->mutex));
> -+}
> -+
> -+/** Delete a mutex
> -+ * @param mutex the mutex to delete */
> -+void
> -+sys_mutex_free(struct sys_mutex **mutex)
> -+{
> -+  pthread_mutex_destroy(&((*mutex)->mutex));
> -+  free(*mutex);
> -+}
> -+
> -+#endif /* !NO_SYS */
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Time */
> -+u32_t
> -+sys_now(void)
> -+{
> -+  struct timespec ts;
> -+
> -+  get_monotonic_time(&ts);
> -+  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+u32_t
> -+sys_jiffies(void)
> -+{
> -+  struct timespec ts;
> -+
> -+  get_monotonic_time(&ts);
> -+  return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Init */
> -+
> -+void
> -+sys_init(void)
> -+{
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Critical section */
> -+#if SYS_LIGHTWEIGHT_PROT
> -+/** sys_prot_t sys_arch_protect(void)
> -+
> -+This optional function does a "fast" critical region protection and returns
> -+the previous protection level. This function is only called during very 
> short
> -+critical regions. An embedded system which supports ISR-based drivers might
> -+want to implement this function by disabling interrupts. Task-based systems
> -+might want to implement this by using a mutex or disabling tasking. This
> -+function should support recursive calls from the same task or interrupt. In
> -+other words, sys_arch_protect() could be called while already protected. In
> -+that case the return value indicates that it is already protected.
> -+
> -+sys_arch_protect() is only required if your port is supporting an operating
> -+system.
> -+*/
> -+sys_prot_t
> -+sys_arch_protect(void)
> -+{
> -+    /* Note that for the UNIX port, we are using a lightweight mutex, and 
> our
> -+     * own counter (which is locked by the mutex). The return code is not 
> actually
> -+     * used. */
> -+    if (lwprot_thread != pthread_self())
> -+    {
> -+        /* We are locking the mutex where it has not been locked before *
> -+        * or is being locked by another thread */
> -+        pthread_mutex_lock(&lwprot_mutex);
> -+        lwprot_thread = pthread_self();
> -+        lwprot_count = 1;
> -+    }
> -+    else
> -+        /* It is already locked by THIS thread */
> -+        lwprot_count++;
> -+    return 0;
> -+}
> -+
> -+/** void sys_arch_unprotect(sys_prot_t pval)
> -+
> -+This optional function does a "fast" set of critical region protection to 
> the
> -+value specified by pval. See the documentation for sys_arch_protect() for
> -+more information. This function is only required if your port is supporting
> -+an operating system.
> -+*/
> -+void
> -+sys_arch_unprotect(sys_prot_t pval)
> -+{
> -+    LWIP_UNUSED_ARG(pval);
> -+    if (lwprot_thread == pthread_self())
> -+    {
> -+        if (--lwprot_count == 0)
> -+        {
> -+            lwprot_thread = (pthread_t) 0xDEAD;
> -+            pthread_mutex_unlock(&lwprot_mutex);
> -+        }
> -+    }
> -+}
> -+#endif /* SYS_LIGHTWEIGHT_PROT */
> +@@ -0,0 +1,668 @@
> ++/*
> ++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> ++ * All rights reserved. 
> ++ * 
> ++ * Redistribution and use in source and binary forms, with or without 
> modification, 
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ *    this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> ++ *    this list of conditions and the following disclaimer in the 
> documentation
> ++ *    and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ *    derived from this software without specific prior written permission. 
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED 
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT 
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
> SPECIAL, 
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT 
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS 
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING 
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY 
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ * 
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++
> ++/*
> ++ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
> ++ *
> ++ *  - Fixed an unlikely sys_thread_new() race condition.
> ++ *
> ++ *  - Made current_thread() work with threads which where
> ++ *    not created with sys_thread_new().  This includes
> ++ *    the main thread and threads made with pthread_create().
> ++ *
> ++ *  - Catch overflows where more than SYS_MBOX_SIZE messages
> ++ *    are waiting to be read.  The sys_mbox_post() routine
> ++ *    will block until there is more room instead of just
> ++ *    leaking messages.
> ++ */
> ++#include "lwip/debug.h"
> ++
> ++#include <string.h>
> ++#include <sys/time.h>
> ++#include <sys/types.h>
> ++#include <stdlib.h>
> ++#include <unistd.h>
> ++#include <pthread.h>
> ++
> ++#include "lwip/def.h"
> ++
> ++#ifdef LWIP_UNIX_MACH
> ++#include <mach/mach.h>
> ++#include <mach/mach_time.h>
> ++#endif
> ++
> ++#include "lwip/sys.h"
> ++#include "lwip/opt.h"
> ++#include "lwip/stats.h"
> ++
> ++static void
> ++get_monotonic_time(struct timespec *ts)
> ++{
> ++#ifdef LWIP_UNIX_MACH
> ++  /* darwin impl (no CLOCK_MONOTONIC) */
> ++  uint64_t t = mach_absolute_time();
> ++  mach_timebase_info_data_t timebase_info = {0, 0};
> ++  mach_timebase_info(&timebase_info);
> ++  uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
> ++  uint64_t sec = nano/1000000000L;
> ++  nano -= sec * 1000000000L;
> ++  ts->tv_sec = sec;
> ++  ts->tv_nsec = nano;
> ++#else
> ++  clock_gettime(CLOCK_MONOTONIC, ts);
> ++#endif
> ++}
> ++
> ++#if !NO_SYS
> ++
> ++static struct sys_thread *threads = NULL;
> ++static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
> ++
> ++struct sys_mbox_msg {
> ++  struct sys_mbox_msg *next;
> ++  void *msg;
> ++};
> ++
> ++#define SYS_MBOX_SIZE 128
> ++
> ++struct sys_mbox {
> ++  int first, last;
> ++  void *msgs[SYS_MBOX_SIZE];
> ++  struct sys_sem *not_empty;
> ++  struct sys_sem *not_full;
> ++  struct sys_sem *mutex;
> ++  int wait_send;
> ++};
> ++
> ++struct sys_sem {
> ++  unsigned int c;
> ++  pthread_condattr_t condattr;
> ++  pthread_cond_t cond;
> ++  pthread_mutex_t mutex;
> ++};
> ++
> ++struct sys_mutex {
> ++  pthread_mutex_t mutex;
> ++};
> ++
> ++struct sys_thread {
> ++  struct sys_thread *next;
> ++  pthread_t pthread;
> ++};
> ++
> ++#if SYS_LIGHTWEIGHT_PROT
> ++static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
> ++static pthread_t lwprot_thread = (pthread_t)0xDEAD;
> ++static int lwprot_count = 0;
> ++#endif /* SYS_LIGHTWEIGHT_PROT */
> ++
> ++static struct sys_sem *sys_sem_new_internal(u8_t count);
> ++static void sys_sem_free_internal(struct sys_sem *sem);
> ++
> ++static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
> ++                       u32_t timeout);
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Threads */
> ++static struct sys_thread * 
> ++introduce_thread(pthread_t id)
> ++{
> ++  struct sys_thread *thread;
> ++
> ++  thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
> ++
> ++  if (thread != NULL) {
> ++    pthread_mutex_lock(&threads_mutex);
> ++    thread->next = threads;
> ++    thread->pthread = id;
> ++    threads = thread;
> ++    pthread_mutex_unlock(&threads_mutex);
> ++  }
> ++
> ++  return thread;
> ++}
> ++
> ++sys_thread_t
> ++sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int 
> stacksize, int prio)
> ++{
> ++  int code;
> ++  pthread_t tmp;
> ++  struct sys_thread *st = NULL;
> ++  LWIP_UNUSED_ARG(name);
> ++  LWIP_UNUSED_ARG(stacksize);
> ++  LWIP_UNUSED_ARG(prio);
> ++
> ++  code = pthread_create(&tmp,
> ++                        NULL, 
> ++                        (void *(*)(void *)) 
> ++                        function, 
> ++                        arg);
> ++  
> ++  if (0 == code) {
> ++    st = introduce_thread(tmp);
> ++  }
> ++  
> ++  if (NULL == st) {
> ++    LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
> ++                       code, (unsigned long)st));
> ++    abort();
> ++  }
> ++  return st;
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Mailbox */
> ++err_t
> ++sys_mbox_new(struct sys_mbox **mb, int size)
> ++{
> ++  struct sys_mbox *mbox;
> ++  LWIP_UNUSED_ARG(size);
> ++
> ++  mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
> ++  if (mbox == NULL) {
> ++    return ERR_MEM;
> ++  }
> ++  mbox->first = mbox->last = 0;
> ++  mbox->not_empty = sys_sem_new_internal(0);
> ++  mbox->not_full = sys_sem_new_internal(0);
> ++  mbox->mutex = sys_sem_new_internal(1);
> ++  mbox->wait_send = 0;
> ++
> ++  SYS_STATS_INC_USED(mbox);
> ++  *mb = mbox;
> ++  return ERR_OK;
> ++}
> ++
> ++void
> ++sys_mbox_free(struct sys_mbox **mb)
> ++{
> ++  if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
> ++    struct sys_mbox *mbox = *mb;
> ++    SYS_STATS_DEC(mbox.used);
> ++    sys_arch_sem_wait(&mbox->mutex, 0);
> ++    
> ++    sys_sem_free_internal(mbox->not_empty);
> ++    sys_sem_free_internal(mbox->not_full);
> ++    sys_sem_free_internal(mbox->mutex);
> ++    mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
> ++    /*  LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
> ++    free(mbox);
> ++  }
> ++}
> ++
> ++err_t
> ++sys_mbox_trypost(struct sys_mbox **mb, void *msg)
> ++{
> ++  u8_t first;
> ++  struct sys_mbox *mbox;
> ++  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++  mbox = *mb;
> ++
> ++  sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
> ++                          (void *)mbox, (void *)msg));
> ++
> ++  if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> ++    sys_sem_signal(&mbox->mutex);
> ++    return ERR_MEM;
> ++  }
> ++
> ++  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> ++
> ++  if (mbox->last == mbox->first) {
> ++    first = 1;
> ++  } else {
> ++    first = 0;
> ++  }
> ++
> ++  mbox->last++;
> ++
> ++  if (first) {
> ++    sys_sem_signal(&mbox->not_empty);
> ++  }
> ++
> ++  sys_sem_signal(&mbox->mutex);
> ++
> ++  return ERR_OK;
> ++}
> ++
> ++void
> ++sys_mbox_post(struct sys_mbox **mb, void *msg)
> ++{
> ++  u8_t first;
> ++  struct sys_mbox *mbox;
> ++  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++  mbox = *mb;
> ++
> ++  sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++  LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, 
> (void *)msg));
> ++
> ++  while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> ++    mbox->wait_send++;
> ++    sys_sem_signal(&mbox->mutex);
> ++    sys_arch_sem_wait(&mbox->not_full, 0);
> ++    sys_arch_sem_wait(&mbox->mutex, 0);
> ++    mbox->wait_send--;
> ++  }
> ++
> ++  mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> ++
> ++  if (mbox->last == mbox->first) {
> ++    first = 1;
> ++  } else {
> ++    first = 0;
> ++  }
> ++
> ++  mbox->last++;
> ++
> ++  if (first) {
> ++    sys_sem_signal(&mbox->not_empty);
> ++  }
> ++
> ++  sys_sem_signal(&mbox->mutex);
> ++}
> ++
> ++u32_t
> ++sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
> ++{
> ++  struct sys_mbox *mbox;
> ++  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++  mbox = *mb;
> ++
> ++  sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++  if (mbox->first == mbox->last) {
> ++    sys_sem_signal(&mbox->mutex);
> ++    return SYS_MBOX_EMPTY;
> ++  }
> ++
> ++  if (msg != NULL) {
> ++    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void 
> *)mbox, *msg));
> ++    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> ++  }
> ++  else{
> ++    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void 
> *)mbox));
> ++  }
> ++
> ++  mbox->first++;
> ++
> ++  if (mbox->wait_send) {
> ++    sys_sem_signal(&mbox->not_full);
> ++  }
> ++
> ++  sys_sem_signal(&mbox->mutex);
> ++
> ++  return 0;
> ++}
> ++
> ++u32_t
> ++sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
> ++{
> ++  u32_t time_needed = 0;
> ++  struct sys_mbox *mbox;
> ++  LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++  mbox = *mb;
> ++
> ++  /* The mutex lock is quick so we don't bother with the timeout
> ++     stuff here. */
> ++  sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++  while (mbox->first == mbox->last) {
> ++    sys_sem_signal(&mbox->mutex);
> ++
> ++    /* We block while waiting for a mail to arrive in the mailbox. We
> ++       must be prepared to timeout. */
> ++    if (timeout != 0) {
> ++      time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
> ++
> ++      if (time_needed == SYS_ARCH_TIMEOUT) {
> ++        return SYS_ARCH_TIMEOUT;
> ++      }
> ++    } else {
> ++      sys_arch_sem_wait(&mbox->not_empty, 0);
> ++    }
> ++
> ++    sys_arch_sem_wait(&mbox->mutex, 0);
> ++  }
> ++
> ++  if (msg != NULL) {
> ++    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void 
> *)mbox, *msg));
> ++    *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> ++  }
> ++  else{
> ++    LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void 
> *)mbox));
> ++  }
> ++
> ++  mbox->first++;
> ++
> ++  if (mbox->wait_send) {
> ++    sys_sem_signal(&mbox->not_full);
> ++  }
> ++
> ++  sys_sem_signal(&mbox->mutex);
> ++
> ++  return time_needed;
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Semaphore */
> ++static struct sys_sem *
> ++sys_sem_new_internal(u8_t count)
> ++{
> ++  struct sys_sem *sem;
> ++
> ++  sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
> ++  if (sem != NULL) {
> ++    sem->c = count;
> ++    pthread_condattr_init(&(sem->condattr));
> ++#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && 
> __ANDROID_API__ < 21))
> ++    pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
> ++#endif
> ++    pthread_cond_init(&(sem->cond), &(sem->condattr));
> ++    pthread_mutex_init(&(sem->mutex), NULL);
> ++  }
> ++  return sem;
> ++}
> ++
> ++err_t
> ++sys_sem_new(struct sys_sem **sem, u8_t count)
> ++{
> ++  SYS_STATS_INC_USED(sem);
> ++  *sem = sys_sem_new_internal(count);
> ++  if (*sem == NULL) {
> ++    return ERR_MEM;
> ++  }
> ++  return ERR_OK;
> ++}
> ++
> ++/*
> ++ * Like cond_wait(), but it calls Hurd's non portable
> ++ * functions to receive cancellation requests
> ++ */
> ++static u32_t
> ++cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> ++{
> ++  struct timespec rtime1, rtime2, ts;
> ++  int ret;
> ++
> ++#ifdef __GNU__
> ++  #define pthread_cond_wait pthread_hurd_cond_wait_np
> ++  #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
> ++#endif
> ++
> ++  if (timeout == 0) {
> ++    ret = pthread_cond_wait(cond, mutex);
> ++    return ret;
> ++  }
> ++
> ++  /* Get a timestamp and add the timeout value. */
> ++  get_monotonic_time(&rtime1);
> ++#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && 
> __ANDROID_API__ < 21)
> ++  ts.tv_sec = timeout / 1000L;
> ++  ts.tv_nsec = (timeout % 1000L) * 1000000L;
> ++  ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> ++#else
> ++  ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> ++  ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> ++  if (ts.tv_nsec >= 1000000000L) {
> ++    ts.tv_sec++;
> ++    ts.tv_nsec -= 1000000000L;
> ++  }
> ++
> ++  ret = pthread_cond_timedwait(cond, mutex, &ts);
> ++#endif
> ++  if (ret == ETIMEDOUT) {
> ++    return SYS_ARCH_TIMEOUT;
> ++  } else if (ret == EINTR) {
> ++    return SYS_ARCH_INTR;
> ++  }
> ++
> ++  /* Calculate for how long we waited for the cond. */
> ++  get_monotonic_time(&rtime2);
> ++  ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> ++  ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> ++  if (ts.tv_nsec < 0) {
> ++    ts.tv_sec--;
> ++    ts.tv_nsec += 1000000000L;
> ++  }
> ++  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> ++}
> ++
> ++/*
> ++ * Like sys_arch_sem_wait(), but it handles thread cancellations.
> ++ */
> ++u32_t
> ++sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
> ++{
> ++  u32_t time_needed = 0;
> ++  struct sys_sem *sem;
> ++  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> ++  sem = *s;
> ++
> ++  pthread_mutex_lock(&(sem->mutex));
> ++  while (sem->c <= 0) {
> ++    if (timeout > 0) {
> ++      time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
> ++
> ++      if (time_needed == SYS_ARCH_TIMEOUT) {
> ++        pthread_mutex_unlock(&(sem->mutex));
> ++        return SYS_ARCH_TIMEOUT;
> ++      } else if(time_needed == SYS_ARCH_INTR) {
> ++        /* This means we were interrupted */
> ++        pthread_mutex_unlock(&(sem->mutex));
> ++        return SYS_ARCH_INTR;
> ++      }
> ++    } else {
> ++      if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
> ++        /* This means we were interrupted */
> ++        pthread_mutex_unlock(&(sem->mutex));
> ++        return SYS_ARCH_INTR;
> ++      }
> ++    }
> ++  }
> ++  sem->c--;
> ++  pthread_mutex_unlock(&(sem->mutex));
> ++  return (u32_t)time_needed;
> ++}
> ++
> ++void
> ++sys_sem_signal(struct sys_sem **s)
> ++{
> ++  struct sys_sem *sem;
> ++  LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> ++  sem = *s;
> ++
> ++  pthread_mutex_lock(&(sem->mutex));
> ++  sem->c++;
> ++
> ++  if (sem->c > 1) {
> ++    sem->c = 1;
> ++  }
> ++
> ++  pthread_cond_broadcast(&(sem->cond));
> ++  pthread_mutex_unlock(&(sem->mutex));
> ++}
> ++
> ++static void
> ++sys_sem_free_internal(struct sys_sem *sem)
> ++{
> ++  pthread_cond_destroy(&(sem->cond));
> ++  pthread_condattr_destroy(&(sem->condattr));
> ++  pthread_mutex_destroy(&(sem->mutex));
> ++  free(sem);
> ++}
> ++
> ++void
> ++sys_sem_free(struct sys_sem **sem)
> ++{
> ++  if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
> ++    SYS_STATS_DEC(sem.used);
> ++    sys_sem_free_internal(*sem);
> ++  }
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Mutex */
> ++/** Create a new mutex
> ++ * @param mutex pointer to the mutex to create
> ++ * @return a new mutex */
> ++err_t
> ++sys_mutex_new(struct sys_mutex **mutex)
> ++{
> ++  struct sys_mutex *mtx;
> ++
> ++  mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
> ++  if (mtx != NULL) {
> ++    pthread_mutex_init(&(mtx->mutex), NULL);
> ++    *mutex = mtx;
> ++    return ERR_OK;
> ++  }
> ++  else {
> ++    return ERR_MEM;
> ++  }
> ++}
> ++
> ++/** Lock a mutex
> ++ * @param mutex the mutex to lock */
> ++void
> ++sys_mutex_lock(struct sys_mutex **mutex)
> ++{
> ++  pthread_mutex_lock(&((*mutex)->mutex));
> ++}
> ++
> ++/** Unlock a mutex
> ++ * @param mutex the mutex to unlock */
> ++void
> ++sys_mutex_unlock(struct sys_mutex **mutex)
> ++{
> ++  pthread_mutex_unlock(&((*mutex)->mutex));
> ++}
> ++
> ++/** Delete a mutex
> ++ * @param mutex the mutex to delete */
> ++void
> ++sys_mutex_free(struct sys_mutex **mutex)
> ++{
> ++  pthread_mutex_destroy(&((*mutex)->mutex));
> ++  free(*mutex);
> ++}
> ++
> ++#endif /* !NO_SYS */
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Time */
> ++u32_t
> ++sys_now(void)
> ++{
> ++  struct timespec ts;
> ++
> ++  get_monotonic_time(&ts);
> ++  return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> ++}
> ++
> ++u32_t
> ++sys_jiffies(void)
> ++{
> ++  struct timespec ts;
> ++
> ++  get_monotonic_time(&ts);
> ++  return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Init */
> ++
> ++void
> ++sys_init(void)
> ++{
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Critical section */
> ++#if SYS_LIGHTWEIGHT_PROT
> ++/** sys_prot_t sys_arch_protect(void)
> ++
> ++This optional function does a "fast" critical region protection and returns
> ++the previous protection level. This function is only called during very 
> short
> ++critical regions. An embedded system which supports ISR-based drivers might
> ++want to implement this function by disabling interrupts. Task-based systems
> ++might want to implement this by using a mutex or disabling tasking. This
> ++function should support recursive calls from the same task or interrupt. In
> ++other words, sys_arch_protect() could be called while already protected. In
> ++that case the return value indicates that it is already protected.
> ++
> ++sys_arch_protect() is only required if your port is supporting an operating
> ++system.
> ++*/
> ++sys_prot_t
> ++sys_arch_protect(void)
> ++{
> ++    /* Note that for the UNIX port, we are using a lightweight mutex, and 
> our
> ++     * own counter (which is locked by the mutex). The return code is not 
> actually
> ++     * used. */
> ++    if (lwprot_thread != pthread_self())
> ++    {
> ++        /* We are locking the mutex where it has not been locked before *
> ++        * or is being locked by another thread */
> ++        pthread_mutex_lock(&lwprot_mutex);
> ++        lwprot_thread = pthread_self();
> ++        lwprot_count = 1;
> ++    }
> ++    else
> ++        /* It is already locked by THIS thread */
> ++        lwprot_count++;
> ++    return 0;
> ++}
> ++
> ++/** void sys_arch_unprotect(sys_prot_t pval)
> ++
> ++This optional function does a "fast" set of critical region protection to 
> the
> ++value specified by pval. See the documentation for sys_arch_protect() for
> ++more information. This function is only required if your port is supporting
> ++an operating system.
> ++*/
> ++void
> ++sys_arch_unprotect(sys_prot_t pval)
> ++{
> ++    LWIP_UNUSED_ARG(pval);
> ++    if (lwprot_thread == pthread_self())
> ++    {
> ++        if (--lwprot_count == 0)
> ++        {
> ++            lwprot_thread = (pthread_t) 0xDEAD;
> ++            pthread_mutex_unlock(&lwprot_mutex);
> ++        }
> ++    }
> ++}
> ++#endif /* SYS_LIGHTWEIGHT_PROT */
> diff --git a/debian/patches/posix b/debian/patches/posix
> index 1818c4d..e92f542 100644
> --- a/debian/patches/posix
> +++ b/debian/patches/posix
> @@ -18,117 +18,117 @@ Won't get to upstream
>  --- /dev/null
>  +++ b/port/include/posix/inet.h
>  @@ -0,0 +1,63 @@
> -+/*
> -+   Copyright (C) 2018 Free Software Foundation, Inc.
> -+   Written by Joan Lledó.
> -+
> -+   This file is part of the GNU Hurd.
> -+
> -+   The GNU Hurd is free software; you can redistribute it and/or
> -+   modify it under the terms of the GNU General Public License as
> -+   published by the Free Software Foundation; either version 2, or (at
> -+   your option) any later version.
> -+
> -+   The GNU Hurd is distributed in the hope that it will be useful, but
> -+   WITHOUT ANY WARRANTY; without even the implied warranty of
> -+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -+   General Public License for more details.
> -+
> -+   You should have received a copy of the GNU General Public License
> -+   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> -+
> -+#ifndef HURD_LWIP_POSIX_INET_H
> -+#define HURD_LWIP_POSIX_INET_H
> -+
> -+#include <arpa/inet.h>
> -+#include <netinet/in.h>
> -+#include <netinet/tcp.h>
> -+#include <netinet/udp.h>
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
> -+                           __SOCKADDR_COMMON_SIZE - \
> -+                           sizeof (in_port_t) - \
> -+                           sizeof (struct in_addr)
> -+
> -+#if LWIP_IPV4
> -+
> -+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) 
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> -+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> -+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t 
> are an u32_t effectively! */
> -+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)   
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> -+
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) 
> {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
> -+                                                                 
> (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
> -+                                                                 
> (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
> -+                                                                 
> (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
> -+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   
> {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
> -+                                                                 
> (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
> -+                                                                 
> (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
> -+                                                                 
> (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
> -+/* ATTENTION: the next define only works because both in6_addr and 
> ip6_addr_t are an u32_t[4] effectively! */
> -+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)   
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> -+#endif /* LWIP_IPV6 */
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* HURD_LWIP_POSIX_INET_H */
> ++/*
> ++   Copyright (C) 2018 Free Software Foundation, Inc.
> ++   Written by Joan Lledó.
> ++
> ++   This file is part of the GNU Hurd.
> ++
> ++   The GNU Hurd is free software; you can redistribute it and/or
> ++   modify it under the terms of the GNU General Public License as
> ++   published by the Free Software Foundation; either version 2, or (at
> ++   your option) any later version.
> ++
> ++   The GNU Hurd is distributed in the hope that it will be useful, but
> ++   WITHOUT ANY WARRANTY; without even the implied warranty of
> ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++   General Public License for more details.
> ++
> ++   You should have received a copy of the GNU General Public License
> ++   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> ++
> ++#ifndef HURD_LWIP_POSIX_INET_H
> ++#define HURD_LWIP_POSIX_INET_H
> ++
> ++#include <arpa/inet.h>
> ++#include <netinet/in.h>
> ++#include <netinet/tcp.h>
> ++#include <netinet/udp.h>
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
> ++                           __SOCKADDR_COMMON_SIZE - \
> ++                           sizeof (in_port_t) - \
> ++                           sizeof (struct in_addr)
> ++
> ++#if LWIP_IPV4
> ++
> ++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) 
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> ++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> ++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t 
> are an u32_t effectively! */
> ++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)   
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> ++
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) 
> {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
> ++                                                                 
> (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
> ++                                                                 
> (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
> ++                                                                 
> (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
> ++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   
> {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
> ++                                                                 
> (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
> ++                                                                 
> (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
> ++                                                                 
> (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
> ++/* ATTENTION: the next define only works because both in6_addr and 
> ip6_addr_t are an u32_t[4] effectively! */
> ++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)   
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> ++#endif /* LWIP_IPV6 */
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* HURD_LWIP_POSIX_INET_H */
>  --- /dev/null
>  +++ b/port/include/posix/socket.h
>  @@ -0,0 +1,45 @@
> -+/*
> -+   Copyright (C) 2018 Free Software Foundation, Inc.
> -+   Written by Joan Lledó.
> -+
> -+   This file is part of the GNU Hurd.
> -+
> -+   The GNU Hurd is free software; you can redistribute it and/or
> -+   modify it under the terms of the GNU General Public License as
> -+   published by the Free Software Foundation; either version 2, or (at
> -+   your option) any later version.
> -+
> -+   The GNU Hurd is distributed in the hope that it will be useful, but
> -+   WITHOUT ANY WARRANTY; without even the implied warranty of
> -+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> -+   General Public License for more details.
> -+
> -+   You should have received a copy of the GNU General Public License
> -+   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> -+
> -+#ifndef HURD_LWIP_POSIX_SOCKET_H
> -+#define HURD_LWIP_POSIX_SOCKET_H
> -+
> -+#include <sys/socket.h>
> -+#include <poll.h>
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+/* Unsuported indetifiers */
> -+#ifndef SO_NO_CHECK
> -+#define SO_NO_CHECK         0x0
> -+#endif
> -+#ifndef MSG_MORE
> -+#define MSG_MORE            0x0
> -+#endif
> -+#ifndef TCP_KEEPALIVE
> -+#define TCP_KEEPALIVE       0x0
> -+#endif
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* HURD_LWIP_POSIX_SOCKET_H */
> ++/*
> ++   Copyright (C) 2018 Free Software Foundation, Inc.
> ++   Written by Joan Lledó.
> ++
> ++   This file is part of the GNU Hurd.
> ++
> ++   The GNU Hurd is free software; you can redistribute it and/or
> ++   modify it under the terms of the GNU General Public License as
> ++   published by the Free Software Foundation; either version 2, or (at
> ++   your option) any later version.
> ++
> ++   The GNU Hurd is distributed in the hope that it will be useful, but
> ++   WITHOUT ANY WARRANTY; without even the implied warranty of
> ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> ++   General Public License for more details.
> ++
> ++   You should have received a copy of the GNU General Public License
> ++   along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.  */
> ++
> ++#ifndef HURD_LWIP_POSIX_SOCKET_H
> ++#define HURD_LWIP_POSIX_SOCKET_H
> ++
> ++#include <sys/socket.h>
> ++#include <poll.h>
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++/* Unsuported indetifiers */
> ++#ifndef SO_NO_CHECK
> ++#define SO_NO_CHECK         0x0
> ++#endif
> ++#ifndef MSG_MORE
> ++#define MSG_MORE            0x0
> ++#endif
> ++#ifndef TCP_KEEPALIVE
> ++#define TCP_KEEPALIVE       0x0
> ++#endif
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* HURD_LWIP_POSIX_SOCKET_H */
>  --- a/src/include/lwip/inet.h
>  +++ b/src/include/lwip/inet.h
>  @@ -41,132 +41,11 @@
> @@ -270,7 +270,7 @@ Won't get to upstream
>   #endif /* LWIP_HDR_INET_H */
>  --- a/src/include/lwip/ip.h
>  +++ b/src/include/lwip/ip.h
> -@@ -94,9 +94,16 @@ struct ip_pcb {
> +@@ -94,9 +94,16 @@
>   /*
>    * Option flags per-socket. These are the same like SO_XXX in sockets.h
>    */
> @@ -290,742 +290,742 @@ Won't get to upstream
>  --- /dev/null
>  +++ b/src/include/lwip/lwip_inet.h
>  @@ -0,0 +1,164 @@
> -+/*
> -+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without 
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ *    this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> -+ *    this list of conditions and the following disclaimer in the 
> documentation
> -+ *    and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ *    derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+#ifndef LWIP_HDR_PRIV_INET_H
> -+#define LWIP_HDR_PRIV_INET_H
> -+
> -+#include "lwip/opt.h"
> -+#include "lwip/def.h"
> -+#include "lwip/ip_addr.h"
> -+#include "lwip/ip6_addr.h"
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
> -+   to prevent this code from redefining it. */
> -+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
> -+typedef u32_t in_addr_t;
> -+#endif
> -+
> -+struct in_addr {
> -+  in_addr_t s_addr;
> -+};
> -+
> -+struct in6_addr {
> -+  union {
> -+    u32_t u32_addr[4];
> -+    u8_t  u8_addr[16];
> -+  } un;
> -+#define s6_addr  un.u8_addr
> -+};
> -+
> -+/** 255.255.255.255 */
> -+#define INADDR_NONE         IPADDR_NONE
> -+/** 127.0.0.1 */
> -+#define INADDR_LOOPBACK     IPADDR_LOOPBACK
> -+/** 0.0.0.0 */
> -+#define INADDR_ANY          IPADDR_ANY
> -+/** 255.255.255.255 */
> -+#define INADDR_BROADCAST    IPADDR_BROADCAST
> -+
> -+/** This macro can be used to initialize a variable of type struct in6_addr
> -+    to the IPv6 wildcard address. */
> -+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
> -+/** This macro can be used to initialize a variable of type struct in6_addr
> -+    to the IPv6 loopback address. */
> -+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
> -+/** This variable is initialized by the system to contain the wildcard IPv6 
> address. */
> -+extern const struct in6_addr in6addr_any;
> -+
> -+/* Definitions of the bits in an (IPv4) Internet address integer.
> -+
> -+   On subnets, host and network parts are found according to
> -+   the subnet mask, not these masks.  */
> -+#define IN_CLASSA(a)        IP_CLASSA(a)
> -+#define IN_CLASSA_NET       IP_CLASSA_NET
> -+#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
> -+#define IN_CLASSA_HOST      IP_CLASSA_HOST
> -+#define IN_CLASSA_MAX       IP_CLASSA_MAX
> -+
> -+#define IN_CLASSB(b)        IP_CLASSB(b)
> -+#define IN_CLASSB_NET       IP_CLASSB_NET
> -+#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
> -+#define IN_CLASSB_HOST      IP_CLASSB_HOST
> -+#define IN_CLASSB_MAX       IP_CLASSB_MAX
> -+
> -+#define IN_CLASSC(c)        IP_CLASSC(c)
> -+#define IN_CLASSC_NET       IP_CLASSC_NET
> -+#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
> -+#define IN_CLASSC_HOST      IP_CLASSC_HOST
> -+#define IN_CLASSC_MAX       IP_CLASSC_MAX
> -+
> -+#define IN_CLASSD(d)        IP_CLASSD(d)
> -+#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
> -+#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but 
> */
> -+#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
> -+#define IN_CLASSD_MAX       IP_CLASSD_MAX
> -+
> -+#define IN_MULTICAST(a)     IP_MULTICAST(a)
> -+
> -+#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
> -+#define IN_BADCLASS(a)      IP_BADCLASS(a)
> -+
> -+#define IN_LOOPBACKNET      IP_LOOPBACKNET
> -+
> -+
> -+#ifndef INET_ADDRSTRLEN
> -+#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
> -+#endif
> -+#if LWIP_IPV6
> -+#ifndef INET6_ADDRSTRLEN
> -+#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
> -+#endif
> -+#endif
> -+
> -+#if LWIP_IPV4
> -+
> -+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) 
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> -+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> -+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t 
> are an u32_t effectively! */
> -+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)   
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> -+
> -+/* directly map this to the lwip internal functions */
> -+#define inet_addr(cp)                   ipaddr_addr(cp)
> -+#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
> -+#define inet_ntoa(addr)                 ip4addr_ntoa((const 
> ip4_addr_t*)&(addr))
> -+#define inet_ntoa_r(addr, buf, buflen)  ip4addr_ntoa_r((const 
> ip4_addr_t*)&(addr), buf, buflen)
> -+
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) 
> {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
> -+                                                                 
> (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
> -+                                                                 
> (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
> -+                                                                 
> (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
> -+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   
> {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
> -+                                                                 
> (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
> -+                                                                 
> (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
> -+                                                                 
> (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
> -+/* ATTENTION: the next define only works because both in6_addr and 
> ip6_addr_t are an u32_t[4] effectively! */
> -+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)   
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> -+
> -+/* directly map this to the lwip internal functions */
> -+#define inet6_aton(cp, addr)            ip6addr_aton(cp, (ip6_addr_t*)addr)
> -+#define inet6_ntoa(addr)                ip6addr_ntoa((const 
> ip6_addr_t*)&(addr))
> -+#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const 
> ip6_addr_t*)&(addr), buf, buflen)
> -+
> -+#endif /* LWIP_IPV6 */
> -+
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* LWIP_HDR_PRIV_INET_H */
> ++/*
> ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without 
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ *    this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> ++ *    this list of conditions and the following disclaimer in the 
> documentation
> ++ *    and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ *    derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++#ifndef LWIP_HDR_PRIV_INET_H
> ++#define LWIP_HDR_PRIV_INET_H
> ++
> ++#include "lwip/opt.h"
> ++#include "lwip/def.h"
> ++#include "lwip/ip_addr.h"
> ++#include "lwip/ip6_addr.h"
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
> ++   to prevent this code from redefining it. */
> ++#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
> ++typedef u32_t in_addr_t;
> ++#endif
> ++
> ++struct in_addr {
> ++  in_addr_t s_addr;
> ++};
> ++
> ++struct in6_addr {
> ++  union {
> ++    u32_t u32_addr[4];
> ++    u8_t  u8_addr[16];
> ++  } un;
> ++#define s6_addr  un.u8_addr
> ++};
> ++
> ++/** 255.255.255.255 */
> ++#define INADDR_NONE         IPADDR_NONE
> ++/** 127.0.0.1 */
> ++#define INADDR_LOOPBACK     IPADDR_LOOPBACK
> ++/** 0.0.0.0 */
> ++#define INADDR_ANY          IPADDR_ANY
> ++/** 255.255.255.255 */
> ++#define INADDR_BROADCAST    IPADDR_BROADCAST
> ++
> ++/** This macro can be used to initialize a variable of type struct in6_addr
> ++    to the IPv6 wildcard address. */
> ++#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
> ++/** This macro can be used to initialize a variable of type struct in6_addr
> ++    to the IPv6 loopback address. */
> ++#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
> ++/** This variable is initialized by the system to contain the wildcard IPv6 
> address. */
> ++extern const struct in6_addr in6addr_any;
> ++
> ++/* Definitions of the bits in an (IPv4) Internet address integer.
> ++
> ++   On subnets, host and network parts are found according to
> ++   the subnet mask, not these masks.  */
> ++#define IN_CLASSA(a)        IP_CLASSA(a)
> ++#define IN_CLASSA_NET       IP_CLASSA_NET
> ++#define IN_CLASSA_NSHIFT    IP_CLASSA_NSHIFT
> ++#define IN_CLASSA_HOST      IP_CLASSA_HOST
> ++#define IN_CLASSA_MAX       IP_CLASSA_MAX
> ++
> ++#define IN_CLASSB(b)        IP_CLASSB(b)
> ++#define IN_CLASSB_NET       IP_CLASSB_NET
> ++#define IN_CLASSB_NSHIFT    IP_CLASSB_NSHIFT
> ++#define IN_CLASSB_HOST      IP_CLASSB_HOST
> ++#define IN_CLASSB_MAX       IP_CLASSB_MAX
> ++
> ++#define IN_CLASSC(c)        IP_CLASSC(c)
> ++#define IN_CLASSC_NET       IP_CLASSC_NET
> ++#define IN_CLASSC_NSHIFT    IP_CLASSC_NSHIFT
> ++#define IN_CLASSC_HOST      IP_CLASSC_HOST
> ++#define IN_CLASSC_MAX       IP_CLASSC_MAX
> ++
> ++#define IN_CLASSD(d)        IP_CLASSD(d)
> ++#define IN_CLASSD_NET       IP_CLASSD_NET     /* These ones aren't really */
> ++#define IN_CLASSD_NSHIFT    IP_CLASSD_NSHIFT  /*   net and host fields, but 
> */
> ++#define IN_CLASSD_HOST      IP_CLASSD_HOST    /*   routing needn't know. */
> ++#define IN_CLASSD_MAX       IP_CLASSD_MAX
> ++
> ++#define IN_MULTICAST(a)     IP_MULTICAST(a)
> ++
> ++#define IN_EXPERIMENTAL(a)  IP_EXPERIMENTAL(a)
> ++#define IN_BADCLASS(a)      IP_BADCLASS(a)
> ++
> ++#define IN_LOOPBACKNET      IP_LOOPBACKNET
> ++
> ++
> ++#ifndef INET_ADDRSTRLEN
> ++#define INET_ADDRSTRLEN     IP4ADDR_STRLEN_MAX
> ++#endif
> ++#if LWIP_IPV6
> ++#ifndef INET6_ADDRSTRLEN
> ++#define INET6_ADDRSTRLEN    IP6ADDR_STRLEN_MAX
> ++#endif
> ++#endif
> ++
> ++#if LWIP_IPV4
> ++
> ++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) 
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> ++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)   
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> ++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t 
> are an u32_t effectively! */
> ++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)   
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> ++
> ++/* directly map this to the lwip internal functions */
> ++#define inet_addr(cp)                   ipaddr_addr(cp)
> ++#define inet_aton(cp, addr)             ip4addr_aton(cp, (ip4_addr_t*)addr)
> ++#define inet_ntoa(addr)                 ip4addr_ntoa((const 
> ip4_addr_t*)&(addr))
> ++#define inet_ntoa_r(addr, buf, buflen)  ip4addr_ntoa_r((const 
> ip4_addr_t*)&(addr), buf, buflen)
> ++
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) 
> {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
> ++                                                                 
> (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
> ++                                                                 
> (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
> ++                                                                 
> (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
> ++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)   
> {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
> ++                                                                 
> (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
> ++                                                                 
> (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
> ++                                                                 
> (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
> ++/* ATTENTION: the next define only works because both in6_addr and 
> ip6_addr_t are an u32_t[4] effectively! */
> ++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)   
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> ++
> ++/* directly map this to the lwip internal functions */
> ++#define inet6_aton(cp, addr)            ip6addr_aton(cp, (ip6_addr_t*)addr)
> ++#define inet6_ntoa(addr)                ip6addr_ntoa((const 
> ip6_addr_t*)&(addr))
> ++#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const 
> ip6_addr_t*)&(addr), buf, buflen)
> ++
> ++#endif /* LWIP_IPV6 */
> ++
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* LWIP_HDR_PRIV_INET_H */
>  --- /dev/null
>  +++ b/src/include/lwip/lwip_sockets.h
>  @@ -0,0 +1,569 @@
> -+/**
> -+ * @file
> -+ * Socket API (to be used from non-TCPIP threads)
> -+ */
> -+
> -+/*
> -+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without 
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ *    this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> -+ *    this list of conditions and the following disclaimer in the 
> documentation
> -+ *    and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ *    derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+
> -+
> -+#ifndef LWIP_HDR_PRIV_SOCKETS_H
> -+#define LWIP_HDR_PRIV_SOCKETS_H
> -+
> -+#include "lwip/opt.h"
> -+
> -+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
> -+
> -+#include "lwip/ip_addr.h"
> -+#include "lwip/err.h"
> -+#include "lwip/inet.h"
> -+#include "lwip/errno.h"
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+#define _HAVE_SA_LEN 1
> -+
> -+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
> -+   to prevent this code from redefining it. */
> -+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
> -+typedef u8_t sa_family_t;
> -+#endif
> -+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
> -+   to prevent this code from redefining it. */
> -+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
> -+typedef u16_t in_port_t;
> -+#endif
> -+
> -+#if LWIP_IPV4
> -+/* members are in network byte order */
> -+struct sockaddr_in {
> -+  u8_t            sin_len;
> -+  sa_family_t     sin_family;
> -+  in_port_t       sin_port;
> -+  struct in_addr  sin_addr;
> -+#define SIN_ZERO_LEN 8
> -+  char            sin_zero[SIN_ZERO_LEN];
> -+};
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+struct sockaddr_in6 {
> -+  u8_t            sin6_len;      /* length of this structure    */
> -+  sa_family_t     sin6_family;   /* AF_INET6                    */
> -+  in_port_t       sin6_port;     /* Transport layer port #      */
> -+  u32_t           sin6_flowinfo; /* IPv6 flow information       */
> -+  struct in6_addr sin6_addr;     /* IPv6 address                */
> -+  u32_t           sin6_scope_id; /* Set of interfaces for scope */
> -+};
> -+#endif /* LWIP_IPV6 */
> -+
> -+struct sockaddr {
> -+  u8_t        sa_len;
> -+  sa_family_t sa_family;
> -+  char        sa_data[14];
> -+};
> -+
> -+struct sockaddr_storage {
> -+  u8_t        s2_len;
> -+  sa_family_t ss_family;
> -+  char        s2_data1[2];
> -+  u32_t       s2_data2[3];
> -+#if LWIP_IPV6
> -+  u32_t       s2_data3[3];
> -+#endif /* LWIP_IPV6 */
> -+};
> -+
> -+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
> -+   to prevent this code from redefining it. */
> -+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
> -+typedef u32_t socklen_t;
> -+#endif
> -+
> -+struct lwip_sock;
> -+
> -+#if !LWIP_TCPIP_CORE_LOCKING
> -+/** Maximum optlen used by setsockopt/getsockopt */
> -+#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
> -+
> -+/** This struct is used to pass data to the set/getsockopt_internal
> -+ * functions running in tcpip_thread context (only a void* is allowed) */
> -+struct lwip_setgetsockopt_data {
> -+  /** socket index for which to change options */
> -+  int s;
> -+  /** level of the option to process */
> -+  int level;
> -+  /** name of the option to process */
> -+  int optname;
> -+  /** set: value to set the option to
> -+    * get: value of the option is stored here */
> -+#if LWIP_MPU_COMPATIBLE
> -+  u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
> -+#else
> -+  union {
> -+     void *p;
> -+     const void *pc;
> -+  } optval;
> -+#endif
> -+  /** size of *optval */
> -+  socklen_t optlen;
> -+  /** if an error occurs, it is temporarily stored here */
> -+  err_t err;
> -+  /** semaphore to wake up the calling task */
> -+  void* completed_sem;
> -+};
> -+#endif /* !LWIP_TCPIP_CORE_LOCKING */
> -+
> -+#if !defined(iovec)
> -+struct iovec {
> -+  void  *iov_base;
> -+  size_t iov_len;
> -+};
> -+#endif
> -+
> -+struct msghdr {
> -+  void         *msg_name;
> -+  socklen_t     msg_namelen;
> -+  struct iovec *msg_iov;
> -+  int           msg_iovlen;
> -+  void         *msg_control;
> -+  socklen_t     msg_controllen;
> -+  int           msg_flags;
> -+};
> -+
> -+/* Socket protocol types (TCP/UDP/RAW) */
> -+#define SOCK_STREAM     1
> -+#define SOCK_DGRAM      2
> -+#define SOCK_RAW        3
> -+
> -+/*
> -+ * Option flags per-socket. These must match the SOF_ flags in ip.h 
> (checked in init.c)
> -+ */
> -+#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
> -+#define SO_KEEPALIVE   0x0008 /* keep connections alive */
> -+#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast 
> messages (see IP_SOF_BROADCAST option) */
> -+
> -+
> -+/*
> -+ * Additional options, not kept in so_options.
> -+ */
> -+#define SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info 
> recording */
> -+#define SO_ACCEPTCONN  0x0002 /* socket has had listen() */
> -+#define SO_DONTROUTE   0x0010 /* Unimplemented: just use interface 
> addresses */
> -+#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when 
> possible */
> -+#define SO_LINGER      0x0080 /* linger on close if data present */
> -+#define SO_DONTLINGER  ((int)(~SO_LINGER))
> -+#define SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in 
> line */
> -+#define SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port 
> reuse */
> -+#define SO_SNDBUF      0x1001 /* Unimplemented: send buffer size */
> -+#define SO_RCVBUF      0x1002 /* receive buffer size */
> -+#define SO_SNDLOWAT    0x1003 /* Unimplemented: send low-water mark */
> -+#define SO_RCVLOWAT    0x1004 /* Unimplemented: receive low-water mark */
> -+#define SO_SNDTIMEO    0x1005 /* send timeout */
> -+#define SO_RCVTIMEO    0x1006 /* receive timeout */
> -+#define SO_ERROR       0x1007 /* get error status and clear */
> -+#define SO_TYPE        0x1008 /* get socket type */
> -+#define SO_CONTIMEO    0x1009 /* Unimplemented: connect timeout */
> -+#define SO_NO_CHECK    0x100a /* don't create UDP checksum */
> -+
> -+
> -+/*
> -+ * Structure used for manipulating linger option.
> -+ */
> -+struct linger {
> -+       int l_onoff;                /* option on/off */
> -+       int l_linger;               /* linger time in seconds */
> -+};
> -+
> -+/*
> -+ * Level number for (get/set)sockopt() to apply to socket itself.
> -+ */
> -+#define  SOL_SOCKET  0xfff    /* options for socket level */
> -+
> -+
> -+#define AF_UNSPEC       0
> -+#define AF_INET         2
> -+#if LWIP_IPV6
> -+#define AF_INET6        10
> -+#else /* LWIP_IPV6 */
> -+#define AF_INET6        AF_UNSPEC
> -+#endif /* LWIP_IPV6 */
> -+#define PF_INET         AF_INET
> -+#define PF_INET6        AF_INET6
> -+#define PF_UNSPEC       AF_UNSPEC
> -+
> -+#define IPPROTO_IP      0
> -+#define IPPROTO_ICMP    1
> -+#define IPPROTO_TCP     6
> -+#define IPPROTO_UDP     17
> -+#if LWIP_IPV6
> -+#define IPPROTO_IPV6    41
> -+#define IPPROTO_ICMPV6  58
> -+#endif /* LWIP_IPV6 */
> -+#define IPPROTO_UDPLITE 136
> -+#define IPPROTO_RAW     255
> -+
> -+/* Flags we can use with send and recv. */
> -+#define MSG_PEEK       0x01    /* Peeks at an incoming message */
> -+#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function 
> block until the full amount of data requested can be returned */
> -+#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. 
> The significance and semantics of out-of-band data are protocol-specific */
> -+#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
> -+#define MSG_MORE       0x10    /* Sender will send more */
> -+
> -+
> -+/*
> -+ * Options for level IPPROTO_IP
> -+ */
> -+#define IP_TOS             1
> -+#define IP_TTL             2
> -+
> -+#if LWIP_TCP
> -+/*
> -+ * Options for level IPPROTO_TCP
> -+ */
> -+#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
> -+#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for 
> pcb->keep_idle milliseconds */
> -+#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as 
> TCP_KEEPALIVE, but use seconds for get/setsockopt */
> -+#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for 
> get/setsockopt */
> -+#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of 
> probes sent for get/setsockopt */
> -+#endif /* LWIP_TCP */
> -+
> -+#if LWIP_IPV6
> -+/*
> -+ * Options for level IPPROTO_IPV6
> -+ */
> -+#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 
> checksum for raw sockets. */
> -+#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict 
> AF_INET6 sockets to IPv6 communications only. */
> -+#endif /* LWIP_IPV6 */
> -+
> -+#if LWIP_UDP && LWIP_UDPLITE
> -+/*
> -+ * Options for level IPPROTO_UDPLITE
> -+ */
> -+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
> -+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
> -+#endif /* LWIP_UDP && LWIP_UDPLITE*/
> -+
> -+
> -+#if LWIP_MULTICAST_TX_OPTIONS
> -+/*
> -+ * Options and types for UDP multicast traffic handling
> -+ */
> -+#define IP_MULTICAST_TTL   5
> -+#define IP_MULTICAST_IF    6
> -+#define IP_MULTICAST_LOOP  7
> -+#endif /* LWIP_MULTICAST_TX_OPTIONS */
> -+
> -+#if LWIP_IGMP
> -+/*
> -+ * Options and types related to multicast membership
> -+ */
> -+#define IP_ADD_MEMBERSHIP  3
> -+#define IP_DROP_MEMBERSHIP 4
> -+
> -+typedef struct ip_mreq {
> -+    struct in_addr imr_multiaddr; /* IP multicast address of group */
> -+    struct in_addr imr_interface; /* local IP address of interface */
> -+} ip_mreq;
> -+#endif /* LWIP_IGMP */
> -+
> -+/*
> -+ * The Type of Service provides an indication of the abstract
> -+ * parameters of the quality of service desired.  These parameters are
> -+ * to be used to guide the selection of the actual service parameters
> -+ * when transmitting a datagram through a particular network.  Several
> -+ * networks offer service precedence, which somehow treats high
> -+ * precedence traffic as more important than other traffic (generally
> -+ * by accepting only traffic above a certain precedence at time of high
> -+ * load).  The major choice is a three way tradeoff between low-delay,
> -+ * high-reliability, and high-throughput.
> -+ * The use of the Delay, Throughput, and Reliability indications may
> -+ * increase the cost (in some sense) of the service.  In many networks
> -+ * better performance for one of these parameters is coupled with worse
> -+ * performance on another.  Except for very unusual cases at most two
> -+ * of these three indications should be set.
> -+ */
> -+#define IPTOS_TOS_MASK          0x1E
> -+#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
> -+#define IPTOS_LOWDELAY          0x10
> -+#define IPTOS_THROUGHPUT        0x08
> -+#define IPTOS_RELIABILITY       0x04
> -+#define IPTOS_LOWCOST           0x02
> -+#define IPTOS_MINCOST           IPTOS_LOWCOST
> -+
> -+/*
> -+ * The Network Control precedence designation is intended to be used
> -+ * within a network only.  The actual use and control of that
> -+ * designation is up to each network. The Internetwork Control
> -+ * designation is intended for use by gateway control originators only.
> -+ * If the actual use of these precedence designations is of concern to
> -+ * a particular network, it is the responsibility of that network to
> -+ * control the access to, and use of, those precedence designations.
> -+ */
> -+#define IPTOS_PREC_MASK                 0xe0
> -+#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
> -+#define IPTOS_PREC_NETCONTROL           0xe0
> -+#define IPTOS_PREC_INTERNETCONTROL      0xc0
> -+#define IPTOS_PREC_CRITIC_ECP           0xa0
> -+#define IPTOS_PREC_FLASHOVERRIDE        0x80
> -+#define IPTOS_PREC_FLASH                0x60
> -+#define IPTOS_PREC_IMMEDIATE            0x40
> -+#define IPTOS_PREC_PRIORITY             0x20
> -+#define IPTOS_PREC_ROUTINE              0x00
> -+
> -+
> -+/*
> -+ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
> -+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
> -+ *
> -+ * Ioctl's have the command encoded in the lower word,
> -+ * and the size of any in or out parameters in the upper
> -+ * word.  The high 2 bits of the upper word are used
> -+ * to encode the in/out status of the parameter; for now
> -+ * we restrict parameters to at most 128 bytes.
> -+ */
> -+#if !defined(FIONREAD) || !defined(FIONBIO)
> -+#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
> -+#define IOC_VOID        0x20000000UL    /* no parameters */
> -+#define IOC_OUT         0x40000000UL    /* copy out parameters */
> -+#define IOC_IN          0x80000000UL    /* copy in parameters */
> -+#define IOC_INOUT       (IOC_IN|IOC_OUT)
> -+                                        /* 0x20000000 distinguishes new &
> -+                                           old ioctl's */
> -+#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
> -+
> -+#define _IOR(x,y,t)     
> (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> -+
> -+#define _IOW(x,y,t)     
> (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> -+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
> -+
> -+#ifndef FIONREAD
> -+#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
> -+#endif
> -+#ifndef FIONBIO
> -+#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking 
> i/o */
> -+#endif
> -+
> -+/* Socket I/O Controls: unimplemented */
> -+#ifndef SIOCSHIWAT
> -+#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
> -+#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
> -+#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
> -+#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
> -+#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
> -+#endif
> -+
> -+/* commands for fnctl */
> -+#ifndef F_GETFL
> -+#define F_GETFL 3
> -+#endif
> -+#ifndef F_SETFL
> -+#define F_SETFL 4
> -+#endif
> -+
> -+/* File status flags and file access modes for fnctl,
> -+   these are bits in an int. */
> -+#ifndef O_NONBLOCK
> -+#define O_NONBLOCK  1 /* nonblocking I/O */
> -+#endif
> -+#ifndef O_NDELAY
> -+#define O_NDELAY    1 /* same as O_NONBLOCK, for compatibility */
> -+#endif
> -+
> -+#ifndef SHUT_RD
> -+  #define SHUT_RD   0
> -+  #define SHUT_WR   1
> -+  #define SHUT_RDWR 2
> -+#endif
> -+
> -+/* FD_SET used for lwip_select */
> -+#ifndef FD_SET
> -+#undef  FD_SETSIZE
> -+/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
> -+#define FD_SETSIZE    MEMP_NUM_NETCONN
> -+#define FDSETSAFESET(n, code) do { \
> -+  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - 
> LWIP_SOCKET_OFFSET) >= 0)) { \
> -+  code; }} while(0)
> -+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < 
> MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
> -+  (code) : 0)
> -+#define FD_SET(n, p)  FDSETSAFESET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |=  (1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> -+#define FD_CLR(n, p)  FDSETSAFESET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> -+#define FD_ISSET(n,p) FDSETSAFEGET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> -+#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
> -+
> -+typedef struct fd_set
> -+{
> -+  unsigned char fd_bits [(FD_SETSIZE+7)/8];
> -+} fd_set;
> -+
> -+#elif LWIP_SOCKET_OFFSET
> -+#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
> -+#elif FD_SETSIZE < MEMP_NUM_NETCONN
> -+#error "external FD_SETSIZE too small for number of sockets"
> -+#endif /* FD_SET */
> -+
> -+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> -+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
> -+#ifndef LWIP_TIMEVAL_PRIVATE
> -+#define LWIP_TIMEVAL_PRIVATE 1
> -+#endif
> -+
> -+#if LWIP_TIMEVAL_PRIVATE
> -+struct timeval {
> -+  long    tv_sec;         /* seconds */
> -+  long    tv_usec;        /* and microseconds */
> -+};
> -+#endif /* LWIP_TIMEVAL_PRIVATE */
> -+
> -+#define lwip_socket_init() /* Compatibility define, no init needed. */
> -+void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: 
> initialize thread-local semaphore */
> -+void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: 
> destroy thread-local semaphore */
> -+
> -+#if LWIP_COMPAT_SOCKETS == 2
> -+/* This helps code parsers/code completion by not having the COMPAT 
> functions as defines */
> -+#define lwip_accept       accept
> -+#define lwip_bind         bind
> -+#define lwip_shutdown     shutdown
> -+#define lwip_getpeername  getpeername
> -+#define lwip_getsockname  getsockname
> -+#define lwip_setsockopt   setsockopt
> -+#define lwip_getsockopt   getsockopt
> -+#define lwip_close        closesocket
> -+#define lwip_connect      connect
> -+#define lwip_listen       listen
> -+#define lwip_recv         recv
> -+#define lwip_recvfrom     recvfrom
> -+#define lwip_send         send
> -+#define lwip_sendmsg      sendmsg
> -+#define lwip_sendto       sendto
> -+#define lwip_socket       socket
> -+#define lwip_select       select
> -+#define lwip_ioctlsocket  ioctl
> -+
> -+#if LWIP_POSIX_SOCKETS_IO_NAMES
> -+#define lwip_read         read
> -+#define lwip_write        write
> -+#define lwip_writev       writev
> -+#undef lwip_close
> -+#define lwip_close        close
> -+#define closesocket(s)    close(s)
> -+#define lwip_fcntl        fcntl
> -+#define lwip_ioctl        ioctl
> -+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> -+#endif /* LWIP_COMPAT_SOCKETS == 2 */
> -+
> -+#if LWIP_COMPAT_SOCKETS
> -+#if LWIP_COMPAT_SOCKETS != 2
> -+/** @ingroup socket */
> -+#define accept(s,addr,addrlen)                    
> lwip_accept(s,addr,addrlen)
> -+/** @ingroup socket */
> -+#define bind(s,name,namelen)                      lwip_bind(s,name,namelen)
> -+/** @ingroup socket */
> -+#define shutdown(s,how)                           lwip_shutdown(s,how)
> -+/** @ingroup socket */
> -+#define getpeername(s,name,namelen)               
> lwip_getpeername(s,name,namelen)
> -+/** @ingroup socket */
> -+#define getsockname(s,name,namelen)               
> lwip_getsockname(s,name,namelen)
> -+/** @ingroup socket */
> -+#define setsockopt(s,level,optname,opval,optlen)  
> lwip_setsockopt(s,level,optname,opval,optlen)
> -+/** @ingroup socket */
> -+#define getsockopt(s,level,optname,opval,optlen)  
> lwip_getsockopt(s,level,optname,opval,optlen)
> -+/** @ingroup socket */
> -+#define closesocket(s)                            lwip_close(s)
> -+/** @ingroup socket */
> -+#define connect(s,name,namelen)                   
> lwip_connect(s,name,namelen)
> -+/** @ingroup socket */
> -+#define listen(s,backlog)                         lwip_listen(s,backlog)
> -+/** @ingroup socket */
> -+#define recv(s,mem,len,flags)                     lwip_recv(s,mem,len,flags)
> -+/** @ingroup socket */
> -+#define recvfrom(s,mem,len,flags,from,fromlen)    
> lwip_recvfrom(s,mem,len,flags,from,fromlen)
> -+/** @ingroup socket */
> -+#define send(s,dataptr,size,flags)                
> lwip_send(s,dataptr,size,flags)
> -+/** @ingroup socket */
> -+#define sendmsg(s,message,flags)                  
> lwip_sendmsg(s,message,flags)
> -+/** @ingroup socket */
> -+#define sendto(s,dataptr,size,flags,to,tolen)     
> lwip_sendto(s,dataptr,size,flags,to,tolen)
> -+/** @ingroup socket */
> -+#define socket(domain,type,protocol)              
> lwip_socket(domain,type,protocol)
> -+/** @ingroup socket */
> -+#define select(maxfdp1,readset,writeset,exceptset,timeout)     
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> -+/** @ingroup socket */
> -+#define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
> -+
> -+#if LWIP_POSIX_SOCKETS_IO_NAMES
> -+/** @ingroup socket */
> -+#define read(s,mem,len)                           lwip_read(s,mem,len)
> -+/** @ingroup socket */
> -+#define write(s,dataptr,len)                      lwip_write(s,dataptr,len)
> -+/** @ingroup socket */
> -+#define writev(s,iov,iovcnt)                      lwip_writev(s,iov,iovcnt)
> -+/** @ingroup socket */
> -+#define close(s)                                  lwip_close(s)
> -+/** @ingroup socket */
> -+#define fcntl(s,cmd,val)                          lwip_fcntl(s,cmd,val)
> -+/** @ingroup socket */
> -+#define ioctl(s,cmd,argp)                         lwip_ioctl(s,cmd,argp)
> -+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> -+#endif /* LWIP_COMPAT_SOCKETS != 2 */
> -+
> -+#if LWIP_IPV4 && LWIP_IPV6
> -+/** @ingroup socket */
> -+#define inet_ntop(af,src,dst,size) \
> -+    (((af) == AF_INET6) ? ip6addr_ntoa_r((const 
> ip6_addr_t*)(src),(dst),(size)) \
> -+     : (((af) == AF_INET) ? ip4addr_ntoa_r((const 
> ip4_addr_t*)(src),(dst),(size)) : NULL))
> -+/** @ingroup socket */
> -+#define inet_pton(af,src,dst) \
> -+    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
> -+     : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
> -+#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
> -+#define inet_ntop(af,src,dst,size) \
> -+    (((af) == AF_INET) ? ip4addr_ntoa_r((const 
> ip4_addr_t*)(src),(dst),(size)) : NULL)
> -+#define inet_pton(af,src,dst) \
> -+    (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
> -+#else /* LWIP_IPV4 && LWIP_IPV6 */
> -+#define inet_ntop(af,src,dst,size) \
> -+    (((af) == AF_INET6) ? ip6addr_ntoa_r((const 
> ip6_addr_t*)(src),(dst),(size)) : NULL)
> -+#define inet_pton(af,src,dst) \
> -+    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
> -+#endif /* LWIP_IPV4 && LWIP_IPV6 */
> -+
> -+#endif /* LWIP_COMPAT_SOCKETS */
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* LWIP_SOCKET */
> -+
> -+#endif /* LWIP_HDR_PRIV_SOCKETS_H */
> ++/**
> ++ * @file
> ++ * Socket API (to be used from non-TCPIP threads)
> ++ */
> ++
> ++/*
> ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without 
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ *    this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright 
> notice,
> ++ *    this list of conditions and the following disclaimer in the 
> documentation
> ++ *    and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ *    derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++
> ++
> ++#ifndef LWIP_HDR_PRIV_SOCKETS_H
> ++#define LWIP_HDR_PRIV_SOCKETS_H
> ++
> ++#include "lwip/opt.h"
> ++
> ++#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
> ++
> ++#include "lwip/ip_addr.h"
> ++#include "lwip/err.h"
> ++#include "lwip/inet.h"
> ++#include "lwip/errno.h"
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++#define _HAVE_SA_LEN 1
> ++
> ++/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
> ++   to prevent this code from redefining it. */
> ++#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
> ++typedef u8_t sa_family_t;
> ++#endif
> ++/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
> ++   to prevent this code from redefining it. */
> ++#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
> ++typedef u16_t in_port_t;
> ++#endif
> ++
> ++#if LWIP_IPV4
> ++/* members are in network byte order */
> ++struct sockaddr_in {
> ++  u8_t            sin_len;
> ++  sa_family_t     sin_family;
> ++  in_port_t       sin_port;
> ++  struct in_addr  sin_addr;
> ++#define SIN_ZERO_LEN 8
> ++  char            sin_zero[SIN_ZERO_LEN];
> ++};
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++struct sockaddr_in6 {
> ++  u8_t            sin6_len;      /* length of this structure    */
> ++  sa_family_t     sin6_family;   /* AF_INET6                    */
> ++  in_port_t       sin6_port;     /* Transport layer port #      */
> ++  u32_t           sin6_flowinfo; /* IPv6 flow information       */
> ++  struct in6_addr sin6_addr;     /* IPv6 address                */
> ++  u32_t           sin6_scope_id; /* Set of interfaces for scope */
> ++};
> ++#endif /* LWIP_IPV6 */
> ++
> ++struct sockaddr {
> ++  u8_t        sa_len;
> ++  sa_family_t sa_family;
> ++  char        sa_data[14];
> ++};
> ++
> ++struct sockaddr_storage {
> ++  u8_t        s2_len;
> ++  sa_family_t ss_family;
> ++  char        s2_data1[2];
> ++  u32_t       s2_data2[3];
> ++#if LWIP_IPV6
> ++  u32_t       s2_data3[3];
> ++#endif /* LWIP_IPV6 */
> ++};
> ++
> ++/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
> ++   to prevent this code from redefining it. */
> ++#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
> ++typedef u32_t socklen_t;
> ++#endif
> ++
> ++struct lwip_sock;
> ++
> ++#if !LWIP_TCPIP_CORE_LOCKING
> ++/** Maximum optlen used by setsockopt/getsockopt */
> ++#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
> ++
> ++/** This struct is used to pass data to the set/getsockopt_internal
> ++ * functions running in tcpip_thread context (only a void* is allowed) */
> ++struct lwip_setgetsockopt_data {
> ++  /** socket index for which to change options */
> ++  int s;
> ++  /** level of the option to process */
> ++  int level;
> ++  /** name of the option to process */
> ++  int optname;
> ++  /** set: value to set the option to
> ++    * get: value of the option is stored here */
> ++#if LWIP_MPU_COMPATIBLE
> ++  u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
> ++#else
> ++  union {
> ++     void *p;
> ++     const void *pc;
> ++  } optval;
> ++#endif
> ++  /** size of *optval */
> ++  socklen_t optlen;
> ++  /** if an error occurs, it is temporarily stored here */
> ++  err_t err;
> ++  /** semaphore to wake up the calling task */
> ++  void* completed_sem;
> ++};
> ++#endif /* !LWIP_TCPIP_CORE_LOCKING */
> ++
> ++#if !defined(iovec)
> ++struct iovec {
> ++  void  *iov_base;
> ++  size_t iov_len;
> ++};
> ++#endif
> ++
> ++struct msghdr {
> ++  void         *msg_name;
> ++  socklen_t     msg_namelen;
> ++  struct iovec *msg_iov;
> ++  int           msg_iovlen;
> ++  void         *msg_control;
> ++  socklen_t     msg_controllen;
> ++  int           msg_flags;
> ++};
> ++
> ++/* Socket protocol types (TCP/UDP/RAW) */
> ++#define SOCK_STREAM     1
> ++#define SOCK_DGRAM      2
> ++#define SOCK_RAW        3
> ++
> ++/*
> ++ * Option flags per-socket. These must match the SOF_ flags in ip.h 
> (checked in init.c)
> ++ */
> ++#define SO_REUSEADDR   0x0004 /* Allow local address reuse */
> ++#define SO_KEEPALIVE   0x0008 /* keep connections alive */
> ++#define SO_BROADCAST   0x0020 /* permit to send and to receive broadcast 
> messages (see IP_SOF_BROADCAST option) */
> ++
> ++
> ++/*
> ++ * Additional options, not kept in so_options.
> ++ */
> ++#define SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info 
> recording */
> ++#define SO_ACCEPTCONN  0x0002 /* socket has had listen() */
> ++#define SO_DONTROUTE   0x0010 /* Unimplemented: just use interface 
> addresses */
> ++#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when 
> possible */
> ++#define SO_LINGER      0x0080 /* linger on close if data present */
> ++#define SO_DONTLINGER  ((int)(~SO_LINGER))
> ++#define SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in 
> line */
> ++#define SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port 
> reuse */
> ++#define SO_SNDBUF      0x1001 /* Unimplemented: send buffer size */
> ++#define SO_RCVBUF      0x1002 /* receive buffer size */
> ++#define SO_SNDLOWAT    0x1003 /* Unimplemented: send low-water mark */
> ++#define SO_RCVLOWAT    0x1004 /* Unimplemented: receive low-water mark */
> ++#define SO_SNDTIMEO    0x1005 /* send timeout */
> ++#define SO_RCVTIMEO    0x1006 /* receive timeout */
> ++#define SO_ERROR       0x1007 /* get error status and clear */
> ++#define SO_TYPE        0x1008 /* get socket type */
> ++#define SO_CONTIMEO    0x1009 /* Unimplemented: connect timeout */
> ++#define SO_NO_CHECK    0x100a /* don't create UDP checksum */
> ++
> ++
> ++/*
> ++ * Structure used for manipulating linger option.
> ++ */
> ++struct linger {
> ++       int l_onoff;                /* option on/off */
> ++       int l_linger;               /* linger time in seconds */
> ++};
> ++
> ++/*
> ++ * Level number for (get/set)sockopt() to apply to socket itself.
> ++ */
> ++#define  SOL_SOCKET  0xfff    /* options for socket level */
> ++
> ++
> ++#define AF_UNSPEC       0
> ++#define AF_INET         2
> ++#if LWIP_IPV6
> ++#define AF_INET6        10
> ++#else /* LWIP_IPV6 */
> ++#define AF_INET6        AF_UNSPEC
> ++#endif /* LWIP_IPV6 */
> ++#define PF_INET         AF_INET
> ++#define PF_INET6        AF_INET6
> ++#define PF_UNSPEC       AF_UNSPEC
> ++
> ++#define IPPROTO_IP      0
> ++#define IPPROTO_ICMP    1
> ++#define IPPROTO_TCP     6
> ++#define IPPROTO_UDP     17
> ++#if LWIP_IPV6
> ++#define IPPROTO_IPV6    41
> ++#define IPPROTO_ICMPV6  58
> ++#endif /* LWIP_IPV6 */
> ++#define IPPROTO_UDPLITE 136
> ++#define IPPROTO_RAW     255
> ++
> ++/* Flags we can use with send and recv. */
> ++#define MSG_PEEK       0x01    /* Peeks at an incoming message */
> ++#define MSG_WAITALL    0x02    /* Unimplemented: Requests that the function 
> block until the full amount of data requested can be returned */
> ++#define MSG_OOB        0x04    /* Unimplemented: Requests out-of-band data. 
> The significance and semantics of out-of-band data are protocol-specific */
> ++#define MSG_DONTWAIT   0x08    /* Nonblocking i/o for this operation only */
> ++#define MSG_MORE       0x10    /* Sender will send more */
> ++
> ++
> ++/*
> ++ * Options for level IPPROTO_IP
> ++ */
> ++#define IP_TOS             1
> ++#define IP_TTL             2
> ++
> ++#if LWIP_TCP
> ++/*
> ++ * Options for level IPPROTO_TCP
> ++ */
> ++#define TCP_NODELAY    0x01    /* don't delay send to coalesce packets */
> ++#define TCP_KEEPALIVE  0x02    /* send KEEPALIVE probes when idle for 
> pcb->keep_idle milliseconds */
> ++#define TCP_KEEPIDLE   0x03    /* set pcb->keep_idle  - Same as 
> TCP_KEEPALIVE, but use seconds for get/setsockopt */
> ++#define TCP_KEEPINTVL  0x04    /* set pcb->keep_intvl - Use seconds for 
> get/setsockopt */
> ++#define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of 
> probes sent for get/setsockopt */
> ++#endif /* LWIP_TCP */
> ++
> ++#if LWIP_IPV6
> ++/*
> ++ * Options for level IPPROTO_IPV6
> ++ */
> ++#define IPV6_CHECKSUM       7  /* RFC3542: calculate and insert the ICMPv6 
> checksum for raw sockets. */
> ++#define IPV6_V6ONLY         27 /* RFC3493: boolean control to restrict 
> AF_INET6 sockets to IPv6 communications only. */
> ++#endif /* LWIP_IPV6 */
> ++
> ++#if LWIP_UDP && LWIP_UDPLITE
> ++/*
> ++ * Options for level IPPROTO_UDPLITE
> ++ */
> ++#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
> ++#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
> ++#endif /* LWIP_UDP && LWIP_UDPLITE*/
> ++
> ++
> ++#if LWIP_MULTICAST_TX_OPTIONS
> ++/*
> ++ * Options and types for UDP multicast traffic handling
> ++ */
> ++#define IP_MULTICAST_TTL   5
> ++#define IP_MULTICAST_IF    6
> ++#define IP_MULTICAST_LOOP  7
> ++#endif /* LWIP_MULTICAST_TX_OPTIONS */
> ++
> ++#if LWIP_IGMP
> ++/*
> ++ * Options and types related to multicast membership
> ++ */
> ++#define IP_ADD_MEMBERSHIP  3
> ++#define IP_DROP_MEMBERSHIP 4
> ++
> ++typedef struct ip_mreq {
> ++    struct in_addr imr_multiaddr; /* IP multicast address of group */
> ++    struct in_addr imr_interface; /* local IP address of interface */
> ++} ip_mreq;
> ++#endif /* LWIP_IGMP */
> ++
> ++/*
> ++ * The Type of Service provides an indication of the abstract
> ++ * parameters of the quality of service desired.  These parameters are
> ++ * to be used to guide the selection of the actual service parameters
> ++ * when transmitting a datagram through a particular network.  Several
> ++ * networks offer service precedence, which somehow treats high
> ++ * precedence traffic as more important than other traffic (generally
> ++ * by accepting only traffic above a certain precedence at time of high
> ++ * load).  The major choice is a three way tradeoff between low-delay,
> ++ * high-reliability, and high-throughput.
> ++ * The use of the Delay, Throughput, and Reliability indications may
> ++ * increase the cost (in some sense) of the service.  In many networks
> ++ * better performance for one of these parameters is coupled with worse
> ++ * performance on another.  Except for very unusual cases at most two
> ++ * of these three indications should be set.
> ++ */
> ++#define IPTOS_TOS_MASK          0x1E
> ++#define IPTOS_TOS(tos)          ((tos) & IPTOS_TOS_MASK)
> ++#define IPTOS_LOWDELAY          0x10
> ++#define IPTOS_THROUGHPUT        0x08
> ++#define IPTOS_RELIABILITY       0x04
> ++#define IPTOS_LOWCOST           0x02
> ++#define IPTOS_MINCOST           IPTOS_LOWCOST
> ++
> ++/*
> ++ * The Network Control precedence designation is intended to be used
> ++ * within a network only.  The actual use and control of that
> ++ * designation is up to each network. The Internetwork Control
> ++ * designation is intended for use by gateway control originators only.
> ++ * If the actual use of these precedence designations is of concern to
> ++ * a particular network, it is the responsibility of that network to
> ++ * control the access to, and use of, those precedence designations.
> ++ */
> ++#define IPTOS_PREC_MASK                 0xe0
> ++#define IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
> ++#define IPTOS_PREC_NETCONTROL           0xe0
> ++#define IPTOS_PREC_INTERNETCONTROL      0xc0
> ++#define IPTOS_PREC_CRITIC_ECP           0xa0
> ++#define IPTOS_PREC_FLASHOVERRIDE        0x80
> ++#define IPTOS_PREC_FLASH                0x60
> ++#define IPTOS_PREC_IMMEDIATE            0x40
> ++#define IPTOS_PREC_PRIORITY             0x20
> ++#define IPTOS_PREC_ROUTINE              0x00
> ++
> ++
> ++/*
> ++ * Commands for ioctlsocket(),  taken from the BSD file fcntl.h.
> ++ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
> ++ *
> ++ * Ioctl's have the command encoded in the lower word,
> ++ * and the size of any in or out parameters in the upper
> ++ * word.  The high 2 bits of the upper word are used
> ++ * to encode the in/out status of the parameter; for now
> ++ * we restrict parameters to at most 128 bytes.
> ++ */
> ++#if !defined(FIONREAD) || !defined(FIONBIO)
> ++#define IOCPARM_MASK    0x7fU           /* parameters must be < 128 bytes */
> ++#define IOC_VOID        0x20000000UL    /* no parameters */
> ++#define IOC_OUT         0x40000000UL    /* copy out parameters */
> ++#define IOC_IN          0x80000000UL    /* copy in parameters */
> ++#define IOC_INOUT       (IOC_IN|IOC_OUT)
> ++                                        /* 0x20000000 distinguishes new &
> ++                                           old ioctl's */
> ++#define _IO(x,y)        (IOC_VOID|((x)<<8)|(y))
> ++
> ++#define _IOR(x,y,t)     
> (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> ++
> ++#define _IOW(x,y,t)     
> (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> ++#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
> ++
> ++#ifndef FIONREAD
> ++#define FIONREAD    _IOR('f', 127, unsigned long) /* get # bytes to read */
> ++#endif
> ++#ifndef FIONBIO
> ++#define FIONBIO     _IOW('f', 126, unsigned long) /* set/clear non-blocking 
> i/o */
> ++#endif
> ++
> ++/* Socket I/O Controls: unimplemented */
> ++#ifndef SIOCSHIWAT
> ++#define SIOCSHIWAT  _IOW('s',  0, unsigned long)  /* set high watermark */
> ++#define SIOCGHIWAT  _IOR('s',  1, unsigned long)  /* get high watermark */
> ++#define SIOCSLOWAT  _IOW('s',  2, unsigned long)  /* set low watermark */
> ++#define SIOCGLOWAT  _IOR('s',  3, unsigned long)  /* get low watermark */
> ++#define SIOCATMARK  _IOR('s',  7, unsigned long)  /* at oob mark? */
> ++#endif
> ++
> ++/* commands for fnctl */
> ++#ifndef F_GETFL
> ++#define F_GETFL 3
> ++#endif
> ++#ifndef F_SETFL
> ++#define F_SETFL 4
> ++#endif
> ++
> ++/* File status flags and file access modes for fnctl,
> ++   these are bits in an int. */
> ++#ifndef O_NONBLOCK
> ++#define O_NONBLOCK  1 /* nonblocking I/O */
> ++#endif
> ++#ifndef O_NDELAY
> ++#define O_NDELAY    1 /* same as O_NONBLOCK, for compatibility */
> ++#endif
> ++
> ++#ifndef SHUT_RD
> ++  #define SHUT_RD   0
> ++  #define SHUT_WR   1
> ++  #define SHUT_RDWR 2
> ++#endif
> ++
> ++/* FD_SET used for lwip_select */
> ++#ifndef FD_SET
> ++#undef  FD_SETSIZE
> ++/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
> ++#define FD_SETSIZE    MEMP_NUM_NETCONN
> ++#define FDSETSAFESET(n, code) do { \
> ++  if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - 
> LWIP_SOCKET_OFFSET) >= 0)) { \
> ++  code; }} while(0)
> ++#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < 
> MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
> ++  (code) : 0)
> ++#define FD_SET(n, p)  FDSETSAFESET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |=  (1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> ++#define FD_CLR(n, p)  FDSETSAFESET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> ++#define FD_ISSET(n,p) FDSETSAFEGET(n, 
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &   (1 << (((n)-LWIP_SOCKET_OFFSET) 
> & 7)))
> ++#define FD_ZERO(p)    memset((void*)(p), 0, sizeof(*(p)))
> ++
> ++typedef struct fd_set
> ++{
> ++  unsigned char fd_bits [(FD_SETSIZE+7)/8];
> ++} fd_set;
> ++
> ++#elif LWIP_SOCKET_OFFSET
> ++#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
> ++#elif FD_SETSIZE < MEMP_NUM_NETCONN
> ++#error "external FD_SETSIZE too small for number of sockets"
> ++#endif /* FD_SET */
> ++
> ++/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> ++ * by your system, set this to 0 and include <sys/time.h> in cc.h */
> ++#ifndef LWIP_TIMEVAL_PRIVATE
> ++#define LWIP_TIMEVAL_PRIVATE 1
> ++#endif
> ++
> ++#if LWIP_TIMEVAL_PRIVATE
> ++struct timeval {
> ++  long    tv_sec;         /* seconds */
> ++  long    tv_usec;        /* and microseconds */
> ++};
> ++#endif /* LWIP_TIMEVAL_PRIVATE */
> ++
> ++#define lwip_socket_init() /* Compatibility define, no init needed. */
> ++void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: 
> initialize thread-local semaphore */
> ++void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: 
> destroy thread-local semaphore */
> ++
> ++#if LWIP_COMPAT_SOCKETS == 2
> ++/* This helps code parsers/code completion by not having the COMPAT 
> functions as defines */
> ++#define lwip_accept       accept
> ++#define lwip_bind         bind
> ++#define lwip_shutdown     shutdown
> ++#define lwip_getpeername  getpeername
> ++#define lwip_getsockname  getsockname
> ++#define lwip_setsockopt   setsockopt
> ++#define lwip_getsockopt   getsockopt
> ++#define lwip_close        closesocket
> ++#define lwip_connect      connect
> ++#define lwip_listen       listen
> ++#define lwip_recv         recv
> ++#define lwip_recvfrom     recvfrom
> ++#define lwip_send         send
> ++#define lwip_sendmsg      sendmsg
> ++#define lwip_sendto       sendto
> ++#define lwip_socket       socket
> ++#define lwip_select       select
> ++#define lwip_ioctlsocket  ioctl
> ++
> ++#if LWIP_POSIX_SOCKETS_IO_NAMES
> ++#define lwip_read         read
> ++#define lwip_write        write
> ++#define lwip_writev       writev
> ++#undef lwip_close
> ++#define lwip_close        close
> ++#define closesocket(s)    close(s)
> ++#define lwip_fcntl        fcntl
> ++#define lwip_ioctl        ioctl
> ++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> ++#endif /* LWIP_COMPAT_SOCKETS == 2 */
> ++
> ++#if LWIP_COMPAT_SOCKETS
> ++#if LWIP_COMPAT_SOCKETS != 2
> ++/** @ingroup socket */
> ++#define accept(s,addr,addrlen)                    
> lwip_accept(s,addr,addrlen)
> ++/** @ingroup socket */
> ++#define bind(s,name,namelen)                      lwip_bind(s,name,namelen)
> ++/** @ingroup socket */
> ++#define shutdown(s,how)                           lwip_shutdown(s,how)
> ++/** @ingroup socket */
> ++#define getpeername(s,name,namelen)               
> lwip_getpeername(s,name,namelen)
> ++/** @ingroup socket */
> ++#define getsockname(s,name,namelen)               
> lwip_getsockname(s,name,namelen)
> ++/** @ingroup socket */
> ++#define setsockopt(s,level,optname,opval,optlen)  
> lwip_setsockopt(s,level,optname,opval,optlen)
> ++/** @ingroup socket */
> ++#define getsockopt(s,level,optname,opval,optlen)  
> lwip_getsockopt(s,level,optname,opval,optlen)
> ++/** @ingroup socket */
> ++#define closesocket(s)                            lwip_close(s)
> ++/** @ingroup socket */
> ++#define connect(s,name,namelen)                   
> lwip_connect(s,name,namelen)
> ++/** @ingroup socket */
> ++#define listen(s,backlog)                         lwip_listen(s,backlog)
> ++/** @ingroup socket */
> ++#define recv(s,mem,len,flags)                     lwip_recv(s,mem,len,flags)
> ++/** @ingroup socket */
> ++#define recvfrom(s,mem,len,flags,from,fromlen)    
> lwip_recvfrom(s,mem,len,flags,from,fromlen)
> ++/** @ingroup socket */
> ++#define send(s,dataptr,size,flags)                
> lwip_send(s,dataptr,size,flags)
> ++/** @ingroup socket */
> ++#define sendmsg(s,message,flags)                  
> lwip_sendmsg(s,message,flags)
> ++/** @ingroup socket */
> ++#define sendto(s,dataptr,size,flags,to,tolen)     
> lwip_sendto(s,dataptr,size,flags,to,tolen)
> ++/** @ingroup socket */
> ++#define socket(domain,type,protocol)              
> lwip_socket(domain,type,protocol)
> ++/** @ingroup socket */
> ++#define select(maxfdp1,readset,writeset,exceptset,timeout)     
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> ++/** @ingroup socket */
> ++#define ioctlsocket(s,cmd,argp)                   lwip_ioctl(s,cmd,argp)
> ++
> ++#if LWIP_POSIX_SOCKETS_IO_NAMES
> ++/** @ingroup socket */
> ++#define read(s,mem,len)                           lwip_read(s,mem,len)
> ++/** @ingroup socket */
> ++#define write(s,dataptr,len)                      lwip_write(s,dataptr,len)
> ++/** @ingroup socket */
> ++#define writev(s,iov,iovcnt)                      lwip_writev(s,iov,iovcnt)
> ++/** @ingroup socket */
> ++#define close(s)                                  lwip_close(s)
> ++/** @ingroup socket */
> ++#define fcntl(s,cmd,val)                          lwip_fcntl(s,cmd,val)
> ++/** @ingroup socket */
> ++#define ioctl(s,cmd,argp)                         lwip_ioctl(s,cmd,argp)
> ++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> ++#endif /* LWIP_COMPAT_SOCKETS != 2 */
> ++
> ++#if LWIP_IPV4 && LWIP_IPV6
> ++/** @ingroup socket */
> ++#define inet_ntop(af,src,dst,size) \
> ++    (((af) == AF_INET6) ? ip6addr_ntoa_r((const 
> ip6_addr_t*)(src),(dst),(size)) \
> ++     : (((af) == AF_INET) ? ip4addr_ntoa_r((const 
> ip4_addr_t*)(src),(dst),(size)) : NULL))
> ++/** @ingroup socket */
> ++#define inet_pton(af,src,dst) \
> ++    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
> ++     : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
> ++#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
> ++#define inet_ntop(af,src,dst,size) \
> ++    (((af) == AF_INET) ? ip4addr_ntoa_r((const 
> ip4_addr_t*)(src),(dst),(size)) : NULL)
> ++#define inet_pton(af,src,dst) \
> ++    (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
> ++#else /* LWIP_IPV4 && LWIP_IPV6 */
> ++#define inet_ntop(af,src,dst,size) \
> ++    (((af) == AF_INET6) ? ip6addr_ntoa_r((const 
> ip6_addr_t*)(src),(dst),(size)) : NULL)
> ++#define inet_pton(af,src,dst) \
> ++    (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
> ++#endif /* LWIP_IPV4 && LWIP_IPV6 */
> ++
> ++#endif /* LWIP_COMPAT_SOCKETS */
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* LWIP_SOCKET */
> ++
> ++#endif /* LWIP_HDR_PRIV_SOCKETS_H */
>  --- a/src/include/lwip/opt.h
>  +++ b/src/include/lwip/opt.h
>  @@ -1760,6 +1760,15 @@
> @@ -1497,7 +1497,7 @@ Won't get to upstream
>   int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
>   int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
>   int lwip_shutdown(int s, int how);
> -@@ -506,88 +78,16 @@ int lwip_select(int maxfdp1, fd_set *rea
> +@@ -506,88 +78,16 @@
>   int lwip_ioctl(int s, long cmd, void *argp);
>   int lwip_fcntl(int s, int cmd, int val);
>   
> @@ -1596,35 +1596,20 @@ Won't get to upstream
>  --- a/port/include/lwipopts.h
>  +++ b/port/include/lwipopts.h
>  @@ -26,6 +26,11 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS   0
> - 
> -+/* Use Glibc's sockets headers */
> -+#define LWIP_STD_SOCKETS  1
> -+#define LWIP_INCLUDE_STD_SOCKETS  "posix/socket.h"
> -+#define LWIP_INCLUDE_STD_INET     "posix/inet.h"
> -+
> - /* Use Glibc malloc()/free() */
> - #define MEM_LIBC_MALLOC   1
> - #define MEMP_MEM_MALLOC   1
> ---- a/port/include/arch/cc.h
> -+++ b/port/include/arch/cc.h
> -@@ -40,6 +40,12 @@
> - /* Use our own ioctls */
> - #include <sys/ioctl.h>
> - 
> -+/* Use our own <sys/socket.h> */
> -+#include <sys/socket.h>
> -+#include <netinet/in.h>
> -+#include <netinet/tcp.h>
> -+#include <netinet/udp.h>
> -+
> - /* Use our own htons() and pals */
> - #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> - 
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS   0
> + 
> ++/* Use Glibc's sockets headers */
> ++#define LWIP_STD_SOCKETS  1
> ++#define LWIP_INCLUDE_STD_SOCKETS  "posix/socket.h"
> ++#define LWIP_INCLUDE_STD_INET     "posix/inet.h"
> ++
> + /* Use Glibc malloc()/free() */
> + #define MEM_LIBC_MALLOC   1
> + #define MEMP_MEM_MALLOC   1
>  --- a/src/api/netdb.c
>  +++ b/src/api/netdb.c
> -@@ -374,7 +374,9 @@ lwip_getaddrinfo(const char *nodename, c
> +@@ -374,7 +374,9 @@
>       /* set up sockaddr */
>       inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
>       sa6->sin6_family = AF_INET6;
> @@ -1634,7 +1619,7 @@ Won't get to upstream
>       sa6->sin6_port = lwip_htons((u16_t)port_nr);
>       ai->ai_family = AF_INET6;
>   #endif /* LWIP_IPV6 */
> -@@ -384,7 +386,9 @@ lwip_getaddrinfo(const char *nodename, c
> +@@ -384,7 +386,9 @@
>       /* set up sockaddr */
>       inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
>       sa4->sin_family = AF_INET;
> @@ -1676,7 +1661,7 @@ Won't get to upstream
>         (sin6)->sin6_family = AF_INET6; \
>         (sin6)->sin6_port = lwip_htons((port)); \
>         (sin6)->sin6_flowinfo = 0; \
> -@@ -537,9 +547,11 @@ lwip_accept(int s, struct sockaddr *addr
> +@@ -537,9 +547,11 @@
>       LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
>   
>       IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
> @@ -1688,7 +1673,7 @@ Won't get to upstream
>       MEMCPY(addr, &tempaddr, *addrlen);
>   
>       LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d 
> addr=", s, newsock));
> -@@ -878,9 +890,11 @@ lwip_recvfrom(int s, void *mem, size_t l
> +@@ -878,9 +890,11 @@
>           if (from && fromlen)
>   #endif /* SOCKETS_DEBUG */
>           {
> @@ -1700,7 +1685,7 @@ Won't get to upstream
>             MEMCPY(from, &saddr, *fromlen);
>           }
>         }
> -@@ -1764,9 +1778,11 @@ lwip_getaddrname(int s, struct sockaddr
> +@@ -1764,9 +1778,11 @@
>     ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
>     LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
>   
> -- 
> 2.11.0
> 
> 
> 
> 

-- 
Samuel
       void *memmem (const void *meule_de_foin, size_t lg_meule,
              const void *aiguille, size_t lg_aiguille);
(extrait de la page de man de memmem -- Manuel du programmeur Linux)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]