Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Add lwip files, for test, not compilable version
Lei Xia [Thu, 25 Sep 2008 17:56:18 +0000 (12:56 -0500)]
39 files changed:
palacios/src/lwip/api/sockets.c
palacios/src/lwip/api/sockets.c~ [new file with mode: 0644]
palacios/src/lwip/arch/sys_arch.c [new file with mode: 0644]
palacios/src/lwip/build/.depend [new file with mode: 0644]
palacios/src/lwip/build/Makefile
palacios/src/lwip/build/api_lib.o [new file with mode: 0644]
palacios/src/lwip/build/api_msg.o [new file with mode: 0644]
palacios/src/lwip/build/err.o [new file with mode: 0644]
palacios/src/lwip/build/errno.h [new file with mode: 0644]
palacios/src/lwip/build/etharp.o [new file with mode: 0644]
palacios/src/lwip/build/icmp.o [new file with mode: 0644]
palacios/src/lwip/build/inet.o [new file with mode: 0644]
palacios/src/lwip/build/inet_chksum.o [new file with mode: 0644]
palacios/src/lwip/build/init.o [new file with mode: 0644]
palacios/src/lwip/build/ip.o [new file with mode: 0644]
palacios/src/lwip/build/ip_addr.o [new file with mode: 0644]
palacios/src/lwip/build/loopif.o [new file with mode: 0644]
palacios/src/lwip/build/mem.o [new file with mode: 0644]
palacios/src/lwip/build/memp.o [new file with mode: 0644]
palacios/src/lwip/build/netbuf.o [new file with mode: 0644]
palacios/src/lwip/build/netdb.o [new file with mode: 0644]
palacios/src/lwip/build/netif.o [new file with mode: 0644]
palacios/src/lwip/build/pbuf.o [new file with mode: 0644]
palacios/src/lwip/build/sockets.o [new file with mode: 0644]
palacios/src/lwip/build/stats.o [new file with mode: 0644]
palacios/src/lwip/build/sys.o [new file with mode: 0644]
palacios/src/lwip/build/tcp.o [new file with mode: 0644]
palacios/src/lwip/build/tcp_in.o [new file with mode: 0644]
palacios/src/lwip/build/tcp_out.o [new file with mode: 0644]
palacios/src/lwip/build/tcpip.o [new file with mode: 0644]
palacios/src/lwip/build/udp.o [new file with mode: 0644]
palacios/src/lwip/include/arch/cc.h
palacios/src/lwip/include/arch/cc.h~
palacios/src/lwip/include/lwip/arch.h
palacios/src/lwip/include/lwip/arch.h~ [new file with mode: 0644]
palacios/src/lwip/include/lwip/sockets.h
palacios/src/lwip/include/lwip/sockets.h~ [new file with mode: 0644]
palacios/src/lwip/include/lwipopts.h
palacios/src/lwip/include/lwipopts.h~ [new file with mode: 0644]

index 88fec43..0853b0e 100644 (file)
@@ -52,6 +52,8 @@
 #include "lwip/udp.h"
 #include "lwip/tcpip.h"
 
+#include "lwip/arch.h"
+
 #include <string.h>
 
 #define NUM_SOCKETS MEMP_NUM_NETCONN
@@ -853,9 +855,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
   struct lwip_select_cb select_cb;
   struct lwip_select_cb *p_selcb;
 
-  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n",
-                  maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
-                  timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, timeout?timeout->tv_sec:-1L, timeout?timeout->tv_usec:-1L));
 
   select_cb.next = 0;
   select_cb.readset = readset;
diff --git a/palacios/src/lwip/api/sockets.c~ b/palacios/src/lwip/api/sockets.c~
new file mode 100644 (file)
index 0000000..c999744
--- /dev/null
@@ -0,0 +1,1926 @@
+/**
+ * @file
+ * Sockets BSD-Like API module
+ *
+ */
+
+/*
+ * 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>
+ *
+ * Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/sockets.h"
+#include "lwip/api.h"
+#include "lwip/sys.h"
+#include "lwip/igmp.h"
+#include "lwip/inet.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+#include "lwip/udp.h"
+#include "lwip/tcpip.h"
+
+#include "lwip/arch.h"
+
+#include <string.h>
+
+#define NUM_SOCKETS MEMP_NUM_NETCONN
+
+/** Contains all internal pointers and states used for a socket */
+struct lwip_socket {
+  /** sockets currently are built on netconns, each socket has one netconn */
+  struct netconn *conn;
+  /** data that was left from the previous read */
+  struct netbuf *lastdata;
+  /** offset in the data that was left from the previous read */
+  u16_t lastoffset;
+  /** number of times data was received, set by event_callback(),
+      tested by the receive and select functions */
+  u16_t rcvevent;
+  /** number of times data was received, set by event_callback(),
+      tested by select */
+  u16_t sendevent;
+  /** socket flags (currently, only used for O_NONBLOCK) */
+  u16_t flags;
+  /** last error that occurred on this socket */
+  int err;
+};
+
+/** Description for a task waiting in select */
+struct lwip_select_cb {
+  /** Pointer to the next waiting task */
+  struct lwip_select_cb *next;
+  /** readset passed to select */
+  fd_set *readset;
+  /** writeset passed to select */
+  fd_set *writeset;
+  /** unimplemented: exceptset passed to select */
+  fd_set *exceptset;
+  /** don't signal the same semaphore twice: set to 1 when signalled */
+  int sem_signalled;
+  /** semaphore to wake up a task waiting for select */
+  sys_sem_t sem;
+};
+
+/** 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 struct for which to change options */
+  struct lwip_socket *sock;
+  /** 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 */
+  void *optval;
+  /** size of *optval */
+  socklen_t *optlen;
+  /** if an error occures, it is temporarily stored here */
+  err_t err;
+};
+
+/** The global array of available sockets */
+static struct lwip_socket sockets[NUM_SOCKETS];
+/** The global list of tasks waiting for select */
+static struct lwip_select_cb *select_cb_list;
+
+/** Semaphore protecting the sockets array */
+static sys_sem_t socksem;
+/** Semaphore protecting select_cb_list */
+static sys_sem_t selectsem;
+
+/** Table to quickly map an lwIP error (err_t) to a socket error
+  * by using -err as an index */
+static const int err_to_errno_table[] = {
+  0,             /* ERR_OK          0      No error, everything OK. */
+  ENOMEM,        /* ERR_MEM        -1      Out of memory error.     */
+  ENOBUFS,       /* ERR_BUF        -2      Buffer error.            */
+  EHOSTUNREACH,  /* ERR_RTE        -3      Routing problem.         */
+  ECONNABORTED,  /* ERR_ABRT       -4      Connection aborted.      */
+  ECONNRESET,    /* ERR_RST        -5      Connection reset.        */
+  ESHUTDOWN,     /* ERR_CLSD       -6      Connection closed.       */
+  ENOTCONN,      /* ERR_CONN       -7      Not connected.           */
+  EINVAL,        /* ERR_VAL        -8      Illegal value.           */
+  EIO,           /* ERR_ARG        -9      Illegal argument.        */
+  EADDRINUSE,    /* ERR_USE        -10     Address in use.          */
+  -1,            /* ERR_IF         -11     Low-level netif error    */
+  -1,            /* ERR_ISCONN     -12     Already connected.       */
+  ETIMEDOUT,     /* ERR_TIMEOUT    -13     Timeout                  */
+  EINPROGRESS    /* ERR_INPROGRESS -14     Operation in progress    */
+};
+
+#define ERR_TO_ERRNO_TABLE_SIZE \
+  (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0]))
+
+#define err_to_errno(err) \
+  ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \
+    err_to_errno_table[-(err)] : EIO)
+
+#ifdef ERRNO
+#define set_errno(err) errno = (err)
+#else
+#define set_errno(err)
+#endif
+
+#define sock_set_errno(sk, e) do { \
+  sk->err = (e); \
+  set_errno(sk->err); \
+} while (0)
+
+/* Forward delcaration of some functions */
+static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
+static void lwip_getsockopt_internal(void *arg);
+static void lwip_setsockopt_internal(void *arg);
+
+/**
+ * Initialize this module. This function has to be called before any other
+ * functions in this module!
+ */
+void
+lwip_socket_init(void)
+{
+  socksem   = sys_sem_new(1);
+  selectsem = sys_sem_new(1);
+}
+
+/**
+ * Map a externally used socket index to the internal socket representation.
+ *
+ * @param s externally used socket index
+ * @return struct lwip_socket for the socket or NULL if not found
+ */
+static struct lwip_socket *
+get_socket(int s)
+{
+  struct lwip_socket *sock;
+
+  if ((s < 0) || (s >= NUM_SOCKETS)) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
+    set_errno(EBADF);
+    return NULL;
+  }
+
+  sock = &sockets[s];
+
+  if (!sock->conn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
+    set_errno(EBADF);
+    return NULL;
+  }
+
+  return sock;
+}
+
+/**
+ * Allocate a new socket for a given netconn.
+ *
+ * @param newconn the netconn for which to allocate a socket
+ * @return the index of the new socket; -1 on error
+ */
+static int
+alloc_socket(struct netconn *newconn)
+{
+  int i;
+
+  /* Protect socket array */
+  sys_sem_wait(socksem);
+
+  /* allocate a new socket identifier */
+  for (i = 0; i < NUM_SOCKETS; ++i) {
+    if (!sockets[i].conn) {
+      sockets[i].conn       = newconn;
+      sockets[i].lastdata   = NULL;
+      sockets[i].lastoffset = 0;
+      sockets[i].rcvevent   = 0;
+      sockets[i].sendevent  = 1; /* TCP send buf is empty */
+      sockets[i].flags      = 0;
+      sockets[i].err        = 0;
+      sys_sem_signal(socksem);
+      return i;
+    }
+  }
+  sys_sem_signal(socksem);
+  return -1;
+}
+
+/* Below this, the well-known socket functions are implemented.
+ * Use google.com or opengroup.org to get a good description :-)
+ *
+ * Exceptions are documented!
+ */
+
+int
+lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+  struct lwip_socket *sock, *nsock;
+  struct netconn *newconn;
+  struct ip_addr naddr;
+  u16_t port;
+  int newsock;
+  struct sockaddr_in sin;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  newconn = netconn_accept(sock->conn);
+  if (!newconn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) failed, err=%d\n", s, sock->conn->err));
+    sock_set_errno(sock, err_to_errno(sock->conn->err));
+    return -1;
+  }
+
+  /* get the IP address and port of the remote host */
+  err = netconn_peer(newconn, &naddr, &port);
+  if (err != ERR_OK) {
+    netconn_delete(newconn);
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  memset(&sin, 0, sizeof(sin));
+  sin.sin_len = sizeof(sin);
+  sin.sin_family = AF_INET;
+  sin.sin_port = htons(port);
+  sin.sin_addr.s_addr = naddr.addr;
+
+  if (*addrlen > sizeof(sin))
+    *addrlen = sizeof(sin);
+
+  SMEMCPY(addr, &sin, *addrlen);
+
+  newsock = alloc_socket(newconn);
+  if (newsock == -1) {
+    netconn_delete(newconn);
+    sock_set_errno(sock, ENFILE);
+    return -1;
+  }
+  LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS));
+  newconn->callback = event_callback;
+  nsock = &sockets[newsock];
+  LWIP_ASSERT("invalid socket pointer", nsock != NULL);
+
+  sys_sem_wait(socksem);
+  /* See event_callback: If data comes in right away after an accept, even
+   * though the server task might not have created a new socket yet.
+   * In that case, newconn->socket is counted down (newconn->socket--),
+   * so nsock->rcvevent is >= 1 here!
+   */
+  nsock->rcvevent += -1 - newconn->socket;
+  newconn->socket = newsock;
+  sys_sem_signal(socksem);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));
+
+  sock_set_errno(sock, 0);
+  return newsock;
+}
+
+int
+lwip_bind(int s, struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_socket *sock;
+  struct ip_addr local_addr;
+  u16_t local_port;
+  err_t err;
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
+             ((((struct sockaddr_in *)name)->sin_family) == AF_INET)),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+
+  local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
+  local_port = ((struct sockaddr_in *)name)->sin_port;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
+  ip_addr_debug_print(SOCKETS_DEBUG, &local_addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));
+
+  err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_close(int s)
+{
+  struct lwip_socket *sock;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
+
+  sock = get_socket(s);
+  if (!sock) {
+    return -1;
+  }
+
+  netconn_delete(sock->conn);
+
+  sys_sem_wait(socksem);
+  if (sock->lastdata) {
+    netbuf_delete(sock->lastdata);
+  }
+  sock->lastdata   = NULL;
+  sock->lastoffset = 0;
+  sock->conn       = NULL;
+  sock_set_errno(sock, 0);
+  sys_sem_signal(socksem);
+  return 0;
+}
+
+int
+lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
+{
+  struct lwip_socket *sock;
+  err_t err;
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
+             ((((struct sockaddr_in *)name)->sin_family) == AF_INET)),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+
+  if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
+    err = netconn_disconnect(sock->conn);
+  } else {
+    struct ip_addr remote_addr;
+    u16_t remote_port;
+
+    remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
+    remote_port = ((struct sockaddr_in *)name)->sin_port;
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
+    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));
+
+    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
+  }
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+/**
+ * Set a socket into listen mode.
+ * The socket may not have been used for another connection previously.
+ *
+ * @param s the socket to set to listening mode
+ * @param backlog (ATTENTION: need TCP_LISTEN_BACKLOG=1)
+ * @return 0 on success, non-zero on failure
+ */
+int
+lwip_listen(int s, int backlog)
+{
+  struct lwip_socket *sock;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  /* limit the "backlog" parameter to fit in an u8_t */
+  if (backlog < 0) {
+    backlog = 0;
+  }
+  if (backlog > 0xff) {
+    backlog = 0xff;
+  }
+
+  err = netconn_listen_with_backlog(sock->conn, backlog);
+
+  if (err != ERR_OK) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
+    sock_set_errno(sock, err_to_errno(err));
+    return -1;
+  }
+
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
+        struct sockaddr *from, socklen_t *fromlen)
+{
+  struct lwip_socket *sock;
+  struct netbuf      *buf;
+  u16_t               buflen, copylen, off = 0;
+  struct ip_addr     *addr;
+  u16_t               port;
+  u8_t                done = 0;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  do {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", (void*)sock->lastdata));
+    /* Check if there is data left from the last recv operation. */
+    if (sock->lastdata) {
+      buf = sock->lastdata;
+    } else {
+      /* If this is non-blocking call, then check first */
+      if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) && !sock->rcvevent) {
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
+        sock_set_errno(sock, EWOULDBLOCK);
+        return -1;
+      }
+
+      /* No data was left from the previous operation, so we try to get
+      some from the network. */
+      sock->lastdata = buf = netconn_recv(sock->conn);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv netbuf=%p\n", (void*)buf));
+
+      if (!buf) {
+        /* We should really do some error checking here. */
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
+        sock_set_errno(sock, (((sock->conn->pcb.ip!=NULL) && (sock->conn->err==ERR_OK))?ETIMEDOUT:err_to_errno(sock->conn->err)));
+        return 0;
+      }
+    }
+
+    buflen = netbuf_len(buf);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%d len=%d off=%d sock->lastoffset=%d\n", buflen, len, off, sock->lastoffset));
+
+    buflen -= sock->lastoffset;
+
+    if (len > buflen) {
+      copylen = buflen;
+    } else {
+      copylen = len;
+    }
+
+    /* copy the contents of the received buffer into
+    the supplied memory pointer mem */
+    netbuf_copy_partial(buf, (u8_t*)mem + off, copylen, sock->lastoffset);
+
+    off += copylen;
+
+    if (netconn_type(sock->conn) == NETCONN_TCP) {
+      len -= copylen;
+      if ( (len <= 0) || (buf->p->flags & PBUF_FLAG_PUSH) || !sock->rcvevent) {
+        done = 1;
+      }
+    } else {
+      done = 1;
+    }
+
+    /* If we don't peek the incoming message... */
+    if ((flags & MSG_PEEK)==0) {
+      /* If this is a TCP socket, check if there is data left in the
+         buffer. If so, it should be saved in the sock structure for next
+         time around. */
+      if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) {
+        sock->lastdata = buf;
+        sock->lastoffset += copylen;
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", (void*)buf));
+      } else {
+        sock->lastdata = NULL;
+        sock->lastoffset = 0;
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", (void*)buf));
+        netbuf_delete(buf);
+      }
+    } else {
+      done = 1;
+    }
+  } while (!done);
+
+  /* Check to see from where the data was.*/
+  if (from && fromlen) {
+    struct sockaddr_in sin;
+
+    if (netconn_type(sock->conn) == NETCONN_TCP) {
+      addr = (struct ip_addr*)&(sin.sin_addr.s_addr);
+      netconn_getaddr(sock->conn, addr, &port, 0);
+    } else {
+      addr = netbuf_fromaddr(buf);
+      port = netbuf_fromport(buf);
+    }
+
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_len = sizeof(sin);
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(port);
+    sin.sin_addr.s_addr = addr->addr;
+
+    if (*fromlen > sizeof(sin))
+      *fromlen = sizeof(sin);
+
+    SMEMCPY(from, &sin, *fromlen);
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
+  } else {
+#if SOCKETS_DEBUG
+    struct sockaddr_in sin;
+
+    if (netconn_type(sock->conn) == NETCONN_TCP) {
+      addr = (struct ip_addr*)&(sin.sin_addr.s_addr);
+      netconn_getaddr(sock->conn, addr, &port, 0);
+    } else {
+      addr = netbuf_fromaddr(buf);
+      port = netbuf_fromport(buf);
+    }
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
+    ip_addr_debug_print(SOCKETS_DEBUG, addr);
+    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off));
+#endif /*  SOCKETS_DEBUG */
+  }
+
+  sock_set_errno(sock, 0);
+  return off;
+}
+
+int
+lwip_read(int s, void *mem, int len)
+{
+  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
+}
+
+int
+lwip_recv(int s, void *mem, int len, unsigned int flags)
+{
+  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
+}
+
+int
+lwip_send(int s, const void *data, int size, unsigned int flags)
+{
+  struct lwip_socket *sock;
+  err_t err;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n",
+                              s, data, size, flags));
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  if (sock->conn->type!=NETCONN_TCP) {
+#if (LWIP_UDP || LWIP_RAW)
+    return lwip_sendto(s, data, size, flags, NULL, 0);
+#else
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    return -1;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+  }
+
+  err = netconn_write(sock->conn, data, size, NETCONN_COPY | ((flags & MSG_MORE)?NETCONN_MORE:0));
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size));
+  sock_set_errno(sock, err_to_errno(err));
+  return (err==ERR_OK?size:-1);
+}
+
+int
+lwip_sendto(int s, const void *data, int size, unsigned int flags,
+       struct sockaddr *to, socklen_t tolen)
+{
+  struct lwip_socket *sock;
+  struct ip_addr remote_addr;
+  int err;
+#if !LWIP_TCPIP_CORE_LOCKING
+  struct netbuf buf;
+  u16_t remote_port;
+#endif
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  if (sock->conn->type==NETCONN_TCP) {
+#if LWIP_TCP
+    return lwip_send(s, data, size, flags);
+#else
+    sock_set_errno(sock, err_to_errno(ERR_ARG));
+    return -1;
+#endif /* LWIP_TCP */
+  }
+
+  LWIP_ASSERT("lwip_sendto: size must fit in u16_t",
+              ((size >= 0) && (size <= 0xffff)));
+  LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||
+             ((tolen == sizeof(struct sockaddr_in)) &&
+             ((((struct sockaddr_in *)to)->sin_family) == AF_INET))),
+             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
+
+#if LWIP_TCPIP_CORE_LOCKING
+  /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */
+  { struct pbuf* p;
+  
+    p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
+    if (p == NULL) {
+      err = ERR_MEM;
+    } else {
+      p->payload = (void*)data;
+      p->len = p->tot_len = size;
+      
+      remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
+      
+      LOCK_TCPIP_CORE();
+      if (sock->conn->type==NETCONN_RAW) {
+        err = sock->conn->err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr);
+      } else {
+        err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((struct sockaddr_in *)to)->sin_port));
+      }
+      UNLOCK_TCPIP_CORE();
+      
+      pbuf_free(p);
+    }
+  }
+#else
+  /* initialize a buffer */
+  buf.p = buf.ptr = NULL;
+  if (to) {
+    remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
+    remote_port      = ntohs(((struct sockaddr_in *)to)->sin_port);
+    buf.addr         = &remote_addr;
+    buf.port         = remote_port;
+  } else {
+    remote_addr.addr = 0;
+    remote_port      = 0;
+    buf.addr         = NULL;
+    buf.port         = 0;
+  }
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=",
+              s, data, size, flags));
+  ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", remote_port));
+    
+  /* make the buffer point to the data that should be sent */
+  if ((err = netbuf_ref(&buf, data, size)) == ERR_OK) {
+    /* send the data */
+    err = netconn_send(sock->conn, &buf);
+  }
+
+  /* deallocated the buffer */
+  if (buf.p != NULL) {
+    pbuf_free(buf.p);
+  }
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+  sock_set_errno(sock, err_to_errno(err));
+  return (err==ERR_OK?size:-1);
+}
+
+int
+lwip_socket(int domain, int type, int protocol)
+{
+  struct netconn *conn;
+  int i;
+
+  LWIP_UNUSED_ARG(domain);
+
+  /* create a netconn */
+  switch (type) {
+  case SOCK_RAW:
+    conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    break;
+  case SOCK_DGRAM:
+    conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ?
+                 NETCONN_UDPLITE : NETCONN_UDP, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    break;
+  case SOCK_STREAM:
+    conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
+                                 domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
+    break;
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n",
+                                 domain, type, protocol));
+    set_errno(EINVAL);
+    return -1;
+  }
+
+  if (!conn) {
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
+    set_errno(ENOBUFS);
+    return -1;
+  }
+
+  i = alloc_socket(conn);
+
+  if (i == -1) {
+    netconn_delete(conn);
+    set_errno(ENFILE);
+    return -1;
+  }
+  conn->socket = i;
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
+  set_errno(0);
+  return i;
+}
+
+int
+lwip_write(int s, const void *data, int size)
+{
+  return lwip_send(s, data, size, 0);
+}
+
+/**
+ * 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
+ * the sockets enabled that had events.
+ *
+ * exceptset is not used for now!!!
+ *
+ * @param maxfdp1 the highest socket index in the sets
+ * @param readset in: set of sockets to check for read events;
+ *                out: set of sockets that had read events
+ * @param writeset in: set of sockets to check for write events;
+ *                 out: set of sockets that had write events
+ * @param exceptset not yet implemented
+ * @return number of sockets that had events (read+write)
+ */
+static int
+lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
+{
+  int i, nready = 0;
+  fd_set lreadset, lwriteset, lexceptset;
+  struct lwip_socket *p_sock;
+  
+  FD_ZERO(&lreadset);
+  FD_ZERO(&lwriteset);
+  FD_ZERO(&lexceptset);
+  
+  /* Go through each socket in each list to count number of sockets which
+  currently match */
+  for(i = 0; i < maxfdp1; i++) {
+    if (FD_ISSET(i, readset)) {
+      /* See if netconn of this socket is ready for read */
+      p_sock = get_socket(i);
+      if (p_sock && (p_sock->lastdata || p_sock->rcvevent)) {
+        FD_SET(i, &lreadset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i));
+        nready++;
+      }
+    }
+    if (FD_ISSET(i, writeset)) {
+      /* See if netconn of this socket is ready for write */
+      p_sock = get_socket(i);
+      if (p_sock && p_sock->sendevent) {
+        FD_SET(i, &lwriteset);
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
+        nready++;
+      }
+    }
+  }
+  *readset = lreadset;
+  *writeset = lwriteset;
+  FD_ZERO(exceptset);
+  
+  return nready;
+}
+
+
+/**
+ * Processing exceptset is not yet implemented.
+ */
+int
+lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+               struct timeval *timeout)
+{
+  int i;
+  int nready;
+  fd_set lreadset, lwriteset, lexceptset;
+  u32_t msectimeout;
+  struct lwip_select_cb select_cb;
+  struct lwip_select_cb *p_selcb;
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n",
+                  maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
+                  timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));
+
+  select_cb.next = 0;
+  select_cb.readset = readset;
+  select_cb.writeset = writeset;
+  select_cb.exceptset = exceptset;
+  select_cb.sem_signalled = 0;
+
+  /* Protect ourselves searching through the list */
+  sys_sem_wait(selectsem);
+
+  if (readset)
+    lreadset = *readset;
+  else
+    FD_ZERO(&lreadset);
+  if (writeset)
+    lwriteset = *writeset;
+  else
+    FD_ZERO(&lwriteset);
+  if (exceptset)
+    lexceptset = *exceptset;
+  else
+    FD_ZERO(&lexceptset);
+
+  /* Go through each socket in each list to count number of sockets which
+     currently match */
+  nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
+
+  /* If we don't have any current events, then suspend if we are supposed to */
+  if (!nready) {
+    if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
+      sys_sem_signal(selectsem);
+      if (readset)
+        FD_ZERO(readset);
+      if (writeset)
+        FD_ZERO(writeset);
+      if (exceptset)
+        FD_ZERO(exceptset);
+  
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
+      set_errno(0);
+  
+      return 0;
+    }
+    
+    /* add our semaphore to list */
+    /* We don't actually need any dynamic memory. Our entry on the
+     * list is only valid while we are in this function, so it's ok
+     * to use local variables */
+    
+    select_cb.sem = sys_sem_new(0);
+    /* Note that we are still protected */
+    /* Put this select_cb on top of list */
+    select_cb.next = select_cb_list;
+    select_cb_list = &select_cb;
+    
+    /* Now we can safely unprotect */
+    sys_sem_signal(selectsem);
+    
+    /* Now just wait to be woken */
+    if (timeout == 0)
+      /* Wait forever */
+      msectimeout = 0;
+    else {
+      msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
+      if(msectimeout == 0)
+        msectimeout = 1;
+    }
+    
+    i = sys_sem_wait_timeout(select_cb.sem, msectimeout);
+    
+    /* Take us off the list */
+    sys_sem_wait(selectsem);
+    if (select_cb_list == &select_cb)
+      select_cb_list = select_cb.next;
+    else
+      for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next) {
+        if (p_selcb->next == &select_cb) {
+          p_selcb->next = select_cb.next;
+          break;
+        }
+      }
+    
+    sys_sem_signal(selectsem);
+    
+    sys_sem_free(select_cb.sem);
+    if (i == 0)  {
+      /* Timeout */
+      if (readset)
+        FD_ZERO(readset);
+      if (writeset)
+        FD_ZERO(writeset);
+      if (exceptset)
+        FD_ZERO(exceptset);
+  
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
+      set_errno(0);
+  
+      return 0;
+    }
+    
+    if (readset)
+      lreadset = *readset;
+    else
+      FD_ZERO(&lreadset);
+    if (writeset)
+      lwriteset = *writeset;
+    else
+      FD_ZERO(&lwriteset);
+    if (exceptset)
+      lexceptset = *exceptset;
+    else
+      FD_ZERO(&lexceptset);
+    
+    /* See what's set */
+    nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
+  } else
+    sys_sem_signal(selectsem);
+  
+  if (readset)
+    *readset = lreadset;
+  if (writeset)
+    *writeset = lwriteset;
+  if (exceptset)
+    *exceptset = lexceptset;
+  
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
+  set_errno(0);
+  
+  return nready;
+}
+
+/**
+ * Callback registered in the netconn layer for each socket-netconn.
+ * Processes recvevent (data available) and wakes up tasks waiting for select.
+ */
+static void
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
+{
+  int s;
+  struct lwip_socket *sock;
+  struct lwip_select_cb *scb;
+
+  LWIP_UNUSED_ARG(len);
+
+  /* Get socket */
+  if (conn) {
+    s = conn->socket;
+    if (s < 0) {
+      /* Data comes in right away after an accept, even though
+       * the server task might not have created a new socket yet.
+       * Just count down (or up) if that's the case and we
+       * will use the data later. Note that only receive events
+       * can happen before the new socket is set up. */
+      sys_sem_wait(socksem);
+      if (conn->socket < 0) {
+        if (evt == NETCONN_EVT_RCVPLUS) {
+          conn->socket--;
+        }
+        sys_sem_signal(socksem);
+        return;
+      }
+      sys_sem_signal(socksem);
+    }
+
+    sock = get_socket(s);
+    if (!sock) {
+      return;
+    }
+  } else {
+    return;
+  }
+
+  sys_sem_wait(selectsem);
+  /* Set event as required */
+  switch (evt) {
+    case NETCONN_EVT_RCVPLUS:
+      sock->rcvevent++;
+      break;
+    case NETCONN_EVT_RCVMINUS:
+      sock->rcvevent--;
+      break;
+    case NETCONN_EVT_SENDPLUS:
+      sock->sendevent = 1;
+      break;
+    case NETCONN_EVT_SENDMINUS:
+      sock->sendevent = 0;
+      break;
+    default:
+      LWIP_ASSERT("unknown event", 0);
+      break;
+  }
+  sys_sem_signal(selectsem);
+
+  /* Now decide if anyone is waiting for this socket */
+  /* NOTE: This code is written this way to protect the select link list
+     but to avoid a deadlock situation by releasing socksem before
+     signalling for the select. This means we need to go through the list
+     multiple times ONLY IF a select was actually waiting. We go through
+     the list the number of waiting select calls + 1. This list is
+     expected to be small. */
+  while (1) {
+    sys_sem_wait(selectsem);
+    for (scb = select_cb_list; scb; scb = scb->next) {
+      if (scb->sem_signalled == 0) {
+        /* Test this select call for our socket */
+        if (scb->readset && FD_ISSET(s, scb->readset))
+          if (sock->rcvevent)
+            break;
+        if (scb->writeset && FD_ISSET(s, scb->writeset))
+          if (sock->sendevent)
+            break;
+      }
+    }
+    if (scb) {
+      scb->sem_signalled = 1;
+      sys_sem_signal(selectsem);
+      sys_sem_signal(scb->sem);
+    } else {
+      sys_sem_signal(selectsem);
+      break;
+    }
+  }
+}
+
+/**
+ * Unimplemented: Close one end of a full-duplex connection.
+ * Currently, the full connection is closed.
+ */
+int
+lwip_shutdown(int s, int how)
+{
+  LWIP_UNUSED_ARG(how);
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
+  return lwip_close(s); /* XXX temporary hack until proper implementation */
+}
+
+static int
+lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
+{
+  struct lwip_socket *sock;
+  struct sockaddr_in sin;
+  struct ip_addr naddr;
+
+  sock = get_socket(s);
+  if (!sock)
+    return -1;
+
+  memset(&sin, 0, sizeof(sin));
+  sin.sin_len = sizeof(sin);
+  sin.sin_family = AF_INET;
+
+  /* get the IP address and port */
+  netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local);
+
+  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
+  ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
+  LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
+
+  sin.sin_port = htons(sin.sin_port);
+  sin.sin_addr.s_addr = naddr.addr;
+
+  if (*namelen > sizeof(sin))
+    *namelen = sizeof(sin);
+
+  SMEMCPY(name, &sin, *namelen);
+  sock_set_errno(sock, 0);
+  return 0;
+}
+
+int
+lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 0);
+}
+
+int
+lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
+{
+  return lwip_getaddrname(s, name, namelen, 1);
+}
+
+int
+lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
+{
+  err_t err = ERR_OK;
+  struct lwip_socket *sock = get_socket(s);
+  struct lwip_setgetsockopt_data data;
+
+  if (!sock)
+    return -1;
+
+  if ((NULL == optval) || (NULL == optlen)) {
+    sock_set_errno(sock, EFAULT);
+    return -1;
+  }
+
+  /* Do length and type checks for the various options first, to keep it readable. */
+  switch (level) {
+   
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+       
+    case SO_ACCEPTCONN:
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_ERROR:
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_CONTIMEO: */
+    /* UNIMPL case SO_SNDTIMEO: */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+#endif /* LWIP_SO_RCVBUF */
+    /* UNIMPL case SO_OOBINLINE: */
+    /* UNIMPL case SO_SNDBUF: */
+    /* UNIMPL case SO_RCVLOWAT: */
+    /* UNIMPL case SO_SNDLOWAT: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    case SO_TYPE:
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+
+    case SO_NO_CHECK:
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+#if LWIP_UDP
+      if ((sock->conn->type != NETCONN_UDP) ||
+          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
+        /* this flag is only available for UDP, not for UDP lite */
+        err = EAFNOSUPPORT;
+      }
+#endif /* LWIP_UDP */
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+                     
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    /* UNIMPL case IP_HDRINCL: */
+    /* UNIMPL case IP_RCVDSTADDR: */
+    /* UNIMPL case IP_RCVIF: */
+    case IP_TTL:
+    case IP_TOS:
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      if (*optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      break;
+    case IP_MULTICAST_IF:
+      if (*optlen < sizeof(struct in_addr)) {
+        err = EINVAL;
+      }
+      break;
+#endif /* LWIP_IGMP */
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+         
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    if (*optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+    
+    /* If this is no TCP socket, ignore any options. */
+    if (sock->conn->type != NETCONN_TCP)
+      return 0;
+
+    switch (optname) {
+    case TCP_NODELAY:
+    case TCP_KEEPALIVE:
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+    case TCP_KEEPINTVL:
+    case TCP_KEEPCNT:
+#endif /* LWIP_TCP_KEEPALIVE */
+      break;
+       
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+/* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    if (*optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+    
+    /* If this is no UDP lite socket, ignore any options. */
+    if (sock->conn->type != NETCONN_UDPLITE)
+      return 0;
+
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+    case UDPLITE_RECV_CSCOV:
+      break;
+       
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP && LWIP_UDPLITE*/
+/* UNDEFINED LEVEL */
+  default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                                  s, level, optname));
+      err = ENOPROTOOPT;
+  }  /* switch */
+
+   
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err);
+    return -1;
+  }
+
+  /* Now do the actual option processing */
+  data.sock = sock;
+  data.level = level;
+  data.optname = optname;
+  data.optval = optval;
+  data.optlen = optlen;
+  data.err = err;
+  tcpip_callback(lwip_getsockopt_internal, &data);
+  sys_arch_sem_wait(sock->conn->op_completed, 0);
+  /* maybe lwip_getsockopt_internal has changed err */
+  err = data.err;
+
+  sock_set_errno(sock, err);
+  return err ? -1 : 0;
+}
+
+static void
+lwip_getsockopt_internal(void *arg)
+{
+  struct lwip_socket *sock;
+#ifdef LWIP_DEBUG
+  int s;
+#endif /* LWIP_DEBUG */
+  int level, optname;
+  void *optval;
+  struct lwip_setgetsockopt_data *data;
+
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+
+  data = (struct lwip_setgetsockopt_data*)arg;
+  sock = data->sock;
+#ifdef LWIP_DEBUG
+  s = data->s;
+#endif /* LWIP_DEBUG */
+  level = data->level;
+  optname = data->optname;
+  optval = data->optval;
+
+  switch (level) {
+   
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    /* The option flags */
+    case SO_ACCEPTCONN:
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_OOBINCLUDE: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /*case SO_USELOOPBACK: UNIMPL */
+      *(int*)optval = sock->conn->pcb.ip->so_options & optname;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n",
+                                  s, optname, (*(int*)optval?"on":"off")));
+      break;
+
+    case SO_TYPE:
+      switch (NETCONNTYPE_GROUP(sock->conn->type)) {
+      case NETCONN_RAW:
+        *(int*)optval = SOCK_RAW;
+        break;
+      case NETCONN_TCP:
+        *(int*)optval = SOCK_STREAM;
+        break;
+      case NETCONN_UDP:
+        *(int*)optval = SOCK_DGRAM;
+        break;
+      default: /* unrecognized socket type */
+        *(int*)optval = sock->conn->type;
+        LWIP_DEBUGF(SOCKETS_DEBUG,
+                    ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
+                    s, *(int *)optval));
+      }  /* switch (sock->conn->type) */
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+    case SO_ERROR:
+      if (sock->err == 0) {
+        sock_set_errno(sock, err_to_errno(sock->conn->err));
+      } 
+      *(int *)optval = sock->err;
+      sock->err = 0;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+      *(int *)optval = sock->conn->recv_timeout;
+      break;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+      *(int *)optval = sock->conn->recv_bufsize;
+      break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_UDP
+    case SO_NO_CHECK:
+      *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0;
+      break;
+#endif /* LWIP_UDP*/
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    case IP_TTL:
+      *(int*)optval = sock->conn->pcb.ip->ttl;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case IP_TOS:
+      *(int*)optval = sock->conn->pcb.ip->tos;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n",
+                  s, *(int *)optval));
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      *(u8_t*)optval = sock->conn->pcb.ip->ttl;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case IP_MULTICAST_IF:
+      ((struct in_addr*) optval)->s_addr = sock->conn->pcb.udp->multicast_ip.addr;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%x\n",
+                  s, *(u32_t *)optval));
+      break;
+#endif /* LWIP_IGMP */
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    switch (optname) {
+    case TCP_NODELAY:
+      *(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n",
+                  s, (*(int*)optval)?"on":"off") );
+      break;
+    case TCP_KEEPALIVE:
+      *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n",
+                  s, *(int *)optval));
+      break;
+
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case TCP_KEEPINTVL:
+      *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n",
+                  s, *(int *)optval));
+      break;
+    case TCP_KEEPCNT:
+      *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n",
+                  s, *(int *)optval));
+      break;
+#endif /* LWIP_TCP_KEEPALIVE */
+
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+  /* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+      *(int*)optval = sock->conn->pcb.udp->chksum_len_tx;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    case UDPLITE_RECV_CSCOV:
+      *(int*)optval = sock->conn->pcb.udp->chksum_len_rx;
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP */
+  } /* switch (level) */
+  sys_sem_signal(sock->conn->op_completed);
+}
+
+int
+lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
+{
+  struct lwip_socket *sock = get_socket(s);
+  int err = ERR_OK;
+  struct lwip_setgetsockopt_data data;
+
+  if (!sock)
+    return -1;
+
+  if (NULL == optval) {
+    sock_set_errno(sock, EFAULT);
+    return -1;
+  }
+
+  /* Do length and type checks for the various options first, to keep it readable. */
+  switch (level) {
+
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case case SO_CONTIMEO: */
+    /* UNIMPL case case SO_SNDTIMEO: */
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+#endif /* LWIP_SO_RCVBUF */
+    /* UNIMPL case SO_OOBINLINE: */
+    /* UNIMPL case SO_SNDBUF: */
+    /* UNIMPL case SO_RCVLOWAT: */
+    /* UNIMPL case SO_SNDLOWAT: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+    case SO_NO_CHECK:
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+#if LWIP_UDP
+      if ((sock->conn->type != NETCONN_UDP) ||
+          ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
+        /* this flag is only available for UDP, not for UDP lite */
+        err = EAFNOSUPPORT;
+      }
+#endif /* LWIP_UDP */
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    /* UNIMPL case IP_HDRINCL: */
+    /* UNIMPL case IP_RCVDSTADDR: */
+    /* UNIMPL case IP_RCVIF: */
+    case IP_TTL:
+    case IP_TOS:
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      if (optlen < sizeof(u8_t)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+    case IP_MULTICAST_IF:
+      if (optlen < sizeof(struct in_addr)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+    case IP_ADD_MEMBERSHIP:
+    case IP_DROP_MEMBERSHIP:
+      if (optlen < sizeof(struct ip_mreq)) {
+        err = EINVAL;
+      }
+      if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
+        err = EAFNOSUPPORT;
+      }
+      break;
+#endif /* LWIP_IGMP */
+      default:
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n",
+                    s, optname));
+        err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    if (optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+
+    /* If this is no TCP socket, ignore any options. */
+    if (sock->conn->type != NETCONN_TCP)
+      return 0;
+
+    switch (optname) {
+    case TCP_NODELAY:
+    case TCP_KEEPALIVE:
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+    case TCP_KEEPINTVL:
+    case TCP_KEEPCNT:
+#endif /* LWIP_TCP_KEEPALIVE */
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP */
+#if LWIP_UDP && LWIP_UDPLITE
+/* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    if (optlen < sizeof(int)) {
+      err = EINVAL;
+      break;
+    }
+
+    /* If this is no UDP lite socket, ignore any options. */
+    if (sock->conn->type != NETCONN_UDPLITE)
+      return 0;
+
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+    case UDPLITE_RECV_CSCOV:
+      break;
+
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
+                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP && LWIP_UDPLITE */
+/* UNDEFINED LEVEL */
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n",
+                s, level, optname));
+    err = ENOPROTOOPT;
+  }  /* switch (level) */
+
+
+  if (err != ERR_OK) {
+    sock_set_errno(sock, err);
+    return -1;
+  }
+
+
+  /* Now do the actual option processing */
+  data.sock = sock;
+  data.level = level;
+  data.optname = optname;
+  data.optval = (void*)optval;
+  data.optlen = &optlen;
+  data.err = err;
+  tcpip_callback(lwip_setsockopt_internal, &data);
+  sys_arch_sem_wait(sock->conn->op_completed, 0);
+  /* maybe lwip_setsockopt_internal has changed err */
+  err = data.err;
+
+  sock_set_errno(sock, err);
+  return err ? -1 : 0;
+}
+
+static void
+lwip_setsockopt_internal(void *arg)
+{
+  struct lwip_socket *sock;
+#ifdef LWIP_DEBUG
+  int s;
+#endif /* LWIP_DEBUG */
+  int level, optname;
+  const void *optval;
+  struct lwip_setgetsockopt_data *data;
+
+  LWIP_ASSERT("arg != NULL", arg != NULL);
+
+  data = (struct lwip_setgetsockopt_data*)arg;
+  sock = data->sock;
+#ifdef LWIP_DEBUG
+  s = data->s;
+#endif /* LWIP_DEBUG */
+  level = data->level;
+  optname = data->optname;
+  optval = data->optval;
+
+  switch (level) {
+
+/* Level: SOL_SOCKET */
+  case SOL_SOCKET:
+    switch (optname) {
+
+    /* The option flags */
+    case SO_BROADCAST:
+    /* UNIMPL case SO_DEBUG: */
+    /* UNIMPL case SO_DONTROUTE: */
+    case SO_KEEPALIVE:
+    /* UNIMPL case SO_OOBINCLUDE: */
+#if SO_REUSE
+    case SO_REUSEADDR:
+    case SO_REUSEPORT:
+#endif /* SO_REUSE */
+    /* UNIMPL case SO_USELOOPBACK: */
+      if (*(int*)optval) {
+        sock->conn->pcb.ip->so_options |= optname;
+      } else {
+        sock->conn->pcb.ip->so_options &= ~optname;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n",
+                  s, optname, (*(int*)optval?"on":"off")));
+      break;
+#if LWIP_SO_RCVTIMEO
+    case SO_RCVTIMEO:
+      sock->conn->recv_timeout = ( *(int*)optval );
+      break;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+    case SO_RCVBUF:
+      sock->conn->recv_bufsize = ( *(int*)optval );
+      break;
+#endif /* LWIP_SO_RCVBUF */
+#if LWIP_UDP
+    case SO_NO_CHECK:
+      if (*(int*)optval) {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM);
+      } else {
+        udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM);
+      }
+      break;
+#endif /* LWIP_UDP */
+    }  /* switch (optname) */
+    break;
+
+/* Level: IPPROTO_IP */
+  case IPPROTO_IP:
+    switch (optname) {
+    case IP_TTL:
+      sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n",
+                  s, sock->conn->pcb.ip->ttl));
+      break;
+    case IP_TOS:
+      sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n",
+                  s, sock->conn->pcb.ip->tos));
+      break;
+#if LWIP_IGMP
+    case IP_MULTICAST_TTL:
+      sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval);
+      break;
+    case IP_MULTICAST_IF:
+      sock->conn->pcb.udp->multicast_ip.addr = ((struct in_addr*) optval)->s_addr;
+      break;
+    case IP_ADD_MEMBERSHIP:
+    case IP_DROP_MEMBERSHIP:
+      {
+        /* If this is a TCP or a RAW socket, ignore these options. */
+        struct ip_mreq *imr = (struct ip_mreq *)optval;
+        if(optname == IP_ADD_MEMBERSHIP){
+          data->err = igmp_joingroup((struct ip_addr*)&(imr->imr_interface.s_addr), (struct ip_addr*)&(imr->imr_multiaddr.s_addr));
+        } else {
+          data->err = igmp_leavegroup((struct ip_addr*)&(imr->imr_interface.s_addr), (struct ip_addr*)&(imr->imr_multiaddr.s_addr));
+        }
+        if(data->err != ERR_OK) {
+          data->err = EADDRNOTAVAIL;
+        }
+      }
+      break;
+#endif /* LWIP_IGMP */
+    }  /* switch (optname) */
+    break;
+
+#if LWIP_TCP
+/* Level: IPPROTO_TCP */
+  case IPPROTO_TCP:
+    switch (optname) {
+    case TCP_NODELAY:
+      if (*(int*)optval) {
+        sock->conn->pcb.tcp->flags |= TF_NODELAY;
+      } else {
+        sock->conn->pcb.tcp->flags &= ~TF_NODELAY;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n",
+                  s, (*(int *)optval)?"on":"off") );
+      break;
+    case TCP_KEEPALIVE:
+      sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n",
+                  s, sock->conn->pcb.tcp->keep_idle));
+      break;
+
+#if LWIP_TCP_KEEPALIVE
+    case TCP_KEEPIDLE:
+      sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %lu\n",
+                  s, sock->conn->pcb.tcp->keep_idle));
+      break;
+    case TCP_KEEPINTVL:
+      sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %lu\n",
+                  s, sock->conn->pcb.tcp->keep_intvl));
+      break;
+    case TCP_KEEPCNT:
+      sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %lu\n",
+                  s, sock->conn->pcb.tcp->keep_cnt));
+      break;
+#endif /* LWIP_TCP_KEEPALIVE */
+
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_TCP*/
+#if LWIP_UDP && LWIP_UDPLITE
+  /* Level: IPPROTO_UDPLITE */
+  case IPPROTO_UDPLITE:
+    switch (optname) {
+    case UDPLITE_SEND_CSCOV:
+      if ((*(int*)optval != 0) && (*(int*)optval < 8)) {
+        /* don't allow illegal values! */
+        sock->conn->pcb.udp->chksum_len_tx = 8;
+      } else {
+        sock->conn->pcb.udp->chksum_len_tx = *(int*)optval;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    case UDPLITE_RECV_CSCOV:
+      if ((*(int*)optval != 0) && (*(int*)optval < 8)) {
+        /* don't allow illegal values! */
+        sock->conn->pcb.udp->chksum_len_rx = 8;
+      } else {
+        sock->conn->pcb.udp->chksum_len_rx = *(int*)optval;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n",
+                  s, (*(int*)optval)) );
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_UDP */
+  }  /* switch (level) */
+  sys_sem_signal(sock->conn->op_completed);
+}
+
+int
+lwip_ioctl(int s, long cmd, void *argp)
+{
+  struct lwip_socket *sock = get_socket(s);
+  u16_t buflen = 0;
+
+  if (!sock)
+    return -1;
+
+  switch (cmd) {
+  case FIONREAD:
+    if (!argp) {
+      sock_set_errno(sock, EINVAL);
+      return -1;
+    }
+
+    SYS_ARCH_GET(sock->conn->recv_avail, *((u16_t*)argp));
+
+    /* Check if there is data left from the last recv operation. /maq 041215 */
+    if (sock->lastdata) {
+      buflen = netbuf_len(sock->lastdata);
+      buflen -= sock->lastoffset;
+
+      *((u16_t*)argp) += buflen;
+    }
+
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp)));
+    sock_set_errno(sock, 0);
+    return 0;
+
+  case FIONBIO:
+    if (argp && *(u32_t*)argp)
+      sock->flags |= O_NONBLOCK;
+    else
+      sock->flags &= ~O_NONBLOCK;
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));
+    sock_set_errno(sock, 0);
+    return 0;
+
+  default:
+    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
+    sock_set_errno(sock, ENOSYS); /* not yet implemented */
+    return -1;
+  } /* switch (cmd) */
+}
+
+#endif /* LWIP_SOCKET */
diff --git a/palacios/src/lwip/arch/sys_arch.c b/palacios/src/lwip/arch/sys_arch.c
new file mode 100644 (file)
index 0000000..abcd0fe
--- /dev/null
@@ -0,0 +1,613 @@
+/*
+ * 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/sys.h"
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+
+#define UMAX(a, b)      ((a) > (b) ? (a) : (b))
+
+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 *mail;
+  struct sys_sem *mutex;
+  int wait_send;
+};
+
+struct sys_sem {
+  unsigned int c;
+  pthread_cond_t cond;
+  pthread_mutex_t mutex;
+};
+
+struct sys_thread {
+  struct sys_thread *next;
+  struct sys_timeouts timeouts;
+  pthread_t pthread;
+};
+
+
+static struct timeval starttime;
+
+static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t lwprot_thread = (pthread_t) 0xDEAD;
+static int lwprot_count = 0;
+
+static struct sys_sem *sys_sem_new_(u8_t count);
+static void sys_sem_free_(struct sys_sem *sem);
+
+static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
+                       u32_t timeout);
+
+/*-----------------------------------------------------------------------------------*/
+static struct sys_thread * 
+introduce_thread(pthread_t id)
+{
+  struct sys_thread *thread;
+  
+  thread = malloc(sizeof(struct sys_thread));
+    
+  if (thread != NULL) {
+    pthread_mutex_lock(&threads_mutex);
+    thread->next = threads;
+    thread->timeouts.next = NULL;
+    thread->pthread = id;
+    threads = thread;
+    pthread_mutex_unlock(&threads_mutex);
+  }
+    
+  return thread;
+}
+/*-----------------------------------------------------------------------------------*/
+static struct sys_thread *
+current_thread(void)
+{
+  struct sys_thread *st;
+  pthread_t pt;
+  pt = pthread_self();
+  pthread_mutex_lock(&threads_mutex);
+
+  for(st = threads; st != NULL; st = st->next) {    
+    if (pthread_equal(st->pthread, pt)) {
+      pthread_mutex_unlock(&threads_mutex);
+      
+      return st;
+    }
+  }
+
+  pthread_mutex_unlock(&threads_mutex);
+
+  st = introduce_thread(pt);
+
+  if (!st) {
+    printf("current_thread???\n");
+    abort();
+  }
+
+  return st;
+}
+/*-----------------------------------------------------------------------------------*/
+sys_thread_t
+sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio)
+{
+  int code;
+  pthread_t tmp;
+  struct sys_thread *st = NULL;
+  
+  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%x",
+                       code, (int)st));
+    abort();
+  }
+  return st;
+}
+/*-----------------------------------------------------------------------------------*/
+struct sys_mbox *
+sys_mbox_new(int size)
+{
+  struct sys_mbox *mbox;
+  
+  mbox = malloc(sizeof(struct sys_mbox));
+  if (mbox != NULL) {
+    mbox->first = mbox->last = 0;
+    mbox->mail = sys_sem_new_(0);
+    mbox->mutex = sys_sem_new_(1);
+    mbox->wait_send = 0;
+  
+#if SYS_STATS
+    lwip_stats.sys.mbox.used++;
+    if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) {
+      lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
+    }
+#endif /* SYS_STATS */
+  }
+  return mbox;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_free(struct sys_mbox *mbox)
+{
+  if (mbox != SYS_MBOX_NULL) {
+#if SYS_STATS
+    lwip_stats.sys.mbox.used--;
+#endif /* SYS_STATS */
+    sys_sem_wait(mbox->mutex);
+    
+    sys_sem_free_(mbox->mail);
+    sys_sem_free_(mbox->mutex);
+    mbox->mail = mbox->mutex = NULL;
+    /*  LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
+    free(mbox);
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+err_t
+sys_mbox_trypost(struct sys_mbox *mbox, void *msg)
+{
+  u8_t first;
+  
+  sys_sem_wait(mbox->mutex);
+  
+  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))
+    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->mail);
+  }
+
+  sys_sem_signal(mbox->mutex);
+
+  return ERR_OK;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_mbox_post(struct sys_mbox *mbox, void *msg)
+{
+  u8_t first;
+  
+  sys_sem_wait(mbox->mutex);
+  
+  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->mail, 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->mail);
+  }
+
+  sys_sem_signal(mbox->mutex);
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_tryfetch(struct sys_mbox *mbox, void **msg)
+{
+  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->mail);
+  }
+
+  sys_sem_signal(mbox->mutex);
+
+  return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u32_t timeout)
+{
+  u32_t time = 0;
+  
+  /* 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 = sys_arch_sem_wait(mbox->mail, timeout);
+      
+      if (time == SYS_ARCH_TIMEOUT) {
+        return SYS_ARCH_TIMEOUT;
+      }
+    } else {
+      sys_arch_sem_wait(mbox->mail, 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->mail);
+  }
+
+  sys_sem_signal(mbox->mutex);
+
+  return time;
+}
+/*-----------------------------------------------------------------------------------*/
+struct sys_sem *
+sys_sem_new(u8_t count)
+{
+#if SYS_STATS
+  lwip_stats.sys.sem.used++;
+  if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max) {
+    lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
+  }
+#endif /* SYS_STATS */
+  return sys_sem_new_(count);
+}
+
+/*-----------------------------------------------------------------------------------*/
+static struct sys_sem *
+sys_sem_new_(u8_t count)
+{
+  struct sys_sem *sem;
+  
+  sem = malloc(sizeof(struct sys_sem));
+  if (sem != NULL) {
+    sem->c = count;
+    pthread_cond_init(&(sem->cond), NULL);
+    pthread_mutex_init(&(sem->mutex), NULL);
+  }
+  return sem;
+}
+
+/*-----------------------------------------------------------------------------------*/
+static u32_t
+cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
+{
+  int tdiff;
+  unsigned long sec, usec;
+  struct timeval rtime1, rtime2;
+  struct timespec ts;
+  struct timezone tz;
+  int retval;
+  
+  if (timeout > 0) {
+    /* Get a timestamp and add the timeout value. */
+    gettimeofday(&rtime1, &tz);
+    sec = rtime1.tv_sec;
+    usec = rtime1.tv_usec;
+    usec += timeout % 1000 * 1000;
+    sec += (int)(timeout / 1000) + (int)(usec / 1000000);
+    usec = usec % 1000000;
+    ts.tv_nsec = usec * 1000;
+    ts.tv_sec = sec;
+    
+    retval = pthread_cond_timedwait(cond, mutex, &ts);
+    
+    if (retval == ETIMEDOUT) {
+      return SYS_ARCH_TIMEOUT;
+    } else {
+      /* Calculate for how long we waited for the cond. */
+      gettimeofday(&rtime2, &tz);
+      tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +
+        (rtime2.tv_usec - rtime1.tv_usec) / 1000;
+      
+      if (tdiff <= 0) {
+        return 0;
+      }
+      
+      return tdiff;
+    }
+  } else {
+    pthread_cond_wait(cond, mutex);
+    return SYS_ARCH_TIMEOUT;
+  }
+}
+/*-----------------------------------------------------------------------------------*/
+u32_t
+sys_arch_sem_wait(struct sys_sem *sem, u32_t timeout)
+{
+  u32_t time = 0;
+  
+  pthread_mutex_lock(&(sem->mutex));
+  while (sem->c <= 0) {
+    if (timeout > 0) {
+      time = cond_wait(&(sem->cond), &(sem->mutex), timeout);
+      
+      if (time == SYS_ARCH_TIMEOUT) {
+        pthread_mutex_unlock(&(sem->mutex));
+        return SYS_ARCH_TIMEOUT;
+      }
+      /*      pthread_mutex_unlock(&(sem->mutex));
+              return time; */
+    } else {
+      cond_wait(&(sem->cond), &(sem->mutex), 0);
+    }
+  }
+  sem->c--;
+  pthread_mutex_unlock(&(sem->mutex));
+  return time;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_signal(struct sys_sem *sem)
+{
+  pthread_mutex_lock(&(sem->mutex));
+  sem->c++;
+
+  if (sem->c > 1) {
+    sem->c = 1;
+  }
+
+  pthread_cond_broadcast(&(sem->cond));
+  pthread_mutex_unlock(&(sem->mutex));
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_sem_free(struct sys_sem *sem)
+{
+  if (sem != SYS_SEM_NULL) {
+#if SYS_STATS
+    lwip_stats.sys.sem.used--;
+#endif /* SYS_STATS */
+    sys_sem_free_(sem);
+  }
+}
+
+/*-----------------------------------------------------------------------------------*/
+static void
+sys_sem_free_(struct sys_sem *sem)
+{
+  pthread_cond_destroy(&(sem->cond));
+  pthread_mutex_destroy(&(sem->mutex));
+  free(sem);
+}
+/*-----------------------------------------------------------------------------------*/
+unsigned long
+sys_unix_now()
+{
+  struct timeval tv;
+  struct timezone tz;
+  long sec, usec;
+  unsigned long msec;
+  gettimeofday(&tv, &tz);
+  
+  sec = tv.tv_sec - starttime.tv_sec;
+  usec = tv.tv_usec - starttime.tv_usec;
+  msec = sec * 1000 + usec / 1000;
+    
+  return msec;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+sys_init()
+{
+  struct timezone tz;
+  gettimeofday(&starttime, &tz);
+}
+/*-----------------------------------------------------------------------------------*/
+struct sys_timeouts *
+sys_arch_timeouts(void)
+{
+  struct sys_thread *thread;
+
+  thread = current_thread();
+  return &thread->timeouts;
+}
+/*-----------------------------------------------------------------------------------*/
+/** 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)
+{
+    if (lwprot_thread == pthread_self())
+    {
+        if (--lwprot_count == 0)
+        {
+            lwprot_thread = (pthread_t) 0xDEAD;
+            pthread_mutex_unlock(&lwprot_mutex);
+        }
+    }
+}
+
+/*-----------------------------------------------------------------------------------*/
+
+#ifndef MAX_JIFFY_OFFSET
+#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+unsigned long
+sys_jiffies(void)
+{
+    struct timeval tv;
+    unsigned long sec = tv.tv_sec;
+    long usec = tv.tv_usec;
+
+    gettimeofday(&tv,NULL);
+
+    if (sec >= (MAX_JIFFY_OFFSET / HZ))
+       return MAX_JIFFY_OFFSET;
+    usec += 1000000L / HZ - 1;
+    usec /= 1000000L / HZ;
+    return HZ * sec + usec;
+}
+
+#if PPP_DEBUG
+
+#include <stdarg.h>
+
+void ppp_trace(int level, const char *format, ...)
+{
+    va_list args;
+
+    (void)level;
+    va_start(args, format);
+    vprintf(format, args);
+    va_end(args);
+}
+#endif
diff --git a/palacios/src/lwip/build/.depend b/palacios/src/lwip/build/.depend
new file mode 100644 (file)
index 0000000..6dc6968
--- /dev/null
@@ -0,0 +1,310 @@
+mem.o: ../core/mem.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/def.h \
+  ../include/lwip/mem.h ../include/lwip/sys.h ../include/lwip/err.h \
+  ../include/arch/sys_arch.h ../include/lwip/stats.h \
+  ../include/lwip/mem.h ../include/lwip/memp.h ../include/lwip/memp_std.h
+memp.o: ../core/memp.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/lwip/udp.h ../include/lwip/pbuf.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/lwip/err.h ../include/lwip/raw.h ../include/lwip/tcp.h \
+  ../include/lwip/sys.h ../include/arch/sys_arch.h ../include/lwip/mem.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/igmp.h ../include/lwip/api.h \
+  ../include/lwip/netbuf.h ../include/lwip/api_msg.h \
+  ../include/ipv4/lwip/igmp.h ../include/lwip/api.h \
+  ../include/lwip/tcpip.h ../include/lwip/api_msg.h \
+  ../include/lwip/netifapi.h ../include/lwip/sys.h \
+  ../include/lwip/stats.h ../include/lwip/memp.h \
+  ../include/netif/etharp.h ../include/lwip/opt.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip.h ../include/ipv4/lwip/ip_frag.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/memp_std.h
+netif.o: ../core/netif.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/def.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/lwip/netif.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/pbuf.h \
+  ../include/lwip/tcp.h ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/lwip/mem.h ../include/ipv4/lwip/ip.h ../include/lwip/def.h \
+  ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/netif.h \
+  ../include/lwip/snmp.h ../include/lwip/netif.h ../include/lwip/udp.h \
+  ../include/ipv4/lwip/igmp.h ../include/netif/etharp.h \
+  ../include/lwip/opt.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip.h
+pbuf.o: ../core/pbuf.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/stats.h \
+  ../include/lwip/mem.h ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/lwip/def.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/pbuf.h ../include/lwip/err.h ../include/lwip/sys.h \
+  ../include/arch/sys_arch.h ../include/arch/perf.h
+stats.o: ../core/stats.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h
+sys.o: ../core/sys.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/sys.h \
+  ../include/lwip/err.h ../include/arch/sys_arch.h ../include/lwip/def.h \
+  ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/lwip/tcpip.h ../include/lwip/api_msg.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/lwip/sys.h ../include/ipv4/lwip/igmp.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/inet.h ../include/lwip/pbuf.h \
+  ../include/lwip/pbuf.h ../include/lwip/api.h ../include/lwip/netbuf.h \
+  ../include/lwip/netifapi.h
+tcp.o: ../core/tcp.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/def.h \
+  ../include/lwip/mem.h ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/lwip/snmp.h ../include/lwip/netif.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/pbuf.h ../include/lwip/udp.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/def.h ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/lwip/tcp.h ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/lwip/mem.h ../include/ipv4/lwip/icmp.h \
+  ../include/lwip/netif.h
+tcp_in.o: ../core/tcp_in.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/tcp.h \
+  ../include/lwip/sys.h ../include/lwip/err.h ../include/arch/sys_arch.h \
+  ../include/lwip/mem.h ../include/lwip/pbuf.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/opt.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/def.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/netif.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/inet_chksum.h ../include/lwip/stats.h \
+  ../include/lwip/memp.h ../include/lwip/snmp.h ../include/lwip/netif.h \
+  ../include/lwip/udp.h ../include/arch/perf.h
+tcp_out.o: ../core/tcp_out.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/tcp.h \
+  ../include/lwip/sys.h ../include/lwip/err.h ../include/arch/sys_arch.h \
+  ../include/lwip/mem.h ../include/lwip/pbuf.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/opt.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/def.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/lwip/sys.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/inet_chksum.h \
+  ../include/lwip/stats.h ../include/lwip/memp.h ../include/lwip/snmp.h \
+  ../include/lwip/netif.h ../include/lwip/udp.h
+udp.o: ../core/udp.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/udp.h \
+  ../include/lwip/pbuf.h ../include/lwip/err.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/lwip/err.h ../include/lwip/def.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/inet_chksum.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/icmp.h \
+  ../include/lwip/netif.h ../include/lwip/stats.h ../include/lwip/mem.h \
+  ../include/lwip/memp.h ../include/lwip/snmp.h ../include/lwip/udp.h \
+  ../include/arch/perf.h ../include/lwip/dhcp.h
+init.o: ../core/init.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/init.h \
+  ../include/lwip/stats.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/lwip/sys.h ../include/lwip/err.h \
+  ../include/arch/sys_arch.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/pbuf.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/pbuf.h ../include/lwip/sockets.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/lwip/err.h ../include/lwip/raw.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/udp.h ../include/lwip/netif.h ../include/lwip/tcp.h \
+  ../include/lwip/sys.h ../include/ipv4/lwip/icmp.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/autoip.h \
+  ../include/ipv4/lwip/igmp.h ../include/lwip/dns.h \
+  ../include/netif/etharp.h ../include/lwip/opt.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip.h
+icmp.o: ../core/ipv4/icmp.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/opt.h \
+  ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/pbuf.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/inet_chksum.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/def.h ../include/lwip/err.h ../include/lwip/def.h \
+  ../include/lwip/stats.h ../include/lwip/mem.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/lwip/snmp.h \
+  ../include/lwip/netif.h ../include/lwip/udp.h ../include/ipv4/lwip/ip.h
+ip.o: ../core/ipv4/ip.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/opt.h ../include/lwip/def.h ../include/lwip/pbuf.h \
+  ../include/lwip/err.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/err.h ../include/lwip/def.h ../include/lwip/mem.h \
+  ../include/ipv4/lwip/ip_frag.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/pbuf.h ../include/ipv4/lwip/ip.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/inet_chksum.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/icmp.h \
+  ../include/ipv4/lwip/igmp.h ../include/lwip/raw.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/udp.h ../include/lwip/netif.h \
+  ../include/lwip/tcp.h ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/lwip/mem.h ../include/ipv4/lwip/icmp.h \
+  ../include/lwip/snmp.h ../include/lwip/udp.h ../include/lwip/dhcp.h \
+  ../include/lwip/stats.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/arch/perf.h
+inet.o: ../core/ipv4/inet.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h \
+  ../include/ipv4/lwip/inet.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/ip_addr.h
+ip_addr.o: ../core/ipv4/ip_addr.c ../include/lwip/opt.h \
+  ../include/lwipopts.h ../include/lwipopts.h ../include/lwip/debug.h \
+  ../include/lwip/arch.h ../include/arch/cc.h \
+  ../../../include/libc/string.h ../include/lwip/opt.h \
+  ../include/lwip/debug.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/opt.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/lwip/err.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/ipv4/lwip/inet.h ../include/lwip/pbuf.h
+inet_chksum.o: ../core/ipv4/inet_chksum.c ../include/lwip/opt.h \
+  ../include/lwipopts.h ../include/lwipopts.h ../include/lwip/debug.h \
+  ../include/lwip/arch.h ../include/arch/cc.h \
+  ../../../include/libc/string.h ../include/lwip/opt.h \
+  ../include/lwip/debug.h ../include/ipv4/lwip/inet_chksum.h \
+  ../include/lwip/opt.h ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h
+api_lib.o: ../api/api_lib.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/api.h \
+  ../include/lwip/netbuf.h ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/lwip/tcpip.h ../include/lwip/api_msg.h \
+  ../include/ipv4/lwip/igmp.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/pbuf.h ../include/lwip/api.h ../include/lwip/netifapi.h \
+  ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/err.h \
+  ../include/lwip/raw.h ../include/ipv4/lwip/ip.h ../include/lwip/udp.h \
+  ../include/lwip/netif.h ../include/lwip/tcp.h ../include/lwip/mem.h \
+  ../include/ipv4/lwip/icmp.h
+api_msg.o: ../api/api_msg.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/api_msg.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/lwip/err.h ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/ipv4/lwip/igmp.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/pbuf.h ../include/lwip/pbuf.h ../include/lwip/api.h \
+  ../include/lwip/netbuf.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/def.h ../include/lwip/err.h ../include/lwip/udp.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/ip.h ../include/lwip/tcp.h \
+  ../include/lwip/mem.h ../include/ipv4/lwip/icmp.h ../include/lwip/raw.h \
+  ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/lwip/tcpip.h ../include/lwip/api_msg.h \
+  ../include/lwip/netifapi.h ../include/ipv4/lwip/igmp.h \
+  ../include/lwip/dns.h
+tcpip.o: ../api/tcpip.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/sys.h \
+  ../include/lwip/err.h ../include/arch/sys_arch.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_frag.h ../include/lwip/opt.h \
+  ../include/lwip/err.h ../include/lwip/pbuf.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/tcp.h \
+  ../include/lwip/sys.h ../include/lwip/mem.h ../include/ipv4/lwip/ip.h \
+  ../include/ipv4/lwip/icmp.h ../include/ipv4/lwip/autoip.h \
+  ../include/lwip/dhcp.h ../include/ipv4/lwip/igmp.h \
+  ../include/lwip/dns.h ../include/lwip/tcpip.h ../include/lwip/api_msg.h \
+  ../include/ipv4/lwip/igmp.h ../include/lwip/api.h \
+  ../include/lwip/netbuf.h ../include/lwip/netifapi.h \
+  ../include/lwip/init.h ../include/netif/etharp.h ../include/lwip/opt.h \
+  ../include/lwip/pbuf.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/netif.h ../include/ipv4/lwip/ip.h \
+  ../include/netif/ppp_oe.h
+err.o: ../api/err.c ../include/lwip/err.h ../include/lwip/opt.h \
+  ../include/lwipopts.h ../include/lwipopts.h ../include/lwip/debug.h \
+  ../include/lwip/arch.h ../include/arch/cc.h \
+  ../../../include/libc/string.h ../include/lwip/debug.h
+sockets.o: ../api/sockets.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/sockets.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/inet.h ../include/ipv4/lwip/ip_addr.h \
+  ../include/lwip/api.h ../include/lwip/netbuf.h ../include/lwip/pbuf.h \
+  ../include/lwip/err.h ../include/lwip/sys.h ../include/arch/sys_arch.h \
+  ../include/lwip/sys.h ../include/ipv4/lwip/igmp.h \
+  ../include/lwip/netif.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/inet.h ../include/lwip/tcp.h ../include/lwip/mem.h \
+  ../include/ipv4/lwip/ip.h ../include/lwip/def.h ../include/lwip/err.h \
+  ../include/ipv4/lwip/icmp.h ../include/lwip/raw.h ../include/lwip/udp.h \
+  ../include/lwip/netif.h ../include/lwip/tcpip.h \
+  ../include/lwip/api_msg.h ../include/ipv4/lwip/igmp.h \
+  ../include/lwip/api.h ../include/lwip/netifapi.h ../include/lwip/arch.h
+netbuf.o: ../api/netbuf.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h ../include/lwip/netbuf.h \
+  ../include/lwip/pbuf.h ../include/lwip/err.h ../include/lwip/memp.h \
+  ../include/lwip/memp_std.h
+netdb.o: ../api/netdb.c ../include/lwip/netdb.h ../include/lwip/opt.h \
+  ../include/lwipopts.h ../include/lwipopts.h ../include/lwip/debug.h \
+  ../include/lwip/arch.h ../include/arch/cc.h \
+  ../../../include/libc/string.h ../include/lwip/debug.h
+loopif.o: ../netif/loopif.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h
+etharp.o: ../netif/etharp.c ../include/lwip/opt.h ../include/lwipopts.h \
+  ../include/lwipopts.h ../include/lwip/debug.h ../include/lwip/arch.h \
+  ../include/arch/cc.h ../../../include/libc/string.h \
+  ../include/lwip/opt.h ../include/lwip/debug.h \
+  ../include/ipv4/lwip/inet.h ../include/lwip/opt.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/def.h ../include/lwip/pbuf.h ../include/lwip/err.h \
+  ../include/lwip/err.h ../include/lwip/stats.h ../include/lwip/mem.h \
+  ../include/lwip/memp.h ../include/lwip/memp_std.h \
+  ../include/lwip/snmp.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/ipv4/lwip/inet.h \
+  ../include/lwip/pbuf.h ../include/lwip/udp.h ../include/ipv4/lwip/ip.h \
+  ../include/lwip/dhcp.h ../include/ipv4/lwip/autoip.h \
+  ../include/netif/etharp.h ../include/lwip/opt.h ../include/lwip/pbuf.h \
+  ../include/ipv4/lwip/ip_addr.h ../include/lwip/netif.h \
+  ../include/ipv4/lwip/ip.h
index 73662b2..3c2ee0f 100644 (file)
@@ -86,8 +86,8 @@ depend dep: .depend
 
 include .depend
 
-$(LWIPLIB): $(LWIPOBJS)
-       $(CC) -g -nostartfiles -shared -static $^ -o $@ 
+##$(LWIPLIB): $(LWIPOBJS)
+##     $(CC) -g -nostartfiles -shared -static $^ -o $@ 
 
 .depend: $(LWIPFILES)
        $(CC) $(CFLAGS) -MM $^ > .depend || rm -f .depend
diff --git a/palacios/src/lwip/build/api_lib.o b/palacios/src/lwip/build/api_lib.o
new file mode 100644 (file)
index 0000000..345a707
Binary files /dev/null and b/palacios/src/lwip/build/api_lib.o differ
diff --git a/palacios/src/lwip/build/api_msg.o b/palacios/src/lwip/build/api_msg.o
new file mode 100644 (file)
index 0000000..ae8048d
Binary files /dev/null and b/palacios/src/lwip/build/api_msg.o differ
diff --git a/palacios/src/lwip/build/err.o b/palacios/src/lwip/build/err.o
new file mode 100644 (file)
index 0000000..a62e642
Binary files /dev/null and b/palacios/src/lwip/build/err.o differ
diff --git a/palacios/src/lwip/build/errno.h b/palacios/src/lwip/build/errno.h
new file mode 100644 (file)
index 0000000..f33b0c9
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/*
+ *     ISO C99 Standard: 7.5 Errors    <errno.h>
+ */
+
+#ifndef        _ERRNO_H
+
+/* The includer defined __need_Emath if he wants only the definitions
+   of EDOM and ERANGE, and not everything else.  */
+#ifndef        __need_Emath
+# define _ERRNO_H      1
+# include <features.h>
+#endif
+
+__BEGIN_DECLS
+
+/* Get the error number constants from the system-specific file.
+   This file will test __need_Emath and _ERRNO_H.  */
+#include <bits/errno.h>
+#undef __need_Emath
+
+#ifdef _ERRNO_H
+
+/* Declare the `errno' variable, unless it's defined as a macro by
+   bits/errno.h.  This is the case in GNU, where it is a per-thread
+   variable.  This redeclaration using the macro still works, but it
+   will be a function declaration without a prototype and may trigger
+   a -Wstrict-prototypes warning.  */
+#ifndef        errno
+extern int errno;
+#endif
+
+#ifdef __USE_GNU
+
+/* The full and simple forms of the name with which the program was
+   invoked.  These variables are set up automatically at startup based on
+   the value of ARGV[0] (this works only if you use GNU ld).  */
+extern char *program_invocation_name, *program_invocation_short_name;
+#endif /* __USE_GNU */
+#endif /* _ERRNO_H */
+
+__END_DECLS
+
+#endif /* _ERRNO_H */
+
+/* The Hurd <bits/errno.h> defines `error_t' as an enumerated type so
+   that printing `error_t' values in the debugger shows the names.  We
+   might need this definition sometimes even if this file was included
+   before.  */
+#if defined __USE_GNU || defined __need_error_t
+# ifndef __error_t_defined
+typedef int error_t;
+#  define __error_t_defined    1
+# endif
+# undef __need_error_t
+#endif
diff --git a/palacios/src/lwip/build/etharp.o b/palacios/src/lwip/build/etharp.o
new file mode 100644 (file)
index 0000000..0f8217b
Binary files /dev/null and b/palacios/src/lwip/build/etharp.o differ
diff --git a/palacios/src/lwip/build/icmp.o b/palacios/src/lwip/build/icmp.o
new file mode 100644 (file)
index 0000000..dde943b
Binary files /dev/null and b/palacios/src/lwip/build/icmp.o differ
diff --git a/palacios/src/lwip/build/inet.o b/palacios/src/lwip/build/inet.o
new file mode 100644 (file)
index 0000000..7c212d2
Binary files /dev/null and b/palacios/src/lwip/build/inet.o differ
diff --git a/palacios/src/lwip/build/inet_chksum.o b/palacios/src/lwip/build/inet_chksum.o
new file mode 100644 (file)
index 0000000..e01beb3
Binary files /dev/null and b/palacios/src/lwip/build/inet_chksum.o differ
diff --git a/palacios/src/lwip/build/init.o b/palacios/src/lwip/build/init.o
new file mode 100644 (file)
index 0000000..e619f5f
Binary files /dev/null and b/palacios/src/lwip/build/init.o differ
diff --git a/palacios/src/lwip/build/ip.o b/palacios/src/lwip/build/ip.o
new file mode 100644 (file)
index 0000000..1f68888
Binary files /dev/null and b/palacios/src/lwip/build/ip.o differ
diff --git a/palacios/src/lwip/build/ip_addr.o b/palacios/src/lwip/build/ip_addr.o
new file mode 100644 (file)
index 0000000..77624ca
Binary files /dev/null and b/palacios/src/lwip/build/ip_addr.o differ
diff --git a/palacios/src/lwip/build/loopif.o b/palacios/src/lwip/build/loopif.o
new file mode 100644 (file)
index 0000000..b184d24
Binary files /dev/null and b/palacios/src/lwip/build/loopif.o differ
diff --git a/palacios/src/lwip/build/mem.o b/palacios/src/lwip/build/mem.o
new file mode 100644 (file)
index 0000000..3b6780f
Binary files /dev/null and b/palacios/src/lwip/build/mem.o differ
diff --git a/palacios/src/lwip/build/memp.o b/palacios/src/lwip/build/memp.o
new file mode 100644 (file)
index 0000000..4592e78
Binary files /dev/null and b/palacios/src/lwip/build/memp.o differ
diff --git a/palacios/src/lwip/build/netbuf.o b/palacios/src/lwip/build/netbuf.o
new file mode 100644 (file)
index 0000000..afa8fa3
Binary files /dev/null and b/palacios/src/lwip/build/netbuf.o differ
diff --git a/palacios/src/lwip/build/netdb.o b/palacios/src/lwip/build/netdb.o
new file mode 100644 (file)
index 0000000..4d7c40d
Binary files /dev/null and b/palacios/src/lwip/build/netdb.o differ
diff --git a/palacios/src/lwip/build/netif.o b/palacios/src/lwip/build/netif.o
new file mode 100644 (file)
index 0000000..98a18e2
Binary files /dev/null and b/palacios/src/lwip/build/netif.o differ
diff --git a/palacios/src/lwip/build/pbuf.o b/palacios/src/lwip/build/pbuf.o
new file mode 100644 (file)
index 0000000..97e3eb8
Binary files /dev/null and b/palacios/src/lwip/build/pbuf.o differ
diff --git a/palacios/src/lwip/build/sockets.o b/palacios/src/lwip/build/sockets.o
new file mode 100644 (file)
index 0000000..52c0cf1
Binary files /dev/null and b/palacios/src/lwip/build/sockets.o differ
diff --git a/palacios/src/lwip/build/stats.o b/palacios/src/lwip/build/stats.o
new file mode 100644 (file)
index 0000000..e8dcec6
Binary files /dev/null and b/palacios/src/lwip/build/stats.o differ
diff --git a/palacios/src/lwip/build/sys.o b/palacios/src/lwip/build/sys.o
new file mode 100644 (file)
index 0000000..f73f62d
Binary files /dev/null and b/palacios/src/lwip/build/sys.o differ
diff --git a/palacios/src/lwip/build/tcp.o b/palacios/src/lwip/build/tcp.o
new file mode 100644 (file)
index 0000000..3878ebf
Binary files /dev/null and b/palacios/src/lwip/build/tcp.o differ
diff --git a/palacios/src/lwip/build/tcp_in.o b/palacios/src/lwip/build/tcp_in.o
new file mode 100644 (file)
index 0000000..b98de60
Binary files /dev/null and b/palacios/src/lwip/build/tcp_in.o differ
diff --git a/palacios/src/lwip/build/tcp_out.o b/palacios/src/lwip/build/tcp_out.o
new file mode 100644 (file)
index 0000000..46e0187
Binary files /dev/null and b/palacios/src/lwip/build/tcp_out.o differ
diff --git a/palacios/src/lwip/build/tcpip.o b/palacios/src/lwip/build/tcpip.o
new file mode 100644 (file)
index 0000000..3583a59
Binary files /dev/null and b/palacios/src/lwip/build/tcpip.o differ
diff --git a/palacios/src/lwip/build/udp.o b/palacios/src/lwip/build/udp.o
new file mode 100644 (file)
index 0000000..4f67516
Binary files /dev/null and b/palacios/src/lwip/build/udp.o differ
index 32f3953..73eb7d3 100644 (file)
 #define __ARCH_CC_H__
 
 /* Include some files for defining library routines */
+
 #include <string.h>
-//#include <sys/time.h>
+
+extern int fflush(FILE *file);
+extern int printf(char *fmt, ...);
+extern void abort (void);
+
 
 /* Define platform endianness */
 #ifndef BYTE_ORDER
@@ -69,9 +74,9 @@ typedef u32_t mem_ptr_t;
 //#include <stdio.h>
 //#include <stdlib.h>
 /* Plaform specific diagnostic output */
-#define LWIP_PLATFORM_DIAG(x)  do {printf x;} while(0)
+#define LWIP_PLATFORM_DIAG(x)  //do {printf x;} while(0)
 
-#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
-                                     x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
+#define LWIP_PLATFORM_ASSERT(x)   do {printf("Assertion \"%s\" failed at line %d in %s\n", \
+                                   x, __LINE__, __FILE__); fflush(NULL); abort();} while(0) 
                                     
 #endif /* __ARCH_CC_H__ */
index b50fcc7..32f3953 100644 (file)
@@ -34,7 +34,7 @@
 
 /* Include some files for defining library routines */
 #include <string.h>
-#include <sys/time.h>
+//#include <sys/time.h>
 
 /* Define platform endianness */
 #ifndef BYTE_ORDER
@@ -66,8 +66,8 @@ typedef u32_t mem_ptr_t;
 #define PACK_STRUCT_END
 
 /* prototypes for printf() and abort() */
-#include <stdio.h>
-#include <stdlib.h>
+//#include <stdio.h>
+//#include <stdlib.h>
 /* Plaform specific diagnostic output */
 #define LWIP_PLATFORM_DIAG(x)  do {printf x;} while(0)
 
index 7d1400b..67d8ee1 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "arch/cc.h"
 
+#include "lwip/opt.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -63,6 +65,8 @@ extern "C" {
 #define LWIP_UNUSED_ARG(x) (void)x
 #endif /* LWIP_UNUSED_ARG */ 
 
+//weird thing, I already defined it in lwipopts.h, does not work? Lei
+#define LWIP_PROVIDE_ERRNO 1
 
 #ifdef LWIP_PROVIDE_ERRNO
 
diff --git a/palacios/src/lwip/include/lwip/arch.h~ b/palacios/src/lwip/include/lwip/arch.h~
new file mode 100644 (file)
index 0000000..5492668
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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_ARCH_H__
+#define __LWIP_ARCH_H__
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#endif
+
+#include "arch/cc.h"
+
+#include "lwipopts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef PACK_STRUCT_BEGIN
+#define PACK_STRUCT_BEGIN
+#endif /* PACK_STRUCT_BEGIN */
+
+#ifndef PACK_STRUCT_END
+#define PACK_STRUCT_END
+#endif /* PACK_STRUCT_END */
+
+#ifndef PACK_STRUCT_FIELD
+#define PACK_STRUCT_FIELD(x) x
+#endif /* PACK_STRUCT_FIELD */
+
+
+#ifndef LWIP_UNUSED_ARG
+#define LWIP_UNUSED_ARG(x) (void)x
+#endif /* LWIP_UNUSED_ARG */ 
+
+
+#define LWIP_PROVIDE_ERRNO 1
+
+#ifdef LWIP_PROVIDE_ERRNO
+
+#define  EPERM     1  /* Operation not permitted */
+#define  ENOENT     2  /* No such file or directory */
+#define  ESRCH     3  /* No such process */
+#define  EINTR     4  /* Interrupted system call */
+#define  EIO     5  /* I/O error */
+#define  ENXIO     6  /* No such device or address */
+#define  E2BIG     7  /* Arg list too long */
+#define  ENOEXEC     8  /* Exec format error */
+#define  EBADF     9  /* Bad file number */
+#define  ECHILD    10  /* No child processes */
+#define  EAGAIN    11  /* Try again */
+#define  ENOMEM    12  /* Out of memory */
+#define  EACCES    13  /* Permission denied */
+#define  EFAULT    14  /* Bad address */
+#define  ENOTBLK    15  /* Block device required */
+#define  EBUSY    16  /* Device or resource busy */
+#define  EEXIST    17  /* File exists */
+#define  EXDEV    18  /* Cross-device link */
+#define  ENODEV    19  /* No such device */
+#define  ENOTDIR    20  /* Not a directory */
+#define  EISDIR    21  /* Is a directory */
+#define  EINVAL    22  /* Invalid argument */
+#define  ENFILE    23  /* File table overflow */
+#define  EMFILE    24  /* Too many open files */
+#define  ENOTTY    25  /* Not a typewriter */
+#define  ETXTBSY    26  /* Text file busy */
+#define  EFBIG    27  /* File too large */
+#define  ENOSPC    28  /* No space left on device */
+#define  ESPIPE    29  /* Illegal seek */
+#define  EROFS    30  /* Read-only file system */
+#define  EMLINK    31  /* Too many links */
+#define  EPIPE    32  /* Broken pipe */
+#define  EDOM    33  /* Math argument out of domain of func */
+#define  ERANGE    34  /* Math result not representable */
+#define  EDEADLK    35  /* Resource deadlock would occur */
+#define  ENAMETOOLONG  36  /* File name too long */
+#define  ENOLCK    37  /* No record locks available */
+#define  ENOSYS    38  /* Function not implemented */
+#define  ENOTEMPTY  39  /* Directory not empty */
+#define  ELOOP    40  /* Too many symbolic links encountered */
+#define  EWOULDBLOCK  EAGAIN  /* Operation would block */
+#define  ENOMSG    42  /* No message of desired type */
+#define  EIDRM    43  /* Identifier removed */
+#define  ECHRNG    44  /* Channel number out of range */
+#define  EL2NSYNC  45  /* Level 2 not synchronized */
+#define  EL3HLT    46  /* Level 3 halted */
+#define  EL3RST    47  /* Level 3 reset */
+#define  ELNRNG    48  /* Link number out of range */
+#define  EUNATCH    49  /* Protocol driver not attached */
+#define  ENOCSI    50  /* No CSI structure available */
+#define  EL2HLT    51  /* Level 2 halted */
+#define  EBADE    52  /* Invalid exchange */
+#define  EBADR    53  /* Invalid request descriptor */
+#define  EXFULL    54  /* Exchange full */
+#define  ENOANO    55  /* No anode */
+#define  EBADRQC    56  /* Invalid request code */
+#define  EBADSLT    57  /* Invalid slot */
+
+#define  EDEADLOCK  EDEADLK
+
+#define  EBFONT    59  /* Bad font file format */
+#define  ENOSTR    60  /* Device not a stream */
+#define  ENODATA    61  /* No data available */
+#define  ETIME    62  /* Timer expired */
+#define  ENOSR    63  /* Out of streams resources */
+#define  ENONET    64  /* Machine is not on the network */
+#define  ENOPKG    65  /* Package not installed */
+#define  EREMOTE    66  /* Object is remote */
+#define  ENOLINK    67  /* Link has been severed */
+#define  EADV    68  /* Advertise error */
+#define  ESRMNT    69  /* Srmount error */
+#define  ECOMM    70  /* Communication error on send */
+#define  EPROTO    71  /* Protocol error */
+#define  EMULTIHOP  72  /* Multihop attempted */
+#define  EDOTDOT    73  /* RFS specific error */
+#define  EBADMSG    74  /* Not a data message */
+#define  EOVERFLOW  75  /* Value too large for defined data type */
+#define  ENOTUNIQ  76  /* Name not unique on network */
+#define  EBADFD    77  /* File descriptor in bad state */
+#define  EREMCHG    78  /* Remote address changed */
+#define  ELIBACC    79  /* Can not access a needed shared library */
+#define  ELIBBAD    80  /* Accessing a corrupted shared library */
+#define  ELIBSCN    81  /* .lib section in a.out corrupted */
+#define  ELIBMAX    82  /* Attempting to link in too many shared libraries */
+#define  ELIBEXEC  83  /* Cannot exec a shared library directly */
+#define  EILSEQ    84  /* Illegal byte sequence */
+#define  ERESTART  85  /* Interrupted system call should be restarted */
+#define  ESTRPIPE  86  /* Streams pipe error */
+#define  EUSERS    87  /* Too many users */
+#define  ENOTSOCK  88  /* Socket operation on non-socket */
+#define  EDESTADDRREQ  89  /* Destination address required */
+#define  EMSGSIZE  90  /* Message too long */
+#define  EPROTOTYPE  91  /* Protocol wrong type for socket */
+#define  ENOPROTOOPT  92  /* Protocol not available */
+#define  EPROTONOSUPPORT  93  /* Protocol not supported */
+#define  ESOCKTNOSUPPORT  94  /* Socket type not supported */
+#define  EOPNOTSUPP  95  /* Operation not supported on transport endpoint */
+#define  EPFNOSUPPORT  96  /* Protocol family not supported */
+#define  EAFNOSUPPORT  97  /* Address family not supported by protocol */
+#define  EADDRINUSE  98  /* Address already in use */
+#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */
+#define  ENETDOWN  100  /* Network is down */
+#define  ENETUNREACH  101  /* Network is unreachable */
+#define  ENETRESET  102  /* Network dropped connection because of reset */
+#define  ECONNABORTED  103  /* Software caused connection abort */
+#define  ECONNRESET  104  /* Connection reset by peer */
+#define  ENOBUFS    105  /* No buffer space available */
+#define  EISCONN    106  /* Transport endpoint is already connected */
+#define  ENOTCONN  107  /* Transport endpoint is not connected */
+#define  ESHUTDOWN  108  /* Cannot send after transport endpoint shutdown */
+#define  ETOOMANYREFS  109  /* Too many references: cannot splice */
+#define  ETIMEDOUT  110  /* Connection timed out */
+#define  ECONNREFUSED  111  /* Connection refused */
+#define  EHOSTDOWN  112  /* Host is down */
+#define  EHOSTUNREACH  113  /* No route to host */
+#define  EALREADY  114  /* Operation already in progress */
+#define  EINPROGRESS  115  /* Operation now in progress */
+#define  ESTALE    116  /* Stale NFS file handle */
+#define  EUCLEAN    117  /* Structure needs cleaning */
+#define  ENOTNAM    118  /* Not a XENIX named type file */
+#define  ENAVAIL    119  /* No XENIX semaphores available */
+#define  EISNAM    120  /* Is a named type file */
+#define  EREMOTEIO  121  /* Remote I/O error */
+#define  EDQUOT    122  /* Quota exceeded */
+
+#define  ENOMEDIUM  123  /* No medium found */
+#define  EMEDIUMTYPE  124  /* Wrong medium type */
+
+
+#define ENSROK    0 /* DNS server returned answer with no data */
+#define ENSRNODATA  160 /* DNS server returned answer with no data */
+#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
+#define ENSRSERVFAIL 162  /* DNS server returned general failure */
+#define ENSRNOTFOUND 163  /* Domain name not found */
+#define ENSRNOTIMP  164 /* DNS server does not implement requested operation */
+#define ENSRREFUSED 165 /* DNS server refused query */
+#define ENSRBADQUERY 166  /* Misformatted DNS query */
+#define ENSRBADNAME 167 /* Misformatted domain name */
+#define ENSRBADFAMILY 168 /* Unsupported address family */
+#define ENSRBADRESP 169 /* Misformatted DNS reply */
+#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
+#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
+#define ENSROF    172 /* End of file */
+#define ENSRFILE  173 /* Error reading file */
+#define ENSRNOMEM 174 /* Out of memory */
+#define ENSRDESTRUCTION 175 /* Application terminated lookup */
+#define ENSRQUERYDOMAINTOOLONG  176 /* Domain name is too long */
+#define ENSRCNAMELOOP 177 /* Domain name is too long */
+
+#ifndef errno
+extern int errno;
+#endif
+
+#endif /* LWIP_PROVIDE_ERRNO */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LWIP_ARCH_H__ */
index 603b62f..b870399 100644 (file)
@@ -68,7 +68,24 @@ struct sockaddr {
 #define SOCK_STREAM     1
 #define SOCK_DGRAM      2
 #define SOCK_RAW        3
-
+       
+#if 0  /* already defined in lwip/arch.h */
+/* added by Lei */
+#define ENOOK          0      /* No error, everything OK. */
+#define ENOMEM        -1      /* Out of memory error.     */
+#define ENOBUFS       -2      /* Buffer error.            */
+#define EHOSTUNREACH  -3      /* Routing problem.         */
+#define ECONNABORTED  -4      /* Connection aborted.      */
+#define ECONNRESET    -5      /* Connection reset.        */
+#define ESHUTDOWN     -6      /* Connection closed.       */
+#define ENOTCONN      -7      /* Not connected.           */
+#define EINVAL        -8      /* Illegal value.           */
+#define EIO           -9      /* Illegal argument.        */
+#define EADDRINUSE    -10     /* Address in use.          */
+#define ETIMEDOUT     -13     /* Timeout                  */
+#define EINPROGRESS   -14     /* Operation in progress    */
+#endif
+       
 /*
  * Option flags per-socket. These must match the SOF_ flags in ip.h!
  */
@@ -297,8 +314,7 @@ int lwip_sendto(int s, const void *dataptr, int size, unsigned int flags,
     struct sockaddr *to, socklen_t tolen);
 int lwip_socket(int domain, int type, int protocol);
 int lwip_write(int s, const void *dataptr, int size);
-int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-                struct timeval *timeout);
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
 int lwip_ioctl(int s, long cmd, void *argp);
 
 #if LWIP_COMPAT_SOCKETS
diff --git a/palacios/src/lwip/include/lwip/sockets.h~ b/palacios/src/lwip/include/lwip/sockets.h~
new file mode 100644 (file)
index 0000000..a62ccd5
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * 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_SOCKETS_H__
+#define __LWIP_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/inet.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* members are in network byte order */
+struct sockaddr_in {
+  u8_t sin_len;
+  u8_t sin_family;
+  u16_t sin_port;
+  struct in_addr sin_addr;
+  char sin_zero[8];
+};
+
+struct sockaddr {
+  u8_t sa_len;
+  u8_t sa_family;
+  char sa_data[14];
+};
+
+#ifndef socklen_t
+#  define socklen_t u32_t
+#endif
+
+/* Socket protocol types (TCP/UDP/RAW) */
+#define SOCK_STREAM     1
+#define SOCK_DGRAM      2
+#define SOCK_RAW        3
+       
+#if 0  /* already defined in lwip/arch.h */
+/* added by Lei */
+#define ENOOK          0      /* No error, everything OK. */
+#define ENOMEM        -1      /* Out of memory error.     */
+#define ENOBUFS       -2      /* Buffer error.            */
+#define EHOSTUNREACH  -3      /* Routing problem.         */
+#define ECONNABORTED  -4      /* Connection aborted.      */
+#define ECONNRESET    -5      /* Connection reset.        */
+#define ESHUTDOWN     -6      /* Connection closed.       */
+#define ENOTCONN      -7      /* Not connected.           */
+#define EINVAL        -8      /* Illegal value.           */
+#define EIO           -9      /* Illegal argument.        */
+#define EADDRINUSE    -10     /* Address in use.          */
+#define ETIMEDOUT     -13     /* Timeout                  */
+#define EINPROGRESS   -14     /* Operation in progress    */
+#endif
+       
+/*
+ * Option flags per-socket. These must match the SOF_ flags in ip.h!
+ */
+#define  SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info recording */
+#define  SO_ACCEPTCONN  0x0002 /* socket has had listen() */
+#define  SO_REUSEADDR   0x0004 /* Unimplemented: allow local address reuse */
+#define  SO_KEEPALIVE   0x0008 /* keep connections alive */
+#define  SO_DONTROUTE   0x0010 /* Unimplemented: just use interface addresses */
+#define  SO_BROADCAST   0x0020 /* Unimplemented: permit sending of broadcast msgs */
+#define  SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
+#define  SO_LINGER      0x0080 /* linger on close if data present */
+#define  SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in line */
+#define  SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port reuse */
+
+#define SO_DONTLINGER   ((int)(~SO_LINGER))
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#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    /* Unimplemented: 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 */
+};
+
+/*
+ * 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
+#define PF_INET         AF_INET
+#define PF_UNSPEC       AF_UNSPEC
+
+#define IPPROTO_IP      0
+#define IPPROTO_TCP     6
+#define IPPROTO_UDP     17
+#define IPPROTO_UDPLITE 136
+
+#define INADDR_ANY       0
+#define INADDR_BROADCAST 0xffffffff
+
+/* 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_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_IGMP
+/*
+ * Options and types for UDP multicast traffic handling
+ */
+#define IP_ADD_MEMBERSHIP  3
+#define IP_DROP_MEMBERSHIP 4
+#define IP_MULTICAST_TTL   5
+#define IP_MULTICAST_IF    6
+#define IP_MULTICAST_LOOP  7
+
+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 */
+
+/* Unimplemented for now... */
+#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
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (Unimplemented)
+ */
+#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
+
+/* Socket flags: */
+#ifndef O_NONBLOCK
+#define O_NONBLOCK    04000U
+#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 FD_SET(n, p)  ((p)->fd_bits[(n)/8] |=  (1 << ((n) & 7)))
+  #define FD_CLR(n, p)  ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7)))
+  #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] &   (1 << ((n) & 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;
+
+#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 */
+
+void lwip_socket_init(void);
+
+int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+int lwip_bind(int s, struct sockaddr *name, socklen_t namelen);
+int lwip_shutdown(int s, int how);
+int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
+int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
+int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
+int lwip_close(int s);
+int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
+int lwip_listen(int s, int backlog);
+int lwip_recv(int s, void *mem, int len, unsigned int flags);
+int lwip_read(int s, void *mem, int len);
+int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
+      struct sockaddr *from, socklen_t *fromlen);
+int lwip_send(int s, const void *dataptr, int size, unsigned int flags);
+int lwip_sendto(int s, const void *dataptr, int size, unsigned int flags,
+    struct sockaddr *to, socklen_t tolen);
+int lwip_socket(int domain, int type, int protocol);
+int lwip_write(int s, const void *dataptr, int size);
+int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
+                struct timeval *timeout);
+int lwip_ioctl(int s, long cmd, void *argp);
+
+#if LWIP_COMPAT_SOCKETS
+#define accept(a,b,c)         lwip_accept(a,b,c)
+#define bind(a,b,c)           lwip_bind(a,b,c)
+#define shutdown(a,b)         lwip_shutdown(a,b)
+#define closesocket(s)        lwip_close(s)
+#define connect(a,b,c)        lwip_connect(a,b,c)
+#define getsockname(a,b,c)    lwip_getsockname(a,b,c)
+#define getpeername(a,b,c)    lwip_getpeername(a,b,c)
+#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
+#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
+#define listen(a,b)           lwip_listen(a,b)
+#define recv(a,b,c,d)         lwip_recv(a,b,c,d)
+#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
+#define send(a,b,c,d)         lwip_send(a,b,c,d)
+#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)
+#define socket(a,b,c)         lwip_socket(a,b,c)
+#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)
+#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)
+
+#if LWIP_POSIX_SOCKETS_IO_NAMES
+#define read(a,b,c)           lwip_read(a,b,c)
+#define write(a,b,c)          lwip_write(a,b,c)
+#define close(s)              lwip_close(s)
+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
+
+#endif /* LWIP_COMPAT_SOCKETS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_SOCKET */
+
+#endif /* __LWIP_SOCKETS_H__ */
index 0c2d74d..0c73919 100644 (file)
  * PPP_SUPPORT==1: Enable PPP.
  */
 #define PPP_SUPPORT                     0
+       
+
+/* use errno provided by lwip, Lei */
+#define LWIP_PROVIDE_ERRNO    1
 
 
 /* Misc */
 
-#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_TIMEVAL_PRIVATE 1
 
 #endif /* __LWIPOPTS_H__ */
diff --git a/palacios/src/lwip/include/lwipopts.h~ b/palacios/src/lwip/include/lwipopts.h~
new file mode 100644 (file)
index 0000000..ae42ea2
--- /dev/null
@@ -0,0 +1,425 @@
+/**
+ * @file
+ *
+ * lwIP Options Configuration
+ */
+
+/*
+ * 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 __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+/*
+ * Include user defined options first. Anything not defined in these files
+ * will be set to standard values. Override anything you dont like!
+ */
+#include "lwipopts.h"
+#include "lwip/debug.h"
+
+/*
+   -----------------------------------------------
+   ---------- Platform specific locking ----------
+   -----------------------------------------------
+*/
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT            0
+
+/** 
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS                          0
+
+/*
+   ------------------------------------
+   ---------- Memory options ----------
+   ------------------------------------
+*/
+
+/**
+ * MEM_ALIGNMENT: should be set to the alignment of the CPU
+ *    4 byte alignment -> #define MEM_ALIGNMENT 4
+ *    2 byte alignment -> #define MEM_ALIGNMENT 2
+ */
+#define MEM_ALIGNMENT                   1
+
+/**
+ * MEM_SIZE: the size of the heap memory. If the application will send
+ * a lot of data that needs to be copied, this should be set high.
+ */
+#define MEM_SIZE                        1600
+
+/*
+   ------------------------------------------------
+   ---------- Internal Memory Pool Sizes ----------
+   ------------------------------------------------
+*/
+/**
+ * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
+ * If the application sends a lot of data out of ROM (or other static memory),
+ * this should be set high.
+ */
+#define MEMP_NUM_PBUF                   16
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#define MEMP_NUM_RAW_PCB                4
+
+/**
+ * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ * per active UDP "connection".
+ * (requires the LWIP_UDP option)
+ */
+#define MEMP_NUM_UDP_PCB                4
+
+/**
+ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB                4
+
+/**
+ * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_PCB_LISTEN         4
+
+/**
+ * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
+ * (requires the LWIP_TCP option)
+ */
+#define MEMP_NUM_TCP_SEG                16
+
+/**
+ * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
+ * reassembly (whole packets, not fragments!)
+ */
+#define MEMP_NUM_REASSDATA              1
+
+/**
+ * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing
+ * packets (pbufs) that are waiting for an ARP request (to resolve
+ * their destination address) to finish.
+ * (requires the ARP_QUEUEING option)
+ */
+#define MEMP_NUM_ARP_QUEUE              2
+
+/**
+ * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
+ * (requires NO_SYS==0)
+ */
+#define MEMP_NUM_SYS_TIMEOUT            3
+
+/**
+ * MEMP_NUM_NETBUF: the number of struct netbufs.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETBUF                 2
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#define MEMP_NUM_NETCONN                4
+
+/**
+ * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
+ * for callback/timeout API communication. 
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_API          8
+
+/**
+ * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
+ * for incoming packets. 
+ * (only needed if you use tcpip.c)
+ */
+#define MEMP_NUM_TCPIP_MSG_INPKT        8
+
+/**
+ * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. 
+ */
+#define PBUF_POOL_SIZE                  8
+
+/*
+   ---------------------------------
+   ---------- ARP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_ARP==1: Enable ARP functionality.
+ */
+#define LWIP_ARP                        1
+
+/*
+   --------------------------------
+   ---------- IP options ----------
+   --------------------------------
+*/
+/**
+ * IP_FORWARD==1: Enables the ability to forward IP packets across network
+ * interfaces. If you are going to run lwIP on a device with only one network
+ * interface, define this to 0.
+ */
+#define IP_FORWARD                      0
+
+/**
+ * IP_OPTIONS: Defines the behavior for IP options.
+ *      IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
+ *      IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
+ */
+#define IP_OPTIONS_ALLOWED              1
+
+/**
+ * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
+ * this option does not affect outgoing packet sizes, which can be controlled
+ * via IP_FRAG.
+ */
+#define IP_REASSEMBLY                   1
+
+/**
+ * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
+ * that this option does not affect incoming packet sizes, which can be
+ * controlled via IP_REASSEMBLY.
+ */
+#define IP_FRAG                         1
+
+/**
+ * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
+ * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
+ * in this time, the whole packet is discarded.
+ */
+#define IP_REASS_MAXAGE                 3
+
+/**
+ * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
+ * Since the received pbufs are enqueued, be sure to configure
+ * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
+ * packets even if the maximum amount of fragments is enqueued for reassembly!
+ */
+#define IP_REASS_MAX_PBUFS              4
+
+/**
+ * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
+ * fragmentation. Otherwise pbufs are allocated and reference the original
+    * packet data to be fragmented.
+*/
+#define IP_FRAG_USES_STATIC_BUF         0
+
+/**
+ * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
+ */
+#define IP_DEFAULT_TTL                  255
+
+/*
+   ----------------------------------
+   ---------- ICMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_ICMP==1: Enable ICMP module inside the IP stack.
+ * Be careful, disable that make your product non-compliant to RFC1122
+ */
+#define LWIP_ICMP                       1
+
+/*
+   ---------------------------------
+   ---------- RAW options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
+ */
+#define LWIP_RAW                        1
+
+/*
+   ----------------------------------
+   ---------- DHCP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DHCP==1: Enable DHCP module.
+ */
+#define LWIP_DHCP                       0
+
+
+/*
+   ------------------------------------
+   ---------- AUTOIP options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_AUTOIP==1: Enable AUTOIP module.
+ */
+#define LWIP_AUTOIP                     0
+
+/*
+   ----------------------------------
+   ---------- SNMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
+ * transport.
+ */
+#define LWIP_SNMP                       0
+
+/*
+   ----------------------------------
+   ---------- IGMP options ----------
+   ----------------------------------
+*/
+/**
+ * LWIP_IGMP==1: Turn on IGMP module. 
+ */
+#define LWIP_IGMP                       0
+
+/*
+   ----------------------------------
+   ---------- DNS options -----------
+   ----------------------------------
+*/
+/**
+ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
+ * transport.
+ */
+#define LWIP_DNS                        0
+
+/*
+   ---------------------------------
+   ---------- UDP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_UDP==1: Turn on UDP.
+ */
+#define LWIP_UDP                        1
+
+/*
+   ---------------------------------
+   ---------- TCP options ----------
+   ---------------------------------
+*/
+/**
+ * LWIP_TCP==1: Turn on TCP.
+ */
+#define LWIP_TCP                        1
+
+#define LWIP_LISTEN_BACKLOG             0
+
+/*
+   ----------------------------------
+   ---------- Pbuf options ----------
+   ----------------------------------
+*/
+/**
+ * PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+ * link level header. The default is 14, the standard value for
+ * Ethernet.
+ */
+#define PBUF_LINK_HLEN                  16
+
+/**
+ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
+ * designed to accomodate single full size TCP frame in one pbuf, including
+ * TCP_MSS, IP header, and link header.
+*
+ */
+#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
+
+/*
+   ------------------------------------
+   ---------- LOOPIF options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
+ */
+#define LWIP_HAVE_LOOPIF                0
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN                    1
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET                     1
+
+/*
+   ----------------------------------------
+   ---------- Statistics options ----------
+   ----------------------------------------
+*/
+/**
+ * LWIP_STATS==1: Enable statistics collection in lwip_stats.
+ */
+#define LWIP_STATS                      0
+/*
+   ---------------------------------
+   ---------- PPP options ----------
+   ---------------------------------
+*/
+/**
+ * PPP_SUPPORT==1: Enable PPP.
+ */
+#define PPP_SUPPORT                     0
+       
+
+/* use errno provided by lwip, Lei */
+#define LWIP_PROVIDE_ERRNO    1
+
+
+/* Misc */
+
+#define LWIP_TIMEVAL_PRIVATE 0
+
+#endif /* __LWIPOPTS_H__ */