From: Lei Xia Date: Thu, 25 Sep 2008 17:56:18 +0000 (-0500) Subject: Add lwip files, for test, not compilable version X-Git-Tag: 1.0~3^2~11^2~17 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=3342bf46adc702e5d5a29270be6ccb9cead9957e;p=palacios-OLD.git Add lwip files, for test, not compilable version --- diff --git a/palacios/src/lwip/api/sockets.c b/palacios/src/lwip/api/sockets.c index 88fec43..0853b0e 100644 --- a/palacios/src/lwip/api/sockets.c +++ b/palacios/src/lwip/api/sockets.c @@ -52,6 +52,8 @@ #include "lwip/udp.h" #include "lwip/tcpip.h" +#include "lwip/arch.h" + #include #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 index 0000000..c999744 --- /dev/null +++ b/palacios/src/lwip/api/sockets.c~ @@ -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 + * + * Improved by Marc Boucher and David Haas + * + */ + +#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 + +#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 index 0000000..abcd0fe --- /dev/null +++ b/palacios/src/lwip/arch/sys_arch.c @@ -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 + * + */ + +/* + * 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 +#include +#include +#include +#include +#include + +#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 + +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 index 0000000..6dc6968 --- /dev/null +++ b/palacios/src/lwip/build/.depend @@ -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 diff --git a/palacios/src/lwip/build/Makefile b/palacios/src/lwip/build/Makefile index 73662b2..3c2ee0f 100644 --- a/palacios/src/lwip/build/Makefile +++ b/palacios/src/lwip/build/Makefile @@ -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 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 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 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 index 0000000..f33b0c9 --- /dev/null +++ b/palacios/src/lwip/build/errno.h @@ -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 + */ + +#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 +#endif + +__BEGIN_DECLS + +/* Get the error number constants from the system-specific file. + This file will test __need_Emath and _ERRNO_H. */ +#include +#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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 index 0000000..4f67516 Binary files /dev/null and b/palacios/src/lwip/build/udp.o differ diff --git a/palacios/src/lwip/include/arch/cc.h b/palacios/src/lwip/include/arch/cc.h index 32f3953..73eb7d3 100644 --- a/palacios/src/lwip/include/arch/cc.h +++ b/palacios/src/lwip/include/arch/cc.h @@ -33,8 +33,13 @@ #define __ARCH_CC_H__ /* Include some files for defining library routines */ + #include -//#include + +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 //#include /* 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__ */ diff --git a/palacios/src/lwip/include/arch/cc.h~ b/palacios/src/lwip/include/arch/cc.h~ index b50fcc7..32f3953 100644 --- a/palacios/src/lwip/include/arch/cc.h~ +++ b/palacios/src/lwip/include/arch/cc.h~ @@ -34,7 +34,7 @@ /* Include some files for defining library routines */ #include -#include +//#include /* 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 -#include +//#include +//#include /* Plaform specific diagnostic output */ #define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0) diff --git a/palacios/src/lwip/include/lwip/arch.h b/palacios/src/lwip/include/lwip/arch.h index 7d1400b..67d8ee1 100644 --- a/palacios/src/lwip/include/lwip/arch.h +++ b/palacios/src/lwip/include/lwip/arch.h @@ -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 index 0000000..5492668 --- /dev/null +++ b/palacios/src/lwip/include/lwip/arch.h~ @@ -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 + * + */ +#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__ */ diff --git a/palacios/src/lwip/include/lwip/sockets.h b/palacios/src/lwip/include/lwip/sockets.h index 603b62f..b870399 100644 --- a/palacios/src/lwip/include/lwip/sockets.h +++ b/palacios/src/lwip/include/lwip/sockets.h @@ -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 index 0000000..a62ccd5 --- /dev/null +++ b/palacios/src/lwip/include/lwip/sockets.h~ @@ -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 + * + */ + + +#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 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__ */ diff --git a/palacios/src/lwip/include/lwipopts.h b/palacios/src/lwip/include/lwipopts.h index 0c2d74d..0c73919 100644 --- a/palacios/src/lwip/include/lwipopts.h +++ b/palacios/src/lwip/include/lwipopts.h @@ -412,10 +412,14 @@ * 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 index 0000000..ae42ea2 --- /dev/null +++ b/palacios/src/lwip/include/lwipopts.h~ @@ -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 + * + */ +#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__ */