Add the following features and bugfixes:

Added select() functionality to sockets library.
Support for errno in sockets library.
Byte ordering fixes.
basic lwip_ioctl(), FIONREAD, get/setsockopt() etc. support

- added additional argument to netif_add to pass state pointer so that the
if_init function has access to context information before
the interface is added, without accessing globals.

- added netif_remove()

- to conserve cpu load the tcpip_tcp_timer should only be active
when tcbs that need it exist.

- pass length of available data to callbacks for NETCONN_EVT_RCV events

- added tcpip_link_input(), a hack to allow processing of PPP
packets in tcpip_thread() context. This saves threads and context
switches.

- renamed incompatible ASSERT() macro to LWIP_ASSERT() to avoid name
collision.

- changed a bunch of %d's to %u's in format strings for unsigned values.

- added ip_frag to lwip_stats.

- changed IP_REASS_MAXAGE and IP_REASS_TMO defaults to more realistic
values.

- added sys_timeout_remove() function to cancel timeouts (needed by PPP
amongst other things).

- tolerate NULL returns from sys_arch_timeouts() since some threads might
not need to use or have timeouts.

- added sys_sem_wait_timeout()

- moved mem_malloc() function to end of mem.c to work around tasking
compiler bug.

- automatically bind to local tcp port if 0.

- allow customization of port ranges for automatic local bindings.

- corrected various typos, spelling errors, etc..

Thanks to Marc Boucher for many of these changes.
This commit is contained in:
davidhaas 2003-02-06 22:18:56 +00:00
parent d2e008d4b4
commit dd2fa15e8a
28 changed files with 1599 additions and 300 deletions

View File

@ -215,8 +215,25 @@ netconn *netconn_new(enum netconn_type t)
conn->acceptmbox = SYS_MBOX_NULL;
conn->sem = SYS_SEM_NULL;
conn->state = NETCONN_NONE;
conn->socket = 0;
conn->callback = 0;
conn->recv_avail = 0;
return conn;
}
/*-----------------------------------------------------------------------------------*/
struct
netconn *netconn_new_with_callback(enum netconn_type t,
void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
{
struct netconn *conn;
/* get a netconn and then initialize callback pointer and socket */
conn = netconn_new(t);
if (conn)
conn->callback = callback;
return conn;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_delete(struct netconn *conn)
@ -437,7 +454,10 @@ netconn_accept(struct netconn *conn)
}
sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);
return newconn;
}
/*-----------------------------------------------------------------------------------*/
@ -476,7 +496,11 @@ netconn_recv(struct netconn *conn)
}
sys_mbox_fetch(conn->recvmbox, (void **)&p);
conn->recv_avail -= p->tot_len;
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS, p->tot_len);
/* If we are closed, we indicate that we no longer wish to recieve
data by setting conn->recvmbox to SYS_MBOX_NULL. */
if(p == NULL) {
@ -509,6 +533,10 @@ netconn_recv(struct netconn *conn)
memp_freep(MEMP_API_MSG, msg);
} else {
sys_mbox_fetch(conn->recvmbox, (void **)&buf);
conn->recv_avail -= buf->p->tot_len;
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
}
@ -620,6 +648,7 @@ netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
sys_sem_free(conn->sem);
conn->sem = SYS_SEM_NULL;
}
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
@ -657,7 +686,3 @@ netconn_err(struct netconn *conn)
return conn->err;
}
/*-----------------------------------------------------------------------------------*/

View File

@ -52,6 +52,10 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
if(conn->recvmbox != SYS_MBOX_NULL) {
conn->err = err;
conn->recv_avail += p->tot_len;
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
sys_mbox_post(conn->recvmbox, p);
}
return ERR_OK;
@ -82,7 +86,11 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
buf->fromaddr = addr;
buf->fromport = port;
}
conn->recv_avail += p->tot_len;
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
sys_mbox_post(conn->recvmbox, buf);
}
}
@ -111,6 +119,11 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
if(conn != NULL && conn->sem != SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
if (conn && conn->callback)
if (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)
(*conn->callback)(conn, NETCONN_EVT_SENDPLUS, len);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
@ -126,12 +139,18 @@ err_tcp(void *arg, err_t err)
conn->err = err;
if(conn->recvmbox != SYS_MBOX_NULL) {
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
sys_mbox_post(conn->recvmbox, NULL);
}
if(conn->mbox != SYS_MBOX_NULL) {
sys_mbox_post(conn->mbox, NULL);
}
if(conn->acceptmbox != SYS_MBOX_NULL) {
/* Register event with callback */
if (conn->callback)
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
sys_mbox_post(conn->acceptmbox, NULL);
}
if(conn->sem != SYS_SEM_NULL) {
@ -155,15 +174,17 @@ setup_tcp(struct netconn *conn)
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
sys_mbox_t *mbox;
sys_mbox_t mbox;
struct netconn *newconn;
struct netconn *conn;
#if API_MSG_DEBUG
#if TCP_DEBUG
tcp_debug_print_state(newpcb->state);
#endif /* TCP_DEBUG */
#endif /* API_MSG_DEBUG */
mbox = (sys_mbox_t *)arg;
conn = (struct netconn *)arg;
mbox = conn->acceptmbox;
newconn = memp_mallocp(MEMP_NETCONN);
if(newconn == NULL) {
return ERR_MEM;
@ -191,7 +212,17 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
}
newconn->acceptmbox = SYS_MBOX_NULL;
newconn->err = err;
sys_mbox_post(*mbox, newconn);
/* Register event with callback */
if (conn->callback)
{
(*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
/* We have to set the callback here even though
* the new socket is unknown. Mark the socket as -1. */
newconn->callback = conn->callback;
newconn->socket = -1;
}
sys_mbox_post(mbox, newconn);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
@ -232,6 +263,13 @@ do_delconn(struct api_msg_msg *msg)
break;
}
}
/* Trigger select() in socket layer */
if (msg->conn->callback)
{
(*msg->conn->callback)(msg->conn, NETCONN_EVT_RCVPLUS, 0);
(*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDPLUS, 0);
}
if(msg->conn->mbox != SYS_MBOX_NULL) {
sys_mbox_post(msg->conn->mbox, NULL);
}
@ -417,7 +455,7 @@ do_listen(struct api_msg_msg *msg)
break;
}
}
tcp_arg(msg->conn->pcb.tcp, (void *)&(msg->conn->acceptmbox));
tcp_arg(msg->conn->pcb.tcp, msg->conn);
tcp_accept(msg->conn->pcb.tcp, accept_function);
}
break;
@ -504,6 +542,12 @@ do_write(struct api_msg_msg *msg)
tcp_output(msg->conn->pcb.tcp);
}
msg->conn->err = err;
if (msg->conn->callback)
if (err == ERR_OK)
{
if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)
(*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
}
break;
}
}

View File

@ -28,22 +28,76 @@
*
* Author: Adam Dunkels <adam@sics.se>
*
* Improved by Marc Boucher <marc@mbsi.ca> and David Haas <dhaas@alum.rpi.edu>
*
*/
#include "lwip/debug.h"
#include "lwip/api.h"
#include "lwip/arch.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#define NUM_SOCKETS 10
#define NUM_SOCKETS MEMP_NUM_NETCONN
struct lwip_socket {
struct netconn *conn;
struct netbuf *lastdata;
u16_t lastoffset;
u16_t rcvevent;
u16_t sendevent;
u16_t flags;
int err;
};
struct lwip_select_cb
{
struct lwip_select_cb *next;
fd_set *readset;
fd_set *writeset;
fd_set *exceptset;
int sem_signalled;
sys_sem_t sem;
};
static struct lwip_socket sockets[NUM_SOCKETS];
static struct lwip_select_cb *select_cb_list = 0;
static sys_sem_t socksem = 0;
static sys_sem_t selectsem = 0;
static void
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
static int err_to_errno_table[11] = {
0, /* ERR_OK 0 No error, everything OK. */
ENOMEM, /* ERR_MEM -1 Out of memory error. */
ENOBUFS, /* ERR_BUF -2 Buffer error. */
ECONNABORTED, /* ERR_ABRT -3 Connection aborted. */
ECONNRESET, /* ERR_RST -4 Connection reset. */
ESHUTDOWN, /* ERR_CLSD -5 Connection closed. */
ENOTCONN, /* ERR_CONN -6 Not connected. */
EINVAL, /* ERR_VAL -7 Illegal value. */
EIO, /* ERR_ARG -8 Illegal argument. */
EHOSTUNREACH, /* ERR_RTE -9 Routing problem. */
EADDRINUSE /* ERR_USE -10 Address in use. */
};
#define err_to_errno(err) \
((err) < (sizeof(err_to_errno_table)/sizeof(int))) ? \
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)
/*-----------------------------------------------------------------------------------*/
static struct lwip_socket *
@ -51,17 +105,20 @@ get_socket(int s)
{
struct lwip_socket *sock;
if(s > NUM_SOCKETS) {
/* errno = EBADF; */
if((s < 0) || (s > NUM_SOCKETS)) {
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
set_errno(EBADF);
return NULL;
}
sock = &sockets[s];
if(sock->conn == NULL) {
/* errno = EBADF; */
if(!sock->conn) {
DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s));
set_errno(EBADF);
return NULL;
}
return sock;
}
/*-----------------------------------------------------------------------------------*/
@ -69,16 +126,28 @@ static int
alloc_socket(struct netconn *newconn)
{
int i;
if (!socksem)
socksem = sys_sem_new(1);
/* Protect socket array */
sys_sem_wait(socksem);
/* allocate a new socket identifier */
for(i = 0; i < NUM_SOCKETS; ++i) {
if(sockets[i].conn == NULL) {
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;
}
/*-----------------------------------------------------------------------------------*/
@ -90,9 +159,11 @@ lwip_accept(int s, struct sockaddr *addr, int *addrlen)
struct ip_addr naddr;
u16_t port;
int newsock;
struct sockaddr_in sin;
DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s));
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
@ -101,14 +172,38 @@ lwip_accept(int s, struct sockaddr *addr, int *addrlen)
/* get the IP address and port of the remote host */
netconn_peer(newconn, &naddr, &port);
((struct sockaddr_in *)addr)->sin_addr.s_addr = naddr.addr;
((struct sockaddr_in *)addr)->sin_port = port;
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);
memcpy(addr, &sin, *addrlen);
newsock = alloc_socket(newconn);
if(newsock == -1) {
netconn_delete(newconn);
/* errno = ENOBUFS; */
sock_set_errno(sock, ENOBUFS);
return -1;
}
newconn->callback = event_callback;
sock = get_socket(newsock);
sys_sem_wait(socksem);
sock->rcvevent += -1 - newconn->socket;
newconn->socket = newsock;
sys_sem_signal(socksem);
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
ip_addr_debug_print(&naddr);
DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port));
#endif
sock_set_errno(sock, 0);
return newsock;
}
/*-----------------------------------------------------------------------------------*/
@ -116,25 +211,34 @@ int
lwip_bind(int s, struct sockaddr *name, int namelen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr;
u16_t remote_port;
struct ip_addr local_addr;
u16_t local_port;
err_t err;
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)name)->sin_port;
local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
local_port = ((struct sockaddr_in *)name)->sin_port;
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
ip_addr_debug_print(&local_addr);
DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port)));
#endif
err = netconn_bind(sock->conn, &remote_addr, ntohs(remote_port));
err = netconn_bind(sock->conn, &local_addr, ntohs(local_port));
if(err != ERR_OK) {
/* errno = ... */
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
sock_set_errno(sock, err_to_errno(err));
return -1;
}
DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s));
sock_set_errno(sock, 0);
return 0;
}
/*-----------------------------------------------------------------------------------*/
@ -143,20 +247,28 @@ lwip_close(int s)
{
struct lwip_socket *sock;
DEBUGF(SOCKETS_DEBUG, ("close: socket %d\n", s));
DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));
if (!socksem)
socksem = sys_sem_new(1);
/* We cannot allow multiple closes of the same socket. */
sys_sem_wait(socksem);
sock = get_socket(s);
if(sock == NULL) {
return -1;
if(!sock) {
sys_sem_signal(socksem);
return -1;
}
netconn_delete(sock->conn);
if(sock->lastdata != NULL) {
if(sock->lastdata) {
netbuf_delete(sock->lastdata);
}
sock->lastdata = NULL;
sock->lastoffset = 0;
sock->conn = NULL;
sys_sem_signal(socksem);
sock_set_errno(sock, 0);
return 0;
}
/*-----------------------------------------------------------------------------------*/
@ -164,28 +276,40 @@ int
lwip_connect(int s, struct sockaddr *name, int namelen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr;
u16_t remote_port;
err_t err;
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
err = netconn_disconnect(sock->conn);
} else {
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)name)->sin_port;
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
}
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;
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
ip_addr_debug_print(&remote_addr);
DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));
#endif
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
}
if(err != ERR_OK) {
/* errno = ... */
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));
sock_set_errno(sock, err_to_errno(err));
return -1;
}
DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));
sock_set_errno(sock, 0);
return 0;
}
/*-----------------------------------------------------------------------------------*/
@ -195,18 +319,21 @@ lwip_listen(int s, int backlog)
struct lwip_socket *sock;
err_t err;
DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
err = netconn_listen(sock->conn);
if(err != ERR_OK) {
/* errno = ... */
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;
}
/*-----------------------------------------------------------------------------------*/
@ -221,21 +348,33 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
u16_t port;
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
/* Check if there is data left from the last recv operation. */
if(sock->lastdata != NULL) {
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)
{
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. */
buf = netconn_recv(sock->conn);
if(buf == NULL) {
if(!buf) {
/* We should really do some error checking here. */
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
sock_set_errno(sock, 0);
return 0;
}
}
@ -255,13 +394,38 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
/* Check to see from where the data was. */
if(from != NULL && fromlen != NULL) {
if(from && fromlen) {
struct sockaddr_in sin;
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);
memcpy(from, &sin, *fromlen);
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
ip_addr_debug_print(addr);
DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
#endif
} else {
#if SOCKETS_DEBUG > 0
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
((struct sockaddr_in *)from)->sin_addr.s_addr = addr->addr;
((struct sockaddr_in *)from)->sin_port = port;
((struct sockaddr_in *)from)->sin_family = AF_INET;
*fromlen = sizeof(struct sockaddr_in);
DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
ip_addr_debug_print(addr);
DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
#endif
}
/* If this is a TCP socket, check if there is data left in the
@ -277,13 +441,14 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
}
sock_set_errno(sock, 0);
return copylen;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_read(int s, void *mem, int len)
{
return lwip_recv(s, mem, len, 0);
return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
}
/*-----------------------------------------------------------------------------------*/
int
@ -299,10 +464,10 @@ lwip_send(int s, void *data, int size, unsigned int flags)
struct netbuf *buf;
err_t err;
DEBUGF(SOCKETS_DEBUG, ("send: socket %d, size %d\n", s, size));
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
@ -311,8 +476,9 @@ lwip_send(int s, void *data, int size, unsigned int flags)
/* create a buffer */
buf = netbuf_new();
if(buf == NULL) {
/* errno = ENOBUFS; */
if(!buf) {
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
sock_set_errno(sock, ENOBUFS);
return -1;
}
@ -334,10 +500,13 @@ lwip_send(int s, void *data, int size, unsigned int flags)
break;
}
if(err != ERR_OK) {
/* errno = ... */
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
sock_set_errno(sock, err_to_errno(err));
return -1;
}
DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
sock_set_errno(sock, 0);
return size;
}
/*-----------------------------------------------------------------------------------*/
@ -351,7 +520,7 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
int ret,connected;
sock = get_socket(s);
if(sock == NULL) {
if(!sock) {
return -1;
}
@ -360,16 +529,23 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)to)->sin_port;
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, size, flags));
ip_addr_debug_print(&remote_addr);
DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));
#endif
netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
ret = lwip_send(s, data, size, flags);
/* reset the remote address and port number
of the connection */
if (connected)
netconn_connect(sock->conn, &addr, port);
if(connected)
netconn_connect(sock->conn, &addr, port);
else
netconn_disconnect(sock->conn);
netconn_disconnect(sock->conn);
return ret;
}
/*-----------------------------------------------------------------------------------*/
@ -382,28 +558,35 @@ lwip_socket(int domain, int type, int protocol)
/* create a netconn */
switch(type) {
case SOCK_DGRAM:
conn = netconn_new(NETCONN_UDP);
conn = netconn_new_with_callback(NETCONN_UDP, event_callback);
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
break;
case SOCK_STREAM:
conn = netconn_new(NETCONN_TCP);
conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
break;
default:
/* errno = ... */
DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol));
set_errno(EINVAL);
return -1;
}
if(conn == NULL) {
DEBUGF(SOCKETS_DEBUG, ("socket: could not create netconn.\n"));
/* errno = ENOBUFS; */
if(!conn) {
DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n"));
set_errno(ENOBUFS);
return -1;
}
i = alloc_socket(conn);
if(i == -1) {
/* errno = ENOBUFS; */
netconn_delete(conn);
set_errno(ENOBUFS);
return -1;
}
conn->socket = i;
DEBUGF(SOCKETS_DEBUG, ("%d\n", i));
set_errno(0);
return i;
}
/*-----------------------------------------------------------------------------------*/
@ -412,4 +595,456 @@ lwip_write(int s, void *data, int size)
{
return lwip_send(s, data, size, 0);
}
/*-----------------------------------------------------------------------------------*/
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);
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);
DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i));
nready++;
}
}
}
*readset = lreadset;
*writeset = lwriteset;
FD_ZERO(exceptset);
return nready;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
const 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;
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 */
if (!selectsem)
selectsem = sys_sem_new(1);
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(socksem);
if (readset)
FD_ZERO(readset);
if (writeset)
FD_ZERO(writeset);
if (exceptset)
FD_ZERO(exceptset);
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 /1000));
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);
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;
DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
set_errno(0);
return nready;
}
/*-----------------------------------------------------------------------------------*/
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;
/* 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. */
if (evt == NETCONN_EVT_RCVPLUS)
conn->socket--;
return;
}
sock = get_socket(s);
if (!sock)
return;
}
else
return;
if (!selectsem)
selectsem = sys_sem_new(1);
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;
}
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;
}
}
}
/*-----------------------------------------------------------------------------------*/
int lwip_shutdown(int s, int how)
{
DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how));
return lwip_close(s); /* XXX temporary hack until proper implementation */
}
int lwip_getpeername (int s, struct sockaddr *name, int *namelen)
{
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 of the remote host */
netconn_peer(sock->conn, &naddr, &sin.sin_port);
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_getpeername(%d, addr=", s));
ip_addr_debug_print(&naddr);
DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
#endif
sin.sin_port = htons(sin.sin_port);
sin.sin_addr.s_addr = naddr.addr;
if(*namelen > sizeof(sin))
*namelen = sizeof(sin);
memcpy(name, &sin, *namelen);
sock_set_errno(sock, 0);
return 0;
}
int lwip_getsockname (int s, struct sockaddr *name, int *namelen)
{
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 of the remote host */
netconn_addr(sock->conn, &naddr, &sin.sin_port);
#if SOCKETS_DEBUG
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockname(%d, addr=", s));
ip_addr_debug_print(naddr);
DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port));
#endif
sin.sin_port = htons(sin.sin_port);
sin.sin_addr.s_addr = naddr->addr;
if(*namelen > sizeof(sin))
*namelen = sizeof(sin);
memcpy(name, &sin, *namelen);
sock_set_errno(sock, 0);
return 0;
}
int lwip_getsockopt (int s, int level, int optname, char *optval, int *optlen)
{
int err = ENOSYS;
struct lwip_socket *sock = get_socket(s);
if(!sock) {
return -1;
}
if(level == SOL_SOCKET) {
switch(optname) {
case SO_ERROR:
if(!optval || !optlen || (*optlen != sizeof(int))) {
err = EINVAL;
break;
}
*(int *)optval = sock->err;
sock->err = 0;
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval));
err = 0;
break;
default:
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
break;
}
} else {
DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
}
sock_set_errno(sock, err);
return err ? -1 : 0;
}
int lwip_setsockopt (int s, int level, int optname, const char *optval, int optlen)
{
struct lwip_socket *sock = get_socket(s);
int err = ENOSYS;
if(!sock) {
return -1;
}
if(level == SOL_SOCKET) {
switch(optname) {
case SO_REUSEADDR:
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, ..)\n", s));
/* XXX just pretend we support this for now */
err = 0;
break;
default:
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
break;
}
} else {
DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
}
sock_set_errno(sock, err);
return err ? -1 : 0;
}
int lwip_ioctl(int s, long cmd, void *argp)
{
struct lwip_socket *sock = get_socket(s);
if(!sock) {
return -1;
}
switch(cmd) {
case FIONREAD:
if(!argp) {
sock_set_errno(sock, EINVAL);
return -1;
}
*((u16_t*)argp) = sock->conn->recv_avail;
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;
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));
sock_set_errno(sock, 0);
return 0;
default:
DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
sock_set_errno(sock, ENOSYS); /* not yet implemented */
return -1;
}
}

View File

@ -49,15 +49,32 @@ static void (* tcpip_init_done)(void *arg) = NULL;
static void *tcpip_init_done_arg;
static sys_mbox_t mbox;
static int tcpip_tcp_timer_active = 0;
/*-----------------------------------------------------------------------------------*/
static void
tcpip_tcp_timer(void *arg)
{
(void)arg;
tcp_tmr();
sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL);
if(tcp_active_pcbs || tcp_tw_pcbs) {
sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL);
} else {
tcpip_tcp_timer_active = 0;
}
}
void
tcp_timer_needed(void)
{
if(!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
tcpip_tcp_timer_active = 1;
sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL);
}
}
/*-----------------------------------------------------------------------------------*/
static void
tcpip_thread(void *arg)
{
@ -67,8 +84,6 @@ tcpip_thread(void *arg)
udp_init();
tcp_init();
sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL);
if(tcpip_init_done != NULL) {
tcpip_init_done(tcpip_init_done_arg);
}
@ -84,6 +99,10 @@ tcpip_thread(void *arg)
DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg));
ip_input(msg->msg.inp.p, msg->msg.inp.netif);
break;
case TCPIP_MSG_LINK:
DEBUGF(TCPIP_DEBUG, ("tcpip_thread: LINK packet %p\n", (void *)msg));
msg->msg.inp.netif->input(msg->msg.inp.p, msg->msg.inp.netif);
break;
default:
break;
}
@ -109,6 +128,24 @@ tcpip_input(struct pbuf *p, struct netif *inp)
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
err_t
tcpip_link_input(struct pbuf *p, struct netif *inp)
{
struct tcpip_msg *msg;
msg = memp_mallocp(MEMP_TCPIP_MSG);
if(msg == NULL) {
pbuf_free(p);
return ERR_MEM;
}
msg->type = TCPIP_MSG_LINK;
msg->msg.inp.p = p;
msg->msg.inp.netif = inp;
sys_mbox_post(mbox, msg);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
tcpip_apimsg(struct api_msg *apimsg)
{
@ -129,7 +166,7 @@ tcpip_init(void (* initfunc)(void *), void *arg)
tcpip_init_done = initfunc;
tcpip_init_done_arg = arg;
mbox = sys_mbox_new();
sys_thread_new((void *)tcpip_thread, NULL);
sys_thread_new(tcpip_thread, NULL);
}
/*-----------------------------------------------------------------------------------*/

View File

@ -913,8 +913,8 @@ void dhcp_stop(struct dhcp_state *state)
{
struct dhcp_state *list_state = client_list;
DEBUGF(DHCP_DEBUG, ("dhcp_stop()"));
ASSERT("dhcp_stop: state != NULL", state != NULL);
ASSERT("dhcp_stop: state->pcb != NULL", state->pcb != NULL);
LWIP_ASSERT("dhcp_stop: state != NULL", state != NULL);
LWIP_ASSERT("dhcp_stop: state->pcb != NULL", state->pcb != NULL);
if (state != NULL)
{
@ -966,24 +966,24 @@ static void dhcp_set_state(struct dhcp_state *state, unsigned char new_state)
static void dhcp_option(struct dhcp_state *state, u8_t option_type, u8_t option_len)
{
ASSERT("dhcp_option_short: state->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", state->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_short: state->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", state->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = option_type;
state->msg_out->options[state->options_out_len++] = option_len;
}
static void dhcp_option_byte(struct dhcp_state *state, u8_t value)
{
ASSERT("dhcp_option_short: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_short: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = value;
}
static void dhcp_option_short(struct dhcp_state *state, u16_t value)
{
ASSERT("dhcp_option_short: state->options_out_len + 2 <= DHCP_OPTIONS_LEN", state->options_out_len + 2 <= DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_short: state->options_out_len + 2 <= DHCP_OPTIONS_LEN", state->options_out_len + 2 <= DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = (value & 0xff00U) >> 8;
state->msg_out->options[state->options_out_len++] = value & 0x00ffU;
}
static void dhcp_option_long(struct dhcp_state *state, u32_t value)
{
ASSERT("dhcp_option_long: state->options_out_len + 4 <= DHCP_OPTIONS_LEN", state->options_out_len + 4 <= DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_long: state->options_out_len + 4 <= DHCP_OPTIONS_LEN", state->options_out_len + 4 <= DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = (value & 0xff000000UL) >> 24;
state->msg_out->options[state->options_out_len++] = (value & 0x00ff0000UL) >> 16;
state->msg_out->options[state->options_out_len++] = (value & 0x0000ff00UL) >> 8;
@ -1177,8 +1177,8 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
static err_t dhcp_create_request(struct dhcp_state *state)
{
u16_t i;
ASSERT("dhcp_create_request: state->p_out == NULL", state->p_out == NULL);
ASSERT("dhcp_create_request: state->msg_out == NULL", state->msg_out == NULL);
LWIP_ASSERT("dhcp_create_request: state->p_out == NULL", state->p_out == NULL);
LWIP_ASSERT("dhcp_create_request: state->msg_out == NULL", state->msg_out == NULL);
state->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
if (state->p_out == NULL)
{
@ -1213,8 +1213,8 @@ static err_t dhcp_create_request(struct dhcp_state *state)
static void dhcp_delete_request(struct dhcp_state *state)
{
ASSERT("dhcp_free_msg: state->p_out != NULL", state->p_out != NULL);
ASSERT("dhcp_free_msg: state->msg_out != NULL", state->msg_out != NULL);
LWIP_ASSERT("dhcp_free_msg: state->p_out != NULL", state->p_out != NULL);
LWIP_ASSERT("dhcp_free_msg: state->msg_out != NULL", state->msg_out != NULL);
pbuf_free(state->p_out);
state->p_out = NULL;
state->msg_out = NULL;
@ -1229,14 +1229,14 @@ static void dhcp_delete_request(struct dhcp_state *state)
static void dhcp_option_trailer(struct dhcp_state *state)
{
ASSERT("dhcp_option_trailer: state->msg_out != NULL", state->msg_out != NULL);
ASSERT("dhcp_option_trailer: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_trailer: state->msg_out != NULL", state->msg_out != NULL);
LWIP_ASSERT("dhcp_option_trailer: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = DHCP_OPTION_END;
// packet is still too small, or not 4 byte aligned?
while ((state->options_out_len < DHCP_MIN_OPTIONS_LEN) || (state->options_out_len & 3))
{
//DEBUGF(DHCP_DEBUG, ("dhcp_option_trailer: state->options_out_len=%u, DHCP_OPTIONS_LEN=%u", state->options_out_len, DHCP_OPTIONS_LEN));
ASSERT("dhcp_option_trailer: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
LWIP_ASSERT("dhcp_option_trailer: state->options_out_len < DHCP_OPTIONS_LEN", state->options_out_len < DHCP_OPTIONS_LEN);
state->msg_out->options[state->options_out_len++] = 0;
}
}

View File

@ -55,7 +55,7 @@ lwip_chksum(void *dataptr, int len)
DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", dataptr, len));
for(acc = 0; len > 1; len -= 2) {
// acc = acc + *((u16_t *)dataptr)++;
/* acc = acc + *((u16_t *)dataptr)++;*/
acc += *(u16_t *)dataptr;
dataptr = (void *)((u16_t *)dataptr + 1);
}
@ -94,9 +94,9 @@ inet_chksum_pseudo(struct pbuf *p,
swapped = 0;
/* iterate through all pbuf in chain */
for(q = p; q != NULL; q = q->next) {
DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", q, q->next));
DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", (void *) q, (void *)q->next));
acc += lwip_chksum(q->payload, q->len);
//DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));
/*DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/
while(acc >> 16) {
acc = (acc & 0xffffUL) + (acc >> 16);
}
@ -104,7 +104,7 @@ inet_chksum_pseudo(struct pbuf *p,
swapped = 1 - swapped;
acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
}
//DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%lx \n", acc));
/*DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%lx \n", acc));*/
}
if(swapped) {

View File

@ -371,6 +371,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
#if IP_REASSEMBLY
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))*8);
p = ip_reass(p);
if(p == NULL) {
return ERR_OK;
@ -523,7 +524,8 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
}
#if IP_FRAG
if (p->tot_len > netif->mtu)
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu))
return ip_frag(p,netif,dest);
#endif
@ -578,20 +580,20 @@ ip_debug_print(struct pbuf *p)
DEBUGF(IP_DEBUG, ("IP header:\n"));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("|%2d |%2d | %2d | %4d | (v, hl, tos, len)\n",
DEBUGF(IP_DEBUG, ("|%2d |%2d | %2u | %4u | (v, hl, tos, len)\n",
IPH_V(iphdr),
IPH_HL(iphdr),
IPH_TOS(iphdr),
ntohs(IPH_LEN(iphdr))));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %5d |%d%d%d| %4d | (id, flags, offset)\n",
DEBUGF(IP_DEBUG, ("| %5u |%u%u%u| %4u | (id, flags, offset)\n",
ntohs(IPH_ID(iphdr)),
ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %2d | %2d | 0x%04x | (ttl, proto, chksum)\n",
DEBUGF(IP_DEBUG, ("| %2u | %2u | 0x%04x | (ttl, proto, chksum)\n",
IPH_TTL(iphdr),
IPH_PROTO(iphdr),
ntohs(IPH_CHKSUM(iphdr))));

View File

@ -45,6 +45,7 @@
#include "lwip/ip_frag.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
/*
@ -74,8 +75,8 @@ copy_from_pbuf(struct pbuf *p, u16_t * offset,
}
#define IP_REASS_BUFSIZE 5760
#define IP_REASS_MAXAGE 10
#define IP_REASS_TMO 100
#define IP_REASS_MAXAGE 30
#define IP_REASS_TMO 1000
static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE];
static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8)];
@ -92,9 +93,11 @@ static u8_t ip_reasstmr;
static void
ip_reass_timer(void *arg)
{
if(ip_reasstmr)
if(ip_reasstmr > 1) {
ip_reasstmr--;
sys_timeout(IP_REASS_TMO, (sys_timeout_handler) ip_reass_timer, NULL);
sys_timeout(IP_REASS_TMO, (sys_timeout_handler) ip_reass_timer, NULL);
} else if(ip_reasstmr == 1)
ip_reasstmr = 0;
}
struct pbuf *
@ -105,6 +108,10 @@ ip_reass(struct pbuf *p)
u16_t offset, len;
u16_t i;
#ifdef IP_STATS
++lwip_stats.ip_frag.recv;
#endif /* IP_STATS */
iphdr = (struct ip_hdr *) ip_reassbuf;
fraghdr = (struct ip_hdr *) p->payload;
/* If ip_reasstmr is zero, no packet is present in the buffer, so we
@ -127,6 +134,9 @@ ip_reass(struct pbuf *p)
ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&
IPH_ID(iphdr) == IPH_ID(fraghdr)) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n"));
#ifdef IP_STATS
++lwip_stats.ip_frag.cachehit;
#endif /* IP_STATS */
/* Find out the offset in the reassembly buffer where we should
copy the fragment. */
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
@ -138,6 +148,7 @@ ip_reass(struct pbuf *p)
DEBUGF(IP_REASS_DEBUG,
("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
offset + len, IP_REASS_BUFSIZE));
sys_timeout_remove((sys_timeout_handler) ip_reass_timer, NULL);
ip_reasstmr = 0;
goto nullreturn;
}
@ -225,6 +236,7 @@ ip_reass(struct pbuf *p)
/* If we have come this far, we have a full packet in the
buffer, so we allocate a pbuf and copy the packet into it. We
also reset the timer. */
sys_timeout_remove((sys_timeout_handler) ip_reass_timer, NULL);
ip_reasstmr = 0;
pbuf_free(p);
p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
@ -242,6 +254,13 @@ ip_reass(struct pbuf *p)
q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
i += q->len;
}
#ifdef IP_STATS
++lwip_stats.ip_frag.fw;
#endif /* IP_STATS */
} else {
#ifdef IP_STATS
++lwip_stats.ip_frag.memerr;
#endif /* IP_STATS */
}
DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));
return p;
@ -249,6 +268,9 @@ ip_reass(struct pbuf *p)
}
nullreturn:
#ifdef IP_STATS
++lwip_stats.ip_frag.drop;
#endif /* IP_STATS */
pbuf_free(p);
return NULL;
}
@ -324,6 +346,9 @@ ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest)
header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);
pbuf_chain(header, rambuf);
netif->output(netif, header, dest);
#ifdef IP_STATS
++lwip_stats.ip_frag.xmit;
#endif /* IP_STATS */
pbuf_dechain(header);
pbuf_free(header);

View File

@ -217,7 +217,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
#if IP_DEBUG
/* DEBUGF("ip_input: \n");
ip_debug_print(p);
DEBUGF("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len);*/
DEBUGF("ip_input: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/
#endif /* IP_DEBUG */
@ -237,7 +237,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
/* send ICMP destination protocol unreachable */
icmp_dest_unreach(p, ICMP_DUR_PROTO);
pbuf_free(p);
DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %d\n",
DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %u\n",
iphdr->nexthdr));
#ifdef IP_STATS
@ -266,7 +266,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
PERF_START;
printf("len %d tot_len %d\n", p->len, p->tot_len);
printf("len %u tot_len %u\n", p->len, p->tot_len);
if(pbuf_header(p, IP_HLEN)) {
DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
#ifdef IP_STATS
@ -275,7 +275,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
return ERR_BUF;
}
printf("len %d tot_len %d\n", p->len, p->tot_len);
printf("len %u tot_len %u\n", p->len, p->tot_len);
iphdr = p->payload;
@ -303,7 +303,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
++lwip_stats.ip.xmit;
#endif /* IP_STATS */
DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %d)\n", netif->name[0], netif->name[1], p->tot_len));
DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %u)\n", netif->name[0], netif->name[1], p->tot_len));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
@ -350,7 +350,7 @@ ip_debug_print(struct pbuf *p)
iphdr->tclass1, iphdr->tclass2,
iphdr->flow1, iphdr->flow2));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %5d | %2d | %2d | (len, nexthdr, hoplim)\n",
DEBUGF(IP_DEBUG, ("| %5u | %2u | %2u | (len, nexthdr, hoplim)\n",
ntohs(iphdr->len),
iphdr->nexthdr,
iphdr->hoplim));

View File

@ -82,12 +82,12 @@ plug_holes(struct mem *mem)
struct mem *nmem;
struct mem *pmem;
ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
ASSERT("plug_holes: mem->used == 0", mem->used == 0);
LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram);
LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end);
LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0);
/* plug hole forward */
ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);
LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE", mem->next <= MEM_SIZE);
nmem = (struct mem *)&ram[mem->next];
if(mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) {
@ -134,6 +134,101 @@ mem_init(void)
#endif /* MEM_STATS */
}
/*-----------------------------------------------------------------------------------*/
void
mem_free(void *rmem)
{
struct mem *mem;
if(rmem == NULL) {
return;
}
sys_sem_wait(mem_sem);
LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
DEBUGF(MEM_DEBUG, ("mem_free: illegal memory\n"));
#ifdef MEM_STATS
++lwip_stats.mem.err;
#endif /* MEM_STATS */
return;
}
mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
LWIP_ASSERT("mem_free: mem->used", mem->used);
mem->used = 0;
if(mem < lfree) {
lfree = mem;
}
#ifdef MEM_STATS
lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram) - SIZEOF_STRUCT_MEM;
#endif /* MEM_STATS */
plug_holes(mem);
sys_sem_signal(mem_sem);
}
/*-----------------------------------------------------------------------------------*/
void *
mem_reallocm(void *rmem, mem_size_t newsize)
{
void *nmem;
nmem = mem_malloc(newsize);
if(nmem == NULL) {
return mem_realloc(rmem, newsize);
}
memcpy(nmem, rmem, newsize);
mem_free(rmem);
return nmem;
}
/*-----------------------------------------------------------------------------------*/
void *
mem_realloc(void *rmem, mem_size_t newsize)
{
mem_size_t size;
mem_size_t ptr, ptr2;
struct mem *mem, *mem2;
sys_sem_wait(mem_sem);
LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
DEBUGF(MEM_DEBUG, ("mem_realloc: illegal memory\n"));
return rmem;
}
mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
ptr = (u8_t *)mem - ram;
size = mem->next - ptr - SIZEOF_STRUCT_MEM;
#ifdef MEM_STATS
lwip_stats.mem.used -= (size - newsize);
#endif /* MEM_STATS */
if(newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
mem2 = (struct mem *)&ram[ptr2];
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
mem->next = ptr2;
if(mem2->next != MEM_SIZE) {
((struct mem *)&ram[mem2->next])->prev = ptr2;
}
plug_holes(mem2);
}
sys_sem_signal(mem_sem);
return rmem;
}
/*-----------------------------------------------------------------------------------*/
void *
mem_malloc(mem_size_t size)
{
@ -187,12 +282,12 @@ mem_malloc(mem_size_t size)
while(lfree->used && lfree != ram_end) {
lfree = (struct mem *)&ram[lfree->next];
}
ASSERT("mem_malloc: !lfree->used", !lfree->used);
LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
}
sys_sem_signal(mem_sem);
ASSERT("mem_malloc: allocated memory not above ram_end.",
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
(u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
ASSERT("mem_malloc: allocated memory properly aligned.",
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
}
@ -205,98 +300,3 @@ mem_malloc(mem_size_t size)
return NULL;
}
/*-----------------------------------------------------------------------------------*/
void
mem_free(void *rmem)
{
struct mem *mem;
if(rmem == NULL) {
return;
}
sys_sem_wait(mem_sem);
ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
DEBUGF(MEM_DEBUG, ("mem_free: illegal memory\n"));
#ifdef MEM_STATS
++lwip_stats.mem.err;
#endif /* MEM_STATS */
return;
}
mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
ASSERT("mem_free: mem->used", mem->used);
mem->used = 0;
if(mem < lfree) {
lfree = mem;
}
#ifdef MEM_STATS
lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram) - SIZEOF_STRUCT_MEM;
#endif /* MEM_STATS */
plug_holes(mem);
sys_sem_signal(mem_sem);
}
/*-----------------------------------------------------------------------------------*/
void *
mem_reallocm(void *rmem, mem_size_t newsize)
{
void *nmem;
nmem = mem_malloc(newsize);
if(nmem == NULL) {
return mem_realloc(rmem, newsize);
}
memcpy(nmem, rmem, newsize);
mem_free(rmem);
return nmem;
}
/*-----------------------------------------------------------------------------------*/
void *
mem_realloc(void *rmem, mem_size_t newsize)
{
mem_size_t size;
mem_size_t ptr, ptr2;
struct mem *mem, *mem2;
sys_sem_wait(mem_sem);
ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
(u8_t *)rmem < (u8_t *)ram_end);
if((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
DEBUGF(MEM_DEBUG, ("mem_realloc: illegal memory\n"));
return rmem;
}
mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
ptr = (u8_t *)mem - ram;
size = mem->next - ptr - SIZEOF_STRUCT_MEM;
#ifdef MEM_STATS
lwip_stats.mem.used -= (size - newsize);
#endif /* MEM_STATS */
if(newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) {
ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize;
mem2 = (struct mem *)&ram[ptr2];
mem2->used = 0;
mem2->next = mem->next;
mem2->prev = ptr;
mem->next = ptr2;
if(mem2->next != MEM_SIZE) {
((struct mem *)&ram[mem2->next])->prev = ptr2;
}
plug_holes(mem2);
}
sys_sem_signal(mem_sem);
return rmem;
}
/*-----------------------------------------------------------------------------------*/

View File

@ -179,7 +179,7 @@ memp_malloc(memp_t type)
struct memp *memp;
void *mem;
ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
memp = memp_tab[type];
@ -192,7 +192,7 @@ memp_malloc(memp_t type)
lwip_stats.memp[type].max = lwip_stats.memp[type].used;
}
#endif /* MEMP_STATS */
ASSERT("memp_malloc: memp properly aligned",
LWIP_ASSERT("memp_malloc: memp properly aligned",
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
@ -245,7 +245,7 @@ memp_free(memp_t type, void *mem)
memp->next = memp_tab[type];
memp_tab[type] = memp;
ASSERT("memp sanity", memp_sanity());
LWIP_ASSERT("memp sanity", memp_sanity());
return;
}

View File

@ -43,6 +43,7 @@ struct netif *netif_default = NULL;
struct netif *
netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw,
void *state,
void (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
{
@ -55,6 +56,7 @@ netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
return NULL;
}
netif->state = state;
netif->num = netifnum++;
netif->input = input;
ip_addr_set(&(netif->ip_addr), ipaddr);
@ -77,6 +79,36 @@ netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
#endif /* NETIF_DEBUG */
return netif;
}
/*-----------------------------------------------------------------------------------*/
void netif_remove(struct netif * netif)
{
if ( netif == NULL ) return;
/* is it the first netif? */
if(netif_list == netif) {
netif_list = netif->next;
}
else
{
/* look for netif further down the list */
struct netif * tmpNetif;
for(tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
if(tmpNetif->next == netif) {
tmpNetif->next = netif->next;
break;
}
}
if(tmpNetif == NULL)
return; /* we didn't find any netif today */
}
if(netif_default == netif)
netif_default = NULL;
DEBUGF(NETIF_DEBUG, ("netif_remove: removed netif"));
mem_free( netif );
}
/*-----------------------------------------------------------------------------------*/
struct netif *
netif_find(char *name)
@ -131,7 +163,7 @@ netif_set_default(struct netif *netif)
{
netif_default = netif;
DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
netif->name[0], netif->name[1]));
netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
}
/*-----------------------------------------------------------------------------------*/
void

View File

@ -78,11 +78,11 @@ static struct pbuf *pbuf_pool_free_cache = NULL;
void
pbuf_init(void)
{
struct pbuf *p, *q;
struct pbuf *p, *q = 0;
u16_t i;
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
LWIP_ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
#ifdef PBUF_STATS
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
@ -191,9 +191,6 @@ pbuf_pool_free(struct pbuf *p)
}
#endif /* PBUF_STATS */
#ifdef SYS_LIGHTWEIGHT_PROT
old_level = sys_arch_protect();
#endif /* SYS_LIGHTWEIGHT_PROT */
if(pbuf_pool_alloc_cache == NULL) {
pbuf_pool_alloc_cache = p;
} else {
@ -244,7 +241,7 @@ pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
case PBUF_RAW:
break;
default:
ASSERT("pbuf_alloc: bad pbuf layer", 0);
LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
return NULL;
}
@ -292,12 +289,12 @@ pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
r = q;
q->ref = 1;
q = q->next;
/*q = q->next; DJH: Appears to be an unnecessary statement*/
rsize -= PBUF_POOL_BUFSIZE;
}
r->next = NULL;
ASSERT("pbuf_alloc: pbuf->payload properly aligned",
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
break;
case PBUF_RAM:
@ -312,7 +309,7 @@ pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
p->next = NULL;
p->flags = PBUF_FLAG_RAM;
ASSERT("pbuf_alloc: pbuf->payload properly aligned",
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
break;
case PBUF_ROM:
@ -328,7 +325,7 @@ pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
p->flags = PBUF_FLAG_ROM;
break;
default:
ASSERT("pbuf_alloc: erroneous flag", 0);
LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);
return NULL;
}
p->ref = 1;
@ -426,7 +423,7 @@ pbuf_realloc(struct pbuf *p, u16_t size)
struct pbuf *q, *r;
u16_t rsize;
ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||
LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||
p->flags == PBUF_FLAG_ROM ||
p->flags == PBUF_FLAG_RAM);
@ -549,11 +546,11 @@ pbuf_free(struct pbuf *p)
PERF_START;
ASSERT("pbuf_free: sane flags", p->flags == PBUF_FLAG_POOL ||
LWIP_ASSERT("pbuf_free: sane flags", p->flags == PBUF_FLAG_POOL ||
p->flags == PBUF_FLAG_ROM ||
p->flags == PBUF_FLAG_RAM);
ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
#ifdef SYS_LIGHTWEIGHT_PROT
/* Since decrementing ref cannot be guarranteed to be a single machine operation
@ -564,7 +561,7 @@ pbuf_free(struct pbuf *p)
/* Decrement reference count. */
p->ref--;
q = NULL;
/*q = NULL; DJH: Unnecessary statement*/
/* If reference count == 0, actually deallocate pbuf. */
if(p->ref == 0) {
#ifdef SYS_LIGHTWEIGHT_PROT

View File

@ -38,6 +38,14 @@
#include "lwip/memp.h"
#if (NO_SYS == 0)
struct sswt_cb
{
int timeflag;
sys_sem_t *psem;
};
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
@ -52,7 +60,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
again:
timeouts = sys_arch_timeouts();
if(timeouts->next == NULL) {
if(!timeouts || !timeouts->next) {
sys_arch_mbox_fetch(mbox, msg, 0);
} else {
if(timeouts->next->time > 0) {
@ -70,7 +78,10 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
h = tmptimeout->h;
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
if(h != NULL) {
DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
h(arg);
}
/* We try again to fetch a message from the mbox. */
goto again;
@ -104,7 +115,7 @@ sys_sem_wait(sys_sem_t sem)
timeouts = sys_arch_timeouts();
if(timeouts->next == NULL) {
if(!timeouts || !timeouts->next) {
sys_arch_sem_wait(sem, 0);
} else {
if(timeouts->next->time > 0) {
@ -122,7 +133,10 @@ sys_sem_wait(sys_sem_t sem)
h = tmptimeout->h;
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
if(h != NULL) {
DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
h(arg);
}
/* We try again to fetch a message from the mbox. */
@ -158,6 +172,9 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
timeouts = sys_arch_timeouts();
DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%u h=%p arg=%p\n", (void *)timeout, msecs, (void *)h, (void *)arg));
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
if(timeouts->next == NULL) {
timeouts->next = timeout;
return;
@ -183,5 +200,86 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
}
}
/* Go through timeout list (for this task only) and remove the first matching entry,
even though the timeout has not triggered yet.
*/
/*-----------------------------------------------------------------------------------*/
void
sys_timeout_remove(sys_timeout_handler h, void *arg)
{
struct sys_timeouts *timeouts;
struct sys_timeout *prev_t, *t;
timeouts = sys_arch_timeouts();
if (timeouts->next == NULL)
return;
for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)
{
if ((t->h == h) && (t->arg == arg))
{
/* We have a match */
/* Unlink from previous in list */
if (prev_t == NULL)
timeouts->next = t->next;
else
prev_t->next = t->next;
/* If not the last one, add time of this one back to next */
if (t->next != NULL)
t->next->time += t->time;
memp_free(MEMP_SYS_TIMEOUT, t);
return;
}
}
return;
}
/*-----------------------------------------------------------------------------------*/
static void
sswt_handler(void *arg)
{
struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
/* Timeout. Set flag to TRUE and signal semephore */
sswt_cb->timeflag = 1;
sys_sem_signal(*(sswt_cb->psem));
}
/* Wait for a semaphore with timeout (specified in ms) */
/* timeout = 0: wait forever */
/* Returns 0 on timeout. 1 otherwise */
/*-----------------------------------------------------------------------------------*/
int
sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
{
struct sswt_cb sswt_cb;
sswt_cb.psem = &sem;
sswt_cb.timeflag = 0;
/* If timeout is zero, then just wait forever */
if (timeout > 0)
/* Create a timer and pass it the address of our flag */
sys_timeout(timeout, sswt_handler, &sswt_cb);
sys_sem_wait(sem);
/* Was it a timeout? */
if (sswt_cb.timeflag)
{
/* timeout */
return 0;
} else {
/* Not a timeout. Remove timeout entry */
sys_timeout_remove(sswt_handler, &sswt_cb);
return 1;
}
}
/*-----------------------------------------------------------------------------------*/
#endif /* NO_SYS */

View File

@ -69,6 +69,8 @@ struct tcp_pcb *tcp_tmp_pcb;
static u8_t tcp_timer;
static u16_t tcp_new_port(void);
/*-----------------------------------------------------------------------------------*/
/*
* tcp_init():
@ -250,6 +252,10 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct tcp_pcb *cpcb;
if(port == 0) {
port = tcp_new_port();
}
/* Check if the address already is in use. */
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs;
cpcb != NULL; cpcb = cpcb->next) {
@ -275,7 +281,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
pcb->local_ip = *ipaddr;
}
pcb->local_port = port;
DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %d\n", port));
DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %u\n", port));
return ERR_OK;
}
#if LWIP_CALLBACK_API
@ -337,7 +343,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
!(pcb->flags & TF_ACK_NOW)) {
tcp_ack(pcb);
}
DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %d bytes, wnd %u (%u).\n",
DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %u bytes, wnd %u (%u).\n",
len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
}
/*-----------------------------------------------------------------------------------*/
@ -352,11 +358,15 @@ static u16_t
tcp_new_port(void)
{
struct tcp_pcb *pcb;
static u16_t port = 4096;
#ifndef TCP_LOCAL_PORT_RANGE_START
#define TCP_LOCAL_PORT_RANGE_START 4096
#define TCP_LOCAL_PORT_RANGE_END 0x7fff
#endif
static u16_t port = TCP_LOCAL_PORT_RANGE_START;
again:
if(++port > 0x7fff) {
port = 4096;
if(++port > TCP_LOCAL_PORT_RANGE_END) {
port = TCP_LOCAL_PORT_RANGE_START;
}
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
@ -393,7 +403,7 @@ tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
err_t ret;
u32_t iss;
DEBUGF(TCP_DEBUG, ("tcp_connect to port %d\n", port));
DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\n", port));
if(ipaddr != NULL) {
pcb->remote_ip = *ipaddr;
} else {
@ -458,9 +468,9 @@ tcp_slowtmr(void)
if (pcb == NULL) DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs"));
while(pcb != NULL) {
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb"));
ASSERT("tcp_slowtmr: active pcb->state != CLOSED", pcb->state != CLOSED);
ASSERT("tcp_slowtmr: active pcb->state != LISTEN", pcb->state != LISTEN);
ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED", pcb->state != CLOSED);
LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN", pcb->state != LISTEN);
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
pcb_remove = 0;
@ -476,7 +486,7 @@ tcp_slowtmr(void)
if(pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
/* Time for a retransmission. */
DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %d pcb->rto %d\n",
DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n",
pcb->rtime, pcb->rto));
/* Double retransmission time-out unless we are trying to
@ -537,11 +547,11 @@ tcp_slowtmr(void)
tcp_pcb_purge(pcb);
/* Remove PCB from tcp_active_pcbs list. */
if(prev != NULL) {
ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
prev->next = pcb->next;
} else {
/* This PCB was the first. */
ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
tcp_active_pcbs = pcb->next;
}
@ -573,7 +583,7 @@ tcp_slowtmr(void)
prev = NULL;
pcb = tcp_tw_pcbs;
while(pcb != NULL) {
ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
pcb_remove = 0;
/* Check if this PCB has stayed long enough in TIME-WAIT */
@ -588,11 +598,11 @@ tcp_slowtmr(void)
tcp_pcb_purge(pcb);
/* Remove PCB from tcp_tw_pcbs list. */
if(prev != NULL) {
ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
prev->next = pcb->next;
} else {
/* This PCB was the first. */
ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
tcp_tw_pcbs = pcb->next;
}
pcb2 = pcb->next;
@ -1002,7 +1012,7 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
}
pcb->state = CLOSED;
ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
}
/*-----------------------------------------------------------------------------------*/
/*
@ -1036,7 +1046,8 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
DEBUGF(TCP_DEBUG, ("| %08lu | (ack no)\n",
tcphdr->ackno));
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(TCP_DEBUG, ("| %2d | |%d%d%d%d%d| %5d | (offset, flags (",
DEBUGF(TCP_DEBUG, ("| %2u | |%u%u%u%u%u| %5u | (offset, flags (",
TCPH_OFFSET(tcphdr),
TCPH_FLAGS(tcphdr) >> 4 & 1,
TCPH_FLAGS(tcphdr) >> 4 & 1,
TCPH_FLAGS(tcphdr) >> 3 & 1,
@ -1047,7 +1058,7 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
DEBUGF(TCP_DEBUG, ("), win)\n"));
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(TCP_DEBUG, ("| 0x%04x | %5d | (chksum, urgp)\n",
DEBUGF(TCP_DEBUG, ("| 0x%04x | %5u | (chksum, urgp)\n",
ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
}
@ -1122,21 +1133,21 @@ tcp_debug_print_pcbs(void)
struct tcp_pcb *pcb;
DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(TCP_DEBUG, ("Local port %d, foreign port %d snd_nxt %lu rcv_nxt %lu ",
DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
pcb->local_port, pcb->remote_port,
pcb->snd_nxt, pcb->rcv_nxt));
tcp_debug_print_state(pcb->state);
}
DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(TCP_DEBUG, ("Local port %d, foreign port %d snd_nxt %lu rcv_nxt %lu ",
DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
pcb->local_port, pcb->remote_port,
pcb->snd_nxt, pcb->rcv_nxt));
tcp_debug_print_state(pcb->state);
}
DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(TCP_DEBUG, ("Local port %d, foreign port %d snd_nxt %lu rcv_nxt %lu ",
DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
pcb->local_port, pcb->remote_port,
pcb->snd_nxt, pcb->rcv_nxt));
tcp_debug_print_state(pcb->state);
@ -1148,12 +1159,12 @@ tcp_pcbs_sane(void)
{
struct tcp_pcb *pcb;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
}
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
}
return 1;
}

View File

@ -157,9 +157,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
for an active connection. */
prev = NULL;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
if(pcb->remote_port == tcphdr->src &&
pcb->local_port == tcphdr->dest &&
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
@ -168,13 +168,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* Move this PCB to the front of the list so that subsequent
lookups will be faster (we exploit locality in TCP segment
arrivals). */
ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
if(prev != NULL) {
prev->next = pcb->next;
pcb->next = tcp_active_pcbs;
tcp_active_pcbs = pcb;
}
ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
break;
}
prev = pcb;
@ -185,7 +185,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
in the TIME-WAIT state. */
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
if(pcb->remote_port == tcphdr->src &&
pcb->local_port == tcphdr->dest &&
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
@ -201,7 +201,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
/* Finally, if we still did not get a match, we check all PCBs that
are LISTENing for incomming connections. */
are LISTENing for incoming connections. */
prev = NULL;
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
if((ip_addr_isany(&(lpcb->local_ip)) ||
@ -326,7 +326,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
pbuf_free(p);
}
ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
PERF_STOP("tcp_input");
}
/*-----------------------------------------------------------------------------------*/
@ -450,7 +450,7 @@ tcp_process(struct tcp_pcb *pcb)
if(acceptable) {
DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
recv_flags = TF_RESET;
pcb->flags &= ~TF_ACK_DELAY;
return ERR_RST;
@ -500,7 +500,7 @@ tcp_process(struct tcp_pcb *pcb)
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
pcb->state = ESTABLISHED;
DEBUGF(DEMO_DEBUG, ("TCP connection established %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
ASSERT("pcb->accept != NULL", pcb->accept != NULL);
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
/* Call the accept function. */
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
if(err != ERR_OK) {
@ -727,7 +727,7 @@ tcp_receive(struct tcp_pcb *pcb)
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */
@ -758,7 +758,7 @@ tcp_receive(struct tcp_pcb *pcb)
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */

View File

@ -129,7 +129,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */
@ -310,7 +310,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d (after enqueued)\n", pcb->snd_queuelen));
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
@ -333,7 +333,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
}
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}

View File

@ -28,7 +28,7 @@
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: udp.c,v 1.16 2003/01/30 15:02:48 likewise Exp $
* $Id: udp.c,v 1.17 2003/02/06 22:18:56 davidhaas Exp $
*/
/*-----------------------------------------------------------------------------------*/
@ -93,6 +93,7 @@ udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
u16_t src, dest;
PERF_START;
(void)inp;
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4;
@ -177,7 +178,7 @@ udp_input(struct pbuf *p, struct netif *inp)
udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %d\n", p->tot_len));
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
src = NTOHS(udphdr->src);
dest = NTOHS(udphdr->dest);
@ -341,7 +342,14 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
err_t err;
struct pbuf *hdr;
DEBUGF(UDP_DEBUG, ("udp_send"));
DEBUGF(UDP_DEBUG, ("udp_send\n"));
if(pcb->local_port == 0) {
err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
if(err != ERR_OK)
return err;
}
/* hdr will point to the UDP header pbuf if an extra header pbuf has
to be allocated. */
hdr = NULL;
@ -359,7 +367,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
/* have p point to header pbuf */
p = hdr;
}
DEBUGF(UDP_DEBUG, ("udp_send: got pbuf"));
DEBUGF(UDP_DEBUG, ("udp_send: got pbuf\n"));
udphdr = p->payload;
udphdr->src = htons(pcb->local_port);
@ -382,11 +390,11 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
src_ip = &(pcb->local_ip);
}
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %d\n", p->tot_len));
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", p->tot_len));
/* UDP Lite protocol? */
if(pcb->flags & UDP_FLAGS_UDPLITE) {
DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u", p->tot_len));
DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", p->tot_len));
/* set UDP message length in UDP header */
udphdr->len = htons(pcb->chksum_len);
/* calculate checksum */
@ -400,7 +408,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
snmp_inc_udpoutdatagrams();
#endif
} else {
DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u", p->tot_len));
DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", p->tot_len));
udphdr->len = htons(p->tot_len);
/* calculate checksum */
if((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
@ -408,11 +416,11 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
/* chksum zero must become 0xffff, as zero means 'no checksum' */
if(udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
}
DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum %x", udphdr->chksum));
DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum %x\n", udphdr->chksum));
#if LWIP_SNMP > 0
snmp_inc_udpoutdatagrams();
#endif
DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if(,,,,IP_PROTO_UDP,)"));
DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if(,,,,IP_PROTO_UDP,)\n"));
/* output to IP */
err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
}
@ -466,6 +474,23 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
}
/* bind local address */
ip_addr_set(&pcb->local_ip, ipaddr);
if(port == 0) {
#ifndef UDP_LOCAL_PORT_RANGE_START
#define UDP_LOCAL_PORT_RANGE_START 4096
#define UDP_LOCAL_PORT_RANGE_END 0x7fff
#endif
port = UDP_LOCAL_PORT_RANGE_START;
ipcb = udp_pcbs;
while((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
if(ipcb->local_port == port) {
port++;
ipcb = udp_pcbs;
} else
ipcb = ipcb->next;
}
if(ipcb) /* no more ports available in local range */
return ERR_USE;
}
pcb->local_port = port;
/* We need to place the PCB on the list if not already there. */
@ -474,7 +499,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
udp_pcbs = pcb;
}
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %d\n", port));
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %u\n", port));
return ERR_OK;
}
/**
@ -492,10 +517,34 @@ err_t
udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct udp_pcb *ipcb;
if(pcb->local_port == 0) {
err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
if(err != ERR_OK)
return err;
}
ip_addr_set(&pcb->remote_ip, ipaddr);
pcb->remote_port = port;
pcb->flags |= UDP_FLAGS_CONNECTED;
/* Nail down local IP for netconn_addr()/getsockname() */
if(ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
struct netif *netif;
if((netif = ip_route(&(pcb->remote_ip))) == NULL) {
DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
#ifdef UDP_STATS
++lwip_stats.udp.rterr;
#endif /* UDP_STATS */
return ERR_RTE;
}
pcb->local_ip = netif->ip_addr;
} else if(ip_addr_isany(&pcb->remote_ip)) {
pcb->local_ip.addr = 0;
}
/* Insert UDP PCB into the list of active UDP PCBs. */
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
if(pcb == ipcb) {
@ -577,10 +626,10 @@ udp_debug_print(struct udp_hdr *udphdr)
{
DEBUGF(UDP_DEBUG, ("UDP header:\n"));
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(UDP_DEBUG, ("| %5d | %5d | (src port, dest port)\n",
DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
ntohs(udphdr->src), ntohs(udphdr->dest)));
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(UDP_DEBUG, ("| %5d | 0x%04x | (len, chksum)\n",
DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n",
ntohs(udphdr->len), ntohs(udphdr->chksum)));
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
return 0;

View File

@ -62,6 +62,13 @@ enum netconn_state {
NETCONN_CLOSE
};
enum netconn_evt {
NETCONN_EVT_RCVPLUS,
NETCONN_EVT_RCVMINUS,
NETCONN_EVT_SENDPLUS,
NETCONN_EVT_SENDMINUS
};
struct netbuf {
struct pbuf *p, *ptr;
struct ip_addr *fromaddr;
@ -81,6 +88,9 @@ struct netconn {
sys_mbox_t recvmbox;
sys_mbox_t acceptmbox;
sys_sem_t sem;
int socket;
u16_t recv_avail;
void (* callback)(struct netconn *, enum netconn_evt, u16_t len);
};
/* Network buffer functions: */
@ -108,6 +118,9 @@ u16_t netbuf_fromport (struct netbuf *buf);
/* Network connection functions: */
struct netconn * netconn_new (enum netconn_type type);
struct
netconn *netconn_new_with_callback(enum netconn_type t,
void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
err_t netconn_delete (struct netconn *conn);
enum netconn_type netconn_type (struct netconn *conn);
err_t netconn_peer (struct netconn *conn,

View File

@ -55,4 +55,158 @@
#define PACK_STRUCT_FIELD(x) x
#endif /* PACK_STRUCT_FIELD */
#ifndef FD_SET
#undef FD_SETSIZE
#define FD_SETSIZE 16
#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;
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
#endif
#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 */
extern int errno;
#endif /* LWIP_PROVIDE_ERRNO */
#endif /* __LWIP_ARCH_H__ */

View File

@ -38,7 +38,7 @@
#ifdef LWIP_DEBUG
#define ASSERT(x,y) if(!(y)) {printf("Assertion \"%s\" failed at line %d in %s\n", \
#define LWIP_ASSERT(x,y) if(!(y)) {printf("Assertion \"%s\" failed at line %d in %s\n", \
x, __LINE__, __FILE__); fflush(NULL); abort();}
/* These defines control the amount of debugging output: */
@ -194,9 +194,9 @@
#else /* LWIP_DEBUG */
/* DEBUG is not defined, so we define null macros for ASSERT and DEBUGF */
/* DEBUG is not defined, so we define null macros for LWIP_ASSERT and DEBUGF */
#define ASSERT(x,y)
#define LWIP_ASSERT(x,y)
#define DEBUGF(debug, x)
/* And we define those to be zero: */

View File

@ -85,9 +85,12 @@ void netif_init(void);
struct netif *netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw,
void *state,
void (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif));
void netif_remove(struct netif * netif);
/* Returns a network interface given its name. The name is of the form
"et0", where the first two letters are the "name" field in the
netif structure, and the digit is in the num field in the same

View File

@ -53,10 +53,59 @@ struct sockaddr {
char sa_data[14];
};
#ifndef socklen_t
#define socklen_t int
#endif
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
#define AF_UNSPEC 0
/*
* Option flags per-socket.
*/
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_DONTLINGER (int)(~SO_LINGER)
/*
* Additional options, not kept in so_options.
*/
#define SO_SNDBUF 0x1001 /* send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
/*
* 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
@ -66,8 +115,62 @@ struct sockaddr {
#define INADDR_ANY 0
#define INADDR_BROADCAST 0xffffffff
/* Flags we can use with send and recv. */
#define MSG_DONTWAIT 0x40 /* Nonblocking i/o for this operation only */
/*
* Commands for ioctlsocket(), taken from the BSD file fcntl.h.
*
*
* 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 0x7f /* parameters must be < 128 bytes */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* 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
#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 */
#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
#ifndef O_NONBLOCK
#define O_NONBLOCK 04000
#endif
int lwip_accept(int s, struct sockaddr *addr, int *addrlen);
int lwip_bind(int s, struct sockaddr *name, int namelen);
int lwip_shutdown(int s, int how);
int lwip_getpeername (int s, struct sockaddr *name, int *namelen);
int lwip_getsockname (int s, struct sockaddr *name, int *namelen);
int lwip_getsockopt (int s, int level, int optname, char *optval, int *optlen);
int lwip_setsockopt (int s, int level, int optname, const char *optval, int optlen);
int lwip_close(int s);
int lwip_connect(int s, struct sockaddr *name, int namelen);
int lwip_listen(int s, int backlog);
@ -80,12 +183,20 @@ int lwip_sendto(int s, void *dataptr, int size, unsigned int flags,
struct sockaddr *to, int tolen);
int lwip_socket(int domain, int type, int protocol);
int lwip_write(int s, void *dataptr, int size);
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
const struct timeval *timeout);
int lwip_ioctl(int s, long cmd, void *argp);
#ifdef 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 close(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 read(a,b,c) lwip_read(a,b,c)
@ -94,7 +205,9 @@ int lwip_write(int s, void *dataptr, int size);
#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 write(a,b,c) lwip_write(a,b,c)
#endif /* LWIP_NO_COMPAT_SOCKETS */
#define select(a,b,c,d,e) lwip_select(a,b,c,d,e)
#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)
#endif /* LWIP_COMPAT_SOCKETS */
#endif /* __LWIP_SOCKETS_H__ */

View File

@ -86,6 +86,7 @@ struct stats_sys {
struct stats_ {
struct stats_proto link;
struct stats_proto ip_frag;
struct stats_proto ip;
struct stats_proto icmp;
struct stats_proto udp;

View File

@ -87,6 +87,7 @@ void sys_init(void);
*
*/
void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
void sys_timeout_remove(sys_timeout_handler h, void *arg);
struct sys_timeouts *sys_arch_timeouts(void);
/* Semaphore functions. */
@ -95,6 +96,7 @@ void sys_sem_signal(sys_sem_t sem);
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout);
void sys_sem_free(sys_sem_t sem);
void sys_sem_wait(sys_sem_t sem);
int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout);
/* Mailbox functions. */
sys_mbox_t sys_mbox_new(void);

View File

@ -396,6 +396,7 @@ int tcp_pcbs_sane(void);
#define tcp_pcbs_sane() 1
#endif /* TCP_DEBUG */
void tcp_timer_needed(void);
/* The TCP PCB lists. */
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
@ -421,17 +422,17 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
for(tcp_tmp_pcb = *pcbs; \
tcp_tmp_pcb != NULL; \
tcp_tmp_pcb = tcp_tmp_pcb->next) { \
ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
} \
/* TODO: state field doesn't exist in listen pcbs */ \
ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
npcb->next = *pcbs; \
ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
*(pcbs) = npcb; \
ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
tcp_timer_needed(); \
} while(0)
#define TCP_RMV(pcbs, npcb) do { \
ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
if(*pcbs == npcb) { \
*pcbs = (*pcbs)->next; \
@ -442,7 +443,7 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
} \
} \
npcb->next = NULL; \
ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
} while(0)
@ -450,6 +451,7 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
#define TCP_REG(pcbs, npcb) do { \
npcb->next = *pcbs; \
*(pcbs) = npcb; \
tcp_timer_needed(); \
} while(0)
#define TCP_RMV(pcbs, npcb) do { \
if(*(pcbs) == npcb) { \

View File

@ -38,10 +38,14 @@
void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
void tcpip_apimsg(struct api_msg *apimsg);
err_t tcpip_input(struct pbuf *p, struct netif *inp);
err_t tcpip_link_input(struct pbuf *p, struct netif *inp);
void tcpip_tcp_timer_needed(void);
enum tcpip_msg_type {
TCPIP_MSG_API,
TCPIP_MSG_INPUT
TCPIP_MSG_INPUT,
TCPIP_MSG_LINK
};
struct tcpip_msg {

View File

@ -3,6 +3,58 @@
* Address Resolution Protocol module for IP over Ethernet
*
* $Log: etharp.c,v $
* Revision 1.24 2003/02/06 22:18:57 davidhaas
* Add the following features and bugfixes:
*
* Added select() functionality to sockets library.
* Support for errno in sockets library.
* Byte ordering fixes.
* basic lwip_ioctl(), FIONREAD, get/setsockopt() etc. support
*
* - added additional argument to netif_add to pass state pointer so that the
* if_init function has access to context information before
* the interface is added, without accessing globals.
*
* - added netif_remove()
*
* - to conserve cpu load the tcpip_tcp_timer should only be active
* when tcbs that need it exist.
*
* - pass length of available data to callbacks for NETCONN_EVT_RCV events
*
* - added tcpip_link_input(), a hack to allow processing of PPP
* packets in tcpip_thread() context. This saves threads and context
* switches.
*
* - renamed incompatible ASSERT() macro to LWIP_ASSERT() to avoid name
* collision.
*
* - changed a bunch of %d's to %u's in format strings for unsigned values.
*
* - added ip_frag to lwip_stats.
*
* - changed IP_REASS_MAXAGE and IP_REASS_TMO defaults to more realistic
* values.
*
* - added sys_timeout_remove() function to cancel timeouts (needed by PPP
* amongst other things).
*
* - tolerate NULL returns from sys_arch_timeouts() since some threads might
* not need to use or have timeouts.
*
* - added sys_sem_wait_timeout()
*
* - moved mem_malloc() function to end of mem.c to work around tasking
* compiler bug.
*
* - automatically bind to local tcp port if 0.
*
* - allow customization of port ranges for automatic local bindings.
*
* - corrected various typos, spelling errors, etc..
*
* Thanks to Marc Boucher for many of these changes.
*
* Revision 1.23 2003/01/18 16:05:24 jani
* When all entries are 0 due to the whole table changing since the last arp tick (past 10 seconds) there's no oldest entry and the new entry does not get a spot.Fix this (from Ed Sutter)
*
@ -319,7 +371,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
} /* for */
/* no matching ARP entry was found */
ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: IP address not yet in table\n"));
/* allowed to insert an entry? */
@ -337,11 +389,11 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: overwriting old stable entry %u\n", i));
/* stable entries should have no queued packets (TODO: allow later) */
#if ARP_QUEUEING
ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL);
LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL);
#endif
} else {
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state));
ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
}
/* set IP address */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);