mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-06-23 13:53:39 +08:00
Initial revision
This commit is contained in:
13
src/FILES
Normal file
13
src/FILES
Normal 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
639
src/api/api_lib.c
Normal 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
544
src/api/api_msg.c
Normal 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
59
src/api/err.c
Normal 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
441
src/api/sockets.c
Normal 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
137
src/api/tcpip.c
Normal 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
1
src/arch/6502/README
Normal file
@@ -0,0 +1 @@
|
||||
The 6502 code is far from complete.
|
||||
47
src/arch/6502/include/arch/cc.h
Normal file
47
src/arch/6502/include/arch/cc.h
Normal 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__ */
|
||||
37
src/arch/6502/include/arch/cpu.h
Normal file
37
src/arch/6502/include/arch/cpu.h
Normal 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__ */
|
||||
40
src/arch/6502/include/arch/lib.h
Normal file
40
src/arch/6502/include/arch/lib.h
Normal 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__ */
|
||||
38
src/arch/6502/include/arch/perf.h
Normal file
38
src/arch/6502/include/arch/perf.h
Normal 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__ */
|
||||
41
src/arch/6502/include/arch/sys_arch.h
Normal file
41
src/arch/6502/include/arch/sys_arch.h
Normal 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
63
src/arch/6502/lib_arch.c
Normal 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
120
src/arch/6502/sys_c64.c
Normal 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
15
src/arch/FILES
Normal 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.
|
||||
47
src/arch/rtxc/include/arch/cc.h
Normal file
47
src/arch/rtxc/include/arch/cc.h
Normal 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__ */
|
||||
37
src/arch/rtxc/include/arch/cpu.h
Normal file
37
src/arch/rtxc/include/arch/cpu.h
Normal 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__ */
|
||||
44
src/arch/rtxc/include/arch/init.h
Normal file
44
src/arch/rtxc/include/arch/init.h
Normal 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__ */
|
||||
|
||||
|
||||
|
||||
|
||||
40
src/arch/rtxc/include/arch/lib.h
Normal file
40
src/arch/rtxc/include/arch/lib.h
Normal 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__ */
|
||||
38
src/arch/rtxc/include/arch/perf.h
Normal file
38
src/arch/rtxc/include/arch/perf.h
Normal 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__ */
|
||||
45
src/arch/rtxc/include/arch/sys_arch.h
Normal file
45
src/arch/rtxc/include/arch/sys_arch.h
Normal 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__ */
|
||||
|
||||
41
src/arch/rtxc/include/netif/cs8900if.h
Normal file
41
src/arch/rtxc/include/netif/cs8900if.h
Normal 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__ */
|
||||
39
src/arch/rtxc/include/netif/sioslipif.h
Normal file
39
src/arch/rtxc/include/netif/sioslipif.h
Normal 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
63
src/arch/rtxc/lib.c
Normal 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 */
|
||||
1
src/arch/rtxc/netif/FILES
Normal file
1
src/arch/rtxc/netif/FILES
Normal file
@@ -0,0 +1 @@
|
||||
sioslipif.c - Implementation of the SLIP protocol on top of a serial line.
|
||||
170
src/arch/rtxc/netif/sioslipif.c
Normal file
170
src/arch/rtxc/netif/sioslipif.c
Normal 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
38
src/arch/rtxc/perf.c
Normal 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
271
src/arch/rtxc/sys_arch.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
51
src/arch/unix/include/arch/cc.h
Normal file
51
src/arch/unix/include/arch/cc.h
Normal 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__ */
|
||||
39
src/arch/unix/include/arch/cpu.h
Normal file
39
src/arch/unix/include/arch/cpu.h
Normal 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__ */
|
||||
41
src/arch/unix/include/arch/init.h
Normal file
41
src/arch/unix/include/arch/init.h
Normal 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__ */
|
||||
|
||||
|
||||
|
||||
|
||||
44
src/arch/unix/include/arch/lib.h
Normal file
44
src/arch/unix/include/arch/lib.h
Normal 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__ */
|
||||
63
src/arch/unix/include/arch/perf.h
Normal file
63
src/arch/unix/include/arch/perf.h
Normal 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__ */
|
||||
48
src/arch/unix/include/arch/sys_arch.h
Normal file
48
src/arch/unix/include/arch/sys_arch.h
Normal 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__ */
|
||||
|
||||
42
src/arch/unix/include/netif/delif.h
Normal file
42
src/arch/unix/include/netif/delif.h
Normal 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__ */
|
||||
41
src/arch/unix/include/netif/dropif.h
Normal file
41
src/arch/unix/include/netif/dropif.h
Normal 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__ */
|
||||
39
src/arch/unix/include/netif/pcapif.h
Normal file
39
src/arch/unix/include/netif/pcapif.h
Normal 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__ */
|
||||
43
src/arch/unix/include/netif/sioslipif.h
Normal file
43
src/arch/unix/include/netif/sioslipif.h
Normal 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__ */
|
||||
39
src/arch/unix/include/netif/tapif.h
Normal file
39
src/arch/unix/include/netif/tapif.h
Normal 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__ */
|
||||
42
src/arch/unix/include/netif/tunif.h
Normal file
42
src/arch/unix/include/netif/tunif.h
Normal 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__ */
|
||||
40
src/arch/unix/include/netif/unixif.h
Normal file
40
src/arch/unix/include/netif/unixif.h
Normal 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__ */
|
||||
73
src/arch/unix/lwip_chksum.c
Normal file
73
src/arch/unix/lwip_chksum.c
Normal 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
310
src/arch/unix/netif/delif.c
Normal 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
162
src/arch/unix/netif/list.c
Normal 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);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
214
src/arch/unix/netif/pcapif.c
Normal file
214
src/arch/unix/netif/pcapif.c
Normal 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 */
|
||||
189
src/arch/unix/netif/sioslipif.c
Normal file
189
src/arch/unix/netif/sioslipif.c
Normal 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
355
src/arch/unix/netif/tapif.c
Normal 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
298
src/arch/unix/netif/tunif.c
Normal 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);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
480
src/arch/unix/netif/unixif.c
Normal file
480
src/arch/unix/netif/unixif.c
Normal 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
64
src/arch/unix/perf.c
Normal 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
453
src/arch/unix/sys_arch.c
Normal 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
162
src/core/inet.c
Normal 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
168
src/core/inet6.c
Normal 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
199
src/core/ipv4/icmp.c
Normal 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
700
src/core/ipv4/ip.c
Normal 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
41
src/core/ipv4/ip_addr.c
Normal 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
1
src/core/ipv6/README
Normal file
@@ -0,0 +1 @@
|
||||
IPv6 support in lwIP is very experimental.
|
||||
184
src/core/ipv6/icmp6.c
Normal file
184
src/core/ipv6/icmp6.c
Normal 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
386
src/core/ipv6/ip6.c
Normal 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
91
src/core/ipv6/ip6_addr.c
Normal 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
297
src/core/mem.c
Normal 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
271
src/core/memp.c
Normal 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
142
src/core/netif.c
Normal 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
597
src/core/pbuf.c
Normal 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
54
src/core/stats.c
Normal 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
187
src/core/sys.c
Normal 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
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
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
589
src/core/tcp_output.c
Normal 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
453
src/core/udp.c
Normal 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
105
src/include/ipv4/lwip/icmp.h
Normal file
105
src/include/ipv4/lwip/icmp.h
Normal 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__ */
|
||||
|
||||
105
src/include/ipv4/lwip/inet.h
Normal file
105
src/include/ipv4/lwip/inet.h
Normal 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
119
src/include/ipv4/lwip/ip.h
Normal 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__ */
|
||||
|
||||
|
||||
89
src/include/ipv4/lwip/ip_addr.h
Normal file
89
src/include/ipv4/lwip/ip_addr.h
Normal 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__ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
90
src/include/ipv6/lwip/icmp.h
Normal file
90
src/include/ipv6/lwip/icmp.h
Normal 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__ */
|
||||
|
||||
60
src/include/ipv6/lwip/inet.h
Normal file
60
src/include/ipv6/lwip/inet.h
Normal 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__ */
|
||||
|
||||
96
src/include/ipv6/lwip/ip.h
Normal file
96
src/include/ipv6/lwip/ip.h
Normal 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__ */
|
||||
|
||||
|
||||
59
src/include/ipv6/lwip/ip_addr.h
Normal file
59
src/include/ipv6/lwip/ip_addr.h
Normal 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
137
src/include/lwip/api.h
Normal 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__ */
|
||||
|
||||
|
||||
93
src/include/lwip/api_msg.h
Normal file
93
src/include/lwip/api_msg.h
Normal 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
58
src/include/lwip/arch.h
Normal 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
136
src/include/lwip/debug.h
Normal 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
44
src/include/lwip/def.h
Normal 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
68
src/include/lwip/err.h
Normal 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
29
src/include/lwip/event.h
Normal 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
47
src/include/lwip/list.h
Normal 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
60
src/include/lwip/mem.h
Normal 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
67
src/include/lwip/memp.h
Normal 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
97
src/include/lwip/netif.h
Normal 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
102
src/include/lwip/opt.h
Normal 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
152
src/include/lwip/pbuf.h
Normal 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__ */
|
||||
99
src/include/lwip/sockets.h
Normal file
99
src/include/lwip/sockets.h
Normal 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
109
src/include/lwip/stats.h
Normal 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
116
src/include/lwip/sys.h
Normal 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
448
src/include/lwip/tcp.h
Normal 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
60
src/include/lwip/tcpip.h
Normal 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
97
src/include/lwip/udp.h
Normal 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
111
src/include/netif/etharp.h
Normal 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__ */
|
||||
39
src/include/netif/ethernetif.h
Normal file
39
src/include/netif/ethernetif.h
Normal 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__ */
|
||||
39
src/include/netif/loopif.h
Normal file
39
src/include/netif/loopif.h
Normal 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
Reference in New Issue
Block a user