Initial revision

This commit is contained in:
likewise
2002-10-19 12:59:30 +00:00
commit f06e955072
145 changed files with 27001 additions and 0 deletions

13
src/FILES Normal file
View File

@@ -0,0 +1,13 @@
api/ - The code for the API.
arch/ - Architectural specific files are kept here.
core/ - The core files including protocol implementations, memory
and buffer management etc.
include/ - lwIP include files.
netif/ - Generic network interface device drivers are kept here.
For more information on the various subdirectories, check the FILES
file in each directory.

639
src/api/api_lib.c Normal file
View File

@@ -0,0 +1,639 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* This is the part of the API that is linked with
the application */
#include "lwip/debug.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/memp.h"
#include "lwip/debug.h"
/*-----------------------------------------------------------------------------------*/
struct
netbuf *netbuf_new(void)
{
struct netbuf *buf;
buf = memp_mallocp(MEMP_NETBUF);
if(buf != NULL) {
buf->p = NULL;
buf->ptr = NULL;
return buf;
} else {
return NULL;
}
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_delete(struct netbuf *buf)
{
if(buf != NULL) {
if(buf->p != NULL) {
pbuf_free(buf->p);
buf->p = buf->ptr = NULL;
}
memp_freep(MEMP_NETBUF, buf);
}
}
/*-----------------------------------------------------------------------------------*/
void *
netbuf_alloc(struct netbuf *buf, u16_t size)
{
/* Deallocate any previously allocated memory. */
if(buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
if(buf->p == NULL) {
return NULL;
}
buf->ptr = buf->p;
return buf->p->payload;
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_free(struct netbuf *buf)
{
if(buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = buf->ptr = NULL;
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
{
if(buf->p != NULL) {
pbuf_free(buf->p);
}
buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_ROM);
buf->p->payload = dataptr;
buf->p->len = buf->p->tot_len = size;
buf->ptr = buf->p;
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_chain(struct netbuf *head, struct netbuf *tail)
{
pbuf_chain(head->p, tail->p);
head->ptr = head->p;
memp_freep(MEMP_NETBUF, tail);
}
/*-----------------------------------------------------------------------------------*/
u16_t
netbuf_len(struct netbuf *buf)
{
return buf->p->tot_len;
}
/*-----------------------------------------------------------------------------------*/
err_t
netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
{
if(buf->ptr == NULL) {
return ERR_BUF;
}
*dataptr = buf->ptr->payload;
*len = buf->ptr->len;
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
s8_t
netbuf_next(struct netbuf *buf)
{
if(buf->ptr->next == NULL) {
return -1;
}
buf->ptr = buf->ptr->next;
if(buf->ptr->next == NULL) {
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_first(struct netbuf *buf)
{
buf->ptr = buf->p;
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
{
struct pbuf *p;
u16_t i, left;
left = 0;
if(buf == NULL) {
return;
}
/* This implementation is bad. It should use bcopy
instead. */
for(p = buf->p; left < len && p != NULL; p = p->next) {
if(offset != 0 && offset >= p->len) {
offset -= p->len;
} else {
for(i = offset; i < p->len; ++i) {
((char *)dataptr)[left] = ((char *)p->payload)[i];
if(++left >= len) {
return;
}
}
offset = 0;
}
}
}
/*-----------------------------------------------------------------------------------*/
void
netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
{
netbuf_copy_partial(buf, dataptr, len, 0);
}
/*-----------------------------------------------------------------------------------*/
struct ip_addr *
netbuf_fromaddr(struct netbuf *buf)
{
return buf->fromaddr;
}
/*-----------------------------------------------------------------------------------*/
u16_t
netbuf_fromport(struct netbuf *buf)
{
return buf->fromport;
}
/*-----------------------------------------------------------------------------------*/
struct
netconn *netconn_new(enum netconn_type t)
{
struct netconn *conn;
conn = memp_mallocp(MEMP_NETCONN);
if(conn == NULL) {
return NULL;
}
conn->type = t;
conn->pcb.tcp = NULL;
if((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
memp_freep(MEMP_NETCONN, conn);
return NULL;
}
conn->recvmbox = SYS_MBOX_NULL;
conn->acceptmbox = SYS_MBOX_NULL;
conn->sem = SYS_SEM_NULL;
conn->state = NETCONN_NONE;
return conn;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_delete(struct netconn *conn)
{
struct api_msg *msg;
void *mem;
if(conn == NULL) {
return ERR_OK;
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return ERR_MEM;
}
msg->type = API_MSG_DELCONN;
msg->msg.conn = conn;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
/* Drain the recvmbox. */
if(conn->recvmbox != SYS_MBOX_NULL) {
while(sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != 0) {
if(conn->type == NETCONN_TCP) {
pbuf_free((struct pbuf *)mem);
} else {
netbuf_delete((struct netbuf *)mem);
}
}
sys_mbox_free(conn->recvmbox);
conn->recvmbox = SYS_MBOX_NULL;
}
/* Drain the acceptmbox. */
if(conn->acceptmbox != SYS_MBOX_NULL) {
while(sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != 0) {
netconn_delete((struct netconn *)mem);
}
sys_mbox_free(conn->acceptmbox);
conn->acceptmbox = SYS_MBOX_NULL;
}
sys_mbox_free(conn->mbox);
conn->mbox = SYS_MBOX_NULL;
if(conn->sem != SYS_SEM_NULL) {
sys_sem_free(conn->sem);
}
/* conn->sem = SYS_SEM_NULL;*/
memp_free(MEMP_NETCONN, conn);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
enum netconn_type
netconn_type(struct netconn *conn)
{
return conn->type;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_peer(struct netconn *conn, struct ip_addr **addr,
u16_t *port)
{
switch(conn->type) {
case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
*addr = &(conn->pcb.udp->remote_ip);
*port = conn->pcb.udp->remote_port;
break;
case NETCONN_TCP:
*addr = &(conn->pcb.tcp->remote_ip);
*port = conn->pcb.tcp->remote_port;
break;
}
return (conn->err = ERR_OK);
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_addr(struct netconn *conn, struct ip_addr **addr,
u16_t *port)
{
switch(conn->type) {
case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP:
*addr = &(conn->pcb.udp->local_ip);
*port = conn->pcb.udp->local_port;
break;
case NETCONN_TCP:
*addr = &(conn->pcb.tcp->local_ip);
*port = conn->pcb.tcp->local_port;
break;
}
return (conn->err = ERR_OK);
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_bind(struct netconn *conn, struct ip_addr *addr,
u16_t port)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if(conn->type != NETCONN_TCP &&
conn->recvmbox == SYS_MBOX_NULL) {
if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
return ERR_MEM;
}
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return (conn->err = ERR_MEM);
}
msg->type = API_MSG_BIND;
msg->msg.conn = conn;
msg->msg.msg.bc.ipaddr = addr;
msg->msg.msg.bc.port = port;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_connect(struct netconn *conn, struct ip_addr *addr,
u16_t port)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if(conn->recvmbox == SYS_MBOX_NULL) {
if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
return ERR_MEM;
}
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return ERR_MEM;
}
msg->type = API_MSG_CONNECT;
msg->msg.conn = conn;
msg->msg.msg.bc.ipaddr = addr;
msg->msg.msg.bc.port = port;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_listen(struct netconn *conn)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if(conn->acceptmbox == SYS_MBOX_NULL) {
conn->acceptmbox = sys_mbox_new();
if(conn->acceptmbox == SYS_MBOX_NULL) {
return ERR_MEM;
}
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return (conn->err = ERR_MEM);
}
msg->type = API_MSG_LISTEN;
msg->msg.conn = conn;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
struct netconn *
netconn_accept(struct netconn *conn)
{
struct netconn *newconn;
if(conn == NULL) {
return NULL;
}
sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
return newconn;
}
/*-----------------------------------------------------------------------------------*/
struct netbuf *
netconn_recv(struct netconn *conn)
{
struct api_msg *msg;
struct netbuf *buf;
struct pbuf *p;
if(conn == NULL) {
return NULL;
}
if(conn->recvmbox == SYS_MBOX_NULL) {
conn->err = ERR_CONN;
return NULL;
}
if(conn->err != ERR_OK) {
return NULL;
}
if(conn->type == NETCONN_TCP) {
if(conn->pcb.tcp->state == LISTEN) {
conn->err = ERR_CONN;
return NULL;
}
buf = memp_mallocp(MEMP_NETBUF);
if(buf == NULL) {
conn->err = ERR_MEM;
return NULL;
}
sys_mbox_fetch(conn->recvmbox, (void **)&p);
/* 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) {
memp_freep(MEMP_NETBUF, buf);
sys_mbox_free(conn->recvmbox);
conn->recvmbox = SYS_MBOX_NULL;
return NULL;
}
buf->p = p;
buf->ptr = p;
buf->fromport = 0;
buf->fromaddr = NULL;
/* Let the stack know that we have taken the data. */
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
conn->err = ERR_MEM;
return buf;
}
msg->type = API_MSG_RECV;
msg->msg.conn = conn;
if(buf != NULL) {
msg->msg.msg.len = buf->p->tot_len;
} else {
msg->msg.msg.len = 1;
}
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
} else {
sys_mbox_fetch(conn->recvmbox, (void **)&buf);
}
DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", buf, conn->err));
return buf;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_send(struct netconn *conn, struct netbuf *buf)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if(conn->err != ERR_OK) {
return conn->err;
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return (conn->err = ERR_MEM);
}
DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
msg->type = API_MSG_SEND;
msg->msg.conn = conn;
msg->msg.msg.p = buf->p;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
{
struct api_msg *msg;
u16_t len;
if(conn == NULL) {
return ERR_VAL;
}
if(conn->err != ERR_OK) {
return conn->err;
}
if(conn->sem == SYS_SEM_NULL) {
conn->sem = sys_sem_new(0);
if(conn->sem == SYS_SEM_NULL) {
return ERR_MEM;
}
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return (conn->err = ERR_MEM);
}
msg->type = API_MSG_WRITE;
msg->msg.conn = conn;
conn->state = NETCONN_WRITE;
while(conn->err == ERR_OK && size > 0) {
msg->msg.msg.w.dataptr = dataptr;
msg->msg.msg.w.copy = copy;
if(conn->type == NETCONN_TCP) {
if(tcp_sndbuf(conn->pcb.tcp) == 0) {
sys_sem_wait(conn->sem);
if(conn->err != ERR_OK) {
goto ret;
}
}
if(size > tcp_sndbuf(conn->pcb.tcp)) {
/* We cannot send more than one send buffer's worth of data at a
time. */
len = tcp_sndbuf(conn->pcb.tcp);
} else {
len = size;
}
} else {
len = size;
}
DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
msg->msg.msg.w.len = len;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
if(conn->err == ERR_OK) {
dataptr = (void *)((char *)dataptr + len);
size -= len;
} else if(conn->err == ERR_MEM) {
conn->err = ERR_OK;
sys_sem_wait(conn->sem);
} else {
goto ret;
}
}
ret:
memp_freep(MEMP_API_MSG, msg);
conn->state = NETCONN_NONE;
if(conn->sem != SYS_SEM_NULL) {
sys_sem_free(conn->sem);
conn->sem = SYS_SEM_NULL;
}
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_close(struct netconn *conn)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return (conn->err = ERR_MEM);
}
conn->state = NETCONN_CLOSE;
again:
msg->type = API_MSG_CLOSE;
msg->msg.conn = conn;
api_msg_post(msg);
sys_mbox_fetch(conn->mbox, NULL);
if(conn->err == ERR_MEM &&
conn->sem != SYS_SEM_NULL) {
sys_sem_wait(conn->sem);
goto again;
}
conn->state = NETCONN_NONE;
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/
err_t
netconn_err(struct netconn *conn)
{
return conn->err;
}
/*-----------------------------------------------------------------------------------*/

544
src/api/api_msg.c Normal file
View File

@@ -0,0 +1,544 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/arch.h"
#include "lwip/api_msg.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/tcpip.h"
/*-----------------------------------------------------------------------------------*/
static err_t
recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct netconn *conn;
conn = arg;
if(conn == NULL) {
pbuf_free(p);
return ERR_VAL;
}
if(conn->recvmbox != SYS_MBOX_NULL) {
conn->err = err;
sys_mbox_post(conn->recvmbox, p);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
#if LWIP_UDP
static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *addr, u16_t port)
{
struct netbuf *buf;
struct netconn *conn;
conn = arg;
if(conn == NULL) {
pbuf_free(p);
return;
}
if(conn->recvmbox != SYS_MBOX_NULL) {
buf = memp_mallocp(MEMP_NETBUF);
if(buf == NULL) {
pbuf_free(p);
return;
} else {
buf->p = p;
buf->ptr = p;
buf->fromaddr = addr;
buf->fromport = port;
}
sys_mbox_post(conn->recvmbox, buf);
}
}
#endif /* LWIP_UDP */
/*-----------------------------------------------------------------------------------*/
static err_t
poll_tcp(void *arg, struct tcp_pcb *pcb)
{
struct netconn *conn;
conn = arg;
if(conn != NULL &&
(conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE) &&
conn->sem != SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct netconn *conn;
conn = arg;
if(conn != NULL && conn->sem != SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
err_tcp(void *arg, err_t err)
{
struct netconn *conn;
conn = arg;
conn->pcb.tcp = NULL;
conn->err = err;
if(conn->recvmbox != SYS_MBOX_NULL) {
sys_mbox_post(conn->recvmbox, NULL);
}
if(conn->mbox != SYS_MBOX_NULL) {
sys_mbox_post(conn->mbox, NULL);
}
if(conn->acceptmbox != SYS_MBOX_NULL) {
sys_mbox_post(conn->acceptmbox, NULL);
}
if(conn->sem != SYS_SEM_NULL) {
sys_sem_signal(conn->sem);
}
}
/*-----------------------------------------------------------------------------------*/
static void
setup_tcp(struct netconn *conn)
{
struct tcp_pcb *pcb;
pcb = conn->pcb.tcp;
tcp_arg(pcb, conn);
tcp_recv(pcb, recv_tcp);
tcp_sent(pcb, sent_tcp);
tcp_poll(pcb, poll_tcp, 4);
tcp_err(pcb, err_tcp);
}
/*-----------------------------------------------------------------------------------*/
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
sys_mbox_t *mbox;
struct netconn *newconn;
#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;
newconn = memp_mallocp(MEMP_NETCONN);
if(newconn == NULL) {
return ERR_MEM;
}
newconn->type = NETCONN_TCP;
newconn->pcb.tcp = newpcb;
setup_tcp(newconn);
newconn->recvmbox = sys_mbox_new();
if(newconn->recvmbox == SYS_MBOX_NULL) {
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->mbox = sys_mbox_new();
if(newconn->mbox == SYS_MBOX_NULL) {
sys_mbox_free(newconn->recvmbox);
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->sem = sys_sem_new(0);
if(newconn->sem == SYS_SEM_NULL) {
sys_mbox_free(newconn->recvmbox);
sys_mbox_free(newconn->mbox);
memp_free(MEMP_NETCONN, newconn);
return ERR_MEM;
}
newconn->acceptmbox = SYS_MBOX_NULL;
newconn->err = err;
sys_mbox_post(*mbox, newconn);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
do_newconn(struct api_msg_msg *msg)
{
}
/*-----------------------------------------------------------------------------------*/
static void
do_delconn(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
msg->conn->pcb.udp->recv_arg = NULL;
udp_remove(msg->conn->pcb.udp);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
if(msg->conn->pcb.tcp->state == LISTEN) {
tcp_accept(msg->conn->pcb.tcp, NULL);
tcp_close(msg->conn->pcb.tcp);
} else {
tcp_arg(msg->conn->pcb.tcp, NULL);
tcp_sent(msg->conn->pcb.tcp, NULL);
tcp_recv(msg->conn->pcb.tcp, NULL);
tcp_poll(msg->conn->pcb.tcp, NULL, 0);
tcp_err(msg->conn->pcb.tcp, NULL);
if(tcp_close(msg->conn->pcb.tcp) != ERR_OK) {
tcp_abort(msg->conn->pcb.tcp);
}
}
break;
}
}
if(msg->conn->mbox != SYS_MBOX_NULL) {
sys_mbox_post(msg->conn->mbox, NULL);
}
}
/*-----------------------------------------------------------------------------------*/
static void
do_bind(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp == NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
msg->conn->pcb.udp = udp_new();
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDPNOCHKSUM:
msg->conn->pcb.udp = udp_new();
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDP:
msg->conn->pcb.udp = udp_new();
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp = tcp_new();
setup_tcp(msg->conn);
break;
}
}
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->err = tcp_bind(msg->conn->pcb.tcp,
msg->msg.bc.ipaddr, msg->msg.bc.port);
break;
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
static err_t
do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct netconn *conn;
conn = arg;
if(conn == NULL) {
return ERR_VAL;
}
conn->err = err;
if(conn->type == NETCONN_TCP && err == ERR_OK) {
setup_tcp(conn);
}
sys_mbox_post(conn->mbox, NULL);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
do_connect(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp == NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
msg->conn->pcb.udp = udp_new();
if(msg->conn->pcb.udp == NULL) {
msg->conn->err = ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDPNOCHKSUM:
msg->conn->pcb.udp = udp_new();
if(msg->conn->pcb.udp == NULL) {
msg->conn->err = ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
case NETCONN_UDP:
msg->conn->pcb.udp = udp_new();
if(msg->conn->pcb.udp == NULL) {
msg->conn->err = ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp = tcp_new();
if(msg->conn->pcb.tcp == NULL) {
msg->conn->err = ERR_MEM;
sys_mbox_post(msg->conn->mbox, NULL);
return;
}
break;
}
}
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
sys_mbox_post(msg->conn->mbox, NULL);
break;
#endif
case NETCONN_TCP:
/* tcp_arg(msg->conn->pcb.tcp, msg->conn);*/
setup_tcp(msg->conn);
tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
do_connected);
/*tcp_output(msg->conn->pcb.tcp);*/
break;
}
}
/*-----------------------------------------------------------------------------------*/
static void
do_listen(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
if(msg->conn->pcb.tcp == NULL) {
msg->conn->err = ERR_MEM;
} else {
if(msg->conn->acceptmbox == SYS_MBOX_NULL) {
msg->conn->acceptmbox = sys_mbox_new();
if(msg->conn->acceptmbox == SYS_MBOX_NULL) {
msg->conn->err = ERR_MEM;
break;
}
}
tcp_arg(msg->conn->pcb.tcp, (void *)&(msg->conn->acceptmbox));
tcp_accept(msg->conn->pcb.tcp, accept_function);
}
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
do_accept(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
do_send(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_send(msg->conn->pcb.udp, msg->msg.p);
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
do_recv(struct api_msg_msg *msg)
{
if(msg->conn->pcb.tcp != NULL) {
if(msg->conn->type == NETCONN_TCP) {
tcp_recved(msg->conn->pcb.tcp, msg->msg.len);
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
do_write(struct api_msg_msg *msg)
{
err_t err;
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
msg->conn->err = ERR_VAL;
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
msg->msg.w.len, msg->msg.w.copy);
/* This is the Nagle algorithm: inhibit the sending of new TCP
segments when new outgoing data arrives from the user if any
previously transmitted data on the connection remains
unacknowledged. */
if(err == ERR_OK && msg->conn->pcb.tcp->unacked == NULL) {
tcp_output(msg->conn->pcb.tcp);
}
msg->conn->err = err;
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
do_close(struct api_msg_msg *msg)
{
err_t err;
if(msg->conn->pcb.tcp != NULL) {
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
break;
#endif /* LWIP_UDP */
case NETCONN_TCP:
if(msg->conn->pcb.tcp->state == LISTEN) {
err = tcp_close(msg->conn->pcb.tcp);
}
msg->conn->err = err;
break;
}
}
sys_mbox_post(msg->conn->mbox, NULL);
}
/*-----------------------------------------------------------------------------------*/
typedef void (* api_msg_decode)(struct api_msg_msg *msg);
static api_msg_decode decode[API_MSG_MAX] = {
do_newconn,
do_delconn,
do_bind,
do_connect,
do_listen,
do_accept,
do_send,
do_recv,
do_write,
do_close
};
void
api_msg_input(struct api_msg *msg)
{
decode[msg->type](&(msg->msg));
}
/*-----------------------------------------------------------------------------------*/
void
api_msg_post(struct api_msg *msg)
{
tcpip_apimsg(msg);
}
/*-----------------------------------------------------------------------------------*/

59
src/api/err.c Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/err.h"
#ifdef LWIP_DEBUG
static char *err_strerr[] = {"Ok.",
"Out of memory error.",
"Buffer error.",
"Connection aborted.",
"Connection reset.",
"Connection closed.",
"Not connected.",
"Illegal value.",
"Illegal argument.",
"Routing problem.",
"Address in use."
};
/*-----------------------------------------------------------------------------------*/
char *
lwip_strerr(err_t err)
{
return err_strerr[-err];
}
/*-----------------------------------------------------------------------------------*/
#endif /* LWIP_DEBUG */

441
src/api/sockets.c Normal file
View File

@@ -0,0 +1,441 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/api.h"
#include "lwip/sockets.h"
#define NUM_SOCKETS 10
struct lwip_socket {
struct netconn *conn;
struct netbuf *lastdata;
u16_t lastoffset;
};
static struct lwip_socket sockets[NUM_SOCKETS];
/*-----------------------------------------------------------------------------------*/
static struct lwip_socket *
get_socket(int s)
{
struct lwip_socket *sock;
if(s > NUM_SOCKETS) {
/* errno = EBADF; */
return NULL;
}
sock = &sockets[s];
if(sock->conn == NULL) {
/* errno = EBADF; */
return NULL;
}
return sock;
}
/*-----------------------------------------------------------------------------------*/
static int
alloc_socket(struct netconn *newconn)
{
int i;
/* allocate a new socket identifier */
for(i = 0; i < NUM_SOCKETS; ++i) {
if(sockets[i].conn == NULL) {
sockets[i].conn = newconn;
sockets[i].lastdata = NULL;
sockets[i].lastoffset = 0;
return i;
}
}
return -1;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_accept(int s, struct sockaddr *addr, int *addrlen)
{
struct lwip_socket *sock;
struct netconn *newconn;
struct ip_addr *naddr;
u16_t port;
int newsock;
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
newconn = netconn_accept(sock->conn);
/* 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;
newsock = alloc_socket(newconn);
if(newsock == -1) {
netconn_delete(newconn);
/* errno = ENOBUFS; */
}
return newsock;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_bind(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) {
return -1;
}
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)name)->sin_port;
err = netconn_bind(sock->conn, &remote_addr, ntohs(remote_port));
if(err != ERR_OK) {
/* errno = ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_close(int s)
{
struct lwip_socket *sock;
DEBUGF(SOCKETS_DEBUG, ("close: socket %d\n", s));
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
netconn_delete(sock->conn);
if(sock->lastdata != NULL) {
netbuf_delete(sock->lastdata);
}
sock->lastdata = NULL;
sock->lastoffset = 0;
sock->conn = NULL;
return 0;
}
/*-----------------------------------------------------------------------------------*/
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) {
return -1;
}
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));
if(err != ERR_OK) {
/* errno = ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_listen(int s, int backlog)
{
struct lwip_socket *sock;
err_t err;
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
err = netconn_listen(sock->conn);
if(err != ERR_OK) {
/* errno = ... */
return -1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
struct sockaddr *from, int *fromlen)
{
struct lwip_socket *sock;
struct netbuf *buf;
u16_t buflen, copylen;
struct ip_addr *addr;
u16_t port;
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
/* Check if there is data left from the last recv operation. */
if(sock->lastdata != NULL) {
buf = sock->lastdata;
} else {
/* 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) {
/* We should really do some error checking here. */
return 0;
}
}
buflen = netbuf_len(buf);
buflen -= sock->lastoffset;
if(len > buflen) {
copylen = buflen;
} else {
copylen = len;
}
/* copy the contents of the received buffer into
the supplied memory pointer mem */
netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
/* If this is a TCP socket, check if there is data left in the
buffer. If so, it should be saved in the sock structure for next
time around. */
if(netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
sock->lastdata = buf;
sock->lastoffset += copylen;
} else {
sock->lastdata = NULL;
sock->lastoffset = 0;
netbuf_delete(buf);
}
/* Check to see from where the data was. */
if(from != NULL && fromlen != NULL) {
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;
*fromlen = sizeof(struct sockaddr_in);
}
/* if the length of the received data is larger than
len, this data is discarded and we return len.
otherwise we return the actual length of the received
data */
if(len > copylen) {
return copylen;
} else {
return len;
}
}
/*-----------------------------------------------------------------------------------*/
int
lwip_read(int s, void *mem, int len)
{
return lwip_recv(s, mem, len, 0);
}
/*-----------------------------------------------------------------------------------*/
int
lwip_recv(int s, void *mem, int len, unsigned int flags)
{
return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
}
/*-----------------------------------------------------------------------------------*/
int
lwip_send(int s, void *data, int size, unsigned int flags)
{
struct lwip_socket *sock;
struct netbuf *buf;
err_t err;
DEBUGF(SOCKETS_DEBUG, ("send: socket %d, size %d\n", s, size));
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
switch(netconn_type(sock->conn)) {
case NETCONN_UDP:
/* create a buffer */
buf = netbuf_new();
if(buf == NULL) {
/* errno = ENOBUFS; */
return -1;
}
/* make the buffer point to the data that should
be sent */
netbuf_ref(buf, data, size);
/* send the data */
err = netconn_send(sock->conn, buf);
/* deallocated the buffer */
netbuf_delete(buf);
break;
case NETCONN_TCP:
err = netconn_write(sock->conn, data, size, NETCONN_COPY);
break;
default:
err = ERR_ARG;
break;
}
if(err != ERR_OK) {
/* errno = ... */
return -1;
}
return size;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_sendto(int s, void *data, int size, unsigned int flags,
struct sockaddr *to, int tolen)
{
struct lwip_socket *sock;
struct ip_addr remote_addr, *addr;
u16_t remote_port, port;
int ret;
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
/* get the peer if currently connected */
netconn_peer(sock->conn, &addr, &port);
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)to)->sin_port;
netconn_connect(sock->conn, &remote_addr, remote_port);
ret = lwip_send(s, data, size, flags);
/* reset the remote address and port number
of the connection */
netconn_connect(sock->conn, addr, port);
return ret;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_socket(int domain, int type, int protocol)
{
struct netconn *conn;
int i;
/* create a netconn */
switch(type) {
case SOCK_DGRAM:
conn = netconn_new(NETCONN_UDP);
break;
case SOCK_STREAM:
conn = netconn_new(NETCONN_TCP);
break;
default:
/* errno = ... */
return -1;
}
if(conn == NULL) {
DEBUGF(SOCKETS_DEBUG, ("socket: could not create netconn.\n"));
/* errno = ENOBUFS; */
return -1;
}
i = alloc_socket(conn);
if(i == -1) {
/* errno = ENOBUFS; */
netconn_delete(conn);
}
return i;
}
/*-----------------------------------------------------------------------------------*/
int
lwip_write(int s, void *data, int size)
{
struct lwip_socket *sock;
err_t err;
DEBUGF(SOCKETS_DEBUG, ("write: socket %d, size %d\n", s, size));
sock = get_socket(s);
if(sock == NULL) {
return -1;
}
switch(netconn_type(sock->conn)) {
case NETCONN_UDP:
return lwip_send(s, data, size, 0);
case NETCONN_TCP:
err = netconn_write(sock->conn, data, size, NETCONN_COPY);
break;
default:
err = ERR_ARG;
break;
}
if(err != ERR_OK) {
/* errno = ... */
return -1;
}
return size;
}
/*-----------------------------------------------------------------------------------*/

137
src/api/tcpip.c Normal file
View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/ip.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/tcpip.h"
static void (* tcpip_init_done)(void *arg) = NULL;
static void *tcpip_init_done_arg;
static sys_mbox_t mbox;
/*-----------------------------------------------------------------------------------*/
static void
tcpip_tcp_timer(void *arg)
{
tcp_tmr();
sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
tcpip_thread(void *arg)
{
struct tcpip_msg *msg;
ip_init();
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);
}
while(1) { /* MAIN Loop */
sys_mbox_fetch(mbox, (void *)&msg);
switch(msg->type) {
case TCPIP_MSG_API:
DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", msg));
api_msg_input(msg->msg.apimsg);
break;
case TCPIP_MSG_INPUT:
DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", msg));
ip_input(msg->msg.inp.p, msg->msg.inp.netif);
break;
default:
break;
}
memp_freep(MEMP_TCPIP_MSG, msg);
}
}
/*-----------------------------------------------------------------------------------*/
err_t
tcpip_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_INPUT;
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)
{
struct tcpip_msg *msg;
msg = memp_mallocp(MEMP_TCPIP_MSG);
if(msg == NULL) {
memp_free(MEMP_API_MSG, apimsg);
return;
}
msg->type = TCPIP_MSG_API;
msg->msg.apimsg = apimsg;
sys_mbox_post(mbox, msg);
}
/*-----------------------------------------------------------------------------------*/
void
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);
}
/*-----------------------------------------------------------------------------------*/

1
src/arch/6502/README Normal file
View File

@@ -0,0 +1 @@
The 6502 code is far from complete.

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif /* __CC_H__ */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CPU_H__
#define __CPU_H__
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* __CPU_H__ */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LIB_H__
#define __LIB_H__
int strlen(const char *str);
int strncmp(const char *str1, const char *str2, int len);
void bcopy(const void *src, void *dest, int len);
void bzero(void *data, int n);
#endif /* __LIB_H__ */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_C64_H__
#define __SYS_C64_H__
#define SYS_MBOX_NULL 0
typedef int sys_sem_t;
typedef int sys_mbox_t;
typedef int sys_thread_t;
#endif /* __SYS_C64_H__ */

63
src/arch/6502/lib_arch.c Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* These are generic implementations of various library functions used
* throughout the lwIP code. When porting, those should be optimized
* for the particular processor architecture, preferably coded in
* assembler.
*/
#include "lwip/arch.h"
/*-----------------------------------------------------------------------------------*/
void
bcopy(const void *src, void *dst, unsigned int size)
{
char *csrc, *cdst;
unsigned int i;
csrc = (char *)src;
cdst = dst;
for(i = 0; i < size; ++i) {
cdst[i] = csrc[i];
}
}
/*-----------------------------------------------------------------------------------*/
void
bzero(void *s, int n)
{
for(--n ;n >= 0; --n) {
((char *)s)[n] = 0;
}
}
/*-----------------------------------------------------------------------------------*/

120
src/arch/6502/sys_c64.c Normal file
View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <c64.h>
#include <time.h>
#include "lwip/sys.h"
#include "lwip/def.h"
struct sys_timeouts timeouts;
/*-----------------------------------------------------------------------------------*/
void
sys_arch_block(u16_t time)
{
u16_t ticks;
ticks = time * (CLK_TCK / 1000) + clock();
printf("ticks %d\n", ticks);
while(clock() != ticks);
}
/*-----------------------------------------------------------------------------------*/
sys_mbox_t
sys_mbox_new(void)
{
return SYS_MBOX_NULL;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_free(sys_mbox_t mbox)
{
return;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(sys_mbox_t mbox, void *data)
{
return;
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u16_t timeout)
{
sys_arch_block(timeout);
return 0;
}
/*-----------------------------------------------------------------------------------*/
sys_sem_t
sys_sem_new(u8_t count)
{
return 0;
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
{
sys_arch_block(timeout);
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_signal(sys_sem_t sem)
{
return;
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_free(sys_sem_t sem)
{
return;
}
/*-----------------------------------------------------------------------------------*/
void
sys_init(void)
{
timeouts.next = NULL;
return;
}
/*-----------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
return &timeouts;
}
/*-----------------------------------------------------------------------------------*/
void
sys_thread_new(void (* function)(void *arg), void *arg)
{
}
/*-----------------------------------------------------------------------------------*/

15
src/arch/FILES Normal file
View File

@@ -0,0 +1,15 @@
6502/ - Architectural files for the 6502 CPU.
rtxc/ - Architectural files for the RTXC operating system.
unix/ - Architectural files for testing on unix-like systems
(assuming gcc and pthreads).
Each subdirectory (may) also include:
perf.c - Optional file that should be implemented when running
performance tests of lwIP.
sys.c - Implementation of the operating system emulation layer.
netif/ - Architectural specific network interfaces.

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif /* __CC_H__ */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CPU_H__
#define __CPU_H__
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* __CPU_H__ */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_INIT_H__
#define __ARCH_INIT_H__
#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
void tcpip_init_done(void *);
int wait_for_tcpip_init(void);
#endif /* __ARCH_INIT_H__ */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LIB_H__
#define __LIB_H__
#include <string.h>
#define bcopy(s, d, l) memcpy(d, s, l)
#define bzero(d, l) memset(d, 0, l)
#endif /* __LIB_H__ */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_RTXC_H__
#define __SYS_RTXC_H__
#include "rtxcapi.h"
#define SYS_MBOX_NULL (QUEUE)0
#define SYS_SEM_NULL (SEMA)0
typedef SEMA sys_sem_t;
typedef QUEUE sys_mbox_t;
typedef TASK sys_thread_t;
#endif /* __SYS_RTXC_H__ */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_CS8900IF_H__
#define __NETIF_CS8900IF_H__
#include "lwip/netif.h"
void cs8900if_init(struct netif *);
u8_t cs8900if_poll(struct netif *);
void cs8900if_input(struct netif *);
#endif /* __NETIF_CS8900IF_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_SIOSLIPIF_H__
#define __NETIF_SIOSLIPIF_H__
#include "lwip/netif.h"
void sioslipif_init(struct netif *);
#endif /* __NETIF_SIOSLIPIF_H__ */

63
src/arch/rtxc/lib.c Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* These are generic implementations of various library functions used
* throughout the lwIP code. When porting, those should be optimized
* for the particular processor architecture, preferably coded in
* assembler.
*/
#if 0 /* Define to 1 if these are really needed. */
/*-----------------------------------------------------------------------------------*/
void
bcopy(const void *src, void *dst, unsigned int size)
{
char *csrc, *cdst;
unsigned int i;
csrc = (char *)src;
cdst = dst;
for(i = 0; i < size; ++i) {
cdst[i] = csrc[i];
}
}
/*-----------------------------------------------------------------------------------*/
void
bzero(void *s, int n)
{
for(--n ;n >= 0; --n) {
((char *)s)[n] = 0;
}
}
/*-----------------------------------------------------------------------------------*/
#endif /* 0 */

View File

@@ -0,0 +1 @@
sioslipif.c - Implementation of the SLIP protocol on top of a serial line.

View File

@@ -0,0 +1,170 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "netif/sioslipif.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#define SLIP_END 0300
#define SLIP_ESC 0333
#define SLIP_ESC_END 0334
#define SLIP_ESC_ESC 0335
/* This variable is used for passing the netif pointer between the
threads. */
static struct netif *netif_pass;
static int infd, outfd;
/*-----------------------------------------------------------------------------------*/
static void
sio_send(u8_t c)
{
write(outfd, &c, 1);
}
/*-----------------------------------------------------------------------------------*/
static u8_t
sio_recv(void)
{
u8_t c;
read(infd, &c, 1);
return c;
}
/*-----------------------------------------------------------------------------------*/
static int
sioslipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct pbuf *q;
int i;
u8_t c;
/* Send pbuf out on the serial I/O device. */
sio_send(SLIP_END);
for(q = p; q != NULL; q = q->next) {
for(i = 0; i < q->len; i++) {
c = ((u8_t *)q->payload)[i];
switch(c) {
case SLIP_END:
sio_send(SLIP_ESC);
sio_send(SLIP_ESC_END);
break;
case SLIP_ESC:
sio_send(SLIP_ESC);
sio_send(SLIP_ESC_ESC);
break;
default:
sio_send(c);
break;
}
}
}
sio_send(SLIP_END);
return 0;
}
/*-----------------------------------------------------------------------------------*/
static struct pbuf *
sioslipif_input(void)
{
u8_t c;
struct pbuf *p, *q;
int recved;
int i;
p = pbuf_alloc(PBUF_LINK, PBUF_MAX_SIZE, PBUF_POOL);
q = p;
recved = i = 0;
while(1) {
c = sio_recv();
switch(c) {
case SLIP_END:
if(recved > 0) {
/* Received whole packet. */
pbuf_realloc(p, recved);
return p;
}
break;
case SLIP_ESC:
c = sio_recv();
switch(c) {
case SLIP_ESC_END:
c = SLIP_END;
break;
case SLIP_ESC_ESC:
c = SLIP_ESC;
break;
}
/* FALLTHROUGH */
default:
if(recved < p->tot_len && q != NULL) {
((u8_t *)q->payload)[i] = c;
recved++;
i++;
if(i >= q->len) {
i = 0;
q = q->next;
}
}
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
sioslipif_loop(void)
{
struct pbuf *p;
struct netif *netif;
netif = netif_pass;
while(1) {
p = sioslipif_input();
netif->input(p, netif);
}
}
/*-----------------------------------------------------------------------------------*/
void
sioslipif_init(struct netif *netif)
{
netif->state = NULL;
netif->name[0] = 's';
netif->name[1] = 'l';
netif->output = sioslipif_output;
netif_pass = netif;
sys_thread_new((void *)sioslipif_loop, NULL);
/* Do some magic to make it possible to receive data from the serial I/O device. */
}
/*-----------------------------------------------------------------------------------*/

38
src/arch/rtxc/perf.c Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "arch/perf.h"
void
perf_init(char *fname)
{
}

271
src/arch/rtxc/sys_arch.c Normal file
View File

@@ -0,0 +1,271 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "rtxcapi.h"
#include "csema.h"
#include "cclock.h"
#include "cqueue.h"
#include "cres.h"
#include "cpart.h"
#include "ctask.h"
struct timeoutlist {
struct sys_timeouts timeouts;
TASK pid;
};
#define SYS_THREAD_MAX 2
static struct timeoutlist timeoutlist[SYS_THREAD_MAX];
static u16_t nextthread = 0;
/*-----------------------------------------------------------------------------------*/
sys_mbox_t
sys_mbox_new(void)
{
QUEUE mbox;
KS_dequeuew(IP_MBOXQ, &mbox);
KS_purgequeue(mbox);
return mbox;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_free(sys_mbox_t mbox)
{
KS_enqueue(IP_MBOXQ, &mbox);
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(sys_mbox_t mbox, void *data)
{
if(KS_enqueue(mbox, &data) != RC_GOOD) {
}
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u16_t timeout)
{
KSRC ret;
u16_t wtime = 1;
if(timeout == 0) {
DEBUGF(SYS_DEBUG, ("PID: %d sys_mbox_fetch: without timeouts\n",KS_inqtask()));
KS_dequeuew(mbox, data);
} else {
ret = KS_dequeuet(mbox, data, (TICKS)timeout/CLKTICK);
if(ret == RC_TIMEOUT) {
/* The call timed out, so we return 0. */
wtime = 0;
} else {
/* Calculate time we waited for the message to arrive. */
/* XXX: we cheat and just pretend that we waited for half the timeout value! */
wtime = timeout / 2;
/* Make sure we don't return 0 here. */
if(wtime == 0) {
wtime = 1;
}
}
}
return wtime;
}
/*-----------------------------------------------------------------------------------*/
sys_sem_t
sys_sem_new(u8_t count)
{
SEMA sem;
KS_dequeuew(IP_SEMQ, &sem);
KS_pend(sem);
if(count > 0) {
KS_signal(sem);
}
return sem;
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
{
KSRC ret;
u16_t wtime = 1;
if(timeout == 0) {
DEBUGF(SYS_DEBUG, ("PID: %d sys_mbox_fetch: without timeouts\n",KS_inqtask()));
KS_wait(sem);
} else {
ret = KS_waitt(sem, (TICKS)timeout/CLKTICK);
if(ret == RC_TIMEOUT) {
/* The call timed out, so we return 0. */
wtime = 0;
} else {
/* Calculate time we waited for the message to arrive. */
/* XXX: we cheat and just pretend that we waited for half the timeout value! */
wtime = timeout / 2;
/* Make sure we don't return 0 here. */
if(wtime == 0) {
wtime = 1;
}
}
}
return wtime;
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_signal(sys_sem_t sem)
{
KS_signal(sem);
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_free(sys_sem_t sem)
{
KS_enqueue(IP_SEMQ, &sem);
}
/*-----------------------------------------------------------------------------------*/
void
sys_init(void)
{
/* posta in alla semaforer i IP_SEMQ, posta in alla mboxar i
IP_MBOXQ */
QUEUE mbox;
SEMA sem;
mbox = IP_Q_01; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_02; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_03; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_04; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_05; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_06; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_07; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_08; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_09; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_10; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_11; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_12; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_13; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_14; KS_enqueue(IP_MBOXQ, &mbox);
mbox = IP_Q_15; KS_enqueue(IP_MBOXQ, &mbox);
sem = IP_S_01; KS_enqueue(IP_SEMQ, &sem);
sem = IP_S_02; KS_enqueue(IP_SEMQ, &sem);
sem = IP_S_03; KS_enqueue(IP_SEMQ, &sem);
}
/*-----------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
int i;
TASK pid;
struct timeoutlist *tl;
DEBUGF(SYS_DEBUG, ("PID: %d sys_mbox_fetch: timeoutlist not empty\n",KS_inqtask()));
pid = KS_inqtask();
for(i = 0; i < nextthread; i++) {
tl = &timeoutlist[i];
if(tl->pid == pid) {
DEBUGF(SYS_DEBUG, ("PID: %d sys_mbox_fetch: corresponding pid found!\n",KS_inqtask()));
return &(tl->timeouts);
}
}
/* Error! */
return NULL;
}
/*-----------------------------------------------------------------------------------*/
struct sys_thread_arg {
void (* thread)(void *);
void *threadarg;
SEMA sem;
};
/*-----------------------------------------------------------------------------------*/
static void
sys_thread(void)
{
struct sys_thread_arg *arg;
void (* thread)(void *);
void *threadarg;
arg = KS_inqtask_arg(0);
if(arg != NULL) {
timeoutlist[nextthread].timeouts.next = NULL;
timeoutlist[nextthread].pid = KS_inqtask();
++nextthread;
thread = arg->thread;
threadarg = arg->threadarg;
KS_signal(arg->sem);
thread(threadarg);
}
KS_terminate(0);
}
/*-----------------------------------------------------------------------------------*/
void
sys_thread_new(void (* function)(void *arg), void *arg)
{
TASK newtask;
PRIORITY pri = 2; /* This may have to be changed. */
char *stack;
int stacksize = 512; /* This may have to be changed. */
struct sys_thread_arg threadarg;
newtask = KS_alloc_task();
stack = KS_allocw(MAP512);
KS_deftask(newtask, pri, (char ks_stk *)stack, (size_t)stacksize, (void (*)(void))sys_thread);
threadarg.thread = function;
threadarg.threadarg = arg;
threadarg.sem = THRDSYNC;
KS_deftask_arg(newtask, &threadarg);
KS_execute(newtask);
KS_wait(THRDSYNC);
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_CC_H__
#define __ARCH_CC_H__
typedef unsigned char u8_t;
typedef signed char s8_t;
/*typedef unsigned short u8_t;
typedef signed short s8_t; */
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef u32_t mem_ptr_t;
#define PACK_STRUCT_FIELD(x) x __attribute__((packed))
#define PACK_STRUCT_STRUCT __attribute__((packed))
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
#endif /* __ARCH_CC_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_CPU_H__
#define __ARCH_CPU_H__
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
#endif /* __ARCH_CPU_H__ */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_INIT_H__
#define __ARCH_INIT_H__
#define TCPIP_INIT_DONE(arg) sys_sem_signal(*(sys_sem_t *)arg)
#endif /* __ARCH_INIT_H__ */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_LIB_H__
#define __ARCH_LIB_H__
#ifndef _STRING_H_
#ifndef _STRING_H
int strlen(const char *str);
int strncmp(const char *str1, const char *str2, int len);
void bcopy(const void *src, void *dest, int len);
void bzero(void *data, int n);
#endif /* _STRING_H */
#endif /* _STRING_H_ */
#endif /* __ARCH_LIB_H__ */

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_PERF_H__
#define __ARCH_PERF_H__
#include <sys/times.h>
#ifdef PERF
#define PERF_START { \
unsigned long __c1l, __c1h, __c2l, __c2h; \
__asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h))
#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \
perf_print(__c1l, __c1h, __c2l, __c2h, x);}
/*#define PERF_START do { \
struct tms __perf_start, __perf_end; \
times(&__perf_start)
#define PERF_STOP(x) times(&__perf_end); \
perf_print_times(&__perf_start, &__perf_end, x);\
} while(0)*/
#else /* PERF */
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* PERF */
void perf_print(unsigned long c1l, unsigned long c1h,
unsigned long c2l, unsigned long c2h,
char *key);
void perf_print_times(struct tms *start, struct tms *end, char *key);
void perf_init(char *fname);
#endif /* __ARCH_PERF_H__ */

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __ARCH_SYS_ARCH_H__
#define __ARCH_SYS_ARCH_H__
#define SYS_MBOX_NULL NULL
#define SYS_SEM_NULL NULL
struct sys_sem;
typedef struct sys_sem * sys_sem_t;
struct sys_mbox;
typedef struct sys_mbox *sys_mbox_t;
struct sys_thread;
typedef struct sys_thread * sys_thread_t;
#endif /* __ARCH_SYS_ARCH_H__ */

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __DELIF_H__
#define __DELIF_H__
#include "lwip/netif.h"
#include "lwip/pbuf.h"
void delif_init(struct netif *netif);
void delif_init_thread(struct netif *netif);
#endif /* __DELIF_H__ */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __DROPIF_H__
#define __DROPIF_H__
#include "lwip/netif.h"
#include "lwip/pbuf.h"
void dropif_init(struct netif *netif);
#endif /* __DROPIF_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __PCAPIF_H__
#define __PCAPIF_H__
#include "lwip/netif.h"
void pcapif_init(struct netif *netif);
#endif /* __PCAPIF_H__ */

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_SIOSLIPIF_H__
#define __NETIF_SIOSLIPIF_H__
#include "lwip/netif.h"
void sioslipif_init(struct netif *);
void sioslipif_init1(struct netif *);
void sioslipif_init2(struct netif *);
#endif /* __NETIF_SIOSLIPIF_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __TAPIF_H__
#define __TAPIF_H__
#include "lwip/netif.h"
void tapif_init(struct netif *netif);
#endif /* __TAPIF_H__ */

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __TUNIF_H__
#define __TUNIF_H__
#include "lwip/netif.h"
#include "lwip/pbuf.h"
void tunif_init(struct netif *netif);
void tunif_init_thread(struct netif *netif);
#endif /* __TUNIF_H__ */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __UNIXIF_H__
#define __UNIXIF_H__
#include "lwip/netif.h"
void unixif_init_server(struct netif *netif);
void unixif_init_client(struct netif *netif);
#endif /* __UNIXIF_H__ */

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/arch.h"
#include "lwip/def.h"
#include "lwip/inet.h"
/*-----------------------------------------------------------------------------------*/
/* lwip_chksum:
*
* Sums up all 16 bit words in a memory portion. Also includes any odd byte.
* This function is used by the other checksum functions.
*
*/
/*-----------------------------------------------------------------------------------*/
#if 0
u16_t
lwip_chksum(void *dataptr, int len)
{
u32_t acc;
for(acc = 0; len > 1; len -= 2) {
acc += *((u16_t *)dataptr)++;
}
/* add up any odd byte */
if(len == 1) {
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", *(u8_t *)dataptr));
}
acc = (acc >> 16) + (acc & 0xffffUL);
if(acc & 0xffff0000 != 0) {
acc = (acc >> 16) + (acc & 0xffffUL);
}
return (u16_t)acc;
}
/*-----------------------------------------------------------------------------------*/
#endif

310
src/arch/unix/netif/delif.c Normal file
View File

@@ -0,0 +1,310 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include <stdlib.h>
#include "lwip/def.h"
#include "netif/delif.h"
#ifdef linux
#include "netif/tapif.h"
#else /* linux */
#include "netif/tunif.h"
#endif /* linux */
#include "lwip/sys.h"
#define DELIF_INPUT_DROPRATE 0.1
#define DELIF_OUTPUT_DROPRATE 0.1
#define DELIF_INPUT_DELAY 500 /* Miliseconds. */
#define DELIF_OUTPUT_DELAY 500 /* Miliseconds. */
#define DELIF_TIMEOUT 10
struct delif {
err_t (* input)(struct pbuf *p, struct netif *inp);
struct netif *netif;
};
struct delif_pbuf {
struct delif_pbuf *next;
struct pbuf *p;
struct ip_addr *ipaddr;
unsigned int time;
};
static struct delif_pbuf *input_list = NULL;
static struct delif_pbuf *output_list = NULL;
/*-----------------------------------------------------------------------------------*/
static void
delif_input_timeout(void *arg)
{
struct netif *netif;
struct delif *delif;
struct delif_pbuf *dp;
unsigned int timeout, now;
timeout = DELIF_TIMEOUT;
netif = arg;
delif = netif->state;
/* Check if there is anything on the input list. */
dp = input_list;
while(dp != NULL) {
now = sys_now();
if(dp->time <= now) {
delif->input(dp->p, netif);
if(dp->next != NULL) {
if(dp->next->time > now) {
timeout = dp->next->time - now;
} else {
timeout = 0;
}
DEBUGF(DELIF_DEBUG, ("delif_output_timeout: timeout %u.\n", timeout));
}
input_list = dp->next;
free(dp);
dp = input_list;
} else {
dp = dp->next;
}
}
sys_timeout(timeout, delif_input_timeout, arg);
}
/*-----------------------------------------------------------------------------------*/
static void
delif_output_timeout(void *arg)
{
struct netif *netif;
struct delif *delif;
struct delif_pbuf *dp;
unsigned int timeout, now;
timeout = DELIF_TIMEOUT;
netif = arg;
delif = netif->state;
/* Check if there is anything on the output list. */
dp = output_list;
while(dp != NULL) {
now = sys_now();
if(dp->time <= now) {
DEBUGF(DELIF_DEBUG, ("delif_output_timeout: now %u dp->time %u\n",
now, dp->time));
delif->netif->output(delif->netif, dp->p, dp->ipaddr);
if(dp->next != NULL) {
if(dp->next->time > now) {
timeout = dp->next->time - now;
} else {
timeout = 0;
}
DEBUGF(DELIF_DEBUG, ("delif_output_timeout: timeout %u.\n", timeout));
}
pbuf_free(dp->p);
output_list = dp->next;
free(dp);
dp = output_list;
} else {
dp = dp->next;
}
}
sys_timeout(timeout, delif_output_timeout, arg);
}
/*-----------------------------------------------------------------------------------*/
static err_t
delif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct delif_pbuf *dp, *np;
struct pbuf *q;
int i, j;
char *data;
DEBUGF(DELIF_DEBUG, ("delif_output\n"));
#ifdef DELIF_OUTPUT_DROPRATE
if(((double)rand()/(double)RAND_MAX) < DELIF_OUTPUT_DROPRATE) {
DEBUGF(DELIF_DEBUG, ("delif_output: Packet dropped\n"));
return 0;
}
#endif /* DELIF_OUTPUT_DROPRATE */
DEBUGF(DELIF_DEBUG, ("delif_output\n"));
dp = malloc(sizeof(struct delif_pbuf));
data = malloc(p->tot_len);
i = 0;
for(q = p; q != NULL; q = q->next) {
for(j = 0; j < q->len; j++) {
data[i] = ((char *)q->payload)[j];
i++;
}
}
dp->p = pbuf_alloc(PBUF_LINK, 0, PBUF_ROM);
dp->p->payload = data;
dp->p->len = p->tot_len;
dp->p->tot_len = p->tot_len;
dp->ipaddr = ipaddr;
dp->time = sys_now() + DELIF_OUTPUT_DELAY;
dp->next = NULL;
if(output_list == NULL) {
output_list = dp;
} else {
for(np = output_list; np->next != NULL; np = np->next);
np->next = dp;
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
delif_input(struct pbuf *p, struct netif *inp)
{
struct delif_pbuf *dp, *np;
DEBUGF(DELIF_DEBUG, ("delif_input\n"));
#ifdef DELIF_INPUT_DROPRATE
if(((double)rand()/(double)RAND_MAX) < DELIF_INPUT_DROPRATE) {
DEBUGF(DELIF_DEBUG, ("delif_input: Packet dropped\n"));
pbuf_free(p);
return ERR_OK;
}
#endif /* DELIF_INPUT_DROPRATE */
dp = malloc(sizeof(struct delif_pbuf));
dp->p = p;
dp->time = sys_now() + DELIF_INPUT_DELAY;
dp->next = NULL;
if(input_list == NULL) {
input_list = dp;
} else {
for(np = input_list; np->next != NULL; np = np->next);
np->next = dp;
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
delif_init(struct netif *netif)
{
struct delif *del;
del = malloc(sizeof(struct delif));
netif->state = del;
netif->name[0] = 'd';
netif->name[1] = 'e';
netif->output = delif_output;
del->netif = malloc(sizeof(struct netif));
#ifdef linux
/* tapif_init(del->netif);*/
tunif_init(del->netif);
#else /* linux */
tunif_init(del->netif);
#endif /* linux */
del->input = netif->input;
del->netif->input = delif_input;
sys_timeout(DELIF_TIMEOUT, delif_input_timeout, netif);
sys_timeout(DELIF_TIMEOUT, delif_output_timeout, netif);
}
/*-----------------------------------------------------------------------------------*/
static void
delif_thread(void *arg)
{
struct netif *netif = arg;
struct delif *del;
sys_sem_t sem;
del = netif->state;
#ifdef linux
tapif_init(del->netif);
#else /* linux */
tunif_init(del->netif);
#endif /* linux */
sys_timeout(DELIF_TIMEOUT, delif_input_timeout, netif);
sys_timeout(DELIF_TIMEOUT, delif_output_timeout, netif);
sem = sys_sem_new(0);
sys_sem_wait(sem);
}
/*-----------------------------------------------------------------------------------*/
void
delif_init_thread(struct netif *netif)
{
struct delif *del;
DEBUGF(DELIF_DEBUG, ("delif_init_thread\n"));
del = malloc(sizeof(struct delif));
netif->state = del;
netif->name[0] = 'd';
netif->name[1] = 'e';
netif->output = delif_output;
del->netif = malloc(sizeof(struct netif));
del->netif->ip_addr = netif->ip_addr;
del->netif->gw = netif->gw;
del->netif->netmask = netif->netmask;
del->input = netif->input;
del->netif->input = delif_input;
sys_thread_new(delif_thread, netif);
}
/*-----------------------------------------------------------------------------------*/

162
src/arch/unix/netif/list.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/list.h"
#include <stdlib.h>
struct list {
struct elem *first, *last;
int size, elems;
};
struct elem {
struct elem *next;
void *data;
};
/*-----------------------------------------------------------------------------------*/
struct list *
list_new(int size)
{
struct list *list;
list = malloc(sizeof(struct list));
list->first = list->last = NULL;
list->size = size;
list->elems = 0;
return list;
}
/*-----------------------------------------------------------------------------------*/
int
list_push(struct list *list, void *data)
{
struct elem *elem;
if(list->elems < list->size) {
elem = malloc(sizeof(struct elem));
elem->data = data;
elem->next = NULL;
if(list->last != NULL) {
list->last->next = elem;
}
list->last = elem;
if(list->first == NULL) {
list->first = elem;
}
list->elems++;
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void *
list_pop(struct list *list)
{
struct elem *elem;
void *data;
if(list->elems > 0) {
elem = list->first;
if(elem == list->last) {
list->last = elem->next;
}
list->first = elem->next;
list->elems--;
data = elem->data;
free(elem);
return data;
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
void *
list_first(struct list *list)
{
return list->first;
}
/*-----------------------------------------------------------------------------------*/
int
list_elems(struct list *list)
{
return list->elems;
}
/*-----------------------------------------------------------------------------------*/
void
list_delete(struct list *list)
{
while(list_pop(list) != NULL);
free(list);
}
/*-----------------------------------------------------------------------------------*/
int
list_remove(struct list *list, void *elem)
{
struct elem *e, *p;
p = NULL;
for(e = list->first; e != NULL; e = e->next) {
if(e->data == elem) {
if(p != NULL) {
p->next = e->next;
} else {
list->first = e->next;
}
if(list->last == e) {
list->last = p;
if(p != NULL) {
p->next = NULL;
}
}
free(e);
list->elems--;
return 1;
}
p = e;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
list_map(struct list *list, void (* func)(void *arg))
{
struct elem *e;
for(e = list->first; e != NULL; e = e->next) {
func(e->data);
}
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -0,0 +1,214 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef linux /* Apparently, this doesn't work under Linux. */
#include "lwip/debug.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#include "netif/etharp.h"
#include "lwip/stats.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "netif/unixif.h"
#include "lwip/sys.h"
#include "lwip/ip.h"
#include "lwip/list.h"
#include "netif/tcpdump.h"
struct pcapif {
pcap_t *pd;
sys_sem_t sem;
u8_t pkt[2048];
u32_t len;
u32_t lasttime;
struct pbuf *p;
struct eth_addr *ethaddr;
};
static char errbuf[PCAP_ERRBUF_SIZE];
/*-----------------------------------------------------------------------------------*/
static err_t
pcapif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
timeout(void *arg)
{
struct netif *netif;
struct pcapif *pcapif;
struct pbuf *p, *q;
u8_t *bufptr;
struct eth_hdr *ethhdr;
netif = (struct netif *)arg;
pcapif = netif->state;
ethhdr = (struct eth_hdr *)pcapif->pkt;
if(htons(ethhdr->type) != ETHTYPE_IP ||
ip_lookup(pcapif->pkt + 14, netif)) {
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_LINK, pcapif->len, PBUF_POOL);
if(p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
bufptr = (u_char *)pcapif->pkt;
for(q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
/* read data into(q->payload, q->len); */
bcopy(bufptr, q->payload, q->len);
bufptr += q->len;
}
ethhdr = p->payload;
switch(htons(ethhdr->type)) {
case ETHTYPE_IP:
arp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case ETHTYPE_ARP:
p = arp_arp_input(netif, pcapif->ethaddr, p);
if(p != NULL) {
printf("ARP outout\n");
pbuf_free(p);
}
break;
default:
pbuf_free(p);
break;
}
}
} else {
printf("ip_lookup dropped\n");
}
sys_sem_signal(pcapif->sem);
}
/*-----------------------------------------------------------------------------------*/
static void
callback(u_char *arg, const struct pcap_pkthdr *hdr, const u_char *pkt)
{
struct netif *netif;
struct pcapif *pcapif;
u32_t time, lasttime;
netif = (struct netif *)arg;
pcapif = netif->state;
pcapif->len = hdr->len;
bcopy(pkt, pcapif->pkt, hdr->len);
time = hdr->ts.tv_sec * 1000 + hdr->ts.tv_usec / 1000;
lasttime = pcapif->lasttime;
pcapif->lasttime = time;
if(lasttime == 0) {
sys_timeout(1000, timeout, netif);
} else {
sys_timeout(time - lasttime, timeout, netif);
}
}
/*-----------------------------------------------------------------------------------*/
static void
pcapif_thread(void *arg)
{
struct netif *netif;
struct pcapif *pcapif;
netif = arg;
pcapif = netif->state;
while(1) {
pcap_loop(pcapif->pd, 1, callback, (u_char *)netif);
sys_sem_wait(pcapif->sem);
if(pcapif->p != NULL) {
netif->input(pcapif->p, netif);
}
}
}
/*-----------------------------------------------------------------------------------*/
void
pcapif_init(struct netif *netif)
{
struct pcapif *p;
p = malloc(sizeof(struct pcapif));
netif->state = p;
netif->name[0] = 'p';
netif->name[1] = 'c';
netif->output = pcapif_output;
p->pd = pcap_open_offline("pcapdump", errbuf);
if(p->pd == NULL) {
printf("pcapif_init: failed %s\n", errbuf);
return;
}
p->sem = sys_sem_new(0);
p->p = NULL;
p->lasttime = 0;
sys_thread_new(pcapif_thread, netif);
}
/*-----------------------------------------------------------------------------------*/
#endif /* linux */

View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "netif/sioslipif.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
/* The maximum size that an incoming packet can have. */
#define MAX_SIZE 1500
#define SLIP_END 0300
#define SLIP_ESC 0333
#define SLIP_ESC_END 0334
#define SLIP_ESC_ESC 0335
/* Define those to whatever is needed to send and receive one byte of
data. */
#define SIO_SEND(c)
#define SIO_RECV(c)
static const unsigned char slip_end = SLIP_END,
slip_esc = SLIP_ESC,
slip_esc_end = SLIP_ESC_END,
slip_esc_esc = SLIP_ESC_ESC;
/*-----------------------------------------------------------------------------------*/
static err_t
sioslipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct pbuf *q;
int i;
unsigned char *ptr;
u8_t c;
/* Send pbuf out on the serial I/O device. */
SIO_SEND(slip_end);
for(q = p; q != NULL; q = q->next) {
ptr = q->payload;
for(i = 0; i < q->len; i++) {
c = *ptr++;
switch(c) {
case SLIP_END:
SIO_SEND(slip_esc);
SIO_SEND(slip_esc_end);
break;
case SLIP_ESC:
SIO_SEND(slip_esc);
SIO_SEND(slip_esc_esc);
break;
default:
SIO_SEND(c);
break;
}
}
}
#ifdef LINK_STATS
stats.link.xmit++;
#endif /* LINK_STATS */
SIO_SEND(slip_end);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static struct pbuf *
sioslipif_input(void)
{
u8_t c;
struct pbuf *p, *q;
int recved;
int i;
q = p = NULL;
recved = i = 0;
c = 0;
while(1) {
SIO_RECV(c);
switch(c) {
case SLIP_END:
if(p == NULL) {
return sioslipif_input();
}
if(recved > 0) {
/* Received whole packet. */
pbuf_realloc(q, recved);
#ifdef LINK_STATS
stats.link.recv++;
#endif /* LINK_STATS */
return q;
}
break;
case SLIP_ESC:
SIO_RECV(c);
switch(c) {
case SLIP_ESC_END:
c = SLIP_END;
break;
case SLIP_ESC_ESC:
c = SLIP_ESC;
break;
}
/* FALLTHROUGH */
default:
if(p == NULL) {
p = pbuf_alloc(PBUF_LINK, 128, PBUF_POOL);
#ifdef LINK_STATS
if(p == NULL) {
stats.link.drop++;
}
#endif /* LINK_STATS */
if(q != NULL) {
pbuf_chain(q, p);
} else {
q = p;
}
}
if(p != NULL && recved < MAX_SIZE) {
((u8_t *)p->payload)[i] = c;
recved++;
i++;
if(i >= p->len) {
i = 0;
p = NULL;
}
}
break;
}
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
static void
sioslipif_loop(void *arg)
{
struct pbuf *p;
struct netif *netif;
netif = arg;
while(1) {
p = sioslipif_input();
netif->input(p, netif);
}
}
/*-----------------------------------------------------------------------------------*/
void
sioslipif_init(struct netif *netif)
{
netif->state = NULL;
netif->name[0] = 's';
netif->name[1] = 'l';
netif->output = sioslipif_output;
sys_thread_new((void *)sioslipif_loop, netif);
/* Do some magic to make it possible to receive data from the serial I/O device. */
}
/*-----------------------------------------------------------------------------------*/

355
src/arch/unix/netif/tapif.c Normal file
View File

@@ -0,0 +1,355 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "netif/etharp.h"
#ifdef linux
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#define DEVTAP "/dev/net/tun"
#else /* linux */
#define DEVTAP "/dev/tap0"
#endif /* linux */
#define IFNAME0 't'
#define IFNAME1 'p'
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
struct tapif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
int fd;
};
/* Forward declarations. */
static void tapif_input(struct netif *netif);
static err_t tapif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
static void tapif_thread(void *data);
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
struct tapif *tapif;
char buf[100];
tapif = netif->state;
/* Obtain MAC address from network interface. */
/* (We just fake an address...) */
tapif->ethaddr->addr[0] = 0x1;
tapif->ethaddr->addr[1] = 0x2;
tapif->ethaddr->addr[2] = 0x3;
tapif->ethaddr->addr[3] = 0x4;
tapif->ethaddr->addr[4] = 0x5;
tapif->ethaddr->addr[5] = 0x6;
/* Do whatever else is needed to initialize interface. */
tapif->fd = open(DEVTAP, O_RDWR);
DEBUGF(TAPIF_DEBUG, ("tapif_init: fd %d\n", tapif->fd));
if(tapif->fd == -1) {
perror("tapif_init");
exit(1);
}
#ifdef linux
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
perror(buf);
exit(1);
}
}
#endif /* Linux */
snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
ip4_addr1(&(netif->gw)),
ip4_addr2(&(netif->gw)),
ip4_addr3(&(netif->gw)),
ip4_addr4(&(netif->gw)));
DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
system(buf);
sys_thread_new(tapif_thread, netif);
}
/*-----------------------------------------------------------------------------------*/
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
/*-----------------------------------------------------------------------------------*/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
char buf[1500];
char *bufptr;
struct tapif *tapif;
tapif = netif->state;
/* initiate transfer(); */
bufptr = &buf[0];
for(q = p; q != NULL; q = q->next) {
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
bcopy(q->payload, bufptr, q->len);
bufptr += q->len;
}
/* signal that packet should be sent(); */
if(write(tapif->fd, buf, p->tot_len) == -1) {
perror("tapif: write");
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
/*-----------------------------------------------------------------------------------*/
static struct pbuf *
low_level_input(struct tapif *tapif)
{
struct pbuf *p, *q;
u16_t len;
char buf[1500];
char *bufptr;
/* Obtain the size of the packet and put it into the "len"
variable. */
len = read(tapif->fd, buf, sizeof(buf));
/* if(((double)rand()/(double)RAND_MAX) < 0.1) {
printf("drop\n");
return NULL;
}*/
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
if(p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
bufptr = &buf[0];
for(q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
/* read data into(q->payload, q->len); */
bcopy(bufptr, q->payload, q->len);
bufptr += q->len;
}
/* acknowledge that packet has been read(); */
} else {
/* drop packet(); */
}
return p;
}
/*-----------------------------------------------------------------------------------*/
static void
tapif_thread(void *arg)
{
struct netif *netif;
struct tapif *tapif;
fd_set fdset;
int ret;
netif = arg;
tapif = netif->state;
while(1) {
FD_ZERO(&fdset);
FD_SET(tapif->fd, &fdset);
/* Wait for a packet to arrive. */
ret = select(tapif->fd + 1, &fdset, NULL, NULL, NULL);
if(ret == 1) {
/* Handle incoming packet. */
tapif_input(netif);
} else if(ret == -1) {
perror("tapif_thread: select");
}
}
}
/*-----------------------------------------------------------------------------------*/
/*
* tapif_output():
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actuall transmission of the packet.
*
*/
/*-----------------------------------------------------------------------------------*/
static err_t
tapif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
p = etharp_output(netif, ipaddr, p);
if(p != NULL) {
return low_level_output(netif, p);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
* tapif_input():
*
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface.
*
*/
/*-----------------------------------------------------------------------------------*/
static void
tapif_input(struct netif *netif)
{
struct tapif *tapif;
struct eth_hdr *ethhdr;
struct pbuf *p, *q;
tapif = netif->state;
p = low_level_input(tapif);
if(p == NULL) {
DEBUGF(TAPIF_DEBUG, ("tapif_input: low_level_input returned NULL\n"));
return;
}
ethhdr = p->payload;
q = NULL;
switch(htons(ethhdr->type)) {
case ETHTYPE_IP:
DEBUGF(TAPIF_DEBUG, ("tapif_input: IP packet\n"));
q = etharp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case ETHTYPE_ARP:
DEBUGF(TAPIF_DEBUG, ("tapif_input: ARP packet\n"));
q = etharp_arp_input(netif, tapif->ethaddr, p);
break;
default:
pbuf_free(p);
break;
}
if(q != NULL) {
low_level_output(netif, q);
pbuf_free(q);
}
}
/*-----------------------------------------------------------------------------------*/
static void
arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/*-----------------------------------------------------------------------------------*/
/*
* tapif_init():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
*/
/*-----------------------------------------------------------------------------------*/
void
tapif_init(struct netif *netif)
{
struct tapif *tapif;
tapif = mem_malloc(sizeof(struct tapif));
netif->state = tapif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = tapif_output;
netif->linkoutput = low_level_output;
tapif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/*-----------------------------------------------------------------------------------*/

298
src/arch/unix/netif/tunif.c Normal file
View File

@@ -0,0 +1,298 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#define IFNAME0 't'
#define IFNAME1 'n'
struct tunif {
/* Add whatever per-interface state that is needed here. */
int fd;
};
/* Forward declarations. */
static void tunif_input(struct netif *netif);
static err_t tunif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
static void tunif_thread(void *data);
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
struct tunif *tunif;
char buf[100];
tunif = netif->state;
/* Obtain MAC address from network interface. */
/* Do whatever else is needed to initialize interface. */
tunif->fd = open("/dev/tun0", O_RDWR);
DEBUGF(TUNIF_DEBUG, ("tunif_init: fd %d\n", tunif->fd));
if(tunif->fd == -1) {
perror("tunif_init");
exit(1);
}
snprintf(buf, sizeof(buf), "ifconfig tun0 inet %d.%d.%d.%d %d.%d.%d.%d",
ip4_addr1(&(netif->gw)),
ip4_addr2(&(netif->gw)),
ip4_addr3(&(netif->gw)),
ip4_addr4(&(netif->gw)),
ip4_addr1(&(netif->ip_addr)),
ip4_addr2(&(netif->ip_addr)),
ip4_addr3(&(netif->ip_addr)),
ip4_addr4(&(netif->ip_addr)));
DEBUGF(TUNIF_DEBUG, ("tunif_init: system(\"%s\");\n", buf));
system(buf);
sys_thread_new(tunif_thread, netif);
}
/*-----------------------------------------------------------------------------------*/
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
/*-----------------------------------------------------------------------------------*/
static err_t
low_level_output(struct tunif *tunif, struct pbuf *p)
{
struct pbuf *q;
char buf[1500];
char *bufptr;
/* initiate transfer(); */
if(((double)rand()/(double)RAND_MAX) < 0.4) {
printf("drop\n");
return ERR_OK;
}
bufptr = &buf[0];
for(q = p; q != NULL; q = q->next) {
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
bcopy(q->payload, bufptr, q->len);
bufptr += q->len;
}
/* signal that packet should be sent(); */
if(write(tunif->fd, buf, p->tot_len) == -1) {
perror("tunif: write");
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
/*-----------------------------------------------------------------------------------*/
static struct pbuf *
low_level_input(struct tunif *tunif)
{
struct pbuf *p, *q;
u16_t len;
char buf[1500];
char *bufptr;
/* Obtain the size of the packet and put it into the "len"
variable. */
len = read(tunif->fd, buf, sizeof(buf));
/* if(((double)rand()/(double)RAND_MAX) < 0.1) {
printf("drop\n");
return NULL;
}*/
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
if(p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
bufptr = &buf[0];
for(q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
/* read data into(q->payload, q->len); */
bcopy(bufptr, q->payload, q->len);
bufptr += q->len;
}
/* acknowledge that packet has been read(); */
} else {
/* drop packet(); */
}
return p;
}
/*-----------------------------------------------------------------------------------*/
static void
tunif_thread(void *arg)
{
struct netif *netif;
struct tunif *tunif;
fd_set fdset;
int ret;
netif = arg;
tunif = netif->state;
while(1) {
FD_ZERO(&fdset);
FD_SET(tunif->fd, &fdset);
/* Wait for a packet to arrive. */
ret = select(tunif->fd + 1, &fdset, NULL, NULL, NULL);
if(ret == 1) {
/* Handle incoming packet. */
tunif_input(netif);
} else if(ret == -1) {
perror("tunif_thread: select");
}
}
}
/*-----------------------------------------------------------------------------------*/
/*
* tunif_output():
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actuall transmission of the packet.
*
*/
/*-----------------------------------------------------------------------------------*/
static err_t
tunif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr)
{
struct tunif *tunif;
tunif = netif->state;
return low_level_output(tunif, p);
}
/*-----------------------------------------------------------------------------------*/
/*
* tunif_input():
*
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface.
*
*/
/*-----------------------------------------------------------------------------------*/
static void
tunif_input(struct netif *netif)
{
struct tunif *tunif;
struct pbuf *p;
tunif = netif->state;
p = low_level_input(tunif);
if(p == NULL) {
DEBUGF(TUNIF_DEBUG, ("tunif_input: low_level_input returned NULL\n"));
return;
}
if(ip_lookup(p->payload, netif)) {
netif->input(p, netif);
}
}
/*-----------------------------------------------------------------------------------*/
/*
* tunif_init():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
*/
/*-----------------------------------------------------------------------------------*/
void
tunif_init(struct netif *netif)
{
struct tunif *tunif;
tunif = mem_malloc(sizeof(struct tunif));
netif->state = tunif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = tunif_output;
low_level_init(netif);
}
/*-----------------------------------------------------------------------------------*/

View File

@@ -0,0 +1,480 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "lwip/stats.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "netif/unixif.h"
#include "lwip/sys.h"
#include "lwip/list.h"
#include "netif/tcpdump.h"
#define UNIXIF_BPS 512000
#define UNIXIF_QUEUELEN 6
/*#define UNIXIF_DROP_FIRST */
struct unixif_buf {
struct pbuf *p;
unsigned short len, tot_len;
void *payload;
};
struct unixif {
int fd;
sys_sem_t sem;
struct list *q;
};
/*-----------------------------------------------------------------------------------*/
static int
unix_socket_client(char *name)
{
int fd, len;
struct sockaddr_un unix_addr;
/* create a Unix domain stream socket */
if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("unixif: unix_socket_client: socket");
return(-1);
}
/* fill socket address structure w/our address */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
sprintf(unix_addr.sun_path, "%s%05d", "/var/tmp/", getpid());
#ifndef linux
len = sizeof(unix_addr.sun_len) + sizeof(unix_addr.sun_family) +
strlen(unix_addr.sun_path) + 1;
unix_addr.sun_len = len;
#else
len = sizeof(unix_addr.sun_family) +
strlen(unix_addr.sun_path) + 1;
#endif /* linux */
unlink(unix_addr.sun_path); /* in case it already exists */
if(bind(fd, (struct sockaddr *) &unix_addr,
sizeof(struct sockaddr_un)) < 0) {
perror("unixif: unix_socket_client: socket");
return(-1);
}
if(chmod(unix_addr.sun_path, S_IRWXU | S_IRWXO) < 0) {
perror("unixif: unix_socket_client: socket");
return(-1);
}
/* fill socket address structure w/server's addr */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, name);
#ifndef linux
len = sizeof(unix_addr.sun_len) + sizeof(unix_addr.sun_family) +
strlen(unix_addr.sun_path) + 1;
unix_addr.sun_len = len;
#else
len = sizeof(unix_addr.sun_family) + strlen(unix_addr.sun_path) + 1;
#endif /* linux */
if(connect(fd, (struct sockaddr *) &unix_addr,
sizeof(struct sockaddr_un)) < 0) {
perror("unixif: unix_socket_client: socket");
return(-1);
}
return(fd);
}
/*-----------------------------------------------------------------------------------*/
static int
unix_socket_server(char *name)
{
int fd, len;
struct sockaddr_un unix_addr;
/* create a Unix domain stream socket */
if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("unixif: unix_socket_server: socket");
return(-1);
}
unlink(name); /* in case it already exists */
/* fill in socket address structure */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, name);
#ifndef linux
len = sizeof(unix_addr.sun_len) + sizeof(unix_addr.sun_family) +
strlen(unix_addr.sun_path) + 1;
unix_addr.sun_len = len;
#else
len = sizeof(unix_addr.sun_family) +
strlen(unix_addr.sun_path) + 1;
#endif /* linux */
/* bind the name to the descriptor */
if(bind(fd, (struct sockaddr *) &unix_addr,
sizeof(struct sockaddr_un)) < 0) {
perror("unixif: unix_socket_server: bind");
return(-1);
}
if(chmod(unix_addr.sun_path, S_IRWXU | S_IRWXO) < 0) {
perror("unixif: unix_socket_server: chmod");
return(-1);
}
if(listen(fd, 5) < 0) { /* tell kernel we're a server */
perror("unixif: unix_socket_server: listen");
return(-1);
}
return(fd);
}
/*-----------------------------------------------------------------------------------*/
static void
unixif_input_handler(void *data)
{
struct netif *netif;
struct unixif *unixif;
char buf[4096], *bufptr;
int len, plen, rlen;
struct pbuf *p, *q;
netif = data;
unixif = netif->state;
len = read(unixif->fd, &plen, sizeof(int));
if(len == -1) {
perror("unixif_irq_handler: read");
abort();
}
DEBUGF(UNIXIF_DEBUG, ("unixif_irq_handler: len == %d plen == %d bytes\n", len, plen));
if(len == sizeof(int)) {
if(plen < 20 || plen > 1500) {
DEBUGF(UNIXIF_DEBUG, ("plen %d!\n", plen));
return;
}
len = read(unixif->fd, buf, plen);
if(len == -1) {
perror("unixif_irq_handler: read");
abort();
}
DEBUGF(UNIXIF_DEBUG, ("unixif_irq_handler: read %d bytes\n", len));
p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL);
if(p != NULL) {
rlen = len;
bufptr = buf;
q = p;
while(rlen > 0) {
bcopy(bufptr, q->payload, rlen > q->len? q->len: rlen);
rlen -= q->len;
bufptr += q->len;
q = q->next;
}
pbuf_realloc(p, len);
#ifdef LINK_STATS
stats.link.recv++;
#endif /* LINK_STATS */
tcpdump(p);
netif->input(p, netif);
} else {
DEBUGF(UNIXIF_DEBUG, ("unixif_irq_handler: could not allocate pbuf\n"));
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
unixif_thread(void *arg)
{
struct netif *netif;
struct unixif *unixif;
DEBUGF(UNIXIF_DEBUG, ("unixif_thread: started.\n"));
netif = arg;
unixif = netif->state;
while(1) {
sys_sem_wait(unixif->sem);
unixif_input_handler(netif);
}
}
/*-----------------------------------------------------------------------------------*/
static void
unixif_thread2(void *arg)
{
struct netif *netif;
struct unixif *unixif;
fd_set fdset;
DEBUGF(UNIXIF_DEBUG, ("unixif_thread2: started.\n"));
netif = arg;
unixif = netif->state;
while(1) {
FD_ZERO(&fdset);
FD_SET(unixif->fd, &fdset);
if(select(unixif->fd + 1, &fdset, NULL, NULL, NULL) > 0) {
sys_sem_signal(unixif->sem);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void unixif_output_timeout(void *arg);
static err_t
unixif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct unixif *unixif;
struct unixif_buf *buf;
unixif = netif->state;
buf = malloc(sizeof(struct unixif_buf));
buf->p = p;
buf->len = p->len;
buf->tot_len = p->tot_len;
buf->payload = p->payload;
if(list_elems(unixif->q) == 0) {
pbuf_ref(p);
list_push(unixif->q, buf);
sys_timeout((double)p->tot_len * 8000.0 / UNIXIF_BPS, unixif_output_timeout,
netif);
DEBUGF(UNIXIF_DEBUG, ("unixif_output: first on list\n"));
} else {
pbuf_ref(p);
if(list_push(unixif->q, buf) == 0) {
#ifdef UNIXIF_DROP_FIRST
struct unixif_buf *buf2;
buf2 = list_pop(unixif->q);
pbuf_free(buf2->p);
free(buf2);
list_push(unixif->q, buf);
#else
free(buf);
pbuf_free(p);
DEBUGF(UNIXIF_DEBUG, ("unixif_output: drop\n"));
#endif /* UNIXIF_DROP_FIRST */
#ifdef LINK_STATS
stats.link.drop++;
#endif /* LINK_STATS */
} else {
DEBUGF(UNIXIF_DEBUG, ("unixif_output: on list\n"));
}
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
unixif_output_timeout(void *arg)
{
struct pbuf *p, *q;
int i, j, len;
unsigned short plen, ptot_len;
struct unixif_buf *buf;
void *payload;
struct netif *netif;
struct unixif *unixif;
char *data;
netif = arg;
unixif = netif->state;
DEBUGF(UNIXIF_DEBUG, ("unixif_output_timeout\n"));
/* buf = unixif->q[0];
unixif->q[0] = unixif->q[1];
unixif->q[1] = NULL;*/
buf = list_pop(unixif->q);
p = buf->p;
plen = p->len;
ptot_len = p->tot_len;
payload = p->payload;
p->len = buf->len;
p->tot_len = buf->tot_len;
p->payload = buf->payload;
if(p->tot_len == 0) {
DEBUGF(UNIXIF_DEBUG, ("p->len!\n"));
abort();
}
data = malloc(p->tot_len);
i = 0;
for(q = p; q != NULL; q = q->next) {
for(j = 0; j < q->len; j++) {
data[i] = ((char *)q->payload)[j];
i++;
}
}
DEBUGF(UNIXIF_DEBUG, ("unixif_output: sending %d (%d) bytes\n",
p->len, p->tot_len));
len = p->tot_len;
if(write(unixif->fd, &len, sizeof(int)) == -1) {
perror("unixif_output: write");
abort();
}
if(write(unixif->fd, data, p->tot_len) == -1) {
perror("unixif_output: write");
abort();
}
tcpdump(p);
#ifdef LINK_STATS
stats.link.xmit++;
#endif /* LINK_STATS */
free(data);
free(buf);
p->len = plen;
p->tot_len = ptot_len;
p->payload = payload;
pbuf_free(p);
/* if(unixif->q[0] != NULL) {
sys_timeout(unixif->q[0]->tot_len * 8000 / UNIXIF_BPS,
unixif_output_timeout, netif);
}*/
if(list_elems(unixif->q) > 0) {
sys_timeout(((struct unixif_buf *)list_first(unixif->q))->tot_len *
8000.0 / UNIXIF_BPS,
unixif_output_timeout, netif);
}
}
/*-----------------------------------------------------------------------------------*/
void
unixif_init_server(struct netif *netif)
{
int fd, fd2;
struct sockaddr_un addr;
socklen_t len;
struct unixif *unixif;
fd = unix_socket_server("/tmp/unixif");
if(fd == -1) {
perror("unixif_server");
abort();
}
DEBUGF(UNIXIF_DEBUG, ("unixif_server: fd %d\n", fd));
unixif = malloc(sizeof(struct unixif));
netif->state = unixif;
netif->name[0] = 'u';
netif->name[1] = 'n';
netif->output = unixif_output;
unixif->q = list_new(UNIXIF_QUEUELEN);
printf("Now run ./simnode.\n");
len = sizeof(addr);
fd2 = accept(fd, (struct sockaddr *)&addr, &len);
if(fd2 == -1) {
perror("unixif_accept");
abort();
}
DEBUGF(UNIXIF_DEBUG, ("unixif_accept: %d\n", fd2));
unixif->fd = fd2;
unixif->sem = sys_sem_new(0);
sys_thread_new(unixif_thread, netif);
sys_thread_new(unixif_thread2, netif);
}
/*-----------------------------------------------------------------------------------*/
void
unixif_init_client(struct netif *netif)
{
struct unixif *unixif;
unixif = malloc(sizeof(struct unixif));
netif->state = unixif;
netif->name[0] = 'u';
netif->name[1] = 'n';
netif->output = unixif_output;
unixif->fd = unix_socket_client("/tmp/unixif");
if(unixif->fd == -1) {
perror("unixif_init");
abort();
}
unixif->q = list_new(UNIXIF_QUEUELEN);
unixif->sem = sys_sem_new(0);
sys_thread_new(unixif_thread, netif);
sys_thread_new(unixif_thread2, netif);
}
/*-----------------------------------------------------------------------------------*/

64
src/arch/unix/perf.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "arch/perf.h"
#include <stdio.h>
static FILE *f;
void
perf_print(unsigned long c1l, unsigned long c1h,
unsigned long c2l, unsigned long c2h,
char *key)
{
unsigned long long start, end;
start = (unsigned long long)c2h << 32 | c2l;
end = (unsigned long long)c1h << 32 | c1l;
fprintf(f, "%s: %llu\n", key, start - end);
fflush(NULL);
}
void
perf_print_times(struct tms *start, struct tms *end, char *key)
{
fprintf(f, "%s: %lu\n", key, end->tms_stime - start->tms_stime);
fflush(NULL);
}
void
perf_init(char *fname)
{
f = fopen(fname, "w");
}

453
src/arch/unix/sys_arch.c Normal file
View File

@@ -0,0 +1,453 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* Wed Apr 17 16:05:29 EDT 2002 (James Roth)
*
* - Fixed an unlikely sys_thread_new() race condition.
*
* - Made current_thread() work with threads which where
* not created with sys_thread_new(). This includes
* the main thread and threads made with pthread_create().
*
* - Catch overflows where more than SYS_MBOX_SIZE messages
* are waiting to be read. The sys_mbox_post() routine
* will block until there is more room instead of just
* leaking messages.
*/
#include "lwip/debug.h"
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/stats.h"
#define UMAX(a, b) ((a) > (b) ? (a) : (b))
static struct sys_thread *threads = NULL;
static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
struct sys_mbox_msg {
struct sys_mbox_msg *next;
void *msg;
};
#define SYS_MBOX_SIZE 128
struct sys_mbox {
int first, last;
void *msgs[SYS_MBOX_SIZE];
struct sys_sem *mail;
struct sys_sem *mutex;
int wait_send;
};
struct sys_sem {
unsigned int c;
pthread_cond_t cond;
pthread_mutex_t mutex;
};
struct sys_thread {
struct sys_thread *next;
struct sys_timeouts timeouts;
pthread_t pthread;
};
static struct timeval starttime;
static struct sys_sem *sys_sem_new_(u8_t count);
static void sys_sem_free_(struct sys_sem *sem);
static u16_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
u16_t timeout);
/*-----------------------------------------------------------------------------------*/
static struct sys_thread *
introduce_thread(pthread_t id)
{
struct sys_thread *thread;
thread = malloc(sizeof(struct sys_thread));
if(thread) {
pthread_mutex_lock(&threads_mutex);
thread->next = threads;
thread->timeouts.next = NULL;
thread->pthread = id;
threads = thread;
pthread_mutex_unlock(&threads_mutex);
}
return thread;
}
/*-----------------------------------------------------------------------------------*/
static struct sys_thread *
current_thread(void)
{
struct sys_thread *st;
pthread_t pt;
pt = pthread_self();
pthread_mutex_lock(&threads_mutex);
for(st = threads; st != NULL; st = st->next) {
if(pthread_equal(st->pthread, pt)) {
pthread_mutex_unlock(&threads_mutex);
return st;
}
}
pthread_mutex_unlock(&threads_mutex);
st = introduce_thread(pt);
if(!st) {
printf("current_thread???\n");
abort();
}
return st;
}
/*-----------------------------------------------------------------------------------*/
void
sys_thread_new(void (*function)(void *arg), void *arg)
{
int code;
pthread_t tmp;
struct sys_thread *st = NULL;
code = pthread_create(&tmp,
NULL,
(void *(*)(void *))
function,
arg);
if(0 == code) {
st = introduce_thread(tmp);
}
if(NULL == st) {
DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%x",
code, (int)st));
abort();
}
}
/*-----------------------------------------------------------------------------------*/
struct sys_mbox *
sys_mbox_new()
{
struct sys_mbox *mbox;
mbox = malloc(sizeof(struct sys_mbox));
mbox->first = mbox->last = 0;
mbox->mail = sys_sem_new_(0);
mbox->mutex = sys_sem_new_(1);
mbox->wait_send = 0;
#ifdef SYS_STATS
stats.sys.mbox.used++;
if(stats.sys.mbox.used > stats.sys.mbox.max) {
stats.sys.mbox.max = stats.sys.mbox.used;
}
#endif /* SYS_STATS */
return mbox;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_free(struct sys_mbox *mbox)
{
if(mbox != SYS_MBOX_NULL) {
#ifdef SYS_STATS
stats.sys.mbox.used--;
#endif /* SYS_STATS */
sys_sem_wait(mbox->mutex);
sys_sem_free_(mbox->mail);
sys_sem_free_(mbox->mutex);
mbox->mail = mbox->mutex = NULL;
/* DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
free(mbox);
}
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(struct sys_mbox *mbox, void *msg)
{
u8_t first;
sys_sem_wait(mbox->mutex);
DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", mbox, msg));
while((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
mbox->wait_send++;
sys_sem_signal(mbox->mutex);
sys_arch_sem_wait(mbox->mail, 0);
sys_arch_sem_wait(mbox->mutex, 0);
mbox->wait_send--;
}
mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
if(mbox->last == mbox->first) {
first = 1;
} else {
first = 0;
}
mbox->last++;
if(first) {
sys_sem_signal(mbox->mail);
}
sys_sem_signal(mbox->mutex);
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u16_t timeout)
{
u16_t time = 1;
/* The mutex lock is quick so we don't bother with the timeout
stuff here. */
sys_arch_sem_wait(mbox->mutex, 0);
while(mbox->first == mbox->last) {
sys_sem_signal(mbox->mutex);
/* We block while waiting for a mail to arrive in the mailbox. We
must be prepared to timeout. */
if(timeout != 0) {
time = sys_arch_sem_wait(mbox->mail, timeout);
/* If time == 0, the sem_wait timed out, and we return 0. */
if(time == 0) {
return 0;
}
} else {
sys_arch_sem_wait(mbox->mail, 0);
}
sys_arch_sem_wait(mbox->mutex, 0);
}
DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", mbox, *msg));
if(msg != NULL) {
*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
}
mbox->first++;
if(mbox->wait_send) {
sys_sem_signal(mbox->mail);
}
sys_sem_signal(mbox->mutex);
return time;
}
/*-----------------------------------------------------------------------------------*/
struct sys_sem *
sys_sem_new(u8_t count)
{
#ifdef SYS_STATS
stats.sys.sem.used++;
if(stats.sys.sem.used > stats.sys.sem.max) {
stats.sys.sem.max = stats.sys.sem.used;
}
#endif /* SYS_STATS */
return sys_sem_new_(count);
}
/*-----------------------------------------------------------------------------------*/
static struct sys_sem *
sys_sem_new_(u8_t count)
{
struct sys_sem *sem;
sem = malloc(sizeof(struct sys_sem));
sem->c = count;
pthread_cond_init(&(sem->cond), NULL);
pthread_mutex_init(&(sem->mutex), NULL);
return sem;
}
/*-----------------------------------------------------------------------------------*/
static u16_t
cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u16_t timeout)
{
int tdiff;
unsigned long sec, usec;
struct timeval rtime1, rtime2;
struct timespec ts;
struct timezone tz;
int retval;
if(timeout > 0) {
/* Get a timestamp and add the timeout value. */
gettimeofday(&rtime1, &tz);
sec = rtime1.tv_sec;
usec = rtime1.tv_usec;
usec += timeout % 1000 * 1000;
sec += (int)(timeout / 1000) + (int)(usec / 1000000);
usec = usec % 1000000;
ts.tv_nsec = usec * 1000;
ts.tv_sec = sec;
retval = pthread_cond_timedwait(cond, mutex, &ts);
if(retval == ETIMEDOUT) {
return 0;
} else {
/* Calculate for how long we waited for the cond. */
gettimeofday(&rtime2, &tz);
tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +
(rtime2.tv_usec - rtime1.tv_usec) / 1000;
if(tdiff <= 0) {
return 1;
}
return tdiff;
}
} else {
pthread_cond_wait(cond, mutex);
return 0;
}
}
/*-----------------------------------------------------------------------------------*/
u16_t
sys_arch_sem_wait(struct sys_sem *sem, u16_t timeout)
{
u16_t time = 1;
pthread_mutex_lock(&(sem->mutex));
while(sem->c <= 0) {
if(timeout > 0) {
time = cond_wait(&(sem->cond), &(sem->mutex), timeout);
if(time == 0) {
pthread_mutex_unlock(&(sem->mutex));
return 0;
}
/* pthread_mutex_unlock(&(sem->mutex));
return time; */
} else {
cond_wait(&(sem->cond), &(sem->mutex), 0);
}
}
sem->c--;
pthread_mutex_unlock(&(sem->mutex));
return time;
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_signal(struct sys_sem *sem)
{
pthread_mutex_lock(&(sem->mutex));
sem->c++;
if(sem->c > 1) {
sem->c = 1;
}
pthread_cond_broadcast(&(sem->cond));
pthread_mutex_unlock(&(sem->mutex));
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_free(struct sys_sem *sem)
{
if(sem != SYS_SEM_NULL) {
#ifdef SYS_STATS
stats.sys.sem.used--;
#endif /* SYS_STATS */
sys_sem_free_(sem);
}
}
/*-----------------------------------------------------------------------------------*/
static void
sys_sem_free_(struct sys_sem *sem)
{
pthread_cond_destroy(&(sem->cond));
pthread_mutex_destroy(&(sem->mutex));
free(sem);
}
/*-----------------------------------------------------------------------------------*/
unsigned long
sys_unix_now()
{
struct timeval tv;
struct timezone tz;
long sec, usec;
unsigned long msec;
gettimeofday(&tv, &tz);
sec = tv.tv_sec - starttime.tv_sec;
usec = tv.tv_usec - starttime.tv_usec;
msec = sec * 1000 + usec / 1000;
return msec;
}
/*-----------------------------------------------------------------------------------*/
void
sys_init()
{
struct timezone tz;
gettimeofday(&starttime, &tz);
}
/*-----------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
struct sys_thread *thread;
thread = current_thread();
return &thread->timeouts;
}
/*-----------------------------------------------------------------------------------*/

162
src/core/inet.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* inet.c
*
* Functions common to all TCP/IP modules, such as the Internet checksum and the
* byte order functions.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/arch.h"
#include "lwip/def.h"
#include "lwip/inet.h"
/*-----------------------------------------------------------------------------------*/
static u16_t
lwip_chksum(void *dataptr, int len)
{
u32_t acc;
for(acc = 0; len > 1; len -= 2) {
acc += *((u16_t *)dataptr)++;
}
/* add up any odd byte */
if(len == 1) {
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", *(u8_t *)dataptr));
}
acc = (acc >> 16) + (acc & 0xffffUL);
if(acc & 0xffff0000 != 0) {
acc = (acc >> 16) + (acc & 0xffffUL);
}
return (u16_t)acc;
}
/*-----------------------------------------------------------------------------------*/
/* inet_chksum_pseudo:
*
* Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum_pseudo(struct pbuf *p,
struct ip_addr *src, struct ip_addr *dest,
u8_t proto, u16_t proto_len)
{
u32_t acc;
struct pbuf *q;
u8_t swapped;
acc = 0;
swapped = 0;
for(q = p; q != NULL; q = q->next) {
acc += lwip_chksum(q->payload, q->len);
while(acc >> 16) {
acc = (acc & 0xffffUL) + (acc >> 16);
}
if(q->len % 2 != 0) {
swapped = 1 - swapped;
acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
}
}
if(swapped) {
acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
}
acc += (src->addr & 0xffffUL);
acc += ((src->addr >> 16) & 0xffffUL);
acc += (dest->addr & 0xffffUL);
acc += ((dest->addr >> 16) & 0xffffUL);
acc += (u32_t)htons((u16_t)proto);
acc += (u32_t)htons(proto_len);
while(acc >> 16) {
acc = (acc & 0xffffUL) + (acc >> 16);
}
return ~(acc & 0xffffUL);
}
/*-----------------------------------------------------------------------------------*/
/* inet_chksum:
*
* Calculates the Internet checksum over a portion of memory. Used primarely for IP
* and ICMP.
*/
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum(void *dataptr, u16_t len)
{
u32_t acc;
acc = lwip_chksum(dataptr, len);
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
return ~(acc & 0xffff);
}
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum_pbuf(struct pbuf *p)
{
u32_t acc;
struct pbuf *q;
u8_t swapped;
acc = 0;
swapped = 0;
for(q = p; q != NULL; q = q->next) {
acc += lwip_chksum(q->payload, q->len);
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
if(q->len % 2 != 0) {
swapped = 1 - swapped;
acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
}
}
if(swapped) {
acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
}
return ~(acc & 0xffff);
}
/*-----------------------------------------------------------------------------------*/

168
src/core/inet6.c Normal file
View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* inet6.c
*
* Functions common to all TCP/IP modules, such as the Internet checksum and the
* byte order functions.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/inet.h"
/*-----------------------------------------------------------------------------------*/
/* chksum:
*
* Sums up all 16 bit words in a memory portion. Also includes any odd byte.
* This function is used by the other checksum functions.
*
* For now, this is not optimized. Must be optimized for the particular processor
* arcitecture on which it is to run. Preferebly coded in assembler.
*/
/*-----------------------------------------------------------------------------------*/
static u32_t
chksum(void *dataptr, u16_t len)
{
u16_t *sdataptr = dataptr;
u32_t acc;
for(acc = 0; len > 1; len -= 2) {
acc += *sdataptr++;
}
/* add up any odd byte */
if(len == 1) {
acc += htons((u16_t)(*(u8_t *)dataptr) << 8);
}
return acc;
}
/*-----------------------------------------------------------------------------------*/
/* inet_chksum_pseudo:
*
* Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum_pseudo(struct pbuf *p,
struct ip_addr *src, struct ip_addr *dest,
u8_t proto, u32_t proto_len)
{
u32_t acc;
struct pbuf *q;
u8_t swapped, i;
acc = 0;
swapped = 0;
for(q = p; q != NULL; q = q->next) {
acc += chksum(q->payload, q->len);
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
if(q->len % 2 != 0) {
swapped = 1 - swapped;
acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
}
}
if(swapped) {
acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
}
for(i = 0; i < 8; i++) {
acc += ((u16_t *)src->addr)[i] & 0xffff;
acc += ((u16_t *)dest->addr)[i] & 0xffff;
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
}
acc += (u16_t)htons((u16_t)proto);
acc += ((u16_t *)&proto_len)[0] & 0xffff;
acc += ((u16_t *)&proto_len)[1] & 0xffff;
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
return ~(acc & 0xffff);
}
/*-----------------------------------------------------------------------------------*/
/* inet_chksum:
*
* Calculates the Internet checksum over a portion of memory. Used primarely for IP
* and ICMP.
*/
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum(void *dataptr, u16_t len)
{
u32_t acc, sum;
acc = chksum(dataptr, len);
sum = (acc & 0xffff) + (acc >> 16);
sum += (sum >> 16);
return ~(sum & 0xffff);
}
/*-----------------------------------------------------------------------------------*/
u16_t
inet_chksum_pbuf(struct pbuf *p)
{
u32_t acc;
struct pbuf *q;
u8_t swapped;
acc = 0;
swapped = 0;
for(q = p; q != NULL; q = q->next) {
acc += chksum(q->payload, q->len);
while(acc >> 16) {
acc = (acc & 0xffff) + (acc >> 16);
}
if(q->len % 2 != 0) {
swapped = 1 - swapped;
acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
}
}
if(swapped) {
acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
}
return ~(acc & 0xffff);
}
/*-----------------------------------------------------------------------------------*/

199
src/core/ipv4/icmp.c Normal file
View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* Some ICMP messages should be passed to the transport protocols. This
is not implemented. */
#include "lwip/debug.h"
#include "lwip/icmp.h"
#include "lwip/inet.h"
#include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h"
/*-----------------------------------------------------------------------------------*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
unsigned char type;
struct icmp_echo_hdr *iecho;
struct ip_hdr *iphdr;
struct ip_addr tmpaddr;
u16_t hlen;
#ifdef ICMP_STATS
++stats.icmp.recv;
#endif /* ICMP_STATS */
iphdr = p->payload;
hlen = IPH_HL(iphdr) * 4/sizeof(u8_t);
pbuf_header(p, -hlen);
type = *((u8_t *)p->payload);
switch(type) {
case ICMP_ECHO:
if(ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) ||
ip_addr_ismulticast(&iphdr->dest)) {
DEBUGF(ICMP_DEBUG, ("Smurf.\n"));
#ifdef ICMP_STATS
++stats.icmp.err;
#endif /* ICMP_STATS */
pbuf_free(p);
return;
}
DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
DEBUGF(DEMO_DEBUG, ("Pong!\n"));
if(p->tot_len < sizeof(struct icmp_echo_hdr)) {
DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
pbuf_free(p);
#ifdef ICMP_STATS
++stats.icmp.lenerr;
#endif /* ICMP_STATS */
return;
}
iecho = p->payload;
if(inet_chksum_pbuf(p) != 0) {
DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
pbuf_free(p);
#ifdef ICMP_STATS
++stats.icmp.chkerr;
#endif /* ICMP_STATS */
return;
}
tmpaddr.addr = iphdr->src.addr;
iphdr->src.addr = iphdr->dest.addr;
iphdr->dest.addr = tmpaddr.addr;
ICMPH_TYPE_SET(iecho, ICMP_ER);
/* adjust the checksum */
if(iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) {
iecho->chksum += htons(ICMP_ECHO << 8) + 1;
} else {
iecho->chksum += htons(ICMP_ECHO << 8);
}
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
pbuf_header(p, hlen);
ip_output_if(p, &(iphdr->src), IP_HDRINCL,
IPH_TTL(iphdr), IP_PROTO_ICMP, inp);
break;
default:
DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type not supported.\n"));
#ifdef ICMP_STATS
++stats.icmp.proterr;
++stats.icmp.drop;
#endif /* ICMP_STATS */
}
pbuf_free(p);
}
/*-----------------------------------------------------------------------------------*/
void
icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
{
struct pbuf *q;
struct ip_hdr *iphdr;
struct icmp_dur_hdr *idur;
q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM);
/* ICMP header + IP header + 8 bytes of data */
iphdr = p->payload;
idur = q->payload;
ICMPH_TYPE_SET(idur, ICMP_DUR);
ICMPH_CODE_SET(idur, t);
bcopy(p->payload, (char *)q->payload + 8, IP_HLEN + 8);
/* calculate checksum */
idur->chksum = 0;
idur->chksum = inet_chksum(idur, q->len);
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
ip_output(q, NULL, &(iphdr->src),
ICMP_TTL, IP_PROTO_ICMP);
pbuf_free(q);
}
/*-----------------------------------------------------------------------------------*/
#if IP_FORWARD
void
icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
{
struct pbuf *q;
struct ip_hdr *iphdr;
struct icmp_te_hdr *tehdr;
q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM);
iphdr = p->payload;
#if ICMP_DEBUG
DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
ip_addr_debug_print(&(iphdr->src));
DEBUGF(ICMP_DEBUG, (" to "));
ip_addr_debug_print(&(iphdr->dest));
DEBUGF(ICMP_DEBUG, ("\n"));
#endif /* ICMP_DEBNUG */
tehdr = q->payload;
ICMPH_TYPE_SET(tehdr, ICMP_TE);
ICMPH_CODE_SET(tehdr, t);
/* copy fields from original packet */
bcopy((char *)p->payload, (char *)q->payload + 8, IP_HLEN + 8);
/* calculate checksum */
tehdr->chksum = 0;
tehdr->chksum = inet_chksum(tehdr, q->len);
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
ip_output(q, NULL, &(iphdr->src),
ICMP_TTL, IP_PROTO_ICMP);
pbuf_free(q);
}
#endif /* IP_FORWARDING > 0 */

700
src/core/ipv4/ip.c Normal file
View File

@@ -0,0 +1,700 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* ip.c
*
* This is the code for the IP layer.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/icmp.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/stats.h"
#include "arch/perf.h"
#if LWIP_DHCP
#include "lwip/dhcp.h"
#endif /* LWIP_DHCP */
/*-----------------------------------------------------------------------------------*/
/* ip_init:
*
* Initializes the IP layer.
*/
/*-----------------------------------------------------------------------------------*/
void
ip_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
/* ip_lookup:
*
* An experimental feature that will be changed in future versions. Do
* not depend on it yet...
*/
/*-----------------------------------------------------------------------------------*/
#ifdef LWIP_DEBUG
u8_t
ip_lookup(void *header, struct netif *inp)
{
struct ip_hdr *iphdr;
iphdr = header;
/* Refuse anything that isn't IPv4. */
if(IPH_V(iphdr) != 4) {
return 0;
}
/* Immediately accept/decline packets that are fragments or has
options. */
#if IP_REASSEMBLY == 0
/* if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
return 0;
}*/
#endif /* IP_REASSEMBLY == 0 */
#if IP_OPTIONS == 0
if(IPH_HL(iphdr) != 5) {
return 0;
}
#endif /* IP_OPTIONS == 0 */
switch(IPH_PROTO(iphdr)) {
#if LWIP_UDP > 0
case IP_PROTO_UDP:
return udp_lookup(iphdr, inp);
break;
#endif /* LWIP_UDP */
#if LWIP_TCP > 0
case IP_PROTO_TCP:
return 1;
#endif /* LWIP_TCP */
case IP_PROTO_ICMP:
return 1;
break;
default:
return 0;
}
}
#endif /* LWIP_DEBUG */
/*-----------------------------------------------------------------------------------*/
/* ip_route:
*
* Finds the appropriate network interface for a given IP address. It
* searches the list of network interfaces linearly. A match is found
* if the masked IP address of the network interface equals the masked
* IP address given to the function.
*/
/*-----------------------------------------------------------------------------------*/
struct netif *
ip_route(struct ip_addr *dest)
{
struct netif *netif;
for(netif = netif_list; netif != NULL; netif = netif->next) {
if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
return netif;
}
}
return netif_default;
}
#if IP_FORWARD
/*-----------------------------------------------------------------------------------*/
/* ip_forward:
*
* Forwards an IP packet. It finds an appropriate route for the
* packet, decrements the TTL value of the packet, adjusts the
* checksum and outputs the packet on the appropriate interface.
*/
/*-----------------------------------------------------------------------------------*/
static void
ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
{
static struct netif *netif;
PERF_START;
if((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%lx found\n",
iphdr->dest.addr));
return;
}
/* Don't forward packets onto the same network interface on which
they arrived. */
if(netif == inp) {
DEBUGF(IP_DEBUG, ("ip_forward: not forward packets back on incoming interface.\n"));
return;
}
/* Decrement TTL and send ICMP if ttl == 0. */
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
if(IPH_TTL(iphdr) == 0) {
/* Don't send ICMP messages in response to ICMP messages */
if(IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
icmp_time_exceeded(p, ICMP_TE_TTL);
}
return;
}
/* Incremental update of the IP checksum. */
if(IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
} else {
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100));
}
DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%lx\n",
iphdr->dest.addr));
#ifdef IP_STATS
++stats.ip.fw;
++stats.ip.xmit;
#endif /* IP_STATS */
PERF_STOP("ip_forward");
netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
}
#endif /* IP_FORWARD */
/*-----------------------------------------------------------------------------------*/
/* ip_reass:
*
* Tries to reassemble a fragmented IP packet.
*/
/*-----------------------------------------------------------------------------------*/
#define IP_REASSEMBLY 1
#define IP_REASS_BUFSIZE 5760
#define IP_REASS_MAXAGE 10
#if IP_REASSEMBLY
static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE];
static u8_t ip_reassbitmap[IP_REASS_BUFSIZE / (8 * 8)];
static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
0x0f, 0x07, 0x03, 0x01};
static u16_t ip_reasslen;
static u8_t ip_reassflags;
#define IP_REASS_FLAG_LASTFRAG 0x01
static u8_t ip_reasstmr;
static struct pbuf *
ip_reass(struct pbuf *p)
{
struct pbuf *q;
struct ip_hdr *fraghdr, *iphdr;
u16_t offset, len;
u16_t i;
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
write the IP header of the fragment into the reassembly
buffer. The timer is updated with the maximum age. */
if(ip_reasstmr == 0) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: new packet\n"));
bcopy(fraghdr, iphdr, IP_HLEN);
ip_reasstmr = IP_REASS_MAXAGE;
ip_reassflags = 0;
/* Clear the bitmap. */
bzero(ip_reassbitmap, sizeof(ip_reassbitmap));
}
/* Check if the incoming fragment matches the one currently present
in the reasembly buffer. If so, we proceed with copying the
fragment into the buffer. */
if(ip_addr_cmp(&iphdr->src, &fraghdr->src) &&
ip_addr_cmp(&iphdr->dest, &fraghdr->dest) &&
IPH_ID(iphdr) == IPH_ID(fraghdr)) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching old packet\n"));
/* Find out the offset in the reassembly buffer where we should
copy the fragment. */
len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4;
offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8;
/* If the offset or the offset + fragment length overflows the
reassembly buffer, we discard the entire packet. */
if(offset > IP_REASS_BUFSIZE ||
offset + len > IP_REASS_BUFSIZE) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: fragment outside of buffer (%d:%d/%d).\n",
offset, offset + len, IP_REASS_BUFSIZE));
ip_reasstmr = 0;
goto nullreturn;
}
/* Copy the fragment into the reassembly buffer, at the right
offset. */
DEBUGF(IP_REASS_DEBUG, ("ip_reass: copying with offset %d into %d:%d\n",
offset, IP_HLEN + offset, IP_HLEN + offset + len));
bcopy((u8_t *)fraghdr + IPH_HL(fraghdr) * 4,
&ip_reassbuf[IP_HLEN + offset], len);
/* Update the bitmap. */
if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: updating single byte in bitmap.\n"));
/* If the two endpoints are in the same byte, we only update
that byte. */
ip_reassbitmap[offset / (8 * 8)] |=
bitmap_bits[(offset / 8 ) & 7] &
~bitmap_bits[((offset + len) / 8 ) & 7];
} else {
/* If the two endpoints are in different bytes, we update the
bytes in the endpoints and fill the stuff inbetween with
0xff. */
ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8 ) & 7];
DEBUGF(IP_REASS_DEBUG, ("ip_reass: updating many bytes in bitmap (%d:%d).\n",
1 + offset / (8 * 8), (offset + len) / (8 * 8)));
for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
ip_reassbitmap[i] = 0xff;
}
ip_reassbitmap[(offset + len) / (8 * 8)] |= ~bitmap_bits[((offset + len) / 8 ) & 7];
}
/* If this fragment has the More Fragments flag set to zero, we
know that this is the last fragment, so we can calculate the
size of the entire packet. We also set the
IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
the final fragment. */
if((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) {
ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
ip_reasslen = offset + len;
DEBUGF(IP_REASS_DEBUG, ("ip_reass: last fragment seen, total len %d\n", ip_reasslen));
}
/* Finally, we check if we have a full packet in the buffer. We do
this by checking if we have the last fragment and if all bits
in the bitmap are set. */
if(ip_reassflags & IP_REASS_FLAG_LASTFRAG) {
/* Check all bytes up to and including all but the last byte in
the bitmap. */
for(i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
if(ip_reassbitmap[i] != 0xff) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n", i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
goto nullreturn;
}
}
/* Check the last byte in the bitmap. It should contain just the
right amount of bits. */
if(ip_reassbitmap[ip_reasslen / (8 * 8)] !=
(u8_t)~bitmap_bits[ip_reasslen / 8 & 7]) {
DEBUGF(IP_REASS_DEBUG, ("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
ip_reassbitmap[ip_reasslen / (8 * 8)]));
goto nullreturn;
}
/* Pretend to be a "normal" (i.e., not fragmented) IP packet
from now on. */
IPH_OFFSET_SET(iphdr, 0);
IPH_CHKSUM_SET(iphdr, 0);
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
/* 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. */
ip_reasstmr = 0;
pbuf_free(p);
p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
if(p != NULL) {
i = 0;
for(q = p; q != NULL; q = q->next) {
/* Copy enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
DEBUGF(IP_REASS_DEBUG, ("ip_reass: bcopy from %p (%d) to %p, %d bytes\n",
&ip_reassbuf[i], i, q->payload, q->len > ip_reasslen - i? ip_reasslen - i: q->len));
bcopy(&ip_reassbuf[i], q->payload,
q->len > ip_reasslen - i? ip_reasslen - i: q->len);
i += q->len;
}
}
DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", p));
return p;
}
}
nullreturn:
pbuf_free(p);
return NULL;
}
#endif /* IP_REASSEMBLY */
/*-----------------------------------------------------------------------------------*/
/* ip_input:
*
* This function is called by the network interface device driver when
* an IP packet is received. The function does the basic checks of the
* IP header such as packet size being at least larger than the header
* size etc. If the packet was not destined for us, the packet is
* forwarded (using ip_forward). The IP checksum is always checked.
*
* Finally, the packet is sent to the upper layer protocol input function.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_input(struct pbuf *p, struct netif *inp) {
static struct ip_hdr *iphdr;
static struct netif *netif;
static u8_t hl;
#ifdef IP_STATS
++stats.ip.recv;
#endif /* IP_STATS */
/* identify the IP header */
iphdr = p->payload;
if(IPH_V(iphdr) != 4) {
DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
pbuf_free(p);
#ifdef IP_STATS
++stats.ip.err;
++stats.ip.drop;
#endif /* IP_STATS */
return ERR_OK;
}
hl = IPH_HL(iphdr);
if(hl * 4 > p->len) {
DEBUGF(IP_DEBUG, ("IP packet dropped due to too short packet %d\n", p->len));
pbuf_free(p);
#ifdef IP_STATS
++stats.ip.lenerr;
++stats.ip.drop;
#endif /* IP_STATS */
return ERR_OK;
}
/* verify checksum */
if(inet_chksum(iphdr, hl * 4) != 0) {
DEBUGF(IP_DEBUG, ("IP packet dropped due to failing checksum 0x%x\n", inet_chksum(iphdr, hl * 4)));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
pbuf_free(p);
#ifdef IP_STATS
++stats.ip.chkerr;
++stats.ip.drop;
#endif /* IP_STATS */
return ERR_OK;
}
/* Trim pbuf. This should have been done at the netif layer,
but we'll do it anyway just to be sure that its done. */
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
/* is this packet for us? */
for(netif = netif_list; netif != NULL; netif = netif->next) {
DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
iphdr->dest.addr, netif->ip_addr.addr,
iphdr->dest.addr & netif->netmask.addr,
netif->ip_addr.addr & netif->netmask.addr,
iphdr->dest.addr & ~(netif->netmask.addr)));
if(ip_addr_isany(&(netif->ip_addr)) ||
ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
break;
}
}
#if LWIP_DHCP
/* If a DHCP packet has arrived on the interface, we pass it up the
stack regardless of destination IP address. The reason is that
DHCP replies are sent to the IP adress that will be given to this
node (as recommended by RFC 1542 section 3.1.1, referred by RFC
2131). */
if(IPH_PROTO(iphdr) == IP_PROTO_UDP &&
((struct udp_hdr *)((u8_t *)iphdr + IPH_HL(iphdr) * 4/sizeof(u8_t)))->src ==
DHCP_SERVER_PORT) {
netif = inp;
}
#endif /* LWIP_DHCP */
if(netif == NULL) {
/* packet not for us, route or discard */
DEBUGF(IP_DEBUG, ("ip_input: packet not for us.\n"));
#if IP_FORWARD
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
ip_forward(p, iphdr, inp);
}
#endif /* IP_FORWARD */
pbuf_free(p);
return ERR_OK;
}
#if IP_REASSEMBLY
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
p = ip_reass(p);
if(p == NULL) {
return ERR_OK;
}
iphdr = p->payload;
}
#else /* IP_REASSEMBLY */
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
pbuf_free(p);
DEBUGF(IP_DEBUG, ("IP packet dropped since it was fragmented (0x%x).\n",
ntohs(IPH_OFFSET(iphdr))));
#ifdef IP_STATS
++stats.ip.opterr;
++stats.ip.drop;
#endif /* IP_STATS */
return ERR_OK;
}
#endif /* IP_REASSEMBLY */
#if IP_OPTIONS == 0
if(hl * 4 > IP_HLEN) {
DEBUGF(IP_DEBUG, ("IP packet dropped since there were IP options.\n"));
pbuf_free(p);
#ifdef IP_STATS
++stats.ip.opterr;
++stats.ip.drop;
#endif /* IP_STATS */
return ERR_OK;
}
#endif /* IP_OPTIONS == 0 */
/* send to upper layers */
#if IP_DEBUG
DEBUGF(IP_DEBUG, ("ip_input: \n"));
ip_debug_print(p);
DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
#endif /* IP_DEBUG */
switch(IPH_PROTO(iphdr)) {
#if LWIP_UDP > 0
case IP_PROTO_UDP:
udp_input(p, inp);
break;
#endif /* LWIP_UDP */
#if LWIP_TCP > 0
case IP_PROTO_TCP:
tcp_input(p, inp);
break;
#endif /* LWIP_TCP */
case IP_PROTO_ICMP:
icmp_input(p, inp);
break;
default:
/* send ICMP destination protocol unreachable unless is was a broadcast */
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
!ip_addr_ismulticast(&(iphdr->dest))) {
p->payload = iphdr;
icmp_dest_unreach(p, ICMP_DUR_PROTO);
}
pbuf_free(p);
DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %d\n", IPH_PROTO(iphdr)));
#ifdef IP_STATS
++stats.ip.proterr;
++stats.ip.drop;
#endif /* IP_STATS */
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/* ip_output_if:
*
* Sends an IP packet on a network interface. This function constructs
* the IP header and calculates the IP header checksum. If the source
* IP address is NULL, the IP address of the outgoing network
* interface is filled in as source address.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl,
u8_t proto, struct netif *netif)
{
static struct ip_hdr *iphdr;
static u16_t ip_id = 0;
if(dest != IP_HDRINCL) {
if(pbuf_header(p, IP_HLEN)) {
DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
#ifdef IP_STATS
++stats.ip.err;
#endif /* IP_STATS */
return ERR_BUF;
}
iphdr = p->payload;
IPH_TTL_SET(iphdr, ttl);
IPH_PROTO_SET(iphdr, proto);
ip_addr_set(&(iphdr->dest), dest);
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
IPH_LEN_SET(iphdr, htons(p->tot_len));
IPH_OFFSET_SET(iphdr, htons(IP_DF));
IPH_ID_SET(iphdr, htons(ip_id));
++ip_id;
if(ip_addr_isany(src)) {
ip_addr_set(&(iphdr->src), &(netif->ip_addr));
} else {
ip_addr_set(&(iphdr->src), src);
}
IPH_CHKSUM_SET(iphdr, 0);
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
} else {
iphdr = p->payload;
dest = &(iphdr->dest);
}
#ifdef IP_STATS
stats.ip.xmit++;
#endif /* IP_STATS */
DEBUGF(IP_DEBUG, ("ip_output_if: %c%c ", netif->name[0], netif->name[1]));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
return netif->output(netif, p, dest);
}
/*-----------------------------------------------------------------------------------*/
/* ip_output:
*
* Simple interface to ip_output_if. It finds the outgoing network
* interface and calls upon ip_output_if to do the actual work.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t proto)
{
static struct netif *netif;
if((netif = ip_route(dest)) == NULL) {
DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
#ifdef IP_STATS
++stats.ip.rterr;
#endif /* IP_STATS */
pbuf_free(p);
return ERR_RTE;
}
return ip_output_if(p, src, dest, ttl, proto, netif);
}
/*-----------------------------------------------------------------------------------*/
#if IP_DEBUG
void
ip_debug_print(struct pbuf *p)
{
struct ip_hdr *iphdr = p->payload;
u8_t *payload;
payload = (u8_t *)iphdr + IP_HLEN/sizeof(u8_t);
DEBUGF(IP_DEBUG, ("IP header:\n"));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("|%2d |%2d | %2d | %4d | (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",
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",
IPH_TTL(iphdr),
IPH_PROTO(iphdr),
ntohs(IPH_CHKSUM(iphdr))));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (src)\n",
ntohl(iphdr->src.addr) >> 24 & 0xff,
ntohl(iphdr->src.addr) >> 16 & 0xff,
ntohl(iphdr->src.addr) >> 8 & 0xff,
ntohl(iphdr->src.addr) & 0xff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (dest)\n",
ntohl(iphdr->dest.addr) >> 24 & 0xff,
ntohl(iphdr->dest.addr) >> 16 & 0xff,
ntohl(iphdr->dest.addr) >> 8 & 0xff,
ntohl(iphdr->dest.addr) & 0xff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
}
#endif /* IP_DEBUG */
/*-----------------------------------------------------------------------------------*/

41
src/core/ipv4/ip_addr.c Normal file
View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
struct ip_addr ip_addr_broadcast = {0xffffffff};
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/

1
src/core/ipv6/README Normal file
View File

@@ -0,0 +1 @@
IPv6 support in lwIP is very experimental.

184
src/core/ipv6/icmp6.c Normal file
View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* Some ICMP messages should be passed to the transport protocols. This
is not implemented. */
#include "lwip/debug.h"
#include "lwip/icmp.h"
#include "lwip/inet.h"
#include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h"
/*-----------------------------------------------------------------------------------*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
unsigned char type;
struct icmp_echo_hdr *iecho;
struct ip_hdr *iphdr;
struct ip_addr tmpaddr;
#ifdef ICMP_STATS
++stats.icmp.recv;
#endif /* ICMP_STATS */
type = ((char *)p->payload)[0];
switch(type) {
case ICMP6_ECHO:
DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
if(p->tot_len < sizeof(struct icmp_echo_hdr)) {
DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
pbuf_free(p);
#ifdef ICMP_STATS
++stats.icmp.lenerr;
#endif /* ICMP_STATS */
return;
}
iecho = p->payload;
iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);
if(inet_chksum_pbuf(p) != 0) {
DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
#ifdef ICMP_STATS
++stats.icmp.chkerr;
#endif /* ICMP_STATS */
/* return;*/
}
DEBUGF(ICMP_DEBUG, ("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len));
ip_addr_set(&tmpaddr, &(iphdr->src));
ip_addr_set(&(iphdr->src), &(iphdr->dest));
ip_addr_set(&(iphdr->dest), &tmpaddr);
iecho->type = ICMP6_ER;
/* adjust the checksum */
if(iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) {
iecho->chksum += htons(ICMP6_ECHO << 8) + 1;
} else {
iecho->chksum += htons(ICMP6_ECHO << 8);
}
DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%x)\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len)));
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
/* DEBUGF("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len);*/
ip_output_if(p, &(iphdr->src), IP_HDRINCL,
iphdr->hoplim, IP_PROTO_ICMP, inp);
break;
default:
DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type not supported.\n"));
#ifdef ICMP_STATS
++stats.icmp.proterr;
++stats.icmp.drop;
#endif /* ICMP_STATS */
}
pbuf_free(p);
}
/*-----------------------------------------------------------------------------------*/
void
icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
{
struct pbuf *q;
struct ip_hdr *iphdr;
struct icmp_dur_hdr *idur;
q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM);
/* ICMP header + IP header + 8 bytes of data */
iphdr = p->payload;
idur = q->payload;
idur->type = (char)ICMP6_DUR;
idur->icode = (char)t;
bcopy(p->payload, (char *)q->payload + 8, IP_HLEN + 8);
/* calculate checksum */
idur->chksum = 0;
idur->chksum = inet_chksum(idur, q->len);
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
ip_output(q, NULL,
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
pbuf_free(q);
}
/*-----------------------------------------------------------------------------------*/
void
icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
{
struct pbuf *q;
struct ip_hdr *iphdr;
struct icmp_te_hdr *tehdr;
DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
q = pbuf_alloc(PBUF_TRANSPORT, 8 + IP_HLEN + 8, PBUF_RAM);
iphdr = p->payload;
tehdr = q->payload;
tehdr->type = (char)ICMP6_TE;
tehdr->icode = (char)t;
/* copy fields from original packet */
bcopy((char *)p->payload, (char *)q->payload + 8, IP_HLEN + 8);
/* calculate checksum */
tehdr->chksum = 0;
tehdr->chksum = inet_chksum(tehdr, q->len);
#ifdef ICMP_STATS
++stats.icmp.xmit;
#endif /* ICMP_STATS */
ip_output(q, NULL,
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
pbuf_free(q);
}

386
src/core/ipv6/ip6.c Normal file
View File

@@ -0,0 +1,386 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* ip.c
*
* This is the code for the IP layer for IPv6.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/icmp.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/stats.h"
#include "arch/perf.h"
/*-----------------------------------------------------------------------------------*/
/* ip_init:
*
* Initializes the IP layer.
*/
/*-----------------------------------------------------------------------------------*/
void
ip_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
/* ip_route:
*
* Finds the appropriate network interface for a given IP address. It searches the
* list of network interfaces linearly. A match is found if the masked IP address of
* the network interface equals the masked IP address given to the function.
*/
/*-----------------------------------------------------------------------------------*/
struct netif *
ip_route(struct ip_addr *dest)
{
struct netif *netif;
for(netif = netif_list; netif != NULL; netif = netif->next) {
if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
return netif;
}
}
return netif_default;
}
/*-----------------------------------------------------------------------------------*/
/* ip_forward:
*
* Forwards an IP packet. It finds an appropriate route for the packet, decrements
* the TTL value of the packet, adjusts the checksum and outputs the packet on the
* appropriate interface.
*/
/*-----------------------------------------------------------------------------------*/
static void
ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
{
struct netif *netif;
PERF_START;
if((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
#if IP_DEBUG
ip_addr_debug_print(&(iphdr->dest));
#endif /* IP_DEBUG */
DEBUGF(IP_DEBUG, ("\n"));
pbuf_free(p);
return;
}
/* Decrement TTL and send ICMP if ttl == 0. */
if(--iphdr->hoplim == 0) {
/* Don't send ICMP messages in response to ICMP messages */
if(iphdr->nexthdr != IP_PROTO_ICMP) {
icmp_time_exceeded(p, ICMP_TE_TTL);
}
pbuf_free(p);
return;
}
/* Incremental update of the IP checksum. */
/* if (iphdr->chksum >= htons(0xffff - 0x100)) {
iphdr->chksum += htons(0x100) + 1;
} else {
iphdr->chksum += htons(0x100);
}*/
DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
#if IP_DEBUG
ip_addr_debug_print(&(iphdr->dest));
#endif /* IP_DEBUG */
DEBUGF(IP_DEBUG, ("\n"));
#ifdef IP_STATS
++stats.ip.fw;
++stats.ip.xmit;
#endif /* IP_STATS */
PERF_STOP("ip_forward");
netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
}
/*-----------------------------------------------------------------------------------*/
/* ip_input:
*
* This function is called by the network interface device driver when an IP packet is
* received. The function does the basic checks of the IP header such as packet size
* being at least larger than the header size etc. If the packet was not destined for
* us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
*
* Finally, the packet is sent to the upper layer protocol input function.
*/
/*-----------------------------------------------------------------------------------*/
void
ip_input(struct pbuf *p, struct netif *inp) {
struct ip_hdr *iphdr;
struct netif *netif;
PERF_START;
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
#ifdef IP_STATS
++stats.ip.recv;
#endif /* IP_STATS */
/* identify the IP header */
iphdr = p->payload;
if(iphdr->v != 6) {
DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
pbuf_free(p);
#ifdef IP_STATS
++stats.ip.err;
++stats.ip.drop;
#endif /* IP_STATS */
return;
}
/* is this packet for us? */
for(netif = netif_list; netif != NULL; netif = netif->next) {
#if IP_DEBUG
DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
ip_addr_debug_print(&(iphdr->dest));
DEBUGF(IP_DEBUG, ("netif->ip_addr "));
ip_addr_debug_print(&(netif->ip_addr));
DEBUGF(IP_DEBUG, ("\n"));
#endif /* IP_DEBUG */
if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
break;
}
}
if(netif == NULL) {
/* packet not for us, route or discard */
#ifdef IP_FORWARD
ip_forward(p, iphdr);
#endif
pbuf_free(p);
return;
}
pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
/* send to upper layers */
#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);*/
#endif /* IP_DEBUG */
pbuf_header(p, -IP_HLEN);
switch(iphdr->nexthdr) {
case IP_PROTO_UDP:
udp_input(p);
break;
case IP_PROTO_TCP:
tcp_input(p);
break;
case IP_PROTO_ICMP:
icmp_input(p, inp);
break;
default:
/* send ICMP destination protocol unreachable */
icmp_dest_unreach(p, ICMP_DUR_PROTO);
pbuf_free(p);
DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %d\n",
iphdr->nexthdr));
#ifdef IP_STATS
++stats.ip.proterr;
++stats.ip.drop;
#endif /* IP_STATS */
}
PERF_STOP("ip_input");
}
/*-----------------------------------------------------------------------------------*/
/* ip_output_if:
*
* Sends an IP packet on a network interface. This function constructs the IP header
* and calculates the IP header checksum. If the source IP address is NULL,
* the IP address of the outgoing network interface is filled in as source address.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl,
u8_t proto, struct netif *netif)
{
struct ip_hdr *iphdr;
PERF_START;
printf("len %d tot_len %d\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
++stats.ip.err;
#endif /* IP_STATS */
return ERR_BUF;
}
printf("len %d tot_len %d\n", p->len, p->tot_len);
iphdr = p->payload;
if(dest != IP_HDRINCL) {
printf("!IP_HDRLINCL\n");
iphdr->hoplim = ttl;
iphdr->nexthdr = proto;
iphdr->len = htons(p->tot_len - IP_HLEN);
ip_addr_set(&(iphdr->dest), dest);
iphdr->v = 6;
if(ip_addr_isany(src)) {
ip_addr_set(&(iphdr->src), &(netif->ip_addr));
} else {
ip_addr_set(&(iphdr->src), src);
}
} else {
dest = &(iphdr->dest);
}
#ifdef IP_STATS
++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));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
PERF_STOP("ip_output_if");
return netif->output(netif, p, dest);
}
/*-----------------------------------------------------------------------------------*/
/* ip_output:
*
* Simple interface to ip_output_if. It finds the outgoing network interface and
* calls upon ip_output_if to do the actual work.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t proto)
{
struct netif *netif;
if((netif = ip_route(dest)) == NULL) {
DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
#ifdef IP_STATS
++stats.ip.rterr;
#endif /* IP_STATS */
return ERR_RTE;
}
return ip_output_if(p, src, dest, ttl, proto, netif);
}
/*-----------------------------------------------------------------------------------*/
#if IP_DEBUG
void
ip_debug_print(struct pbuf *p)
{
struct ip_hdr *iphdr = p->payload;
char *payload;
payload = (char *)iphdr + IP_HLEN;
DEBUGF(IP_DEBUG, ("IP header:\n"));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("|%2d | %x%x | %x%x | (v, traffic class, flow label)\n",
iphdr->v,
iphdr->tclass1, iphdr->tclass2,
iphdr->flow1, iphdr->flow2));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %5d | %2d | %2d | (len, nexthdr, hoplim)\n",
ntohs(iphdr->len),
iphdr->nexthdr,
iphdr->hoplim));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
ntohl(iphdr->src.addr[0]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
ntohl(iphdr->src.addr[1]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
ntohl(iphdr->src.addr[2]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
ntohl(iphdr->src.addr[3]) & 0xffff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
ntohl(iphdr->dest.addr[0]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
ntohl(iphdr->dest.addr[1]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
ntohl(iphdr->dest.addr[2]) & 0xffff));
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
ntohl(iphdr->dest.addr[3]) & 0xffff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
}
#endif /* IP_DEBUG */
/*-----------------------------------------------------------------------------------*/

91
src/core/ipv6/ip6_addr.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
/*-----------------------------------------------------------------------------------*/
int
ip_addr_maskcmp(struct ip_addr *addr1, struct ip_addr *addr2,
struct ip_addr *mask)
{
return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) &&
(addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) &&
(addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) &&
(addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3]));
}
/*-----------------------------------------------------------------------------------*/
int
ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2)
{
return(addr1->addr[0] == addr2->addr[0] &&
addr1->addr[1] == addr2->addr[1] &&
addr1->addr[2] == addr2->addr[2] &&
addr1->addr[3] == addr2->addr[3]);
}
/*-----------------------------------------------------------------------------------*/
void
ip_addr_set(struct ip_addr *dest, struct ip_addr *src)
{
bcopy(src, dest, sizeof(struct ip_addr));
/* dest->addr[0] = src->addr[0];
dest->addr[1] = src->addr[1];
dest->addr[2] = src->addr[2];
dest->addr[3] = src->addr[3];*/
}
/*-----------------------------------------------------------------------------------*/
int
ip_addr_isany(struct ip_addr *addr)
{
if(addr == NULL) return 1;
return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0);
}
/*-----------------------------------------------------------------------------------*/
/*#if IP_DEBUG*/
void
ip_addr_debug_print(struct ip_addr *addr)
{
printf("%lx:%lx:%lx:%lx:%lx:%lx:%lx:%lx",
ntohl(addr->addr[0]) >> 16 & 0xffff,
ntohl(addr->addr[0]) & 0xffff,
ntohl(addr->addr[1]) >> 16 & 0xffff,
ntohl(addr->addr[1]) & 0xffff,
ntohl(addr->addr[2]) >> 16 & 0xffff,
ntohl(addr->addr[2]) & 0xffff,
ntohl(addr->addr[3]) >> 16 & 0xffff,
ntohl(addr->addr[3]) & 0xffff);
}
/*#endif*/ /* IP_DEBUG */
/*-----------------------------------------------------------------------------------*/

297
src/core/mem.c Normal file
View File

@@ -0,0 +1,297 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* mem.c
*
* Memory manager.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
struct mem {
mem_size_t next, prev;
u8_t used;
#if MEM_ALIGNMENT == 2
u8_t dummy;
#endif /* MEM_ALIGNEMNT == 2 */
};
static struct mem *ram_end;
static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];
#define MIN_SIZE 12
#define SIZEOF_STRUCT_MEM MEM_ALIGN_SIZE(sizeof(struct mem))
/*#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \
(((sizeof(struct mem) % MEM_ALIGNMENT) == 0)? 0 : \
(4 - (sizeof(struct mem) % MEM_ALIGNMENT))))*/
static struct mem *lfree; /* pointer to the lowest free block */
static sys_sem_t mem_sem;
/*-----------------------------------------------------------------------------------*/
static void
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);
/* plug hole forward */
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) {
if(lfree == nmem) {
lfree = mem;
}
mem->next = nmem->next;
((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram;
}
/* plug hole backward */
pmem = (struct mem *)&ram[mem->prev];
if(pmem != mem && pmem->used == 0) {
if(lfree == mem) {
lfree = pmem;
}
pmem->next = mem->next;
((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram;
}
}
/*-----------------------------------------------------------------------------------*/
void
mem_init(void)
{
struct mem *mem;
bzero(ram, MEM_SIZE);
mem = (struct mem *)ram;
mem->next = MEM_SIZE;
mem->prev = 0;
mem->used = 0;
ram_end = (struct mem *)&ram[MEM_SIZE];
ram_end->used = 1;
ram_end->next = MEM_SIZE;
ram_end->prev = MEM_SIZE;
mem_sem = sys_sem_new(1);
lfree = (struct mem *)ram;
#ifdef MEM_STATS
stats.mem.avail = MEM_SIZE;
#endif /* MEM_STATS */
}
/*-----------------------------------------------------------------------------------*/
void *
mem_malloc(mem_size_t size)
{
mem_size_t ptr, ptr2;
struct mem *mem, *mem2;
if(size == 0) {
return NULL;
}
/* Expand the size of the allocated memory region so that we can
adjust for alignment. */
if((size % MEM_ALIGNMENT) != 0) {
size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT);
}
if(size > MEM_SIZE) {
return NULL;
}
sys_sem_wait(mem_sem);
for(ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) {
mem = (struct mem *)&ram[ptr];
if(!mem->used &&
mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) {
ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
mem2 = (struct mem *)&ram[ptr2];
mem2->prev = ptr;
mem2->next = mem->next;
mem->next = ptr2;
if(mem2->next != MEM_SIZE) {
((struct mem *)&ram[mem2->next])->prev = ptr2;
}
mem2->used = 0;
mem->used = 1;
#ifdef MEM_STATS
stats.mem.used += size;
/* if(stats.mem.max < stats.mem.used) {
stats.mem.max = stats.mem.used;
} */
if(stats.mem.max < ptr2) {
stats.mem.max = ptr2;
}
#endif /* MEM_STATS */
if(mem == lfree) {
/* Find next free block after mem */
while(lfree->used && lfree != ram_end) {
lfree = (struct mem *)&ram[lfree->next];
}
ASSERT("mem_malloc: !lfree->used", !lfree->used);
}
sys_sem_signal(mem_sem);
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.",
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
}
}
DEBUGF(MEM_DEBUG, ("mem_malloc: could not allocate %d bytes\n", (int)size));
#ifdef MEM_STATS
++stats.mem.err;
#endif /* MEM_STATS */
sys_sem_signal(mem_sem);
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
++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
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);
}
bcopy(rmem, nmem, 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_free: 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
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;
}
/*-----------------------------------------------------------------------------------*/

271
src/core/memp.c Normal file
View File

@@ -0,0 +1,271 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwipopts.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/tcpip.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
struct memp {
struct memp *next;
};
static struct memp *memp_tab[MEMP_MAX];
static const u16_t memp_sizes[MEMP_MAX] = {
sizeof(struct pbuf),
sizeof(struct udp_pcb),
sizeof(struct tcp_pcb),
sizeof(struct tcp_pcb_listen),
sizeof(struct tcp_seg),
sizeof(struct netbuf),
sizeof(struct netconn),
sizeof(struct api_msg),
sizeof(struct tcpip_msg),
sizeof(struct sys_timeout)
};
static const u16_t memp_num[MEMP_MAX] = {
MEMP_NUM_PBUF,
MEMP_NUM_UDP_PCB,
MEMP_NUM_TCP_PCB,
MEMP_NUM_TCP_PCB_LISTEN,
MEMP_NUM_TCP_SEG,
MEMP_NUM_NETBUF,
MEMP_NUM_NETCONN,
MEMP_NUM_API_MSG,
MEMP_NUM_TCPIP_MSG,
MEMP_NUM_SYS_TIMEOUT
};
static u8_t memp_memory[(MEMP_NUM_PBUF *
MEM_ALIGN_SIZE(sizeof(struct pbuf) +
sizeof(struct memp)) +
MEMP_NUM_UDP_PCB *
MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
sizeof(struct memp)) +
MEMP_NUM_TCP_PCB *
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
sizeof(struct memp)) +
MEMP_NUM_TCP_PCB_LISTEN *
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
sizeof(struct memp)) +
MEMP_NUM_TCP_SEG *
MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
sizeof(struct memp)) +
MEMP_NUM_NETBUF *
MEM_ALIGN_SIZE(sizeof(struct netbuf) +
sizeof(struct memp)) +
MEMP_NUM_NETCONN *
MEM_ALIGN_SIZE(sizeof(struct netconn) +
sizeof(struct memp)) +
MEMP_NUM_API_MSG *
MEM_ALIGN_SIZE(sizeof(struct api_msg) +
sizeof(struct memp)) +
MEMP_NUM_TCPIP_MSG *
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
sizeof(struct memp)) +
MEMP_NUM_SYS_TIMEOUT *
MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
sizeof(struct memp)))];
/*-----------------------------------------------------------------------------------*/
static sys_sem_t mutex;
/*-----------------------------------------------------------------------------------*/
#ifdef LWIP_DEBUG
static int
memp_sanity(void)
{
int i, c;
struct memp *m, *n;
for(i = 0; i < MEMP_MAX; i++) {
for(m = memp_tab[i]; m != NULL; m = m->next) {
c = 1;
for(n = memp_tab[i]; n != NULL; n = n->next) {
if(n == m) {
--c;
}
if(c < 0)
abort();
}
}
}
return 1;
}
#endif /* LWIP_DEBUG */
/*-----------------------------------------------------------------------------------*/
void
memp_init(void)
{
struct memp *m, *memp;
u16_t i, j;
u16_t size;
#ifdef MEMP_STATS
for(i = 0; i < MEMP_MAX; ++i) {
stats.memp[i].used = stats.memp[i].max =
stats.memp[i].err = stats.memp[i].reclaimed = 0;
stats.memp[i].avail = memp_num[i];
}
#endif /* MEMP_STATS */
memp = (struct memp *)&memp_memory[0];
for(i = 0; i < MEMP_MAX; ++i) {
size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
if(memp_num[i] > 0) {
memp_tab[i] = memp;
m = memp;
for(j = 0; j < memp_num[i]; ++j) {
m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
memp = m;
m = m->next;
}
memp->next = NULL;
memp = m;
} else {
memp_tab[i] = NULL;
}
}
mutex = sys_sem_new(1);
}
/*-----------------------------------------------------------------------------------*/
void *
memp_malloc(memp_t type)
{
struct memp *memp;
ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
memp = memp_tab[type];
if(memp != NULL) {
memp_tab[type] = memp->next;
memp->next = NULL;
#ifdef MEMP_STATS
++stats.memp[type].used;
if(stats.memp[type].used > stats.memp[type].max) {
stats.memp[type].max = stats.memp[type].used;
}
#endif /* MEMP_STATS */
ASSERT("memp_malloc: memp properly aligned",
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
return MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
} else {
DEBUGF(MEMP_DEBUG, ("memp_malloc: out of memory in pool %d\n", type));
#ifdef MEMP_STATS
++stats.memp[type].err;
#endif /* MEMP_STATS */
return NULL;
}
}
/*-----------------------------------------------------------------------------------*/
void *
memp_mallocp(memp_t type)
{
void *mem;
sys_sem_wait(mutex);
mem = memp_malloc(type);
sys_sem_signal(mutex);
return mem;
}
/*-----------------------------------------------------------------------------------*/
#if 0
void *
memp_realloc(memp_t fromtype, memp_t totype, void *mem)
{
void *rmem;
u16_t size;
if(mem == NULL) {
return NULL;
}
rmem = memp_malloc(totype);
if(rmem != NULL) {
size = memp_sizes[totype];
if(memp_sizes[fromtype] < size) {
size = memp_sizes[fromtype];
}
bcopy(mem, rmem, size);
memp_free(fromtype, mem);
}
return rmem;
}
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/
void
memp_free(memp_t type, void *mem)
{
struct memp *memp;
if(mem == NULL) {
return;
}
memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
#ifdef MEMP_STATS
stats.memp[type].used--;
#endif /* MEMP_STATS */
memp->next = memp_tab[type];
memp_tab[type] = memp;
ASSERT("memp sanity", memp_sanity());
return;
}
/*-----------------------------------------------------------------------------------*/
void
memp_freep(memp_t type, void *mem)
{
sys_sem_wait(mutex);
memp_free(type, mem);
sys_sem_signal(mutex);
}
/*-----------------------------------------------------------------------------------*/

142
src/core/netif.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
struct netif *netif_list = NULL;
struct netif *netif_default = NULL;
/*-----------------------------------------------------------------------------------*/
struct netif *
netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw,
void (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
{
struct netif *netif;
static int netifnum = 0;
netif = mem_malloc(sizeof(struct netif));
if(netif == NULL) {
return NULL;
}
netif->num = netifnum++;
netif->input = input;
ip_addr_set(&(netif->ip_addr), ipaddr);
ip_addr_set(&(netif->netmask), netmask);
ip_addr_set(&(netif->gw), gw);
init(netif);
netif->next = netif_list;
netif_list = netif;
#if NETIF_DEBUG
DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
netif->name[0], netif->name[1]));
ip_addr_debug_print(ipaddr);
DEBUGF(NETIF_DEBUG, (" netmask "));
ip_addr_debug_print(netmask);
DEBUGF(NETIF_DEBUG, (" gw "));
ip_addr_debug_print(gw);
DEBUGF(NETIF_DEBUG, ("\n"));
#endif /* NETIF_DEBUG */
return netif;
}
/*-----------------------------------------------------------------------------------*/
struct netif *
netif_find(char *name)
{
struct netif *netif;
u8_t num;
if(name == NULL) {
return NULL;
}
num = name[2] - '0';
for(netif = netif_list; netif != NULL; netif = netif->next) {
if(num == netif->num &&
name[0] == netif->name[0] &&
name[1] == netif->name[1]) {
DEBUGF(NETIF_DEBUG, ("netif_find: found %s\n", name));
return netif;
}
}
DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %s\n", name));
return NULL;
}
/*-----------------------------------------------------------------------------------*/
void
netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
{
ip_addr_set(&(netif->ip_addr), ipaddr);
DEBUGF(NETIF_DEBUG, ("netif: setting IP address of interface %c%c to %d.%d.%d.%d\n",
netif->name[0], netif->name[1],
(u8_t)(ntohl(ipaddr->addr) >> 24 & 0xff),
(u8_t)(ntohl(ipaddr->addr) >> 16 & 0xff),
(u8_t)(ntohl(ipaddr->addr) >> 8 & 0xff),
(u8_t)(ntohl(ipaddr->addr) & 0xff)));
}
/*-----------------------------------------------------------------------------------*/
void
netif_set_gw(struct netif *netif, struct ip_addr *gw)
{
ip_addr_set(&(netif->gw), gw);
}
/*-----------------------------------------------------------------------------------*/
void
netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
{
ip_addr_set(&(netif->netmask), netmask);
}
/*-----------------------------------------------------------------------------------*/
void
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]));
}
/*-----------------------------------------------------------------------------------*/
void
netif_init(void)
{
netif_list = netif_default = NULL;
}
/*-----------------------------------------------------------------------------------*/

597
src/core/pbuf.c Normal file
View File

@@ -0,0 +1,597 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* pbuf.c
*
* Functions for the manipulation of pbufs. The pbufs holds all packets in the
* system.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "arch/perf.h"
static u8_t pbuf_pool_memory[(PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf)))];
static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;
static sys_sem_t pbuf_pool_free_sem;
static struct pbuf *pbuf_pool = NULL;
static struct pbuf *pbuf_pool_alloc_cache = NULL;
static struct pbuf *pbuf_pool_free_cache = NULL;
/*-----------------------------------------------------------------------------------*/
/* pbuf_init():
*
* Initializes the pbuf module. A large part of memory is allocated
* for holding the pool of pbufs. The size of the individual pbufs in
* the pool is given by the size parameter, and the number of pbufs in
* the pool by the num parameter.
*
* After the memory has been allocated, the pbufs are set up. The
* ->next pointer in each pbuf is set up to point to the next pbuf in
* the pool.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_init(void)
{
struct pbuf *p, *q;
u16_t i;
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
#ifdef PBUF_STATS
stats.pbuf.avail = PBUF_POOL_SIZE;
#endif /* PBUF_STATS */
/* Set up ->next pointers to link the pbufs of the pool together. */
p = pbuf_pool;
for(i = 0; i < PBUF_POOL_SIZE; ++i) {
p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));
p->len = p->tot_len = PBUF_POOL_BUFSIZE;
p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf)));
q = p;
p = p->next;
}
/* The ->next pointer of last pbuf is NULL to indicate that there
are no more pbufs in the pool. */
q->next = NULL;
pbuf_pool_alloc_lock = 0;
pbuf_pool_free_lock = 0;
pbuf_pool_free_sem = sys_sem_new(1);
}
/*-----------------------------------------------------------------------------------*/
/* The following two functions are only called from pbuf_alloc(). */
/*-----------------------------------------------------------------------------------*/
static struct pbuf *
pbuf_pool_alloc(void)
{
struct pbuf *p = NULL;
/* First, see if there are pbufs in the cache. */
if(pbuf_pool_alloc_cache) {
p = pbuf_pool_alloc_cache;
if(p) {
pbuf_pool_alloc_cache = p->next;
}
} else {
/* Next, check the actual pbuf pool, but if the pool is locked, we
pretend to be out of buffers and return NULL. */
if(pbuf_pool_free_lock) {
#ifdef PBUF_STATS
++stats.pbuf.alloc_locked;
#endif /* PBUF_STATS */
return NULL;
}
pbuf_pool_alloc_lock = 1;
if(!pbuf_pool_free_lock) {
p = pbuf_pool;
if(p) {
pbuf_pool = p->next;
}
#ifdef PBUF_STATS
} else {
++stats.pbuf.alloc_locked;
#endif /* PBUF_STATS */
}
pbuf_pool_alloc_lock = 0;
}
#ifdef PBUF_STATS
if(p != NULL) {
++stats.pbuf.used;
if(stats.pbuf.used > stats.pbuf.max) {
stats.pbuf.max = stats.pbuf.used;
}
}
#endif /* PBUF_STATS */
return p;
}
/*-----------------------------------------------------------------------------------*/
static void
pbuf_pool_free(struct pbuf *p)
{
struct pbuf *q;
#ifdef PBUF_STATS
for(q = p; q != NULL; q = q->next) {
--stats.pbuf.used;
}
#endif /* PBUF_STATS */
if(pbuf_pool_alloc_cache == NULL) {
pbuf_pool_alloc_cache = p;
} else {
for(q = pbuf_pool_alloc_cache; q->next != NULL; q = q->next);
q->next = p;
}
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_alloc():
*
* Allocates a pbuf at protocol layer l. The actual memory allocated
* for the pbuf is determined by the layer at which the pbuf is
* allocated and the requested size (from the size parameter). The
* flag parameter decides how and where the pbuf should be allocated
* as follows:
*
* * PBUF_RAM: buffer memory for pbuf is allocated as one large
* chunk. This includes protocol headers as well.
* * RBUF_ROM: no buffer memory is allocated for the pbuf, even for
* protocol headers. Additional headers must be prepended
* by allocating another pbuf and chain in to the front of
* the ROM pbuf.
* * PBUF_ROOL: the pbuf is allocated as a pbuf chain, with pbufs from
* the pbuf pool that is allocated during pbuf_init().
*/
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
{
struct pbuf *p, *q, *r;
u16_t offset;
s32_t rsize;
offset = 0;
switch(l) {
case PBUF_TRANSPORT:
offset += PBUF_TRANSPORT_HLEN;
/* FALLTHROUGH */
case PBUF_IP:
offset += PBUF_IP_HLEN;
offset += PBUF_LINK_HLEN;
/* FALLTHROUGH */
case PBUF_LINK:
break;
case PBUF_RAW:
break;
default:
ASSERT("pbuf_alloc: bad pbuf layer", 0);
return NULL;
}
switch(flag) {
case PBUF_POOL:
/* Allocate head of pbuf chain into p. */
p = pbuf_pool_alloc();
if(p == NULL) {
#ifdef PBUF_STATS
++stats.pbuf.err;
#endif /* PBUF_STATS */
return NULL;
}
p->next = NULL;
/* Set the payload pointer so that it points offset bytes into
pbuf data memory. */
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
/* The total length of the pbuf is the requested size. */
p->tot_len = size;
/* Set the length of the first pbuf is the chain. */
p->len = size > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: size;
p->flags = PBUF_FLAG_POOL;
/* Allocate the tail of the pbuf chain. */
r = p;
rsize = size - p->len;
while(rsize > 0) {
q = pbuf_pool_alloc();
if(q == NULL) {
DEBUGF(PBUF_DEBUG, ("pbuf_alloc: Out of pbufs in pool,\n"));
#ifdef PBUF_STATS
++stats.pbuf.err;
#endif /* PBUF_STATS */
pbuf_pool_free(p);
return NULL;
}
q->next = NULL;
r->next = q;
q->len = rsize > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rsize;
q->flags = PBUF_FLAG_POOL;
q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
r = q;
q->ref = 1;
q = q->next;
rsize -= PBUF_POOL_BUFSIZE;
}
r->next = NULL;
ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
break;
case PBUF_RAM:
/* If pbuf is to be allocated in RAM, allocate memory for it. */
p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + size + offset));
if(p == NULL) {
return NULL;
}
/* Set up internal structure of the pbuf. */
p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));
p->len = p->tot_len = size;
p->next = NULL;
p->flags = PBUF_FLAG_RAM;
ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
break;
case PBUF_ROM:
/* If the pbuf should point to ROM, we only need to allocate
memory for the pbuf structure. */
p = memp_mallocp(MEMP_PBUF);
if(p == NULL) {
return NULL;
}
p->payload = NULL;
p->len = p->tot_len = size;
p->next = NULL;
p->flags = PBUF_FLAG_ROM;
break;
default:
ASSERT("pbuf_alloc: erroneous flag", 0);
return NULL;
}
p->ref = 1;
return p;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_refresh():
*
* Moves free buffers from the pbuf_pool_free_cache to the pbuf_pool
* list (if possible).
*
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_refresh(void)
{
struct pbuf *p;
sys_sem_wait(pbuf_pool_free_sem);
if(pbuf_pool_free_cache != NULL) {
pbuf_pool_free_lock = 1;
if(!pbuf_pool_alloc_lock) {
if(pbuf_pool == NULL) {
pbuf_pool = pbuf_pool_free_cache;
} else {
for(p = pbuf_pool; p->next != NULL; p = p->next);
p->next = pbuf_pool_free_cache;
}
pbuf_pool_free_cache = NULL;
#ifdef PBUF_STATS
} else {
++stats.pbuf.refresh_locked;
#endif /* PBUF_STATS */
}
pbuf_pool_free_lock = 0;
}
sys_sem_signal(pbuf_pool_free_sem);
}
#define PBUF_POOL_FREE(p) do { \
sys_sem_wait(pbuf_pool_free_sem); \
p->next = pbuf_pool_free_cache; \
pbuf_pool_free_cache = p; \
sys_sem_signal(pbuf_pool_free_sem); \
} while(0)
/*-----------------------------------------------------------------------------------*/
/* pbuf_realloc:
*
* Reallocates the memory for a pbuf. If the pbuf is in ROM, this as
* simple as to adjust the ->tot_len and ->len fields. If the pbuf is
* a pbuf chain, as it might be with both pbufs in dynamically
* allocated RAM and for pbufs from the pbuf pool, we have to step
* through the chain until we find the new endpoint in the pbuf chain.
* Then the pbuf that is right on the endpoint is resized and any
* further pbufs on the chain are deallocated.
*/
/*-----------------------------------------------------------------------------------*/
void
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 ||
p->flags == PBUF_FLAG_ROM ||
p->flags == PBUF_FLAG_RAM);
if(p->tot_len <= size) {
return;
}
switch(p->flags) {
case PBUF_FLAG_POOL:
/* First, step over any pbufs that should still be in the chain. */
rsize = size;
q = p;
while(rsize > q->len) {
rsize -= q->len;
q = q->next;
}
/* Adjust the length of the pbuf that will be halved. */
q->len = rsize;
/* And deallocate any left over pbufs. */
r = q->next;
q->next = NULL;
q = r;
while(q != NULL) {
r = q->next;
PBUF_POOL_FREE(q);
#ifdef PBUF_STATS
--stats.pbuf.used;
#endif /* PBUF_STATS */
q = r;
}
break;
case PBUF_FLAG_ROM:
p->len = size;
break;
case PBUF_FLAG_RAM:
/* First, step over the pbufs that should still be in the chain. */
rsize = size;
q = p;
while(rsize > q->len) {
rsize -= q->len;
q = q->next;
}
if(q->flags == PBUF_FLAG_RAM) {
/* Reallocate and adjust the length of the pbuf that will be halved. */
mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rsize);
}
q->len = rsize;
/* And deallocate any left over pbufs. */
r = q->next;
q->next = NULL;
q = r;
while(q != NULL) {
r = q->next;
pbuf_free(q);
q = r;
}
break;
}
p->tot_len = size;
pbuf_refresh();
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_header():
*
* Adjusts the ->payload pointer so that space for a header appears in
* the pbuf. Also, the ->tot_len and ->len fields are adjusted.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_header(struct pbuf *p, s16_t header_size)
{
void *payload;
if(p->flags & PBUF_FLAG_ROM) {
return 1;
}
payload = p->payload;
p->payload = (u8_t *)p->payload - header_size/sizeof(u8_t);
DEBUGF(PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", payload, p->payload, header_size));
if((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
DEBUGF(PBUF_DEBUG, ("pbuf_header: failed %p %p\n",
(u8_t *)p->payload,
(u8_t *)p + sizeof(struct pbuf)));
p->payload = payload;
return 1;
}
p->len += header_size;
p->tot_len += header_size;
return 0;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_free():
*
* Decrements the reference count and deallocates the pbuf if the
* reference count is zero. If the pbuf is a chain all pbufs in the
* chain are deallocated.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_free(struct pbuf *p)
{
struct pbuf *q;
u8_t count = 0;
if(p == NULL) {
return 0;
}
PERF_START;
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);
/* Decrement reference count. */
p->ref--;
q = NULL;
/* If reference count == 0, actually deallocate pbuf. */
if(p->ref == 0) {
while(p != NULL) {
/* Check if this is a pbuf from the pool. */
if(p->flags == PBUF_FLAG_POOL) {
p->len = p->tot_len = PBUF_POOL_BUFSIZE;
p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
q = p->next;
PBUF_POOL_FREE(p);
#ifdef PBUF_STATS
--stats.pbuf.used;
#endif /* PBUF_STATS */
} else if(p->flags == PBUF_FLAG_ROM) {
q = p->next;
memp_freep(MEMP_PBUF, p);
} else {
q = p->next;
mem_free(p);
}
p = q;
++count;
}
pbuf_refresh();
}
PERF_STOP("pbuf_free");
return count;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_clen():
*
* Returns the length of the pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_clen(struct pbuf *p)
{
u8_t len;
if(p == NULL) {
return 0;
}
for(len = 0; p != NULL; p = p->next) {
++len;
}
return len;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_ref():
*
* Increments the reference count of the pbuf.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_ref(struct pbuf *p)
{
if(p == NULL) {
return;
}
++(p->ref);
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_chain():
*
* Chains the two pbufs h and t together. The ->tot_len field of the
* first pbuf (h) is adjusted.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_chain(struct pbuf *h, struct pbuf *t)
{
struct pbuf *p;
if(t == NULL) {
return;
}
for(p = h; p->next != NULL; p = p->next);
p->next = t;
h->tot_len += t->tot_len;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_dechain():
*
* Adjusts the ->tot_len field of the pbuf and returns the tail (if
* any) of the pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_dechain(struct pbuf *p)
{
struct pbuf *q;
q = p->next;
if (q != NULL) {
q->tot_len = p->tot_len - p->len;
}
p->tot_len = p->len;
p->next = NULL;
return q;
}
/*-----------------------------------------------------------------------------------*/

54
src/core/stats.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/mem.h"
#ifdef STATS
struct stats_ stats;
#endif /* STATS */
/*-----------------------------------------------------------------------------------*/
void
stats_init(void)
{
#ifdef STATS
bzero(&stats, sizeof(struct stats_));
#endif /* STATS */
}
/*-----------------------------------------------------------------------------------*/

187
src/core/sys.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#ifndef NO_SYS
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_fetch(sys_mbox_t mbox, void **msg)
{
u16_t time;
struct sys_timeouts *timeouts;
struct sys_timeout *tmptimeout;
sys_timeout_handler h;
void *arg;
again:
timeouts = sys_arch_timeouts();
if(timeouts->next == NULL) {
sys_arch_mbox_fetch(mbox, msg, 0);
} else {
if(timeouts->next->time > 0) {
time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
} else {
time = 0;
}
if(time == 0) {
/* If time == 0, a timeout occured before a message could be
fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout = timeouts->next;
timeouts->next = tmptimeout->next;
h = tmptimeout->h;
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
/* We try again to fetch a message from the mbox. */
goto again;
} else {
/* If time > 0, a message was received before the timeout
occured. The time variable is set to the number of
microseconds we waited for the message. */
if(time <= timeouts->next->time) {
timeouts->next->time -= time;
} else {
timeouts->next->time = 0;
}
}
}
}
/*-----------------------------------------------------------------------------------*/
void
sys_sem_wait(sys_sem_t sem)
{
u16_t time;
struct sys_timeouts *timeouts;
struct sys_timeout *tmptimeout;
sys_timeout_handler h;
void *arg;
/* while(sys_arch_sem_wait(sem, 1000) == 0);
return;*/
again:
timeouts = sys_arch_timeouts();
if(timeouts->next == NULL) {
sys_arch_sem_wait(sem, 0);
} else {
if(timeouts->next->time > 0) {
time = sys_arch_sem_wait(sem, timeouts->next->time);
} else {
time = 0;
}
if(time == 0) {
/* If time == 0, a timeout occured before a message could be
fetched. We should now call the timeout handler and
deallocate the memory allocated for the timeout. */
tmptimeout = timeouts->next;
timeouts->next = tmptimeout->next;
h = tmptimeout->h;
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
h(arg);
/* We try again to fetch a message from the mbox. */
goto again;
} else {
/* If time > 0, a message was received before the timeout
occured. The time variable is set to the number of
microseconds we waited for the message. */
if(time <= timeouts->next->time) {
timeouts->next->time -= time;
} else {
timeouts->next->time = 0;
}
}
}
}
/*-----------------------------------------------------------------------------------*/
void
sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg)
{
struct sys_timeouts *timeouts;
struct sys_timeout *timeout, *t;
timeout = memp_malloc(MEMP_SYS_TIMEOUT);
if(timeout == NULL) {
return;
}
timeout->next = NULL;
timeout->h = h;
timeout->arg = arg;
timeout->time = msecs;
timeouts = sys_arch_timeouts();
if(timeouts->next == NULL) {
timeouts->next = timeout;
return;
}
if(timeouts->next->time > msecs) {
timeouts->next->time -= msecs;
timeout->next = timeouts->next;
timeouts->next = timeout;
} else {
for(t = timeouts->next; t != NULL; t = t->next) {
timeout->time -= t->time;
if(t->next == NULL ||
t->next->time > timeout->time) {
if(t->next != NULL) {
t->next->time -= timeout->time;
}
timeout->next = t->next;
t->next = timeout;
break;
}
}
}
}
/*-----------------------------------------------------------------------------------*/
#endif /* NO_SYS */

1158
src/core/tcp.c Normal file

File diff suppressed because it is too large Load Diff

1122
src/core/tcp_input.c Normal file

File diff suppressed because it is too large Load Diff

589
src/core/tcp_output.c Normal file
View File

@@ -0,0 +1,589 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* tcp_output.c
*
* The output functions of TCP.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/opt.h"
#include "arch/lib.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/tcp.h"
#include "lwip/stats.h"
#define MIN(x,y) (x) < (y)? (x): (y)
/* Forward declarations.*/
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
/*-----------------------------------------------------------------------------------*/
err_t
tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
{
return tcp_enqueue(pcb, NULL, 0, flags, 1, NULL, 0);
}
/*-----------------------------------------------------------------------------------*/
err_t
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
{
if(pcb->state == SYN_SENT ||
pcb->state == SYN_RCVD ||
pcb->state == ESTABLISHED ||
pcb->state == CLOSE_WAIT) {
if(len > 0) {
return tcp_enqueue(pcb, (void *)arg, len, 0, copy, NULL, 0);
}
return ERR_OK;
} else {
return ERR_CONN;
}
}
/*-----------------------------------------------------------------------------------*/
err_t
tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
u8_t flags, u8_t copy,
u8_t *optdata, u8_t optlen)
{
struct pbuf *p;
struct tcp_seg *seg, *useg, *queue;
u32_t left, seqno;
u16_t seglen;
void *ptr;
u8_t queuelen;
left = len;
ptr = arg;
if(len > pcb->snd_buf) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too much data %d\n", len));
return ERR_MEM;
}
seqno = pcb->snd_lbb;
queue = NULL;
DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d\n", pcb->snd_queuelen));
queuelen = pcb->snd_queuelen;
if(queuelen >= TCP_SND_QUEUELEN) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));
goto memerr;
}
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */
seg = NULL;
seglen = 0;
while(queue == NULL || left > 0) {
seglen = left > pcb->mss? pcb->mss: left;
/* allocate memory for tcp_seg, and fill in fields */
seg = memp_malloc(MEMP_TCP_SEG);
if(seg == NULL) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for tcp_seg\n"));
goto memerr;
}
seg->next = NULL;
seg->p = NULL;
if(queue == NULL) {
queue = seg;
} else {
for(useg = queue; useg->next != NULL; useg = useg->next);
useg->next = seg;
}
/* If copy is set, memory should be allocated
and data copied into pbuf, otherwise data comes from
ROM or other static memory, and need not be copied. If
optdata is != NULL, we have options instead of data. */
if(optdata != NULL) {
if((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
goto memerr;
}
++queuelen;
seg->dataptr = seg->p->payload;
} else if(copy) {
if((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for pbuf copy\n"));
goto memerr;
}
++queuelen;
if(arg != NULL) {
bcopy(ptr, seg->p->payload, seglen);
}
seg->dataptr = seg->p->payload;
} else {
/* Do not copy the data. */
if((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for pbuf non-copy\n"));
goto memerr;
}
++queuelen;
p->payload = ptr;
seg->dataptr = ptr;
if((seg->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM)) == NULL) {
pbuf_free(p);
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
goto memerr;
}
++queuelen;
pbuf_chain(seg->p, p);
}
if(queuelen > TCP_SND_QUEUELEN) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));
goto memerr;
}
seg->len = seglen;
/* if((flags & TCP_SYN) || (flags & TCP_FIN)) {
++seg->len;
}*/
/* build TCP header */
if(pbuf_header(seg->p, TCP_HLEN)) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
#ifdef TCP_STATS
++stats.tcp.err;
#endif /* TCP_STATS */
goto memerr;
}
seg->tcphdr = seg->p->payload;
seg->tcphdr->src = htons(pcb->local_port);
seg->tcphdr->dest = htons(pcb->remote_port);
seg->tcphdr->seqno = htonl(seqno);
seg->tcphdr->urgp = 0;
TCPH_FLAGS_SET(seg->tcphdr, flags);
/* don't fill in tcphdr->ackno and tcphdr->wnd until later */
if(optdata == NULL) {
TCPH_OFFSET_SET(seg->tcphdr, 5 << 4);
} else {
TCPH_OFFSET_SET(seg->tcphdr, (5 + optlen / 4) << 4);
/* Copy options into data portion of segment.
Options can thus only be sent in non data carrying
segments such as SYN|ACK. */
bcopy(optdata, seg->dataptr, optlen);
}
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: queueing %lu:%lu (0x%x)\n",
ntohl(seg->tcphdr->seqno),
ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
flags));
left -= seglen;
seqno += seglen;
ptr = (void *)((char *)ptr + seglen);
}
/* Go to the last segment on the ->unsent queue. */
if(pcb->unsent == NULL) {
useg = NULL;
} else {
for(useg = pcb->unsent; useg->next != NULL; useg = useg->next);
}
/* If there is room in the last pbuf on the unsent queue,
chain the first pbuf on the queue together with that. */
if(useg != NULL &&
TCP_TCPLEN(useg) != 0 &&
!(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
!(flags & (TCP_SYN | TCP_FIN)) &&
useg->len + queue->len <= pcb->mss) {
/* Remove TCP header from first segment. */
pbuf_header(queue->p, -TCP_HLEN);
pbuf_chain(useg->p, queue->p);
useg->len += queue->len;
useg->next = queue->next;
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: chaining, new len %u\n", useg->len));
if(seg == queue) {
seg = NULL;
}
memp_free(MEMP_TCP_SEG, queue);
} else {
if(useg == NULL) {
pcb->unsent = queue;
} else {
useg->next = queue;
}
}
if((flags & TCP_SYN) || (flags & TCP_FIN)) {
++len;
}
pcb->snd_lbb += len;
pcb->snd_buf -= len;
pcb->snd_queuelen = queuelen;
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 ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */
/* Set the PSH flag in the last segment that we enqueued, but only
if the segment has data (indicated by seglen > 0). */
if(seg != NULL && seglen > 0 && seg->tcphdr != NULL) {
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_PSH);
}
return ERR_OK;
memerr:
#ifdef TCP_STATS
++stats.tcp.memerr;
#endif /* TCP_STATS */
if(queue != NULL) {
tcp_segs_free(queue);
}
#ifdef LWIP_DEBUG
if(pcb->snd_queuelen != 0) {
ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
pcb->unsent != NULL);
}
#endif /* LWIP_DEBUG */
DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %d (with mem err)\n", pcb->snd_queuelen));
return ERR_MEM;
}
/*-----------------------------------------------------------------------------------*/
/* find out what we can send and send it */
err_t
tcp_output(struct tcp_pcb *pcb)
{
struct pbuf *p;
struct tcp_hdr *tcphdr;
struct tcp_seg *seg, *useg;
u32_t wnd;
#if TCP_CWND_DEBUG
int i = 0;
#endif /* TCP_CWND_DEBUG */
/* First, check if we are invoked by the TCP input processing
code. If so, we do not output anything. Instead, we rely on the
input processing code to call us when input processing is done
with. */
if(tcp_input_pcb == pcb) {
return ERR_OK;
}
wnd = MIN(pcb->snd_wnd, pcb->cwnd);
seg = pcb->unsent;
/* If the TF_ACK_NOW flag is set, we check if there is data that is
to be sent. If data is to be sent out, we'll just piggyback our
acknowledgement with the outgoing segment. If no data will be
sent (either because the ->unsent queue is empty or because the
window doesn't allow it) we'll have to construct an empty ACK
segment and send it. */
if(pcb->flags & TF_ACK_NOW &&
(seg == NULL ||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM);
if(p == NULL) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: (ACK) could not allocate pbuf\n"));
return ERR_BUF;
}
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: sending ACK for %lu\n", pcb->rcv_nxt));
if(pbuf_header(p, TCP_HLEN)) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue: (ACK) no room for TCP header in pbuf.\n"));
#ifdef TCP_STATS
++stats.tcp.err;
#endif /* TCP_STATS */
pbuf_free(p);
return ERR_BUF;
}
tcphdr = p->payload;
tcphdr->src = htons(pcb->local_port);
tcphdr->dest = htons(pcb->remote_port);
tcphdr->seqno = htonl(pcb->snd_nxt);
tcphdr->ackno = htonl(pcb->rcv_nxt);
TCPH_FLAGS_SET(tcphdr, TCP_ACK);
tcphdr->wnd = htons(pcb->rcv_wnd);
tcphdr->urgp = 0;
TCPH_OFFSET_SET(tcphdr, 5 << 4);
tcphdr->chksum = 0;
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
IP_PROTO_TCP, p->tot_len);
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
IP_PROTO_TCP);
pbuf_free(p);
return ERR_OK;
}
#if TCP_OUTPUT_DEBUG
if(seg == NULL) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", pcb->unsent));
}
#endif /* TCP_OUTPUT_DEBUG */
#if TCP_CWND_DEBUG
if(seg == NULL) {
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, seg == NULL, ack %lu\n",
pcb->snd_wnd, pcb->cwnd, wnd,
pcb->lastack));
} else {
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu\n",
pcb->snd_wnd, pcb->cwnd, wnd,
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
ntohl(seg->tcphdr->seqno), pcb->lastack));
}
#endif /* TCP_CWND_DEBUG */
while(seg != NULL &&
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
pcb->rtime = 0;
#if TCP_CWND_DEBUG
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu, i%d\n",
pcb->snd_wnd, pcb->cwnd, wnd,
ntohl(seg->tcphdr->seqno) + seg->len -
pcb->lastack,
ntohl(seg->tcphdr->seqno), pcb->lastack, i));
++i;
#endif /* TCP_CWND_DEBUG */
pcb->unsent = seg->next;
if(pcb->state != SYN_SENT) {
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_ACK);
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
}
tcp_output_segment(seg, pcb);
pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
if(TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
pcb->snd_max = pcb->snd_nxt;
}
/* put segment on unacknowledged list if length > 0 */
if(TCP_TCPLEN(seg) > 0) {
seg->next = NULL;
if(pcb->unacked == NULL) {
pcb->unacked = seg;
} else {
for(useg = pcb->unacked; useg->next != NULL; useg = useg->next);
useg->next = seg;
}
/* seg->rtime = 0;*/
} else {
tcp_seg_free(seg);
}
seg = pcb->unsent;
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
{
u16_t len;
struct netif *netif;
/* The TCP header has already been constructed, but the ackno and
wnd fields remain. */
seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
/* silly window avoidance */
if(pcb->rcv_wnd < pcb->mss) {
seg->tcphdr->wnd = 0;
} else {
seg->tcphdr->wnd = htons(pcb->rcv_wnd);
}
/* If we don't have a local IP address, we get one by
calling ip_route(). */
if(ip_addr_isany(&(pcb->local_ip))) {
netif = ip_route(&(pcb->remote_ip));
if(netif == NULL) {
return;
}
ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
}
pcb->rtime = 0;
if(pcb->rttest == 0) {
pcb->rttest = tcp_ticks;
pcb->rtseq = ntohl(seg->tcphdr->seqno);
DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq));
}
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n",
htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
seg->len));
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
seg->p->len -= len;
seg->p->tot_len -= len;
seg->p->payload = seg->tcphdr;
seg->tcphdr->chksum = 0;
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
&(pcb->local_ip),
&(pcb->remote_ip),
IP_PROTO_TCP, seg->p->tot_len);
#ifdef TCP_STATS
++stats.tcp.xmit;
#endif /* TCP_STATS */
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
IP_PROTO_TCP);
}
/*-----------------------------------------------------------------------------------*/
void
tcp_rst(u32_t seqno, u32_t ackno,
struct ip_addr *local_ip, struct ip_addr *remote_ip,
u16_t local_port, u16_t remote_port)
{
struct pbuf *p;
struct tcp_hdr *tcphdr;
p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_RAM);
if(p == NULL) {
if(p == NULL) {
DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
return;
}
}
if(pbuf_header(p, TCP_HLEN)) {
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_send_data: no room for TCP header in pbuf.\n"));
#ifdef TCP_STATS
++stats.tcp.err;
#endif /* TCP_STATS */
return;
}
tcphdr = p->payload;
tcphdr->src = htons(local_port);
tcphdr->dest = htons(remote_port);
tcphdr->seqno = htonl(seqno);
tcphdr->ackno = htonl(ackno);
TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
tcphdr->wnd = htons(TCP_WND);
tcphdr->urgp = 0;
TCPH_OFFSET_SET(tcphdr, 5 << 4);
tcphdr->chksum = 0;
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
IP_PROTO_TCP, p->tot_len);
#ifdef TCP_STATS
++stats.tcp.xmit;
#endif /* TCP_STATS */
ip_output(p, local_ip, remote_ip, TCP_TTL, IP_PROTO_TCP);
pbuf_free(p);
DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %lu ackno %lu.\n", seqno, ackno));
}
/*-----------------------------------------------------------------------------------*/
void
tcp_rexmit(struct tcp_pcb *pcb)
{
struct tcp_seg *seg;
if(pcb->unacked == NULL) {
return;
}
/* Move all unacked segments to the unsent queue. */
for(seg = pcb->unacked; seg->next != NULL; seg = seg->next);
seg->next = pcb->unsent;
pcb->unsent = pcb->unacked;
pcb->unacked = NULL;
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
++pcb->nrtx;
pcb->rtime = 0;
/* Don't take any rtt measurements after retransmitting. */
pcb->rttest = 0;
/* Do the actual retransmission. */
tcp_output(pcb);
}

453
src/core/udp.c Normal file
View File

@@ -0,0 +1,453 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
/* udp.c
*
* The code for the User Datagram Protocol UDP.
*
*/
/*-----------------------------------------------------------------------------------*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/udp.h"
#include "lwip/icmp.h"
#include "lwip/stats.h"
#include "arch/perf.h"
/*-----------------------------------------------------------------------------------*/
/* The list of UDP PCBs. */
#if LWIP_UDP
static struct udp_pcb *udp_pcbs = NULL;
static struct udp_pcb *pcb_cache = NULL;
#endif /* LWIP_UDP */
#if UDP_DEBUG
int udp_debug_print(struct udp_hdr *udphdr);
#endif /* UDP_DEBUG */
/*-----------------------------------------------------------------------------------*/
void
udp_init(void)
{
udp_pcbs = pcb_cache = NULL;
}
#if LWIP_UDP
/*-----------------------------------------------------------------------------------*/
/* udp_lookup:
*
* An experimental feature that will be changed in future versions. Do
* not depend on it yet...
*/
/*-----------------------------------------------------------------------------------*/
#ifdef LWIP_DEBUG
u8_t
udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
{
struct udp_pcb *pcb;
struct udp_hdr *udphdr;
u16_t src, dest;
PERF_START;
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4/sizeof(u8_t);
src = NTOHS(udphdr->src);
dest = NTOHS(udphdr->dest);
pcb = pcb_cache;
if(pcb != NULL &&
pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
return 1;
} else {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
if(pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
pcb_cache = pcb;
break;
}
}
if(pcb == NULL) {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
if(pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
}
}
PERF_STOP("udp_lookup");
if(pcb != NULL) {
return 1;
} else {
return 1;
}
}
#endif /* LWIP_DEBUG */
/*-----------------------------------------------------------------------------------*/
void
udp_input(struct pbuf *p, struct netif *inp)
{
struct udp_hdr *udphdr;
struct udp_pcb *pcb;
struct ip_hdr *iphdr;
u16_t src, dest;
PERF_START;
#ifdef UDP_STATS
++stats.udp.recv;
#endif /* UDP_STATS */
iphdr = p->payload;
pbuf_header(p, -(UDP_HLEN + IPH_HL(iphdr) * 4));
udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %d\n", p->tot_len));
src = NTOHS(udphdr->src);
dest = NTOHS(udphdr->dest);
#if UDP_DEBUG
udp_debug_print(udphdr);
#endif /* UDP_DEBUG */
/* Demultiplex packet. First, go for a perfect match. */
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
pcb->local_port, ntohs(udphdr->dest)));
if(pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
if(pcb == NULL) {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
pcb->local_port, dest));
if(pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
}
/* Check checksum if this is a match or if it was directed at us. */
/* if(pcb != NULL ||
ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) {*/
if(pcb != NULL) {
DEBUGF(UDP_DEBUG, ("udp_input: calculating checksum\n"));
pbuf_header(p, UDP_HLEN);
#ifdef IPv6
if(iphdr->nexthdr == IP_PROTO_UDPLITE) {
#else
if(IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
#endif /* IPv4 */
/* Do the UDP Lite checksum */
if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
DEBUGF(UDP_DEBUG, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
#ifdef UDP_STATS
++stats.udp.chkerr;
++stats.udp.drop;
#endif /* UDP_STATS */
pbuf_free(p);
goto end;
}
} else {
if(udphdr->chksum != 0) {
if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDP, p->tot_len) != 0) {
DEBUGF(UDP_DEBUG, ("udp_input: UDP datagram discarded due to failing checksum\n"));
#ifdef UDP_STATS
++stats.udp.chkerr;
++stats.udp.drop;
#endif /* UDP_STATS */
pbuf_free(p);
goto end;
}
}
}
pbuf_header(p, -UDP_HLEN);
if(pcb != NULL) {
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
} else {
DEBUGF(UDP_DEBUG, ("udp_input: not for us.\n"));
/* No match was found, send ICMP destination port unreachable unless
destination address was broadcast/multicast. */
if(!ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) &&
!ip_addr_ismulticast(&iphdr->dest)) {
/* deconvert from host to network byte order */
udphdr->src = htons(udphdr->src);
udphdr->dest = htons(udphdr->dest);
/* adjust pbuf pointer */
p->payload = iphdr;
icmp_dest_unreach(p, ICMP_DUR_PORT);
}
#ifdef UDP_STATS
++stats.udp.proterr;
++stats.udp.drop;
#endif /* UDP_STATS */
pbuf_free(p);
}
} else {
pbuf_free(p);
}
end:
PERF_STOP("udp_input");
}
/*-----------------------------------------------------------------------------------*/
err_t
udp_send(struct udp_pcb *pcb, struct pbuf *p)
{
struct udp_hdr *udphdr;
struct netif *netif;
struct ip_addr *src_ip;
err_t err;
struct pbuf *hdr;
/* hdr will point to the UDP header pbuf if an extra header pbuf has
to be allocated. */
hdr = NULL;
if(pbuf_header(p, UDP_HLEN)) {
hdr = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
if(hdr == NULL) {
return ERR_MEM;
}
pbuf_chain(hdr, p);
p = hdr;
}
udphdr = p->payload;
udphdr->src = htons(pcb->local_port);
udphdr->dest = htons(pcb->remote_port);
udphdr->chksum = 0x0000;
if((netif = ip_route(&(pcb->remote_ip))) == NULL) {
DEBUGF(UDP_DEBUG, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
#ifdef UDP_STATS
++stats.udp.rterr;
#endif /* UDP_STATS */
return ERR_RTE;
}
if(ip_addr_isany(&pcb->local_ip)) {
src_ip = &(netif->ip_addr);
} else {
src_ip = &(pcb->local_ip);
}
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %d\n", p->tot_len));
if(pcb->flags & UDP_FLAGS_UDPLITE) {
udphdr->len = htons(pcb->chksum_len);
/* calculate checksum */
udphdr->chksum = inet_chksum_pseudo(p, src_ip, &(pcb->remote_ip),
IP_PROTO_UDP, pcb->chksum_len);
if(udphdr->chksum == 0x0000) {
udphdr->chksum = 0xffff;
}
err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDPLITE, netif);
} else {
udphdr->len = htons(p->tot_len);
/* calculate checksum */
if((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
udphdr->chksum = inet_chksum_pseudo(p, src_ip, &pcb->remote_ip,
IP_PROTO_UDP, p->tot_len);
if(udphdr->chksum == 0x0000) {
udphdr->chksum = 0xffff;
}
}
err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
}
if(hdr != NULL) {
pbuf_dechain(hdr);
pbuf_free(hdr);
}
#ifdef UDP_STATS
++stats.udp.xmit;
#endif /* UDP_STATS */
return err;
}
/*-----------------------------------------------------------------------------------*/
err_t
udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct udp_pcb *ipcb;
ip_addr_set(&pcb->local_ip, ipaddr);
pcb->local_port = port;
/* Insert UDP PCB into the list of active UDP PCBs. */
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
if(pcb == ipcb) {
/* Already on the list, just return. */
return ERR_OK;
}
}
/* We need to place the PCB on the list. */
pcb->next = udp_pcbs;
udp_pcbs = pcb;
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %d\n", port));
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
err_t
udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct udp_pcb *ipcb;
ip_addr_set(&pcb->remote_ip, ipaddr);
pcb->remote_port = port;
/* Insert UDP PCB into the list of active UDP PCBs. */
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
if(pcb == ipcb) {
/* Already on the list, just return. */
return ERR_OK;
}
}
/* We need to place the PCB on the list. */
pcb->next = udp_pcbs;
udp_pcbs = pcb;
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
udp_recv(struct udp_pcb *pcb,
void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
struct ip_addr *addr, u16_t port),
void *recv_arg)
{
pcb->recv = recv;
pcb->recv_arg = recv_arg;
}
/*-----------------------------------------------------------------------------------*/
void
udp_remove(struct udp_pcb *pcb)
{
struct udp_pcb *pcb2;
if(udp_pcbs == pcb) {
udp_pcbs = udp_pcbs->next;
} else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
if(pcb2->next != NULL && pcb2->next == pcb) {
pcb2->next = pcb->next;
}
}
memp_free(MEMP_UDP_PCB, pcb);
}
/*-----------------------------------------------------------------------------------*/
struct udp_pcb *
udp_new(void) {
struct udp_pcb *pcb;
pcb = memp_malloc(MEMP_UDP_PCB);
if(pcb != NULL) {
bzero(pcb, sizeof(struct udp_pcb));
return pcb;
}
return NULL;
}
/*-----------------------------------------------------------------------------------*/
#if UDP_DEBUG
int
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",
ntohs(udphdr->src), ntohs(udphdr->dest)));
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(UDP_DEBUG, ("| %5d | 0x%04x | (len, chksum)\n",
ntohs(udphdr->len), ntohs(udphdr->chksum)));
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
return 0;
}
#endif /* UDP_DEBUG */
/*-----------------------------------------------------------------------------------*/
#endif /* LWIP_UDP */

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_ICMP_H__
#define __LWIP_ICMP_H__
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#define ICMP_ER 0 /* echo reply */
#define ICMP_DUR 3 /* destination unreachable */
#define ICMP_SQ 4 /* source quench */
#define ICMP_RD 5 /* redirect */
#define ICMP_ECHO 8 /* echo */
#define ICMP_TE 11 /* time exceeded */
#define ICMP_PP 12 /* parameter problem */
#define ICMP_TS 13 /* timestamp */
#define ICMP_TSR 14 /* timestamp reply */
#define ICMP_IRQ 15 /* information request */
#define ICMP_IR 16 /* information reply */
enum icmp_dur_type {
ICMP_DUR_NET = 0, /* net unreachable */
ICMP_DUR_HOST = 1, /* host unreachable */
ICMP_DUR_PROTO = 2, /* protocol unreachable */
ICMP_DUR_PORT = 3, /* port unreachable */
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
ICMP_DUR_SR = 5 /* source route failed */
};
enum icmp_te_type {
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
};
void icmp_input(struct pbuf *p, struct netif *inp);
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
PACK_STRUCT_BEGIN
struct icmp_echo_hdr {
PACK_STRUCT_FIELD(u16_t _type_code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u16_t id);
PACK_STRUCT_FIELD(u16_t seqno);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
PACK_STRUCT_BEGIN
struct icmp_dur_hdr {
PACK_STRUCT_FIELD(u16_t _type_code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u32_t unused);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
PACK_STRUCT_BEGIN
struct icmp_te_hdr {
PACK_STRUCT_FIELD(u16_t _type_code);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u32_t unused);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#define ICMPH_TYPE(hdr) (NTOHS((hdr)->_type_code) >> 8)
#define ICMPH_CODE(hdr) (NTOHS((hdr)->_type_code) & 0xff)
#define ICMPH_TYPE_SET(hdr, type) ((hdr)->_type_code = HTONS(ICMPH_CODE(hdr) | ((type) << 8)))
#define ICMPH_CODE_SET(hdr, code) ((hdr)->_type_code = HTONS((code) | (ICMPH_TYPE(hdr) << 8)))
#endif /* __LWIP_ICMP_H__ */

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_INET_H__
#define __LWIP_INET_H__
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
u16_t inet_chksum(void *dataptr, u16_t len);
u16_t inet_chksum_pbuf(struct pbuf *p);
u16_t inet_chksum_pseudo(struct pbuf *p,
struct ip_addr *src, struct ip_addr *dest,
u8_t proto, u16_t proto_len);
#ifdef HTONS
#undef HTONS
#endif /* HTONS */
#ifdef NTOHS
#undef NTOHS
#endif /* NTOHS */
#ifdef HTONL
#undef HTONL
#endif /* HTONL */
#ifdef NTOHL
#undef NTOHL
#endif /* NTOHL */
#ifdef htons
#undef htons
#endif /* htons */
#ifdef htonl
#undef htonl
#endif /* htonl */
#ifdef ntohs
#undef ntohs
#endif /* ntohs */
#ifdef ntohl
#undef ntohl
#endif /* ntohl */
#ifndef HTONS
# if BYTE_ORDER == BIG_ENDIAN
# define HTONS(n) (n)
# else /* BYTE_ORDER == BIG_ENDIAN */
# define HTONS(n) (((((u16_t)(n) & 0xff)) << 8) | (((u16_t)(n) & 0xff00) >> 8))
# endif /* BYTE_ORDER == BIG_ENDIAN */
#endif /* HTONS */
#define htons HTONS
#define NTOHS HTONS
#define ntohs htons
#ifndef HTONL
# if BYTE_ORDER == BIG_ENDIAN
# define HTONL(n) (n)
# else /* BYTE_ORDER == BIG_ENDIAN */
# define HTONL(n) (((((u32_t)(n) & 0xff)) << 24) | \
((((u32_t)(n) & 0xff00)) << 8) | \
((((u32_t)(n) & 0xff0000)) >> 8) | \
((((u32_t)(n) & 0xff000000)) >> 24))
# endif /* BYTE_ORDER == BIG_ENDIAN */
#endif /* HTONL */
#define htonl HTONL
#define NTOHL HTONL
#define ntohl htonl
#endif /* __LWIP_INET_H__ */

119
src/include/ipv4/lwip/ip.h Normal file
View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_IP_H__
#define __LWIP_IP_H__
#include "lwip/arch.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/err.h"
void ip_init(void);
u8_t ip_lookup(void *header, struct netif *inp);
struct netif *ip_route(struct ip_addr *dest);
err_t ip_input(struct pbuf *p, struct netif *inp);
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t proto);
err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t proto,
struct netif *netif);
#define IP_HLEN 20
#define IP_PROTO_ICMP 1
#define IP_PROTO_UDP 17
#define IP_PROTO_UDPLITE 170
#define IP_PROTO_TCP 6
/* This is passed as the destination address to ip_output_if (not
to ip_output), meaning that an IP header already is constructed
in the pbuf. This is used when TCP retransmits. */
#ifdef IP_HDRINCL
#undef IP_HDRINCL
#endif /* IP_HDRINCL */
#define IP_HDRINCL NULL
PACK_STRUCT_BEGIN
struct ip_hdr {
/* version / header length / type of service */
PACK_STRUCT_FIELD(u16_t _v_hl_tos);
/* total length */
PACK_STRUCT_FIELD(u16_t _len);
/* identification */
PACK_STRUCT_FIELD(u16_t _id);
/* fragment offset field */
PACK_STRUCT_FIELD(u16_t _offset);
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
/* time to live / protocol*/
PACK_STRUCT_FIELD(u16_t _ttl_proto);
/* checksum */
PACK_STRUCT_FIELD(u16_t _chksum);
/* source and destination IP addresses */
PACK_STRUCT_FIELD(struct ip_addr src);
PACK_STRUCT_FIELD(struct ip_addr dest);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#define IPH_V(hdr) (NTOHS((hdr)->_v_hl_tos) >> 12)
#define IPH_HL(hdr) ((NTOHS((hdr)->_v_hl_tos) >> 8) & 0x0f)
#define IPH_TOS(hdr) HTONS((NTOHS((hdr)->_v_hl_tos) & 0xff))
#define IPH_LEN(hdr) ((hdr)->_len)
#define IPH_ID(hdr) ((hdr)->_id)
#define IPH_OFFSET(hdr) ((hdr)->_offset)
#define IPH_TTL(hdr) (NTOHS((hdr)->_ttl_proto) >> 8)
#define IPH_PROTO(hdr) (NTOHS((hdr)->_ttl_proto) & 0xff)
#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = HTONS(((v) << 12) | ((hl) << 8) | (tos))
#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = HTONS(IPH_PROTO(hdr) | ((ttl) << 8))
#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = HTONS((proto) | (IPH_TTL(hdr) << 8))
#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
#if IP_DEBUG
void ip_debug_print(struct pbuf *p);
#endif /* IP_DEBUG */
#endif /* __LWIP_IP_H__ */

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_IP_ADDR_H__
#define __LWIP_IP_ADDR_H__
#include "lwip/arch.h"
#define IP_ADDR_ANY 0
#define IP_ADDR_BROADCAST (&ip_addr_broadcast)
PACK_STRUCT_BEGIN
struct ip_addr {
PACK_STRUCT_FIELD(u32_t addr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
extern struct ip_addr ip_addr_broadcast;
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))
#define ip_addr_set(dest, src) (dest)->addr = \
((src) == IP_ADDR_ANY? IP_ADDR_ANY:\
((struct ip_addr *)src)->addr)
#define ip_addr_maskcmp(addr1, addr2, mask) (((addr1)->addr & \
(mask)->addr) == \
((addr2)->addr & \
(mask)->addr))
#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
#define ip_addr_isbroadcast(addr1, mask) (((((addr1)->addr) & ~((mask)->addr)) == \
(0xffffffff & ~((mask)->addr))) || \
((addr1)->addr == 0xffffffff) || \
((addr1)->addr == 0x00000000))
#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
#define ip_addr_debug_print(ipaddr) DEBUGF(LWIP_DEBUG, ("%d.%d.%d.%d", \
(u8_t)(ntohl((ipaddr)->addr) >> 24) & 0xff, \
(u8_t)(ntohl((ipaddr)->addr) >> 16) & 0xff, \
(u8_t)(ntohl((ipaddr)->addr) >> 8) & 0xff, \
(u8_t)ntohl((ipaddr)->addr) & 0xff))
#define ip4_addr1(ipaddr) ((u8_t)(ntohl((ipaddr)->addr) >> 24) & 0xff)
#define ip4_addr2(ipaddr) ((u8_t)(ntohl((ipaddr)->addr) >> 16) & 0xff)
#define ip4_addr3(ipaddr) ((u8_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)
#define ip4_addr4(ipaddr) ((u8_t)(ntohl((ipaddr)->addr)) & 0xff)
#endif /* __LWIP_IP_ADDR_H__ */

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_ICMP_H__
#define __LWIP_ICMP_H__
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#define ICMP6_DUR 1
#define ICMP6_TE 3
#define ICMP6_ECHO 128 /* echo */
#define ICMP6_ER 129 /* echo reply */
enum icmp_dur_type {
ICMP_DUR_NET = 0, /* net unreachable */
ICMP_DUR_HOST = 1, /* host unreachable */
ICMP_DUR_PROTO = 2, /* protocol unreachable */
ICMP_DUR_PORT = 3, /* port unreachable */
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
ICMP_DUR_SR = 5 /* source route failed */
};
enum icmp_te_type {
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
};
void icmp_input(struct pbuf *p, struct netif *inp);
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
struct icmp_echo_hdr {
u8_t type;
u8_t icode;
u16_t chksum;
u16_t id;
u16_t seqno;
};
struct icmp_dur_hdr {
u8_t type;
u8_t icode;
u16_t chksum;
u32_t unused;
};
struct icmp_te_hdr {
u8_t type;
u8_t icode;
u16_t chksum;
u32_t unused;
};
#endif /* __LWIP_ICMP_H__ */

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_INET_H__
#define __LWIP_INET_H__
#include "lwip/arch.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
u16_t inet_chksum(void *data, u16_t len);
u16_t inet_chksum_pbuf(struct pbuf *p);
u16_t inet_chksum_pseudo(struct pbuf *p,
struct ip_addr *src, struct ip_addr *dest,
u8_t proto, u32_t proto_len);
#ifndef _MACHINE_ENDIAN_H_
#ifndef _NETINET_IN_H
#ifndef _LINUX_BYTEORDER_GENERIC_H
u16_t htons(u16_t n);
u16_t ntohs(u16_t n);
u32_t htonl(u32_t n);
u32_t ntohl(u32_t n);
#endif /* _LINUX_BYTEORDER_GENERIC_H */
#endif /* _NETINET_IN_H */
#endif /* _MACHINE_ENDIAN_H_ */
#endif /* __LWIP_INET_H__ */

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_IP_H__
#define __LWIP_IP_H__
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#define IP_HLEN 40
#define IP_PROTO_ICMP 58
#define IP_PROTO_UDP 17
#define IP_PROTO_UDPLITE 170
#define IP_PROTO_TCP 6
/* This is passed as the destination address to ip_output_if (not
to ip_output), meaning that an IP header already is constructed
in the pbuf. This is used when TCP retransmits. */
#ifdef IP_HDRINCL
#undef IP_HDRINCL
#endif /* IP_HDRINCL */
#define IP_HDRINCL NULL
/* The IPv6 header. */
struct ip_hdr {
#if BYTE_ORDER == LITTLE_ENDIAN
u8_t tclass1:4, v:4;
u8_t flow1:4, tclass2:4;
#else
u8_t v:4, tclass1:4;
u8_t tclass2:8, flow1:4;
#endif
u16_t flow2;
u16_t len; /* payload length */
u8_t nexthdr; /* next header */
u8_t hoplim; /* hop limit (TTL) */
struct ip_addr src, dest; /* source and destination IP addresses */
};
void ip_init(void);
#include "lwip/netif.h"
struct netif *ip_route(struct ip_addr *dest);
void ip_input(struct pbuf *p, struct netif *inp);
/* source and destination addresses in network byte order, please */
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
unsigned char ttl, unsigned char proto);
err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
unsigned char ttl, unsigned char proto,
struct netif *netif);
#if IP_DEBUG
void ip_debug_print(struct pbuf *p);
#endif /* IP_DEBUG */
#endif /* __LWIP_IP_H__ */

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_IP_ADDR_H__
#define __LWIP_IP_ADDR_H__
#include "lwip/arch.h"
#define IP_ADDR_ANY 0
struct ip_addr {
u32_t addr[4];
};
#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
(ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
(ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
(ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
int ip_addr_maskcmp(struct ip_addr *addr1, struct ip_addr *addr2,
struct ip_addr *mask);
int ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
int ip_addr_isany(struct ip_addr *addr);
#if IP_DEBUG
void ip_addr_debug_print(struct ip_addr *addr);
#endif /* IP_DEBUG */
#endif /* __LWIP_IP_ADDR_H__ */

137
src/include/lwip/api.h Normal file
View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_API_H__
#define __LWIP_API_H__
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/ip.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/err.h"
#define NETCONN_NOCOPY 0x00
#define NETCONN_COPY 0x01
enum netconn_type {
NETCONN_TCP,
NETCONN_UDP,
NETCONN_UDPLITE,
NETCONN_UDPNOCHKSUM
};
enum netconn_state {
NETCONN_NONE,
NETCONN_WRITE,
NETCONN_ACCEPT,
NETCONN_RECV,
NETCONN_CONNECT,
NETCONN_CLOSE
};
struct netbuf {
struct pbuf *p, *ptr;
struct ip_addr *fromaddr;
u16_t fromport;
err_t err;
};
struct netconn {
enum netconn_type type;
enum netconn_state state;
union {
struct tcp_pcb *tcp;
struct udp_pcb *udp;
} pcb;
err_t err;
sys_mbox_t mbox;
sys_mbox_t recvmbox;
sys_mbox_t acceptmbox;
sys_sem_t sem;
};
/* Network buffer functions: */
struct netbuf * netbuf_new (void);
void netbuf_delete (struct netbuf *buf);
void * netbuf_alloc (struct netbuf *buf, u16_t size);
void netbuf_free (struct netbuf *buf);
void netbuf_ref (struct netbuf *buf,
void *dataptr, u16_t size);
void netbuf_chain (struct netbuf *head,
struct netbuf *tail);
u16_t netbuf_len (struct netbuf *buf);
err_t netbuf_data (struct netbuf *buf,
void **dataptr, u16_t *len);
s8_t netbuf_next (struct netbuf *buf);
void netbuf_first (struct netbuf *buf);
void netbuf_copy (struct netbuf *buf,
void *dataptr, u16_t len);
struct ip_addr * netbuf_fromaddr (struct netbuf *buf);
u16_t netbuf_fromport (struct netbuf *buf);
/* Network connection functions: */
struct netconn * netconn_new (enum netconn_type type);
err_t netconn_delete (struct netconn *conn);
enum netconn_type netconn_type (struct netconn *conn);
err_t netconn_peer (struct netconn *conn,
struct ip_addr **addr,
u16_t *port);
err_t netconn_addr (struct netconn *conn,
struct ip_addr **addr,
u16_t *port);
err_t netconn_bind (struct netconn *conn,
struct ip_addr *addr,
u16_t port);
err_t netconn_connect (struct netconn *conn,
struct ip_addr *addr,
u16_t port);
err_t netconn_listen (struct netconn *conn);
struct netconn * netconn_accept (struct netconn *conn);
struct netbuf * netconn_recv (struct netconn *conn);
err_t netconn_send (struct netconn *conn,
struct netbuf *buf);
err_t netconn_write (struct netconn *conn,
void *dataptr, u16_t size,
u8_t copy);
err_t netconn_close (struct netconn *conn);
err_t netconn_err (struct netconn *conn);
#endif /* __LWIP_API_H__ */

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_API_MSG_H__
#define __LWIP_API_MSG_H__
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/ip.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/api.h"
enum api_msg_type {
API_MSG_NEWCONN,
API_MSG_DELCONN,
API_MSG_BIND,
API_MSG_CONNECT,
API_MSG_LISTEN,
API_MSG_ACCEPT,
API_MSG_SEND,
API_MSG_RECV,
API_MSG_WRITE,
API_MSG_CLOSE,
API_MSG_MAX
};
struct api_msg_msg {
struct netconn *conn;
enum netconn_type conntype;
union {
struct pbuf *p;
struct {
struct ip_addr *ipaddr;
u16_t port;
} bc;
struct {
void *dataptr;
u16_t len;
unsigned char copy;
} w;
sys_mbox_t mbox;
u16_t len;
} msg;
};
struct api_msg {
enum api_msg_type type;
struct api_msg_msg msg;
};
void api_msg_input(struct api_msg *msg);
void api_msg_post(struct api_msg *msg);
#endif /* __LWIP_API_MSG_H__ */

58
src/include/lwip/arch.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_ARCH_H__
#define __LWIP_ARCH_H__
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#include "arch/cpu.h"
#include "arch/cc.h"
#ifndef PACK_STRUCT_BEGIN
#define PACK_STRUCT_BEGIN
#endif /* PACK_STRUCT_BEGIN */
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif /* PACK_STRUCT_END */
#ifndef PACK_STRUCT_FIELD
#define PACK_STRUCT_FIELD(x) x
#endif /* PACK_STRUCT_FIELD */
#endif /* __LWIP_ARCH_H__ */

136
src/include/lwip/debug.h Normal file
View File

@@ -0,0 +1,136 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_DEBUG_H__
#define __LWIP_DEBUG_H__
#ifdef LWIP_DEBUG
#define 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: */
#define MEM_TRACKING
#define DEMO_DEBUG 1
#define ETHARP_DEBUG 1
#define NETIF_DEBUG 0
#define PBUF_DEBUG 0
#define DELIF_DEBUG 0
#define DROPIF_DEBUG 0
#define TUNIF_DEBUG 0
#define UNIXIF_DEBUG 0
#define TAPIF_DEBUG 1
#define API_LIB_DEBUG 0
#define API_MSG_DEBUG 0
#define SOCKETS_DEBUG 1
#define ICMP_DEBUG 0
#define INET_DEBUG 0
#define IP_DEBUG 1
#define IP_REASS_DEBUG 1
#define MEM_DEBUG 0
#define MEMP_DEBUG 0
#define SYS_DEBUG 0
#define TCP_DEBUG 0
#define TCP_INPUT_DEBUG 0
#define TCP_FR_DEBUG 0
#define TCP_RTO_DEBUG 0
#define TCP_REXMIT_DEBUG 0
#define TCP_CWND_DEBUG 0
#define TCP_WND_DEBUG 0
#define TCP_OUTPUT_DEBUG 0
#define TCP_RST_DEBUG 0
#define TCP_QLEN_DEBUG 0
#define UDP_DEBUG 0
#define TCPIP_DEBUG 0
#define TCPDUMP_DEBUG 0
#define DHCP_DEBUG 1
#include <stdio.h>
#define DEBUGF(debug, x) do { if(debug){ printf x; } } while(0)
#else /* LWIP_DEBUG */
/* DEBUG is not defined, so we define null macros for ASSERT and DEBUGF */
#define ASSERT(x,y)
#define DEBUGF(debug, x)
/* And we define those to be zero: */
#define DEMO_DEBUG 0
#define ETHARP_DEBUG 0
#define NETIF_DEBUG 0
#define PBUF_DEBUG 0
#define DELIF_DEBUG 0
#define DROPIF_DEBUG 0
#define TUNIF_DEBUG 0
#define UNIXIF_DEBUG 0
#define TAPIF_DEBUG 0
#define API_LIB_DEBUG 0
#define API_MSG_DEBUG 0
#define SOCKETS_DEBUG 0
#define ICMP_DEBUG 0
#define INET_DEBUG 0
#define IP_DEBUG 0
#define IP_REASS_DEBUG 0
#define MEM_DEBUG 0
#define MEMP_DEBUG 0
#define SYS_DEBUG 0
#define TCP_DEBUG 0
#define TCP_INPUT_DEBUG 0
#define TCP_FR_DEBUG 0
#define TCP_RTO_DEBUG 0
#define TCP_REXMIT_DEBUG 0
#define TCP_CWND_DEBUG 0
#define TCP_WND_DEBUG 0
#define TCP_OUTPUT_DEBUG 0
#define TCP_RST_DEBUG 0
#define TCP_QLEN_DEBUG 0
#define UDP_DEBUG 0
#define TCPIP_DEBUG 0
#define TCPDUMP_DEBUG 0
#define DHCP_DEBUG 0
#endif /* LWIP_DEBUG */
#endif /* __LWIP_DEBUG_H__ */

44
src/include/lwip/def.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_DEF_H__
#define __LWIP_DEF_H__
#define UMAX(a, b) ((a) > (b) ? (a) : (b))
#ifndef NULL
#define NULL ((void *)0)
#endif
#include "arch/lib.h"
#endif /* __LWIP_DEF_H__ */

68
src/include/lwip/err.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_ERR_H__
#define __LWIP_ERR_H__
#include "lwip/debug.h"
#include "arch/cc.h"
typedef s8_t err_t;
/* Definitions for error constants. */
#define ERR_OK 0 /* No error, everything OK. */
#define ERR_MEM -1 /* Out of memory error. */
#define ERR_BUF -2 /* Buffer error. */
#define ERR_ABRT -3 /* Connection aborted. */
#define ERR_RST -4 /* Connection reset. */
#define ERR_CLSD -5 /* Connection closed. */
#define ERR_CONN -6 /* Not connected. */
#define ERR_VAL -7 /* Illegal value. */
#define ERR_ARG -8 /* Illegal argument. */
#define ERR_RTE -9 /* Routing problem. */
#define ERR_USE -10 /* Address in use. */
#ifdef LWIP_DEBUG
extern char *lwip_strerr(err_t err);
#else
#define lwip_strerr(x) ""
#endif /* LWIP_DEBUG */
#endif /* __LWIP_ERR_H__ */

29
src/include/lwip/event.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef __LWIP_EVENT_H__
#define __LWIP_EVENT_H__
#include "lwip/opt.h"
#if LWIP_EVENT_API
#include "lwip/pbuf.h"
enum lwip_event {
LWIP_EVENT_ACCEPT,
LWIP_EVENT_SENT,
LWIP_EVENT_RECV,
LWIP_EVENT_CONNECTED,
LWIP_EVENT_POLL,
LWIP_EVENT_ERR
};
struct tcp_pcb;
err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
enum lwip_event,
struct pbuf *p,
u16_t size,
err_t err);
#endif /* LWIP_EVENT_API */
#endif /* __LWIP_EVENT_H__ */

47
src/include/lwip/list.h Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_LIST_H__
#define __LWIP_LIST_H__
struct list;
struct list *list_new(int size);
int list_push(struct list *list, void *elem);
void *list_pop(struct list *list);
int list_remove(struct list *list, void *elem);
void *list_first(struct list *list);
int list_elems(struct list *list);
void list_delete(struct list *list);
void list_map(struct list *list, void (* func)(void *arg));
#endif /* __LWIP_LIST_H__ */

60
src/include/lwip/mem.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_MEM_H__
#define __LWIP_MEM_H__
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/arch.h"
#if MEM_SIZE > 64000l
typedef u32_t mem_size_t;
#else
typedef u16_t mem_size_t;
#endif /* MEM_SIZE > 64000 */
void mem_init(void);
void *mem_malloc(mem_size_t size);
void mem_free(void *mem);
void *mem_realloc(void *mem, mem_size_t size);
void *mem_reallocm(void *mem, mem_size_t size);
#define MEM_ALIGN_SIZE(size) (size + \
((((size) % MEM_ALIGNMENT) == 0)? 0 : \
(MEM_ALIGNMENT - ((size) % MEM_ALIGNMENT))))
#define MEM_ALIGN(addr) (void *)MEM_ALIGN_SIZE((mem_ptr_t)addr)
#endif /* __LWIP_MEM_H__ */

67
src/include/lwip/memp.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_MEMP_H__
#define __LWIP_MEMP_H__
#include "lwip/debug.h"
#include "arch/cc.h"
#include "lwipopts.h"
typedef enum {
MEMP_PBUF,
MEMP_UDP_PCB,
MEMP_TCP_PCB,
MEMP_TCP_PCB_LISTEN,
MEMP_TCP_SEG,
MEMP_NETBUF,
MEMP_NETCONN,
MEMP_API_MSG,
MEMP_TCPIP_MSG,
MEMP_SYS_TIMEOUT,
MEMP_MAX
} memp_t;
void memp_init(void);
void *memp_malloc(memp_t type);
void *memp_realloc(memp_t fromtype, memp_t totype, void *mem);
void memp_free(memp_t type, void *mem);
void *memp_mallocp(memp_t type);
void memp_freep(memp_t type, void *mem);
#endif /* __LWIP_MEMP_H__ */

97
src/include/lwip/netif.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_NETIF_H__
#define __LWIP_NETIF_H__
#include "lwip/opt.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
#include "lwip/pbuf.h"
struct netif {
struct netif *next;
u8_t num;
struct ip_addr ip_addr;
struct ip_addr netmask; /* netmask in network byte order */
struct ip_addr gw;
char hwaddr[6];
/* This function is called by the network device driver
when it wants to pass a packet to the TCP/IP stack. */
err_t (* input)(struct pbuf *p, struct netif *inp);
/* The following two fields should be filled in by the
initialization function for the device driver. */
char name[2];
/* This function is called by the IP module when it wants
to send a packet on the interface. */
err_t (* output)(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
/* This field can be set bu the device driver and could point
to state information for the device. */
void *state;
};
/* The list of network interfaces. */
extern struct netif *netif_list;
extern struct netif *netif_default;
/* netif_init() must be called first. */
void netif_init(void);
struct netif *netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw,
void (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, 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
structure. */
struct netif *netif_find(char *name);
void netif_set_default(struct netif *netif);
void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
void netif_set_netmask(struct netif *netif, struct ip_addr *netmast);
void netif_set_gw(struct netif *netif, struct ip_addr *gw);
#endif /* __LWIP_NETIF_H__ */

102
src/include/lwip/opt.h Normal file
View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_OPT_H__
#define __LWIP_OPT_H__
#include "lwipopts.h"
/* Define some handy default values for configuration parameters. */
#ifndef ICMP_TTL
#define ICMP_TTL 255
#endif
#ifndef UDP_TTL
#define UDP_TTL 255
#endif
#ifndef TCP_TTL
#define TCP_TTL 255
#endif
#ifndef TCP_MSS
#define TCP_MSS 128 /* A *very* conservative default. */
#endif
#ifndef TCP_WND
#define TCP_WND 2048
#endif
#ifndef TCP_MAXRTX
#define TCP_MAXRTX 12
#endif
#ifndef TCP_SYNMAXRTX
#define TCP_SYNMAXRTX 6
#endif
#ifndef MEM_ALIGNMENT
#define MEM_ALIGNMENT 1
#endif
#ifndef PBUF_POOL_SIZE
#define PBUF_POOL_SIZE 16
#endif
#ifndef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE 128
#endif
#ifndef PBUF_LINK_HLEN
#define PBUF_LINK_HLEN 0
#endif
#ifndef LWIP_UDP
#define LWIP_UDP 1
#endif
#ifndef LWIP_TCP
#define LWIP_TCP 1
#endif
#ifndef LWIP_EVENT_API
#define LWIP_EVENT_API 0
#define LWIP_CALLBACK_API 1
#else
#define LWIP_EVENT_API 1
#define LWIP_CALLBACK_API 0
#endif /* LWIP_CALLBACK_API */
#endif /* __LWIP_OPT_H__ */

152
src/include/lwip/pbuf.h Normal file
View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*-----------------------------------------------------------------------------------*/
#ifndef __LWIP_PBUF_H__
#define __LWIP_PBUF_H__
#include "lwip/debug.h"
#include "lwip/arch.h"
#define PBUF_TRANSPORT_HLEN 20
#define PBUF_IP_HLEN 20
typedef enum {
PBUF_TRANSPORT,
PBUF_IP,
PBUF_LINK,
PBUF_RAW
} pbuf_layer;
typedef enum {
PBUF_RAM,
PBUF_ROM,
PBUF_POOL
} pbuf_flag;
/* Definitions for the pbuf flag field (these are not the flags that
are passed to pbuf_alloc()). */
#define PBUF_FLAG_RAM 0x00 /* Flags that pbuf data is stored in RAM. */
#define PBUF_FLAG_ROM 0x01 /* Flags that pbuf data is stored in ROM. */
#define PBUF_FLAG_POOL 0x02 /* Flags that the pbuf comes from the
pbuf pool. */
struct pbuf {
struct pbuf *next;
/* Pointer to the actual data in the buffer. */
void *payload;
/* Total length of buffer + additionally chained buffers. */
u16_t tot_len;
/* Length of this buffer. */
u16_t len;
/* Flags and reference count. */
u16_t flags, ref;
};
/* pbuf_init():
Initializes the pbuf module. The num parameter determines how many
pbufs that should be allocated to the pbuf pool, and the size
parameter specifies the size of the data allocated to those. */
void pbuf_init(void);
/* pbuf_alloc():
Allocates a pbuf at protocol layer l. The actual memory allocated
for the pbuf is determined by the layer at which the pbuf is
allocated and the requested size (from the size parameter). The
flag parameter decides how and where the pbuf should be allocated
as follows:
* PBUF_RAM: buffer memory for pbuf is allocated as one large
chunk. This includesprotocol headers as well.
* RBUF_ROM: no buffer memory is allocated for the pbuf, even for
protocol headers. Additional headers must be
prepended by allocating another pbuf and chain in to
the front of the ROM pbuf.
* PBUF_ROOL: the pbuf is allocated as a pbuf chain, with pbufs from
the pbuf pool that is allocated during pbuf_init(). */
struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
/* pbuf_realloc():
Shrinks the pbuf to the size given by the size parameter.
*/
void pbuf_realloc(struct pbuf *p, u16_t size);
/* pbuf_header():
Tries to move the p->payload pointer header_size number of bytes
upward within the pbuf. The return value is non-zero if it
fails. If so, an additional pbuf should be allocated for the header
and it should be chained to the front. */
u8_t pbuf_header(struct pbuf *p, s16_t header_size);
/* pbuf_ref():
Increments the reference count of the pbuf p.
*/
void pbuf_ref(struct pbuf *p);
/* pbuf_free():
Decrements the reference count and deallocates the pbuf if the
reference count is zero. If the pbuf is a chain all pbufs in the
chain are deallocated. */
u8_t pbuf_free(struct pbuf *p);
/* pbuf_clen():
Returns the length of the pbuf chain. */
u8_t pbuf_clen(struct pbuf *p);
/* pbuf_chain():
Chains pbuf t on the end of pbuf h. Pbuf h will have it's tot_len
field adjusted accordingly. Pbuf t should no be used any more after
a call to this function, since pbuf t is now a part of pbuf h. */
void pbuf_chain(struct pbuf *h, struct pbuf *t);
/* pbuf_dechain():
Picks off the first pbuf from the pbuf chain p. Returns the tail of
the pbuf chain or NULL if the pbuf p was not chained. */
struct pbuf *pbuf_dechain(struct pbuf *p);
#endif /* __LWIP_PBUF_H__ */

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_SOCKETS_H__
#define __LWIP_SOCKETS_H__
struct in_addr {
u32_t s_addr;
};
struct sockaddr_in {
u8_t sin_len;
u8_t sin_family;
u16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr {
u8_t sa_len;
u8_t sa_family;
char sa_data[14];
};
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define AF_INET 2
#define PF_INET AF_INET
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define INADDR_ANY 0
#define INADDR_BROADCAST 0xffffffff
int lwip_accept(int s, struct sockaddr *addr, int *addrlen);
int lwip_bind(int s, struct sockaddr *name, int namelen);
int lwip_close(int s);
int lwip_connect(int s, struct sockaddr *name, int namelen);
int lwip_listen(int s, int backlog);
int lwip_recv(int s, void *mem, int len, unsigned int flags);
int lwip_read(int s, void *mem, int len);
int lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
int lwip_send(int s, void *dataptr, int size, unsigned int flags);
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);
#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 close(s) lwip_close(s)
#define connect(a,b,c) lwip_connect(a,b,c)
#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)
#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
#define send(a,b,c,d) lwip_send(a,b,c,d)
#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f)
#define socket(a,b,c) lwip_socket(a,b,c)
#define write(a,b,c) lwip_write(a,b,c)
#endif /* LWIP_NO_COMPAT_SOCKETS */
#endif /* __LWIP_SOCKETS_H__ */

109
src/include/lwip/stats.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_STATS_H__
#define __LWIP_STATS_H__
#include "lwip/opt.h"
#include "arch/cc.h"
#include "lwip/memp.h"
#ifdef STATS
struct stats_proto {
u16_t xmit; /* Transmitted packets. */
u16_t rexmit; /* Retransmitted packets. */
u16_t recv; /* Received packets. */
u16_t fw; /* Forwarded packets. */
u16_t drop; /* Dropped packets. */
u16_t chkerr; /* Checksum error. */
u16_t lenerr; /* Invalid length error. */
u16_t memerr; /* Out of memory error. */
u16_t rterr; /* Routing error. */
u16_t proterr; /* Protocol error. */
u16_t opterr; /* Error in options. */
u16_t err; /* Misc error. */
u16_t cachehit;
};
struct stats_mem {
u16_t avail;
u16_t used;
u16_t max;
u16_t err;
u16_t reclaimed;
};
struct stats_pbuf {
u16_t avail;
u16_t used;
u16_t max;
u16_t err;
u16_t reclaimed;
u16_t alloc_locked;
u16_t refresh_locked;
};
struct stats_syselem {
u16_t used;
u16_t max;
u16_t err;
};
struct stats_sys {
struct stats_syselem sem;
struct stats_syselem mbox;
};
struct stats_ {
struct stats_proto link;
struct stats_proto ip;
struct stats_proto icmp;
struct stats_proto udp;
struct stats_proto tcp;
struct stats_pbuf pbuf;
struct stats_mem mem;
struct stats_mem memp[MEMP_MAX];
struct stats_sys sys;
};
extern struct stats_ stats;
#endif /* STATS */
void stats_init(void);
#endif /* __LWIP_STATS_H__ */

116
src/include/lwip/sys.h Normal file
View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_SYS_H__
#define __LWIP_SYS_H__
#include "arch/cc.h"
#include "lwip/opt.h"
#if NO_SYS
/* For a totally minimal and standalone system, we provide null
definitions of the sys_ functions. */
typedef u8_t sys_sem_t;
typedef u8_t sys_mbox_t;
struct sys_timeout {u8_t dummy;};
#define sys_init()
#define sys_timeout(m,h,a)
#define sys_sem_new(c) c
#define sys_sem_signal(s)
#define sys_sem_wait(s)
#define sys_sem_free(s)
#define sys_mbox_new() 0
#define sys_mbox_fetch(m,d)
#define sys_mbox_post(m,d)
#define sys_mbox_free(m)
#define sys_thread_new(t,a)
#else /* NO_SYS */
#include "arch/sys_arch.h"
typedef void (* sys_timeout_handler)(void *arg);
struct sys_timeout {
struct sys_timeout *next;
u16_t time;
sys_timeout_handler h;
void *arg;
};
struct sys_timeouts {
struct sys_timeout *next;
};
/* sys_init() must be called before anthing else. */
void sys_init(void);
/*
* sys_timeout():
*
* Schedule a timeout a specified amount of milliseconds in the
* future. When the timeout occurs, the specified timeout handler will
* be called. The handler will be passed the "arg" argument when
* called.
*
*/
void sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg);
struct sys_timeouts *sys_arch_timeouts(void);
/* Semaphore functions. */
sys_sem_t sys_sem_new(u8_t count);
void sys_sem_signal(sys_sem_t sem);
u16_t sys_arch_sem_wait(sys_sem_t sem, u16_t timeout);
void sys_sem_free(sys_sem_t sem);
void sys_sem_wait(sys_sem_t sem);
/* Mailbox functions. */
sys_mbox_t sys_mbox_new(void);
void sys_mbox_post(sys_mbox_t mbox, void *msg);
u16_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout);
void sys_mbox_free(sys_mbox_t mbox);
void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
/* Thread functions. */
void sys_thread_new(void (* thread)(void *arg), void *arg);
/* The following functions are used only in Unix code, and
can be omitted when porting the stack. */
/* Returns the current time in microseconds. */
unsigned long sys_now(void);
#endif /* NO_SYS */
#endif /* __LWIP_SYS_H__ */

448
src/include/lwip/tcp.h Normal file
View File

@@ -0,0 +1,448 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_TCP_H__
#define __LWIP_TCP_H__
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/opt.h"
#include "lwip/ip.h"
#include "lwip/icmp.h"
#include "lwip/sys.h"
#include "lwip/err.h"
#include "lwip/event.h"
struct tcp_pcb;
/* Functions for interfacing with TCP: */
/* Lower layer interface to TCP: */
void tcp_init (void); /* Must be called first to
initialize TCP. */
void tcp_tmr (void); /* Must be called every
TCP_TMR_INTERVAL
ms. (Typically 100 ms). */
/* Application program's interface: */
struct tcp_pcb * tcp_new (void);
struct tcp_pcb * tcp_alloc (u8_t prio);
void tcp_arg (struct tcp_pcb *pcb, void *arg);
void tcp_accept (struct tcp_pcb *pcb,
err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
err_t err));
void tcp_recv (struct tcp_pcb *pcb,
err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err));
void tcp_sent (struct tcp_pcb *pcb,
err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
u16_t len));
void tcp_poll (struct tcp_pcb *pcb,
err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
u8_t interval);
void tcp_err (struct tcp_pcb *pcb,
void (* err)(void *arg, err_t err));
#define tcp_mss(pcb) ((pcb)->mss)
#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
void tcp_recved (struct tcp_pcb *pcb, u16_t len);
err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port);
err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port, err_t (* connected)(void *arg,
struct tcp_pcb *tpcb,
err_t err));
struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb);
void tcp_abort (struct tcp_pcb *pcb);
err_t tcp_close (struct tcp_pcb *pcb);
err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
u8_t copy);
void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
#define TCP_PRIO_MIN 1
#define TCP_PRIO_NORMAL 64
#define TCP_PRIO_MAX 127
/* It is also possible to call these two functions at the right
intervals (instead of calling tcp_tmr()). */
void tcp_slowtmr (void);
void tcp_fasttmr (void);
/* Only used by IP to pass a TCP segment to TCP: */
void tcp_input (struct pbuf *p, struct netif *inp);
/* Used within the TCP code only: */
err_t tcp_output (struct tcp_pcb *pcb);
void tcp_rexmit (struct tcp_pcb *pcb);
#define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0)
#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0)
#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_PSH 0x08
#define TCP_ACK 0x10
#define TCP_URG 0x20
#define TCP_FLAGS 0x3f
/* Length of the TCP header, excluding options. */
#define TCP_HLEN 20
#define TCP_TMR_INTERVAL 100 /* The TCP timer interval in
milliseconds. */
#define TCP_FAST_INTERVAL 200 /* the fine grained timeout in
milliseconds */
#define TCP_SLOW_INTERVAL 500 /* the coarse grained timeout in
milliseconds */
#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */
#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */
#define TCP_OOSEQ_TIMEOUT 6 /* x RTO */
#define TCP_MSL 60000 /* The maximum segment lifetime in microseconds */
PACK_STRUCT_BEGIN
struct tcp_hdr {
PACK_STRUCT_FIELD(u16_t src);
PACK_STRUCT_FIELD(u16_t dest);
PACK_STRUCT_FIELD(u32_t seqno);
PACK_STRUCT_FIELD(u32_t ackno);
PACK_STRUCT_FIELD(u16_t _offset_flags);
PACK_STRUCT_FIELD(u16_t wnd);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u16_t urgp);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#define TCPH_OFFSET(hdr) (NTOHS((hdr)->_offset_flags) >> 8)
#define TCPH_FLAGS(hdr) (NTOHS((hdr)->_offset_flags) & 0xff)
#define TCPH_OFFSET_SET(hdr, offset) (hdr)->_offset_flags = HTONS(((offset) << 8) | TCPH_FLAGS(hdr))
#define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = HTONS((TCPH_OFFSET(hdr) << 8) | (flags))
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
enum tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
/* the TCP protocol control block */
struct tcp_pcb {
struct tcp_pcb *next; /* for the linked list */
u8_t prio;
void *callback_arg;
struct ip_addr local_ip;
u16_t local_port;
struct ip_addr remote_ip;
u16_t remote_port;
/* receiver varables */
u32_t rcv_nxt; /* next seqno expected */
u16_t rcv_wnd; /* receiver window */
enum tcp_state state; /* TCP state */
/* Timers */
u16_t tmr;
u8_t polltmr, pollinterval;
/* Retransmission timer. */
u8_t rtime;
u16_t mss; /* maximum segment size */
u8_t flags;
#define TF_ACK_DELAY 0x01U /* Delayed ACK. */
#define TF_ACK_NOW 0x02U /* Immediate ACK. */
#define TF_INFR 0x04U /* In fast recovery. */
#define TF_RESET 0x08U /* Connection was reset. */
#define TF_CLOSED 0x10U /* Connection was sucessfully closed. */
#define TF_GOT_FIN 0x20U /* Connection was closed by the remote end. */
/* RTT estimation variables. */
u16_t rttest; /* RTT estimate in 500ms ticks */
u32_t rtseq; /* sequence number being timed */
s16_t sa, sv;
u16_t rto; /* retransmission time-out */
u8_t nrtx; /* number of retransmissions */
/* fast retransmit/recovery */
u32_t lastack; /* Highest acknowledged seqno. */
u8_t dupacks;
/* congestion avoidance/control variables */
u16_t cwnd;
u16_t ssthresh;
/* sender variables */
u32_t snd_nxt, /* next seqno to be sent */
snd_max, /* Highest seqno sent. */
snd_wnd, /* sender window */
snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
window update. */
snd_lbb; /* Sequence number of next byte to be buffered. */
u16_t acked;
u16_t snd_buf; /* Avaliable buffer space for sending (in bytes). */
u8_t snd_queuelen; /* Avaliable buffer space for sending (in tcp_segs). */
/* These are ordered by sequence number: */
struct tcp_seg *unsent; /* Unsent (queued) segments. */
struct tcp_seg *unacked; /* Sent but unacknowledged segments. */
#if TCP_QUEUE_OOSEQ
struct tcp_seg *ooseq; /* Received out of sequence segments. */
#endif /* TCP_QUEUE_OOSEQ */
#if LWIP_CALLBACK_API
/* Function to be called when more send buffer space is avaliable. */
err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space);
/* Function to be called when (in-sequence) data has arrived. */
err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
/* Function to be called when a connection has been set up. */
err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
/* Function to call when a listener has been connected. */
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
/* Function which is called periodically. */
err_t (* poll)(void *arg, struct tcp_pcb *pcb);
/* Function to be called whenever a fatal error occurs. */
void (* errf)(void *arg, err_t err);
#endif /* LWIP_CALLBACK_API */
};
struct tcp_pcb_listen {
struct tcp_pcb_listen *next; /* for the linked list */
u8_t prio;
void *callback_arg;
struct ip_addr local_ip;
u16_t local_port;
#if LWIP_CALLBACK_API
/* Function to call when a listener has been connected. */
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
#endif /* LWIP_CALLBACK_API */
};
#if LWIP_EVENT_API
#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_ACCEPT, NULL, 0, err)
#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_SENT, NULL, space, ERR_OK)
#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_RECV, (p), 0, (err))
#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_CONNECTED, NULL, 0, (err))
#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\
LWIP_EVENT_POLL, NULL, 0, ERR_OK)
#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \
LWIP_EVENT_ERR, NULL, 0, (err))
#else /* LWIP_EVENT_API */
#define TCP_EVENT_ACCEPT(pcb,err,ret) \
if((pcb)->accept != NULL) \
(ret = (pcb)->accept((pcb)->callback_arg,(pcb),(err)))
#define TCP_EVENT_SENT(pcb,space,ret) \
if((pcb)->sent != NULL) \
(ret = (pcb)->sent((pcb)->callback_arg,(pcb),(space)))
#define TCP_EVENT_RECV(pcb,p,err,ret) \
if((pcb)->recv != NULL) \
(ret = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)))
#define TCP_EVENT_CONNECTED(pcb,err,ret) \
if((pcb)->connected != NULL) \
(ret = (pcb)->connected((pcb)->callback_arg,(pcb),(err)))
#define TCP_EVENT_POLL(pcb,ret) \
if((pcb)->poll != NULL) \
(ret = (pcb)->poll((pcb)->callback_arg,(pcb)))
#define TCP_EVENT_ERR(errf,arg,err) \
if((errf) != NULL) \
(errf)((arg),(err))
#endif /* LWIP_EVENT_API */
/* This structure is used to repressent TCP segments when queued. */
struct tcp_seg {
struct tcp_seg *next; /* used when putting segements on a queue */
struct pbuf *p; /* buffer containing data + TCP header */
void *dataptr; /* pointer to the TCP data in the pbuf */
u16_t len; /* the TCP length of this segment */
struct tcp_hdr *tcphdr; /* the TCP header */
};
/* Internal functions and global variables: */
struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
void tcp_pcb_purge(struct tcp_pcb *pcb);
void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
u8_t tcp_segs_free(struct tcp_seg *seg);
u8_t tcp_seg_free(struct tcp_seg *seg);
struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
#define tcp_ack(pcb) if((pcb)->flags & TF_ACK_DELAY) { \
(pcb)->flags &= ~TF_ACK_DELAY; \
(pcb)->flags |= TF_ACK_NOW; \
tcp_output(pcb); \
} else { \
(pcb)->flags |= TF_ACK_DELAY; \
}
#define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
tcp_output(pcb)
err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags);
err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len,
u8_t flags, u8_t copy,
u8_t *optdata, u8_t optlen);
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
void tcp_rst(u32_t seqno, u32_t ackno,
struct ip_addr *local_ip, struct ip_addr *remote_ip,
u16_t local_port, u16_t remote_port);
u32_t tcp_next_iss(void);
extern struct tcp_pcb *tcp_input_pcb;
extern u32_t tcp_ticks;
#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
void tcp_debug_print(struct tcp_hdr *tcphdr);
void tcp_debug_print_flags(u8_t flags);
void tcp_debug_print_state(enum tcp_state s);
void tcp_debug_print_pcbs(void);
int tcp_pcbs_sane(void);
#else
#define tcp_pcbs_sane() 1
#endif /* TCP_DEBUG */
/* The TCP PCB lists. */
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
state in which they accept or send
data. */
extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
/* Axoims about the above lists:
1) Every TCP PCB that is not CLOSED is in one of the lists.
2) A PCB is only in one of the lists.
3) All PCBs in the tcp_listen_pcbs list is in LISTEN state.
4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state.
*/
/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB
with a PCB list or removes a PCB from a list, respectively. */
#if 0
#define TCP_REG(pcbs, npcb) do {\
DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
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); \
} \
ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
npcb->next = *pcbs; \
ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
*(pcbs) = npcb; \
ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
} while(0)
#define TCP_RMV(pcbs, npcb) do { \
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; \
} else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
tcp_tmp_pcb->next = npcb->next; \
break; \
} \
} \
npcb->next = NULL; \
ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
} while(0)
#else /* LWIP_DEBUG */
#define TCP_REG(pcbs, npcb) do { \
npcb->next = *pcbs; \
*(pcbs) = npcb; \
} while(0)
#define TCP_RMV(pcbs, npcb) do { \
if(*(pcbs) == npcb) { \
(*(pcbs)) = (*pcbs)->next; \
} else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
tcp_tmp_pcb->next = npcb->next; \
break; \
} \
} \
npcb->next = NULL; \
} while(0)
#endif /* LWIP_DEBUG */
#endif /* __LWIP_TCP_H__ */

60
src/include/lwip/tcpip.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_TCPIP_H__
#define __LWIP_TCPIP_H__
#include "lwip/api_msg.h"
#include "lwip/pbuf.h"
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);
enum tcpip_msg_type {
TCPIP_MSG_API,
TCPIP_MSG_INPUT
};
struct tcpip_msg {
enum tcpip_msg_type type;
sys_sem_t *sem;
union {
struct api_msg *apimsg;
struct {
struct pbuf *p;
struct netif *netif;
} inp;
} msg;
};
#endif /* __LWIP_TCPIP_H__ */

97
src/include/lwip/udp.h Normal file
View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIP_UDP_H__
#define __LWIP_UDP_H__
#include "lwip/arch.h"
#include "lwip/pbuf.h"
#include "lwip/inet.h"
#include "lwip/ip.h"
#include "lwip/err.h"
#define UDP_HLEN 8
struct udp_hdr {
PACK_STRUCT_FIELD(u16_t src);
PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */
PACK_STRUCT_FIELD(u16_t len);
PACK_STRUCT_FIELD(u16_t chksum);
} PACK_STRUCT_STRUCT;
#define UDP_FLAGS_NOCHKSUM 0x01
#define UDP_FLAGS_UDPLITE 0x02
struct udp_pcb {
struct udp_pcb *next;
struct ip_addr local_ip, remote_ip;
u16_t local_port, remote_port;
u8_t flags;
u16_t chksum_len;
void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *addr, u16_t port);
void *recv_arg;
};
/* The following functions is the application layer interface to the
UDP code. */
struct udp_pcb * udp_new (void);
void udp_remove (struct udp_pcb *pcb);
err_t udp_bind (struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port);
err_t udp_connect (struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port);
void udp_recv (struct udp_pcb *pcb,
void (* recv)(void *arg, struct udp_pcb *upcb,
struct pbuf *p,
struct ip_addr *addr,
u16_t port),
void *recv_arg);
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
#define udp_flags(pcb) ((pcb)->flags)
#define udp_setflags(pcb, f) ((pcb)->flags = (f))
/* The following functions is the lower layer interface to UDP. */
u8_t udp_lookup (struct ip_hdr *iphdr, struct netif *inp);
void udp_input (struct pbuf *p, struct netif *inp);
void udp_init (void);
#endif /* __LWIP_UDP_H__ */

111
src/include/netif/etharp.h Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Swedish Institute
* of Computer Science and its contributors.
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*
*/
#ifndef __NETIF_ETHARP_H__
#define __NETIF_ETHARP_H__
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
PACK_STRUCT_BEGIN
struct eth_addr {
PACK_STRUCT_FIELD(u8_t addr[6]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
PACK_STRUCT_BEGIN
struct eth_hdr {
PACK_STRUCT_FIELD(struct eth_addr dest);
PACK_STRUCT_FIELD(struct eth_addr src);
PACK_STRUCT_FIELD(u16_t type);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#define ARP_TMR_INTERVAL 10000
#define ETHTYPE_ARP 0x0806
#define ETHTYPE_IP 0x0800
/* Initializes ARP. */
void etharp_init(void);
/* The etharp_tmr() function should be called every ETHARP_TMR_INTERVAL
microseconds (10 seconds). This function is responsible for
expiring old entries in the ARP table. */
void etharp_tmr(void);
/* Should be called for all incoming packets of IP kind. The function
does not alter the packet in any way, it just updates the ARP
table. After this function has been called, the normal TCP/IP stack
input function should be called.
The function may return a pbuf containing a packet that had
previously been queued for transmission. The device driver must
transmit this packet onto the network, and call pbuf_free() for the
pbuf.
*/
struct pbuf *etharp_ip_input(struct netif *netif, struct pbuf *p);
/* Should be called for incoming ARP packets. The pbuf in the argument
is freed by this function. If the function returns a pbuf (i.e.,
returns non-NULL), that pbuf constitutes an ARP reply and should be
sent out on the Ethernet.
The driver must call pbuf_free() for the returned pbuf when the
packet has been sent.
*/
struct pbuf *etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
struct pbuf *p);
/* The etharp_output() function should be called for all outgoing
packets. The pbuf returned by the function should be sent out on
the Ethernet.
The function prepares the packet for transmission over the Ethernet
by adding an Ethernet header. If there is no IP -> MAC address
mapping, the function will queue the outgoing packet and return an
ARP request.
*/
struct pbuf *etharp_output(struct netif *netif, struct ip_addr *ipaddr,
struct pbuf *q);
#endif /* __NETIF_ARP_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_ETHERNETIF_H__
#define __NETIF_ETHERNETIF_H__
#include "lwip/netif.h"
void ethernetif_init(struct netif *netif);
#endif /* __NETIF_ETHERNETIF_H__ */

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __NETIF_LOOPIF_H__
#define __NETIF_LOOPIF_H__
#include "lwip/netif.h"
void loopif_init(struct netif *netif);
#endif /* __NETIF_LOOPIF_H__ */

Some files were not shown because too many files have changed in this diff Show More