Initial revision

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

284
CHANGELOG Normal file
View File

@ -0,0 +1,284 @@
(0.5.3) Changes since version 0.5.2
++ Bugfixes:
* memp_malloc(MEMP_API_MSG) could fail with multiple application
threads because it wasn't protected by semaphores.
++ Other changes:
* struct ip_addr now packed.
* The name of the time variable in arp.c has been changed to ctime
to avoid conflicts with the time() function.
(0.5.2) Changes since version 0.5.1
++ New features:
* A new TCP function, tcp_tmr(), now handles both TCP timers.
++ Bugfixes:
* A bug in tcp_parseopt() could cause the stack to hang because of a
malformed TCP option.
* The address of new connections in the accept() function in the BSD
socket library was not handled correctly.
* pbuf_dechain() did not update the ->tot_len field of the tail.
* Aborted TCP connections were not handled correctly in all
situations.
++ Other changes:
* All protocol header structs are now packed.
* The ->len field in the tcp_seg structure now counts the actual
amount of data, and does not add one for SYN and FIN segments.
(0.5.1) Changes since version 0.5.0
++ New features:
* Possible to run as a user process under Linux.
* Preliminary support for cross platform packed structs.
* ARP timer now implemented.
++ Bugfixes:
* TCP output queue length was badly initialized when opening
connections.
* TCP delayed ACKs were not sent correctly.
* Explicit initialization of BSS segment variables.
* read() in BSD socket library could drop data.
* Problems with memory alignment.
* Situations when all TCP buffers were used could lead to
starvation.
* TCP MSS option wasn't parsed correctly.
* Problems with UDP checksum calculation.
* IP multicast address tests had endianess problems.
* ARP requests had wrong destination hardware address.
++ Other changes:
* struct eth_addr changed from u16_t[3] array to u8_t[6].
* A ->linkoutput() member was added to struct netif.
* TCP and UDP ->dest_* struct members where changed to ->remote_*.
* ntoh* macros are now null definitions for big endian CPUs.
(0.5.0) Changes since version 0.4.2
++ New features:
* Redesigned operating system emulation layer to make porting easier.
* Better control over TCP output buffers.
* Documenation added.
++ Bugfixes:
* Locking issues in buffer management.
* Bugfixes in the sequential API.
* IP forwarding could cause memory leakage. This has been fixed.
++ Other changes:
* Directory structure somewhat changed; the core/ tree has been
collapsed.
(0.4.2) Changes since version 0.4.1
++ New features:
* Experimental ARP implementation added.
* Skeleton Ethernet driver added.
* Experimental BSD socket API library added.
++ Bugfixes:
* In very intense situations, memory leakage could occur. This has
been fixed.
++ Other changes:
* Variables named "data" and "code" have been renamed in order to
avoid name conflicts in certain compilers.
* Variable++ have in appliciable cases been translated to ++variable
since some compilers generate better code in the latter case.
(0.4.1) Changes since version 0.4
++ New features:
* TCP: Connection attempts time out earlier than data
transmissions. Nagle algorithm implemented. Push flag set on the
last segment in a burst.
* UDP: experimental support for UDP-Lite extensions.
++ Bugfixes:
* TCP: out of order segments were in some cases handled incorrectly,
and this has now been fixed. Delayed acknowledgements was broken
in 0.4, has now been fixed. Binding to an address that is in use
now results in an error. Reset connections sometimes hung an
application; this has been fixed.
* Checksum calculation sometimes failed for chained pbufs with odd
lengths. This has been fixed.
* API: a lot of bug fixes in the API. The UDP API has been improved
and tested. Error reporting and handling has been
improved. Logical flaws and race conditions for incoming TCP
connections has been found and removed.
* Memory manager: alignment issues. Reallocating memory sometimes
failed, this has been fixed.
* Generic library: bcopy was flawed and has been fixed.
++ Other changes:
* API: all datatypes has been changed from generic ones such as
ints, to specified ones such as u16_t. Functions that return
errors now have the correct type (err_t).
* General: A lot of code cleaned up and debugging code removed. Many
portability issues have been fixed.
* The license was changed; the advertising clause was removed.
* C64 port added.
* Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri
Kosunen, Mikael Caleres, and Frits Wilmink for reporting and
fixing bugs!
(0.4) Changes since version 0.3.1
* Memory management has been radically changed; instead of
allocating memory from a shared heap, memory for objects that are
rapidly allocated and deallocated is now kept in pools. Allocation
and deallocation from those memory pools is very fast. The shared
heap is still present but is used less frequently.
* The memory, memory pool, and packet buffer subsystems now support
4-, 2-, or 1-byte alignment.
* "Out of memory" situations are handled in a more robust way.
* Stack usage has been reduced.
* Easier configuration of lwIP parameters such as memory usage,
TTLs, statistics gathering, etc. All configuration parameters are
now kept in a single header file "lwipopts.h".
* The directory structure has been changed slightly so that all
architecture specific files are kept under the src/arch
hierarchy.
* Error propagation has been improved, both in the protocol modules
and in the API.
* The code for the RTXC architecture has been implemented, tested
and put to use.
* Bugs have been found and corrected in the TCP, UDP, IP, API, and
the Internet checksum modules.
* Bugs related to porting between a 32-bit and a 16-bit architecture
have been found and corrected.
* The license has been changed slightly to conform more with the
original BSD license, including the advertisement clause.
(0.3.1) Changes since version 0.3
* Fix of a fatal bug in the buffer management. Pbufs with allocated
RAM never returned the RAM when the pbuf was deallocated.
* TCP congestion control, window updates and retransmissions did not
work correctly. This has now been fixed.
* Bugfixes in the API.
(0.3) Changes since version 0.2
* New and improved directory structure. All include files are now
kept in a dedicated include/ directory.
* The API now has proper error handling. A new function,
netconn_err(), now returns an error code for the connection in
case of errors.
* Improvements in the memory management subsystem. The system now
keeps a pointer to the lowest free memory block. A new function,
mem_malloc2() tries to allocate memory once, and if it fails tries
to free some memory and retry the allocation.
* Much testing has been done with limited memory
configurations. lwIP now does a better job when overloaded.
* Some bugfixes and improvements to the buffer (pbuf) subsystem.
* Many bugfixes in the TCP code:
- Fixed a bug in tcp_close().
- The TCP receive window was incorrectly closed when out of
sequence segments was received. This has been fixed.
- Connections are now timed-out of the FIN-WAIT-2 state.
- The initial congestion window could in some cases be too
large. This has been fixed.
- The retransmission queue could in some cases be screwed up. This
has been fixed.
- TCP RST flag now handled correctly.
- Out of sequence data was in some cases never delivered to the
application. This has been fixed.
- Retransmitted segments now contain the correct acknowledgment
number and advertised window.
- TCP retransmission timeout backoffs are not correctly computed
(ala BSD). After a number of retransmissions, TCP now gives up
the connection.
* TCP connections now are kept on three lists, one for active
connections, one for listening connections, and one for
connections that are in TIME-WAIT. This greatly speeds up the fast
timeout processing for sending delayed ACKs.
* TCP now provides proper feedback to the application when a
connection has been successfully set up.
* More comments have been added to the code. The code has also been
somewhat cleaned up.
(0.2) Initial public release.

29
COPYING Normal file
View File

@ -0,0 +1,29 @@
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. 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.

5
FILES Normal file
View File

@ -0,0 +1,5 @@
src/ - The source code for the lwIP TCP/IP stack.
proj/ - Makefiles and code for compiling lwIP.
See also the FILES file in each subdirectory.

289
doc/rawapi.txt Normal file
View File

@ -0,0 +1,289 @@
Raw TCP/IP interface for lwIP 0.5
Author: Adam Dunkels
$Id: rawapi.txt,v 1.1 2002/10/19 12:59:32 likewise Exp $
lwIP provides two Application Program's Interfaces (APIs) for programs
to use for communication with the TCP/IP code: the sequential API
(often just called "the API") and the raw TCP/IP interface. This
document is intended as a description of the latter. For lwIP versions
lower than 0.5, this API was not documented.
The sequential API provides a way for ordinary, sequential, programs
to use the lwIP stack. It is quite similar to the BSD socket API. The
model of execution is based on the open-read-write-close
paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
code and the application program must reside in different execution
contexts (threads).
The raw TCP/IP interface allows the application program to integrate
better with the TCP/IP code. Program execution is event based by
having callback functions being called from within the TCP/IP
code. The TCP/IP code and the application program both run in the same
thread. The sequential API has a much higher overhead and is not very
well suited for small systems since it forces a multithreaded paradigm
on the application.
The raw TCP/IP interface is not only faster in terms of code execution
time but is also less memory intensive. The drawback is that program
development is somewhat harder and application programs written for
the raw TCP/IP interface are more difficult to understand. Still, this
is the preferred way of writing applications that should be small in
code size and memory usage.
Both APIs can be used simultaneously by different application
programs. In fact, the sequential API is implemented as an application
program using the raw TCP/IP interface.
--- Callbacks
Program execution is driven by callbacks. Each callback is an ordinary
C function that is called from within the TCP/IP code. Every callback
function is passed the current TCP or UDP connection state as an
argument. Also, in order to be able to keep program specific state,
the callback functions are called with a program specified argument
that is independent of the TCP/IP state.
The function for setting the application connection state is:
- void tcp_arg(struct tcp_pcb *pcb, void *arg)
Specifies the program specific state that should be passed to all
other callback functions. The "pcb" argument is the current TCP
connection control block, and the "arg" argument is the argument
that will be passed to the callbacks.
--- TCP connection setup
The functions used for setting up connections is similar to that of
the sequential API and of the BSD socket API. A new TCP connection
identifier (i.e., a protocol control block - PCB) is created with the
tcp_new() function. This PCB can then be either set to listen for new
incoming connections or be explicitly connected to another host.
- struct tcp_pcb *tcp_new(void)
Creates a new connection identifier (PCB). If memory is not
available for creating the new pcb, NULL is returned.
- err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port)
Binds the pcb to a local IP address and port number. The IP address
can be specified as IP_ADDR_ANY in order to bind the connection to
all local IP addresses.
If another connection is bound to the same port, the function will
return ERR_USE, otherwise ERR_OK is returned.
- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb)
Commands a pcb to start listening for incoming connections. When an
incoming connection is accepted, the function specified with the
tcp_accept() function will be called. The pcb will have to be bound
to a local port with the tcp_bind() function.
The tcp_listen() function returns a new connection identifier, and
the one passed as an argument to the function will be
deallocated. The reason for this behavior is that less memory is
needed for a connection that is listening, so tcp_listen() will
reclaim the memory needed for the original connection and allocate a
new smaller memory block for the listening connection.
tcp_listen() may return NULL if no memory was available for the
listening connection. If so, the memory associated with the pcb
passed as an argument to tcp_listen() will not be deallocated.
- void tcp_accept(struct tcp_pcb *pcb,
err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
err_t err))
Specified the callback function that should be called when a new
connection arrives on a listening connection.
- 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));
Sets up the pcb to connect to the remote host and sends the
initial SYN segment which opens the connection.
The tcp_connect() function returns immediately; it does not wait for
the connection to be properly setup. Instead, it will call the
function specified as the fourth argument (the "connected" argument)
when the connection is established. If the connection could not be
properly established, either because the other host refused the
connection or because the other host didn't answer, the "connected"
function will be called with an the "err" argument set accordingly.
The tcp_connect() function can return ERR_MEM if no memory is
available for enqueueing the SYN segment. If the SYN indeed was
enqueued successfully, the tcp_connect() function returns ERR_OK.
--- Sending TCP data
TCP data is sent by enqueueing the data with a call to
tcp_write(). When the data is successfully transmitted to the remote
host, the application will be notified with a call to a specified
callback function.
- err_t tcp_write(struct tcp_pcb *pcb, void *dataptr, u16_t len,
u8_t copy)
Enqueues the data pointed to by the argument dataptr. The length of
the data is passed as the len parameter. The copy argument is either
0 or 1 and indicates whether the new memory should be allocated for
the data to be copied into. If the argument is 0, no new memory
should be allocated and the data should only be referenced by
pointer.
The tcp_write() function will fail and return ERR_MEM if the length
of the data exceeds the current send buffer size or if the length of
the queue of outgoing segment is larger than the upper limit defined
in lwipopts.h. The number of bytes available in the output queue can
be retrieved with the tcp_sndbuf() function.
The proper way to use this function is to call the function with at
most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
the application should wait until some of the currently enqueued
data has been successfully received by the other host and try again.
- void tcp_sent(struct tcp_pcb *pcb,
err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
u16_t len))
Specifies the callback function that should be called when data has
successfully been received (i.e., acknowledged) by the remote
host. The len argument passed to the callback function gives the
amount bytes that was acknowledged by the last acknowledgment.
--- Receiving TCP data
TCP data reception is callback based - an application specified
callback function is called when new data arrives. When the
application has taken the data, it has to call the tcp_recved()
function to indicate that TCP can advertise increase the receive
window.
- void tcp_recv(struct tcp_pcb *pcb,
err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err))
Sets the callback function that will be called when new data
arrives. The callback function will be passed a NULL pbuf to
indicate that the remote host has closed the connection.
- void tcp_recved(struct tcp_pcb *pcb, u16_t len)
Must be called when the application has received the data. The len
argument indicates the length of the received data.
--- Application polling
When a connection is idle (i.e., no data is either transmitted or
received), lwIP will repeatedly poll the application by calling a
specified callback function. This can be used either as a watchdog
timer for killing connections that have stayed idle for too long, or
as a method of waiting for memory to become available. For instance,
if a call to tcp_write() has failed because memory wasn't available,
the application may use the polling functionality to call tcp_write()
again when the connection has been idle for a while.
- void tcp_poll(struct tcp_pcb *pcb, u8_t interval,
err_t (* poll)(void *arg, struct tcp_pcb *tpcb))
Specifies the polling interval and the callback function that should
be called to poll the application. The interval is specified in
number of TCP coarse grained timer shots, which typically occurs
twice a second. An interval of 10 means that the application would
be polled every 5 seconds.
--- Closing and aborting connections
- err_t tcp_close(struct tcp_pcb *pcb)
Closes the connection. The function may return ERR_MEM if no memory
was available for closing the connection. If so, the application
should wait and try again either by using the acknowledgment
callback or the polling functionality. If the close succeeds, the
function returns ERR_OK.
The pcb is deallocated by the TCP code after a call to tcp_close().
- void tcp_abort(struct tcp_pcb *pcb)
Aborts the connection by sending a RST (reset) segment to the remote
host. The pcb is deallocated. This function never fails.
If a connection is aborted because of an error, the application is
alerted of this event by the err callback. Errors that might abort a
connection are when there is a shortage of memory. The callback
function to be called is set using the tcp_err() function.
- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg,
err_t err))
The error callback function does not get the pcb passed to it as a
parameter since the pcb may already have been deallocated.
--- Lower layer TCP interface
TCP provides a simple interface to the lower layers of the
system. During system initialization, the function tcp_init() has
to be called before any other TCP function is called. When the system
is running, the two timer functions tcp_fasttmr() and tcp_slowtmr()
must be called with regular intervals. The tcp_fasttmr() should be
called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and
tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds.
--- UDP interface
The UDP interface is similar to that of TCP, but due to the lower
level of complexity of UDP, the interface is significantly simpler.
- struct udp_pcb *udp_new(void)
Creates a new UDP pcb which can be used for UDP communication. The
pcb is not active until it has either been bound to a local address
or connected to a remote address.
- void udp_remove(struct udp_pcb *pcb)
Removes and deallocates the pcb.
- err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port)
Binds the pcb to a local address. The IP-address argument "ipaddr"
can be IP_ADDR_ANY to indicate that it should listen to any local IP
address. The function currently always return ERR_OK.
- err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port)
Sets the remote end of the pcb. This function does not generate any
network traffic, but only set the remote address of the pcb.
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
Sends the pbuf p. The pbuf is not deallocated.
- 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)
Specifies a callback function that should be called when a UDP
datagram is received.

125
doc/sys_arch.txt Normal file
View File

@ -0,0 +1,125 @@
sys_arch interface for lwIP 0.5
Author: Adam Dunkels
$Id: sys_arch.txt,v 1.1 2002/10/19 12:59:33 likewise Exp $
The operating system emulation layer provides a common interface
between the lwIP code and the underlying operating system kernel. The
general idea is that porting lwIP to new architectures requires only
small changes to a few header files and a new sys_arch
implementation. It is also possible to do a sys_arch implementation
that does not rely on any underlying operating system.
The sys_arch provides semaphores and mailboxes to lwIP. For the full
lwIP functionality, multiple threads support can be implemented in the
sys_arch, but this is not required for the basic lwIP
functionality. Previous versions of lwIP required the sys_arch to
implement timer scheduling as well but as of lwIP 0.5 this is
implemented in a higher layer.
Semaphores can be either counting or binary - lwIP works with both
kinds. Mailboxes are used for message passing and can be implemented
either as a queue which allows multiple messages to be posted to a
mailbox, or as a rendez-vous point where only one message can be
posted at a time. lwIP works with both kinds, but the former type will
be more efficient. A message in a mailbox is just a pointer, nothing
more.
Semaphores are represented by the type "sys_sem_t" which is typedef'd
in the sys_arch.h file. Mailboxes are equivalently represented by the
type "sys_mbox_t". lwIP does not place any restrictions on how
sys_sem_t or sys_mbox_t are represented internally.
The following functions must be implemented by the sys_arch:
- void sys_init(void)
Is called to initialize the sys_arch layer.
- sys_sem_t sys_sem_new(u8_t count)
Creates and returns a new semaphore. The "count" argument specifies
the initial state of the semaphore.
- void sys_sem_free(sys_sem_t sem)
Deallocates a semaphore.
- void sys_sem_signal(sys_sem_t sem)
Signals a semaphore.
- u16_t sys_arch_sem_wait(sys_sem_t sem, u16_t timeout)
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the amount
of time spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return
value is zero. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), care must be taken to ensure that
the function does not return a zero value since this is used to
indicate that a timeout occured. A suitable way to implement this is
to check if the time spent waiting is zero and if so, the value 1 is
returned.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
- sys_mbox_t sys_mbox_new(void)
Creates an empty mailbox.
- void sys_mbox_free(sys_mbox_t mbox)
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
- void sys_mbox_post(sys_mbox_t mbox, void *msg)
Posts the "msg" to the mailbox.
- u16_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout)
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
The return values are the same as for the sys_arch_sem_wait()
function and the function must not return zero even if a message was
present in the mailbox and the time spent waiting was zero
milliseconds.
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
- struct sys_timeouts *sys_arch_timeouts(void)
Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
each thread has a list of timeouts which is repressented as a linked
list of sys_timeout structures. The sys_timeouts structure holds a
pointer to a linked list of timeouts. This function is called by
the lwIP timeout scheduler and must not return a NULL value.
In a single threadd sys_arch implementation, this function will
simply return a pointer to a global sys_timeouts variable stored in
the sys_arch module.
If threads are supported by the underlying operating system and if
such functionality is needed in lwIP, the following function will have
to be implemented as well:
- void sys_thread_new(void (* thread)(void *arg), void *arg)
Starts a new thread that will begin its execution in the function
"thread()". The "arg" argument will be passed as an argument to the
thread() function.

94
proj/minimal/Makefile Normal file
View File

@ -0,0 +1,94 @@
# 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. 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>
#
# $Id: Makefile,v 1.1 2002/10/19 12:59:33 likewise Exp $
CCDEP=gcc
CC=gcc
CFLAGS=-g -Wall -DIPv4 -Os -fpack-struct
LWIPARCH=unix
ARFLAGS=rs
LWIPDIR=../../src
CFLAGS:=$(CFLAGS) \
-I$(LWIPDIR)/include -I$(LWIPDIR)/arch/$(LWIPARCH)/include -I$(LWIPDIR)/include/ipv4 \
-Iapps -I.
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \
$(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/stats.c $(LWIPDIR)/core/sys.c \
$(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_input.c \
$(LWIPDIR)/core/tcp_output.c $(LWIPDIR)/core/udp.c
CORE4FILES=$(LWIPDIR)/core/ipv4/icmp.c $(LWIPDIR)/core/ipv4/ip.c \
$(LWIPDIR)/core/inet.c $(LWIPDIR)/core/ipv4/ip_addr.c
# NETIFFILES: Files implementing various generic network interface functions.'
NETIFFILES=$(LWIPDIR)/netif/etharp.c mintapif.c
# LWIPFILES: All the above.
LWIPFILES=$(COREFILES) $(CORE4FILES) $(NETIFFILES)
LWIPFILESW=$(wildcard $(LWIPFILES))
LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
# APPFILES
APPFILES=echo.c
LWIPLIB=liblwip4.a
APPLIB=liblwipapps.a
APPOBJS=$(notdir $(APPFILES:.c=.o))
%.o:
$(CC) $(CFLAGS) -c $(<:.o=.c)
all ipv4 compile: minimal
.PHONY: all
clean:
rm -f *.o $(LWIPLIB) $(APPLIB) minimal .depend* *.core core
depend dep: .depend
include .depend
$(APPLIB): $(APPOBJS)
$(AR) $(ARFLAGS) $(APPLIB) $?
$(LWIPLIB): $(LWIPOBJS)
$(AR) $(ARFLAGS) $(LWIPLIB) $?
.depend: main.c $(LWIPFILES) $(APPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
minimal: .depend $(LWIPLIB) $(APPLIB) main.o $(APPFILES)
$(CC) $(CFLAGS) $(LDFLAGS) -o minimal main.o $(APPLIB) $(LWIPLIB)

3
proj/minimal/README Normal file
View File

@ -0,0 +1,3 @@
This is an example of a very minimal lwIP project. It runs in a single
thread and runs a single example application - an echo server. The
echo application is implemented using the raw API.

220
proj/minimal/echo.c Normal file
View File

@ -0,0 +1,220 @@
/*
* 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/stats.h"
#include "lwip/tcp.h"
struct echo_state {
struct pbuf *p;
u8_t failed;
#define FAILED_MAX 8
};
/*-----------------------------------------------------------------------------------*/
static void
echo_err(void *arg, err_t err)
{
struct echo_state *es = arg;
if(arg != NULL) {
pbuf_free(es->p);
mem_free(arg);
}
}
/*-----------------------------------------------------------------------------------*/
static void
close_conn(struct tcp_pcb *pcb, struct echo_state *es)
{
tcp_arg(pcb, NULL);
#if 0
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
#endif /* 0 */
if(es != NULL) {
pbuf_free(es->p);
mem_free(es);
}
tcp_close(pcb);
}
/*-----------------------------------------------------------------------------------*/
static void
send_buf(struct tcp_pcb *pcb, struct echo_state *es)
{
struct pbuf *q;
do {
q = es->p;
es->p = pbuf_dechain(q);
if(tcp_write(pcb, q->payload, q->len, 1) == ERR_MEM) {
pbuf_chain(q, es->p);
es->p = q;
return;
}
tcp_recved(pcb, q->len);
pbuf_free(q);
} while(es->p != NULL);
}
/*-----------------------------------------------------------------------------------*/
static err_t
echo_poll(void *arg, struct tcp_pcb *pcb)
{
struct echo_state *es;
if(arg == NULL) {
return tcp_close(pcb);
}
es = arg;
if(es->failed >= FAILED_MAX) {
close_conn(pcb, es);
tcp_abort(pcb);
return ERR_ABRT;
}
if(es->p != NULL) {
++es->failed;
send_buf(pcb, es);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
echo_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct echo_state *es;
es = arg;
if(es != NULL && es->p != NULL) {
send_buf(pcb, es);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
echo_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct echo_state *es;
es = arg;
if(p == NULL) {
close_conn(pcb, es);
return ERR_OK;
}
if(es->p != NULL) {
pbuf_chain(es->p, p);
} else {
es->p = p;
}
send_buf(pcb, es);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
echo_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct echo_state *es;
tcp_setprio(pcb, TCP_PRIO_MIN);
/* Allocate memory for the structure that holds the state of the
connection. */
es = mem_malloc(sizeof(struct echo_state));
if(es == NULL) {
return ERR_MEM;
}
/* Initialize the structure. */
es->p = NULL;
es->failed = 0;
/* Tell TCP that this is the structure we wish to be passed for our
callbacks. */
tcp_arg(pcb, es);
/* Tell TCP that we wish to be informed of incoming data by a call
to the http_recv() function. */
#if 0
tcp_recv(pcb, echo_recv);
tcp_err(pcb, echo_err);
#endif /* 0 */
tcp_poll(pcb, echo_poll, 2);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
echo_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 7);
pcb = tcp_listen(pcb);
#if 0
tcp_accept(pcb, echo_accept);
#endif /* 0 */
}
/*-----------------------------------------------------------------------------------*/
err_t
lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
enum lwip_event ev, struct pbuf *p,
u16_t size, err_t err)
{
switch(ev) {
case LWIP_EVENT_ACCEPT:
return echo_accept(arg, pcb, err);
case LWIP_EVENT_SENT:
return echo_sent(arg, pcb, size);
case LWIP_EVENT_RECV:
return echo_recv(arg, pcb, p, err);
case LWIP_EVENT_ERR:
echo_err(arg, err);
break;
case LWIP_EVENT_POLL:
return echo_poll(arg, pcb);
default:
break;
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/

168
proj/minimal/lwipopts.h Normal file
View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#define NO_SYS 1
#define LWIP_EVENT_API 1
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 2
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 1000
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 8
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 4
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 2
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 8
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 0
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 0
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#define MEMP_NUM_API_MSG 0
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG 0
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 0
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 8
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 128
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 16
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 0
/* TCP Maximum segment size. */
#define TCP_MSS 128
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 256
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
/* TCP receive window. */
#define TCP_WND 512
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* ---------- ARP options ---------- */
#define ARP_TABLE_SIZE 10
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 0
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS 1
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK 1
/* ---------- UDP options ---------- */
#define LWIP_UDP 0
#define UDP_TTL 255
/* ---------- Statistics options ---------- */
/*#define STATS*/
#ifdef STATS
#define LINK_STATS
#define IP_STATS
#define ICMP_STATS
#define UDP_STATS
#define TCP_STATS
#define MEM_STATS
#define MEMP_STATS
#define PBUF_STATS
#define SYS_STATS
#endif /* STATS */
#endif /* __LWIPOPTS_H__ */

101
proj/minimal/main.c Normal file
View File

@ -0,0 +1,101 @@
/*
* 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/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/ip.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "mintapif.h"
/*-----------------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
struct ip_addr ipaddr, netmask, gw;
struct netif *netif;
#ifdef PERF
perf_init("/tmp/minimal.perf");
#endif /* PERF */
#ifdef STATS
stats_init();
#endif /* STATS */
mem_init();
memp_init();
pbuf_init();
netif_init();
ip_init();
udp_init();
tcp_init();
printf("TCP/IP initialized.\n");
IP4_ADDR(&gw, 192,168,0,1);
IP4_ADDR(&ipaddr, 192,168,0,2);
IP4_ADDR(&netmask, 255,255,255,0);
netif = netif_add(&ipaddr, &netmask, &gw, mintapif_init, ip_input);
netif_set_default(netif);
echo_init();
printf("Applications started.\n");
while(1) {
if(mintapif_wait(netif, 100) == MINTAPIF_TIMEOUT) {
tcp_tmr();
}
}
return 0;
}
/*-----------------------------------------------------------------------------------*/

354
proj/minimal/mintapif.c Normal file
View File

@ -0,0 +1,354 @@
/*-----------------------------------------------------------------------------------*/
/*
* 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 <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.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 */
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "netif/etharp.h"
#include "mintapif.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'
struct mintapif {
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
u32_t lasttime;
int fd;
};
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
/* Forward declarations. */
static void mintapif_input(struct netif *netif);
static err_t mintapif_output(struct netif *netif, struct pbuf *p,
struct ip_addr *ipaddr);
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
struct mintapif *mintapif;
char buf[1024];
mintapif = netif->state;
/* Obtain MAC address from network interface. */
mintapif->ethaddr->addr[0] = 1;
mintapif->ethaddr->addr[1] = 2;
mintapif->ethaddr->addr[2] = 3;
mintapif->ethaddr->addr[3] = 4;
mintapif->ethaddr->addr[4] = 5;
mintapif->ethaddr->addr[5] = 6;
/* Do whatever else is needed to initialize interface. */
mintapif->fd = open(DEVTAP, O_RDWR);
if(mintapif->fd == -1) {
perror("tapif: tapif_init: open");
exit(1);
}
#ifdef linux
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(mintapif->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)));
system(buf);
mintapif->lasttime = 0;
}
/*-----------------------------------------------------------------------------------*/
/*
* 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 mintapif *mintapif;
struct pbuf *q;
char buf[1500];
char *bufptr;
mintapif = 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(mintapif->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 mintapif *mintapif)
{
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(mintapif->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(); */
printf("Could not allocate pbufs\n");
}
return p;
}
/*-----------------------------------------------------------------------------------*/
/*
* mintapif_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
mintapif_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;
}
/*-----------------------------------------------------------------------------------*/
/*
* mintapif_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
mintapif_input(struct netif *netif)
{
struct mintapif *mintapif;
struct eth_hdr *ethhdr;
struct pbuf *p, *q;
mintapif = netif->state;
p = low_level_input(mintapif);
if(p != NULL) {
#ifdef LINK_STATS
stats.link.recv++;
#endif /* LINK_STATS */
ethhdr = p->payload;
q = NULL;
switch(htons(ethhdr->type)) {
case ETHTYPE_IP:
q = etharp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case ETHTYPE_ARP:
q = etharp_arp_input(netif, mintapif->ethaddr, p);
break;
default:
pbuf_free(p);
break;
}
if(q != NULL) {
low_level_output(netif, q);
pbuf_free(q);
}
}
}
/*-----------------------------------------------------------------------------------*/
/*
* mintapif_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
mintapif_init(struct netif *netif)
{
struct mintapif *mintapif;
mintapif = mem_malloc(sizeof(struct mintapif));
netif->state = mintapif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = mintapif_output;
netif->linkoutput = low_level_output;
mintapif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
}
/*-----------------------------------------------------------------------------------*/
enum mintapif_signal
mintapif_wait(struct netif *netif, u16_t time)
{
fd_set fdset;
struct timeval tv, now;
struct timezone tz;
int ret;
struct mintapif *mintapif;
mintapif = netif->state;
while(1) {
if(mintapif->lasttime >= (u32_t)time * 1000) {
mintapif->lasttime = 0;
return MINTAPIF_TIMEOUT;
}
tv.tv_sec = 0;
tv.tv_usec = (u32_t)time * 1000 - mintapif->lasttime;
FD_ZERO(&fdset);
FD_SET(mintapif->fd, &fdset);
gettimeofday(&now, &tz);
ret = select(mintapif->fd + 1, &fdset, NULL, NULL, &tv);
if(ret == 0) {
mintapif->lasttime = 0;
return MINTAPIF_TIMEOUT;
}
gettimeofday(&tv, &tz);
mintapif->lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
mintapif_input(netif);
}
return MINTAPIF_PACKET;
}

45
proj/minimal/mintapif.h Normal file
View File

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

111
proj/unixsim/Makefile Normal file
View File

@ -0,0 +1,111 @@
# Copyright (c) 2001, Swedish Institute of Computer Science.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. 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>
#
# $Id: Makefile,v 1.1 2002/10/19 12:59:37 likewise Exp $
CCDEP=gcc
CC=gcc
CFLAGS=-g -Wall -DIPv4 -DLWIP_DEBUG -pedantic
LDFLAGS=-lpcap
LWIPARCH=unix
ARFLAGS=rs
LWIPDIR=../../src
CFLAGS:=$(CFLAGS) \
-I$(LWIPDIR)/include -I$(LWIPDIR)/arch/$(LWIPARCH)/include -I$(LWIPDIR)/include/ipv4 \
-Iapps -I.
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \
$(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/stats.c $(LWIPDIR)/core/sys.c \
$(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_input.c \
$(LWIPDIR)/core/tcp_output.c $(LWIPDIR)/core/udp.c
CORE4FILES=$(LWIPDIR)/core/ipv4/icmp.c $(LWIPDIR)/core/ipv4/ip.c \
$(LWIPDIR)/core/inet.c $(LWIPDIR)/core/ipv4/ip_addr.c
# APIFILES: The files which implement the sequential and socket APIs.
APIFILES=$(LWIPDIR)/api/api_lib.c $(LWIPDIR)/api/api_msg.c $(LWIPDIR)/api/tcpip.c \
$(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c
# NETIFFILES: Files implementing various generic network interface functions.'
NETIFFILES=$(LWIPDIR)/netif/loopif.c \
$(LWIPDIR)/netif/tcpdump.c $(LWIPDIR)/netif/etharp.c
# ARCHFILES: Archiecture specific files.
ARCHFILES=$(wildcard $(LWIPDIR)/arch/$(LWIPARCH)/*.c $(LWIPDIR)/arch/$(LWIPARCH)/netif/*.c)
# APPFILES: Applications.
APPFILES=apps/fs.c apps/httpd.c \
apps/udpecho.c apps/tcpecho.c \
apps/shell.c
# LWIPFILES: All the above.
LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
LWIPFILESW=$(wildcard $(LWIPFILES))
LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
LWIPLIB=liblwip4.a
APPLIB=liblwipapps.a
APPOBJS=$(notdir $(APPFILES:.c=.o))
%.o:
$(CC) $(CFLAGS) -c $(<:.o=.c)
all ipv4 compile: simhost simnode simrouter
.PHONY: all
clean:
rm -f *.o $(LWIPLIB) $(APPLIB) simhost simnode simrouter *.s .depend* *.core core
depend dep: .depend
include .depend
$(APPLIB): $(APPOBJS)
$(AR) $(ARFLAGS) $(APPLIB) $?
$(LWIPLIB): $(LWIPOBJS)
$(AR) $(ARFLAGS) $(LWIPLIB) $?
.depend: simhost.c simnode.c simrouter.c $(LWIPFILES) $(APPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
simhost: .depend $(LWIPLIB) $(APPLIB) simhost.o $(APPFILES)
$(CC) $(CFLAGS) $(LDFLAGS) -pthread -o simhost simhost.o $(APPLIB) $(LWIPLIB)
simrouter: .depend $(LWIPLIB) $(APPLIB) simrouter.o
$(CC) $(CFLAGS) $(LDFLAGS) -pthread -o simrouter simrouter.o $(APPLIB) $(LWIPLIB)
simnode: .depend $(LWIPLIB) $(APPLIB) simnode.o
$(CC) $(CFLAGS) $(LDFLAGS) -pthread -o simnode simnode.o $(APPLIB) $(LWIPLIB)

47
proj/unixsim/README Normal file
View File

@ -0,0 +1,47 @@
This directory contains an example of how a project using lwIP might
look. It is also the development platform of lwIP, since it can be run
as a user process under FreeBSD or Linux. There are also a number of
example applications (including a simple web server) in the apps/
directory.
Some short instructions on how to build and run lwIP on a FreeBSD or
Linux host. For FreeBSD, the tap interface must be enabled in the
kernel configuration and the kernel must be recompiled. The tap
interface is enabled by adding the line "pseudo-device tap" in the
kernel configuration. See Chapter 9 in the FreeBSD handbook for
instructions on how to build a custom FreeBSD kernel.
* Compile the code. This must be done by using GNU Make. Under
FreeBSD, GNU Make can be found in the ports collection under
/usr/ports/devel/gmake (type "make install distclean" to
install). Under Linux, GNU Make is the default "make".
> gmake (FreeBSD)
> make (Linux)
* The compilation process produces the executable file "simhost". To
run this, you have to be root.
> su (Type password for the root account)
# ./simhost
* The lwIP TCP/IP stack is now running with IP address
192.168.0.2. Some things that you can try:
To see the packets that are going to and from the lwIP stack, run
tcpdump:
# tcpdump -l -n -i tap0
You can ping lwIP:
> ping 192.168.0.2
For a telnet shell, run:
> telnet 192.168.0.2
Finally, "simhost" also includes a simple web server; the URL is
of course http://192.168.0.2/.

55
proj/unixsim/apps/fs.c Normal file
View File

@ -0,0 +1,55 @@
/*
* 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/def.h"
#include "fs.h"
#include "fsdata.h"
#include "fsdata.c"
/*-----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
int
fs_open(char *name, struct fs_file *file)
{
struct fsdata_file_noconst *f;
for(f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next) {
if(!strcmp(name, f->name)) {
file->data = f->data;
file->len = f->len;
return 1;
}
}
return 0;
}
/*-----------------------------------------------------------------------------------*/

44
proj/unixsim/apps/fs.h Normal file
View File

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

View File

@ -0,0 +1,191 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - Documentation</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
[Documentation]
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr>
<tr>
<td><center><h2>Documentation</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
<ul>
<li><a href="os.html">Using lwIP with and without an operating
system</a>.
<br><br>
<li>The lwIP source archive contains documentation on how to port lwIP
and how to write applications using the native API. They can also be
found here: <a href="doc/sys_arch.txt">sys_arch.txt</a>, <a
href="doc/rawapi.txt">rawapi.txt</a>.
<br><br>
<li>Selected messages from the mailinglist: <a
href="maillist/msg00231.html">lwIP memory buffers and allocators</a>,
<a href="maillist/msg00227.html">Threads, semaphores and raw interface
question</a>, <a href="maillist/msg00242.html">Threads, semaphores and
raw interface question [2]</a>. <a href="maillist/msg00460.html">Some notes on using lwIP with the development enviroment ADS
1.1 from ARM.</a>
<br><br>
<li>A report describing the design and implementation of an old
version of lwIP. The algorithms and data structures used both in the
protocol implementations and in the sub systems such as the memory and
buffer management systems are described. Also included in this report
is a reference manual for the lwIP sequential API and some code
examples of using lwIP. <a href="doc/lwip.pdf">PDF</a>, <a
href="doc/lwip.ps.gz">.ps.gz</a>.
<br><br>
<li>Slides from a presentation that talks a bit about lwIP: <a
href="doc/pres.pdf">PDF</a> (86k), <a href="doc/pres.ps.gz">.ps.gz</a>
(36k).
</ul>
<p align="justify">
For more documentation regarding lwIP and a proxy architecture to
support TCP/IP communication for small clients, look in <a
href="/~adam/publications.html">Adam Dunkels' masters thesis</a>.
</p>
<p align="justify">
The <a href="mailinglist.html">lwIP mailing list</a> can be used to
discuss lwIP.
</p>
<p align="justify">
For questions or suggestions, please contact the author at <a
href="mailto:Adam Dunkels <adam@sics.se>">Adam Dunkels
&lt;adam@sics.se&gt;</a>.
</p>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:01 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
[Documentation]
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,232 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - Download</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
[Download]
|
<a href="links.html">Links</a>
<hr>
</td></tr>
<tr>
<td><center><h2>Download</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
<p align="justify">
lwIP is avaliable for download provided that you read and accept <a
href="licence.html">this</a> BSD-style license.
</p>
<h3>Release versions</h3>
<p align="justify">
The latest version is 0.5.3. (Older versions are also provided for an
unknown reason.)
</p>
<ul>
<li>Version 0.5.3 (latest): <a
href="download/?f=lwip-0.5.3.tar.gz">lwip-0.5.3.tar.gz</a>
<br><br>
<li>
<font size="-2">
Obsolete versions: <a
href="download/?f=lwip-0.5.2.tar.gz">lwip-0.5.2.tar.gz</a>
<a
href="download/?f=lwip-0.5.1.tar.gz">lwip-0.5.1.tar.gz</a>
<a
href="download/?f=lwip-0.5.0.tar.gz">lwip-0.5.0.tar.gz</a>
<a
href="download/?f=lwip-0.4.2.tar.gz">lwip-0.4.2.tar.gz</a>
<a
href="download/?f=lwip-0.4.1.tar.gz">lwip-0.4.1.tar.gz</a>
<a
href="download/?f=lwip-0.4.tar.gz">lwip-0.4.tar.gz</a>
<a
href="download/?f=lwip-0.3.1.tar.gz">lwip-0.3.1.tar.gz</a>
<a
href="download/?f=lwip-0.3.tar.gz">lwip-0.3.tar.gz</a>
<a
href="download/?f=lwip-0.2.tar.gz">lwip-0.2.tar.gz</a>
</font>
<br>
</ul>
<h3>Development version</h3>
<p align="justify">
The latest development code from the CVS is also avaliable <a
href="download/?f=lwip-cvs.tar.gz">here</a>. Note that this code may
very well be unstable and might not even compile.
</p>
<h3>Source code online</h3>
<p align="justify">
Joe MacDonald has put an HTML version of the latest lwIP source code
online at <a
href="http://www.deserted.net/lwIP/">http://www.deserted.net/lwIP/</a>.
</p>
<h3>Ports</h3>
<p align="justify">
Florian Shulze has ported lwIP to DJGPP/MS-DOS and to Visual C++
6.0/Win32. They can be downloaded <a
href="http://homepages.fh-giessen.de/~hg10836/dev/djgpp/lwipdjgpptest-0.1.zip">here</a>
(DJGPP/MS-DOS) and <a
href="http://homepages.fh-giessen.de/~hg10836/crowproductions/dev/lwip-win32-msvc-0.1.zip">here</a>
(Visual C++ 6.0/Win32).
</p>
<h3>Add-ons/drivers/applications</h3>
<h4>DHCP client</h4>
<p align="justify">
Leon Woestenberg from Axon Digital Design B.V. has written a CS8900a
network interface driver and is currently developing a DHCP client for
lwIP. They can both be found <a
href="http://www.esrac.ele.tue.nl/~leon/lwip/">here</a>. The plan is
to eventually integrate Leon's DHCP client in the main lwIP
distribution.
</p>
<h4>IGMPv2 implementation</h4>
<p align="justify">
Steve Reynolds of Citel Technologies Ltd. has donated his IGMPv2
implementation for lwIP to the community. It is avaliable for download
<a href="download/igmpfiles.zip">here</a> (note that the copyright and
license differs slightly from lwIP - read the license in the igmp.c
file). The plan is to integrate his code into the main lwIP
distribution.
</p>
<h4>Alternative BSD socket layer</h4>
<p align="justify">
Paul Sheer has incorporated lwIP into his PaulOS system and has
written an alternative BSD socket layer. It is avaliable for download
<a href="download/bsdsocket.c">here</a>. It is copyright Paul Sheer
and licensed under the <a
href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.
</p>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:06 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
[Download]
|
<a href="links.html">Links</a>
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

View File

@ -0,0 +1,169 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - lwIP source code licence</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr>
<tr>
<td><center><h2>lwIP source code licence</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
Copyright (c) 2001, Swedish Institute of Computer Science.
All rights reserved.<br>
<br>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:<br>
<ol>
<li> Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.<br>
<br>
<li> 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.<br>
<br>
<li> 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. <br>
</ol>
<br>
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. <br>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:01 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,266 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - Links</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
[Links]
<hr>
</td></tr>
<tr>
<td><center><h2>Links</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
lwIP pages:
<ul>
<li><a href="http://www.esrac.ele.tue.nl/~leon/lwip/">Leon Woestenberg's lwIP page</a>
</ul>
Companies using lwIP in their products:
<ul>
<li>UK based <a href="http://www.tangentdevices.co.uk/">Tangent Devices Ltd</a> are incorporating lwIP in their film
and video post-production equipment.
<li><a href="http://www.axon.tv">Axon Digital Design BV</a> in The
Netherlands is merging lwIP with their current IP stack for use in the
Synapse modular broadcasting system.
</ul>
Projects using lwIP:
<ul>
<li><a href="http://www.cdt.luth.se/projects/arena/">The ARENA Project</a> - Hockey players equipped with pulse and breathing sensors running lwIP.<br>
<li><a href="http://bart.sm.luth.se/eis2001/">The Embedded Internet Systems 2001 Student Project</a> - Flow meter and belt tension sensors
running lwIP.<br>
<li><a href="http://dcdev.allusion.net/">KOS</a> - The KOS operating system for
Sega Dreamcast uses lwIP.<br>
</ul>
Other small TCP/IP implementations:
<ul>
<li><a href="http://dunkels.com/adam/uip/">uIP</a> - A very small TCP/IP
implementation, suitable for systems with hundreds of bytes free RAM
and a few kilobytes of free code space.<br>
<li><a href="http://ucip.sourceforge.net/">uC/IP</a> - uC/IP is a BSD-based
TCP/IP protocol stack for microcontrollers.<br>
<li><a href="http://liquorice.sourceforge.net">Liquorice</a> - Liquorice
includes a TCP/IP stack.<br>
<li><a href="http://www.nenie.org/cpcip/">CPC/IP</a> - A TCP/IP stack for
Amstrad CPCs.<br>
<li><a href="http://lng.sourceforge.net/">LUnix</a> - LUnix contains a small
TCP/IP stack.<br>
<li><a href="http://www.sweetcherrie.com/jolz64/jos/">JOS</a> - JOS includes a
TCP/IP implementation.<br>
<li><a href="http://www.csonline.net/bpaddock/tinytcp/default.htm">TinyTCP</a> - A very slim
TCP, IP, and FTP implementation.<br>
<li><a href="http://kyllikki.fluff.org/hardware/wwwpic2/">WWWpic2</a> - Small
HTTP/TCP/IP implementation for a PIC.<br>
<li><a href="http://www.rmbeales.fsnet.co.uk/files/html/picserver/picservd.htm">PIC Web Server</a> - Small HTTP/TCP/IP/SLIP PIC implementation.<br>
</ul>
Very small web servers:
<ul>
<li><a href="http://world.std.com/~fwhite/ace/">webACE</a> - World's Smallest
Web Server.<br>
<li><a href="http://www-ccs.cs.umass.edu/~shri/iPic.html">iPIC</a> - A Match
Head Sized Web Server.<br>
</ul>
Related RFCs:
<ul>
<li>J. Postel, <a
href="ftp://ftp.ietf.org/rfc/rfc791.txt">Internet Protocol</a>, RFC791, September 1981.
<li>J. Postel, <a
href="ftp://ftp.ietf.org/rfc/rfc792.txt">Internet Control Message Protocol</a>, RFC792, September 1981.
<li>J. Postel, <a
href="ftp://ftp.ietf.org/rfc/rfc768.txt">User Datagram Protocol</a>, RFC768, August 1980.
<li>J. Postel, <a
href="ftp://ftp.ietf.org/rfc/rfc793.txt">Transmission Control Protocol</a>, RFC793, September 1981.
<li>D. D. Clark, <a
href="ftp://ftp.ietf.org/rfc/rfc813.txt">Window and Acknowledgement Strategy in TCP</a>, RFC813, July 1982.
<li>D. D. Clark, <a
href="ftp://ftp.ietf.org/rfc/rfc817.txt">Modularity and Efficiency in Protocol Implementation</a>, RFC817, July 1982.
<li>R. Braden, <a
href="ftp://ftp.ietf.org/rfc/rfc1122.txt">Requirements for Internet Hosts -- Communication Layers</a>, RFC1122, October 1989.
<li>T. Mallory and A. Kullberg, <a
href="ftp://ftp.ietf.org/rfc/rfc1141.txt">Incremental Updating of the Internet Checksum</a>, RFC1141, January 1990.
<li>A. Rijsinghani, <a
href="ftp://ftp.ietf.org/rfc/rfc1624.txt">Computation of the Internet Checksum via Incremental Update</a>, RFC1624, May 1994.
<li>R. Braden, <a
href="ftp://ftp.ietf.org/rfc/rfc1337.txt">TIME-WAIT Assasination Hazards in TCP</a>, RFC1337, May 1992.
<li>B. Carpenter, <a
href="ftp://ftp.ietf.org/rfc/rfc1958.txt">Architectural Principles of the Internet</a>, RFC1958, June 1996.
<li>M. Allman, V. Paxson and W. Stevens, <a
href="ftp://ftp.ietf.org/rfc/rfc2581.txt">TCP Congestion Control</a>, RFC2581, April 1999.
<li>S. Parker and C. Schmechel, <a
href="ftp://ftp.ietf.org/rfc/rfc2398.txt">Some Testing Tools for TCP Implementors</a>, RFC2398, August 1998.
</ul>
Related publications:
<ul>
<li>V. Jacobson. Congestion avoidance and control. In <i>Proceedings of
the SIGCOMM '88 Conference</i>, Stanford, California, August 1988.
<li>V. Jacobson. 4.3BSD TCP header prediction. <i>ACM Computer
Communications Review</i>, 20(2), April 1990.
<li>P. Karn and C. Partridge. Improving round-trip time estimates
in reliablie transport protocols. In <i>Proceedings of the SIGCOMM '87
Conference</i>, Stowe, Vermont, August 1987.
<li>J. Kay and J. Pasquale. Profiling and Reducing Processing
Overheads in TCP/IP. <i>IEEE/ACM Transactions of Networking</i>, 4(6), December 1996.
<li>L. Larzon, M. Degermark, and S. Pink. UDP Lite for
real-time multimedia applications. In <i>Proceedings of the IEEE
International Conference of Communications</i>, Vancouver, British
Columbia, Canada, June 1999.
<li>P. E. McKenney and K. F. Dove. Efcient demultiplexing of
incoming TCP packets. In <i>Proceedings of the SIGCOMM '92 Conference</i>, Baltimore, Maryland, August 1992.
<li>C. Partridge and S. Pink. A faster UDP. <i>IEEE/ACM Transactions
in Networking</i>, 1(4), August 1993.
</ul>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:02 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
[Links]
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,187 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - Mailing list</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
[Mailing list]
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr>
<tr>
<td><center><h2>Mailing list</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
<p align="justify">
The lwIP mailing list is the place to discuss lwIP. All topics related
to lwIP, such as porting or using lwIP, writing device drivers or
application programs for lwIP can be discussed here.
</p>
<h3>Archives</h3>
<p align="justify">
Archives can be found <a href="maillist/">here</a>.
</p>
<h3>Subscribe</h3>
<p align="justify">
To subscribe, send a mail to <a
href="mailto:majordomo@sics.se">majordomo@sics.se</a> with the message
<pre>
subscribe lwip
</pre>
in the message body. The subject should be kept blank.
</p>
<p align="justify">
In a few minutes, you should receive a welcome message and some
information regarding the subscription, including instructions for
unsubscribing. Save those messages for future reference.
</p>
<p align="justify">
You are now an lwIP mailing list subscriber!
</p>
<h3>Post</h3>
<p align="justify">
Posting to the lwIP mailing list is a simple as sending a mail to the
address <a href="mailto:lwip@sics.se">lwip@sics.se</a>.
</p>
<h3>Unsubscribe</h3>
<p align="justify">
To subscribe, send a mail to <a
href="mailto:majordomo@sics.se">majordomo@sics.se</a> with the message
<pre>
unsubscribe lwip
</pre>
in the message body. The subject should be kept blank.
</p>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:02 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
[Mailing list]
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,225 @@
<html>
<head><title>lwIP - A Lightweight TCP/IP Stack - OS vs non-OS</title></head>
<body bgcolor="white">
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td>
<center><h1>lwIP - A Lightweight TCP/IP Stack</h1></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr>
<tr>
<td><center><h2>OS vs non-OS</h2></center>
</td></tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0"><tr>
<td width="50">
&nbsp;
</td>
<td bgcolor="white" width="540">
<h2>Using lwIP with or without an operating system</h2>
<p align="justify">
There has been a few questions about how lwIP can be used in a
standalone environment (i.e., an environment without a multi-threaded
operating system) lately. The purpose of this document is to describe
how lwIP is designed to be used with and without a multi-threaded
operating system.
</p>
<center><img src="os.png"></center>
<h3>The lwIP single-threaded core</h3>
<p align="justify">
The core of lwIP consists of the actual implementations of the IP,
ICMP, UDP, and TCP protocols, as well as the support functions such as
buffer and memory management. The core components are the only ones
that are needed when lwIP is to be run in a single-threaded (non-OS)
environment.
</p>
<p align="justify">
The core components can be viewed as a software library which has the
following interface:
</p>
<ul>
<li><tt>ip_input(pbuf, netif)</tt>: Takes an IP packet and the incoming network
interface as arguments and does the TCP/IP processing for the packet.
<li><tt>tcp_tmr()</tt>: Should be called every 100 ms. Does all TCP
timer processing such as doing retransmissions.
</ul>
<p align="justify">
Because none of the core functions ever needs to block when run in a
single-threaded environment, the <tt>sys_arch</tt> (the operating
system abstraction layer) does not need to implement locking
semaphores or mailboxes. In future versions of lwIP, the dependancy of
the <tt>sys_arch</tt> will be removed in the single-threaded case.
</p>
<p align="justify">
A simple main loop for a single-threaded system might look
like this:
</p>
<pre>
while(1) {
if(poll_driver(netif) == PACKET_READY) {
pbuf = get_packet(netif);
ip_input(pbuf, netif);
}
if(clock() - last_time == 100 * CLOCK_MS) {
tcp_tmr();
last_time = clock();
}
}
</pre>
<h3>lwIP in a multi-threaded system</h3>
<p align="justify">
lwIP is designed to be able to be run in a multi-threaded system with
applications running in concurrent threads. The model used in this
case is that all TCP/IP processing is done in a single thread. The
application thread communicate with the TCP/IP thread using the
sequential API.
</p>
<center><img src="threads.png"></center>
<p align="justify">
The inter-thread communication is implemented in the two files
<tt>api_lib.c</tt> and <tt>api_msg.c</tt>. The former contains the
functions used by the application programs and the latter implements
the TCP/IP stack interface. A third file, <tt>tcpip.c</tt>, handles
incoming packets and timer events as described in the previous
section.
</p>
<p align="justify">
When run in a multi-threaded environment, incoming packets are handled
by the function <tt>tcpip_input()</tt>, which takes the same arguments
as the <tt>ip_input()</tt> function. The difference between the two
functions is that the <tt>tcpip_input()</tt> function does not process
the incoming packet immediately. It merely puts the packet on a queue
which later is drained by the TCP/IP thread.
</p>
<p align="justify">
When being run in a multi-threaded system, timer events are taken care
of internally in <tt>tcpip.c</tt>.
</p>
<p align="right">
<font size="-1"><i>
$Date: 2002/10/19 13:00:03 $
</i></font>
</p>
</td>
<td width="50">
&nbsp;
</td>
</tr></table>
<table width="640" border="0" cellpadding="0"
cellspacing="0">
<tr><td align="center">
<hr>
<a href="index.html">Introduction</a>
|
<a href="news.html">News</a>
|
<a href="documentation.html">Documentation</a>
|
<a href="mailinglist.html">Mailing list</a>
|
<a href="changelog.html">Changelog</a>
|
<a href="download.html">Download</a>
|
<a href="links.html">Links</a>
<hr>
</td></tr><tr>
<td>
<div align="right">
<a href="http://www.sics.se/~adam/">Adam Dunkels</a></div>
</td>
</tr>
</table>
</body>
</html>

BIN
proj/unixsim/apps/fs/os.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

4188
proj/unixsim/apps/fsdata.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
/*
* 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 __FSDATA_H__
#define __FSDATA_H__
struct fsdata_file {
const struct fsdata_file *next;
const char *name;
const char *data;
const int len;
};
struct fsdata_file_noconst {
struct fsdata_file *next;
char *name;
char *data;
int len;
};
#endif /* __FSDATA_H__ */

244
proj/unixsim/apps/httpd.c Normal file
View File

@ -0,0 +1,244 @@
/*
* 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/stats.h"
#include "httpd.h"
#include "lwip/tcp.h"
#include "fs.h"
struct http_state {
char *file;
u32_t left;
u8_t retries;
};
/*-----------------------------------------------------------------------------------*/
static void
conn_err(void *arg, err_t err)
{
struct http_state *hs;
hs = arg;
mem_free(hs);
}
/*-----------------------------------------------------------------------------------*/
static void
close_conn(struct tcp_pcb *pcb, struct http_state *hs)
{
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
mem_free(hs);
tcp_close(pcb);
}
/*-----------------------------------------------------------------------------------*/
static void
send_data(struct tcp_pcb *pcb, struct http_state *hs)
{
err_t err;
u16_t len;
/* We cannot send more data than space avaliable in the send
buffer. */
if(tcp_sndbuf(pcb) < hs->left) {
len = tcp_sndbuf(pcb);
} else {
len = hs->left;
}
do {
err = tcp_write(pcb, hs->file, len, 0);
if(err == ERR_MEM) {
len /= 2;
}
} while(err == ERR_MEM && len > 1);
if(err == ERR_OK) {
hs->file += len;
hs->left -= len;
/* } else {
printf("send_data: error %s len %d %d\n", lwip_strerr(err), len, tcp_sndbuf(pcb));*/
}
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_poll(void *arg, struct tcp_pcb *pcb)
{
struct http_state *hs;
hs = arg;
/* printf("Polll\n");*/
if(hs == NULL) {
/* printf("Null, close\n");*/
tcp_abort(pcb);
return ERR_ABRT;
} else {
++hs->retries;
if(hs->retries == 4) {
tcp_abort(pcb);
return ERR_ABRT;
}
send_data(pcb, hs);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct http_state *hs;
hs = arg;
hs->retries = 0;
if(hs->left > 0) {
send_data(pcb, hs);
} else {
close_conn(pcb, hs);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
int i;
char *data;
struct fs_file file;
struct http_state *hs;
hs = arg;
if(err == ERR_OK && p != NULL) {
/* Inform TCP that we have taken the data. */
tcp_recved(pcb, p->tot_len);
if(hs->file == NULL) {
data = p->payload;
if(strncmp(data, "GET ", 4) == 0) {
for(i = 0; i < 40; i++) {
if(((char *)data + 4)[i] == ' ' ||
((char *)data + 4)[i] == '\r' ||
((char *)data + 4)[i] == '\n') {
((char *)data + 4)[i] = 0;
}
}
if(*(char *)(data + 4) == '/' &&
*(char *)(data + 5) == 0) {
fs_open("/index.html", &file);
} else if(!fs_open((char *)data + 4, &file)) {
fs_open("/404.html", &file);
}
hs->file = file.data;
hs->left = file.len;
/* printf("data %p len %ld\n", hs->file, hs->left);*/
pbuf_free(p);
send_data(pcb, hs);
/* Tell TCP that we wish be to informed of data that has been
successfully sent by a call to the http_sent() function. */
tcp_sent(pcb, http_sent);
} else {
pbuf_free(p);
close_conn(pcb, hs);
}
} else {
pbuf_free(p);
}
}
if(err == ERR_OK && p == NULL) {
close_conn(pcb, hs);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct http_state *hs;
tcp_setprio(pcb, TCP_PRIO_MIN);
/* Allocate memory for the structure that holds the state of the
connection. */
hs = mem_malloc(sizeof(struct http_state));
if(hs == NULL) {
printf("http_accept: Out of memory\n");
return ERR_MEM;
}
/* Initialize the structure. */
hs->file = NULL;
hs->left = 0;
hs->retries = 0;
/* Tell TCP that this is the structure we wish to be passed for our
callbacks. */
tcp_arg(pcb, hs);
/* Tell TCP that we wish to be informed of incoming data by a call
to the http_recv() function. */
tcp_recv(pcb, http_recv);
tcp_err(pcb, conn_err);
tcp_poll(pcb, http_poll, 4);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
httpd_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 80);
pcb = tcp_listen(pcb);
tcp_accept(pcb, http_accept);
}
/*-----------------------------------------------------------------------------------*/

37
proj/unixsim/apps/httpd.h Normal file
View File

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

View File

@ -0,0 +1,97 @@
#!/usr/bin/perl
open(OUTPUT, "> fsdata.c");
chdir("fs");
open(FILES, "find . -type f |");
while($file = <FILES>) {
# Do not include files in CVS directories nor backup files.
if($file =~ /(CVS|~)/) {
next;
}
chop($file);
open(HEADER, "> /tmp/header") || die $!;
if($file =~ /404/) {
print(HEADER "HTTP/1.0 404 File not found\r\n");
} else {
print(HEADER "HTTP/1.0 200 OK\r\n");
}
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
if($file =~ /\.html$/) {
print(HEADER "Content-type: text/html\r\n");
} elsif($file =~ /\.gif$/) {
print(HEADER "Content-type: image/gif\r\n");
} elsif($file =~ /\.png$/) {
print(HEADER "Content-type: image/png\r\n");
} elsif($file =~ /\.jpg$/) {
print(HEADER "Content-type: image/jpeg\r\n");
} elsif($file =~ /\.class$/) {
print(HEADER "Content-type: application/octet-stream\r\n");
} elsif($file =~ /\.ram$/) {
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
} else {
print(HEADER "Content-type: text/plain\r\n");
}
print(HEADER "\r\n");
close(HEADER);
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
system("cat /tmp/header $file > /tmp/file");
} else {
system("cp $file /tmp/file");
}
open(FILE, "/tmp/file");
unlink("/tmp/file");
unlink("/tmp/header");
$file =~ s/\.//;
$fvar = $file;
$fvar =~ s-/-_-g;
$fvar =~ s-\.-_-g;
print(OUTPUT "static const char data".$fvar."[] = {\n");
print(OUTPUT "\t/* $file */\n\t");
for($j = 0; $j < length($file); $j++) {
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
}
printf(OUTPUT "0,\n");
$i = 0;
while(read(FILE, $data, 1)) {
if($i == 0) {
print(OUTPUT "\t");
}
printf(OUTPUT "%#02x, ", unpack("C", $data));
$i++;
if($i == 10) {
print(OUTPUT "\n");
$i = 0;
}
}
print(OUTPUT "};\n\n");
close(FILE);
push(@fvars, $fvar);
push(@files, $file);
}
for($i = 0; $i < @fvars; $i++) {
$file = $files[$i];
$fvar = $fvars[$i];
if($i == 0) {
$prevfile = "NULL";
} else {
$prevfile = "file" . $fvars[$i - 1];
}
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
}
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define FS_NUMFILES $i");

1056
proj/unixsim/apps/shell.c Normal file

File diff suppressed because it is too large Load Diff

37
proj/unixsim/apps/shell.h Normal file
View File

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

View File

@ -0,0 +1,88 @@
/*
* 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/sys.h"
#include "lwip/api.h"
/*-----------------------------------------------------------------------------------*/
static void
tcpecho_thread(void *arg)
{
struct netconn *conn, *newconn;
err_t err;
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
/* Bind connection to well known port number 7. */
netconn_bind(conn, NULL, 7);
/* Tell connection to go into listening mode. */
netconn_listen(conn);
while(1) {
/* Grab new connection. */
newconn = netconn_accept(conn);
/*printf("accepted new connection %p\n", newconn);*/
/* Process the new connection. */
if(newconn != NULL) {
struct netbuf *buf;
void *data;
u16_t len;
while((buf = netconn_recv(newconn)) != NULL) {
/*printf("Recved\n");*/
do {
netbuf_data(buf, &data, &len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK) {
/* printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err));*/
}
} while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
/*printf("Got EOF, looping\n");*/
/* Close connection and discard connection identifier. */
netconn_delete(newconn);
}
}
}
/*-----------------------------------------------------------------------------------*/
void
tcpecho_init(void)
{
sys_thread_new(tcpecho_thread, NULL);
}
/*-----------------------------------------------------------------------------------*/

View File

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

View File

@ -0,0 +1,65 @@
/*
* 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/api.h"
#include "lwip/sys.h"
/*-----------------------------------------------------------------------------------*/
void
udpecho_thread(void *arg)
{
static struct netconn *conn;
static struct netbuf *buf;
static struct ip_addr *addr;
static unsigned short port;
char buffer[4096];
conn = netconn_new(NETCONN_UDP);
netconn_bind(conn, NULL, 7);
while(1) {
buf = netconn_recv(conn);
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
netconn_connect(conn, addr, port);
netconn_send(conn, buf);
netbuf_copy(buf, buffer, sizeof(buffer));
printf("got %s\n", buffer);
netbuf_delete(buf);
}
}
/*-----------------------------------------------------------------------------------*/
void
udpecho_init(void)
{
sys_thread_new(udpecho_thread, NULL);
}

View File

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

171
proj/unixsim/lwipopts.h Normal file
View File

@ -0,0 +1,171 @@
/*
* 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 __LWIPOPTS_H__
#define __LWIPOPTS_H__
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 1
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 1600
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 16
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 4
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 5
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 16
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 3
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 2
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 4
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#define MEMP_NUM_API_MSG 8
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG 8
/* These two control is reclaimer functions should be compiled
in. Should always be turned on (1). */
#define MEM_RECLAIM 1
#define MEMP_RECLAIM 1
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 6
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 128
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 16
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 128
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 256
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
/* TCP receive window. */
#define TCP_WND 1024
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* ---------- ARP options ---------- */
#define ARP_TABLE_SIZE 10
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 1
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS 1
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK 1
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define UDP_TTL 255
/* ---------- Statistics options ---------- */
#define STATS
#ifdef STATS
#define LINK_STATS
#define IP_STATS
#define ICMP_STATS
#define UDP_STATS
#define TCP_STATS
#define MEM_STATS
#define MEMP_STATS
#define PBUF_STATS
#define SYS_STATS
#endif /* STATS */
#endif /* __LWIPOPTS_H__ */

189
proj/unixsim/simhost.c Normal file
View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/debug.h"
#include <unistd.h>
#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "netif/tapif.h"
#include "netif/tunif.h"
#include "netif/unixif.h"
#include "netif/dropif.h"
#include "netif/pcapif.h"
#include "netif/loopif.h"
#include "netif/tcpdump.h"
#include "lwip/ip_addr.h"
#include "arch/perf.h"
#include "httpd.h"
#include "udpecho.h"
#include "tcpecho.h"
#include "shell.h"
/*-----------------------------------------------------------------------------------*/
static void
tcp_timeout(void *data)
{
#if TCP_DEBUG
tcp_debug_print_pcbs();
#endif /* TCP_DEBUG */
sys_timeout(5000, tcp_timeout, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
tcpip_init_done(void *arg)
{
sys_sem_t *sem;
sem = arg;
sys_sem_signal(*sem);
}
/*-----------------------------------------------------------------------------------*/
static void
main_thread(void *arg)
{
struct ip_addr ipaddr, netmask, gw;
sys_sem_t sem;
netif_init();
sem = sys_sem_new(0);
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(sem);
sys_sem_free(sem);
printf("TCP/IP initialized.\n");
#if LWIP_DHCP
{
struct netif *netif;
IP4_ADDR(&gw, 0,0,0,0);
IP4_ADDR(&ipaddr, 0,0,0,0);
IP4_ADDR(&netmask, 0,0,0,0);
netif = netif_add(&ipaddr, &netmask, &gw, tapif_init,
tcpip_input);
netif_set_default(netif);
dhcp_init();
dhcp_start(netif);
}
#else
IP4_ADDR(&gw, 192,168,0,1);
IP4_ADDR(&ipaddr, 192,168,0,2);
IP4_ADDR(&netmask, 255,255,255,0);
/* netif_set_default(netif_add(&ipaddr, &netmask, &gw, tapif_init,
tcpip_input));*/
netif_set_default(netif_add(&ipaddr, &netmask, &gw, tapif_init,
tcpip_input));
#endif
/* Only used for testing purposes: */
/* IP4_ADDR(&gw, 193,10,66,1);
IP4_ADDR(&ipaddr, 193,10,66,107);
IP4_ADDR(&netmask, 255,255,252,0);
netif_add(&ipaddr, &netmask, &gw, pcapif_init,
tcpip_input);*/
IP4_ADDR(&gw, 127,0,0,1);
IP4_ADDR(&ipaddr, 127,0,0,1);
IP4_ADDR(&netmask, 255,0,0,0);
netif_add(&ipaddr, &netmask, &gw, loopif_init,
tcpip_input);
tcpecho_init();
shell_init();
httpd_init();
udpecho_init();
printf("Applications started.\n");
/* sys_timeout(5000, tcp_timeout, NULL);*/
#ifdef MEM_PERF
mem_perf_init("/tmp/memstats.client");
#endif /* MEM_PERF */
/* Block for ever. */
sem = sys_sem_new(0);
sys_sem_wait(sem);
}
/*-----------------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
#ifdef PERF
perf_init("/tmp/simhost.perf");
#endif /* PERF */
#ifdef STATS
stats_init();
#endif /* STATS */
sys_init();
mem_init();
memp_init();
pbuf_init();
tcpdump_init();
printf("System initialized.\n");
sys_thread_new((void *)(main_thread), NULL);
pause();
return 0;
}
/*-----------------------------------------------------------------------------------*/

157
proj/unixsim/simnode.c Normal file
View File

@ -0,0 +1,157 @@
/*
* 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 <unistd.h>
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "netif/unixif.h"
#include "netif/dropif.h"
#include "netif/loopif.h"
#include "netif/tcpdump.h"
#include "netif/sioslipif.h"
#include "lwip/ip_addr.h"
#include "arch/perf.h"
#include "httpd.h"
#include "udpecho.h"
#include "tcpecho.h"
#include "shell.h"
/*-----------------------------------------------------------------------------------*/
static void
tcp_timeout(void *data)
{
#if TCP_DEBUG
tcp_debug_print_pcbs();
#endif /* TCP_DEBUG */
sys_timeout(5000, tcp_timeout, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
tcpip_init_done(void *arg)
{
sys_sem_t *sem;
sem = arg;
sys_sem_signal(*sem);
}
/*-----------------------------------------------------------------------------------*/
static void
main_thread(void *arg)
{
struct ip_addr ipaddr, netmask, gw;
sys_sem_t sem;
IP4_ADDR(&gw, 192,168,1,1);
IP4_ADDR(&ipaddr, 192,168,1,2);
IP4_ADDR(&netmask, 255,255,255,0);
netif_set_default(netif_add(&ipaddr, &netmask, &gw, unixif_init_client,
tcpip_input));
/* netif_set_default(netif_add(&ipaddr, &netmask, &gw, sioslipif_init1,
tcpip_input)); */
sem = sys_sem_new(0);
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(sem);
sys_sem_free(sem);
printf("TCP/IP initialized.\n");
tcpecho_init();
shell_init();
httpd_init();
udpecho_init();
printf("Applications started.\n");
sys_timeout(5000, tcp_timeout, NULL);
#ifdef MEM_PERF
mem_perf_init("/tmp/memstats.client");
#endif /* MEM_PERF */
sem = sys_sem_new(0);
sys_sem_wait(sem);
}
/*-----------------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
#ifdef PERF
perf_init("/tmp/client.perf");
#endif /* PERF */
#ifdef STATS
stats_init();
#endif /* STATS */
sys_init();
mem_init();
memp_init();
pbuf_init();
tcpdump_init();
printf("System initialized.\n");
sys_thread_new((void *)(main_thread), NULL);
pause();
return 0;
}
/*-----------------------------------------------------------------------------------*/

167
proj/unixsim/simrouter.c Normal file
View File

@ -0,0 +1,167 @@
/*
* 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 <unistd.h>
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "netif/tapif.h"
#include "netif/unixif.h"
#include "netif/dropif.h"
#include "netif/loopif.h"
#include "netif/tcpdump.h"
#include "netif/sioslipif.h"
#include "lwip/ip_addr.h"
#include "arch/perf.h"
#include "httpd.h"
#include "udpecho.h"
#include "tcpecho.h"
#include "shell.h"
/*-----------------------------------------------------------------------------------*/
static void
tcp_timeout(void *data)
{
#if TCP_DEBUG
tcp_debug_print_pcbs();
#endif /* TCP_DEBUG */
sys_timeout(5000, tcp_timeout, NULL);
}
/*-----------------------------------------------------------------------------------*/
static void
tcpip_init_done(void *arg)
{
sys_sem_t *sem;
sem = arg;
sys_sem_signal(*sem);
}
/*-----------------------------------------------------------------------------------*/
static void
main_thread(void *arg)
{
struct ip_addr ipaddr, netmask, gw;
sys_sem_t sem;
IP4_ADDR(&gw, 192,168,0,1);
IP4_ADDR(&ipaddr, 192,168,0,2);
IP4_ADDR(&netmask, 255,255,255,0);
netif_set_default(netif_add(&ipaddr, &netmask, &gw, tapif_init,
tcpip_input));
IP4_ADDR(&gw, 192,168,1,1);
IP4_ADDR(&ipaddr, 192,168,1,1);
IP4_ADDR(&netmask, 255,255,255,0);
netif_set_default(netif_add(&ipaddr, &netmask, &gw, unixif_init_server,
tcpip_input));
system("route add 192.168.1.1 192.168.0.2");
system("route add 192.168.1.2 192.168.0.2");
/*netif_set_default(netif_add(&ipaddr, &netmask, &gw, sioslipif_init1,
tcpip_input)); */
sem = sys_sem_new(0);
tcpip_init(tcpip_init_done, &sem);
sys_sem_wait(sem);
sys_sem_free(sem);
printf("TCP/IP initialized.\n");
tcpecho_init();
shell_init();
httpd_init();
udpecho_init();
printf("Applications started.\n");
sys_timeout(5000, tcp_timeout, NULL);
#ifdef MEM_PERF
mem_perf_init("/tmp/memstats.client");
#endif /* MEM_PERF */
sem = sys_sem_new(0);
sys_sem_wait(sem);
}
/*-----------------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
#ifdef PERF
perf_init("/tmp/client.perf");
#endif /* PERF */
#ifdef STATS
stats_init();
#endif /* STATS */
sys_init();
mem_init();
memp_init();
pbuf_init();
tcpdump_init();
printf("System initialized.\n");
sys_thread_new((void *)(main_thread), NULL);
pause();
return 0;
}
/*-----------------------------------------------------------------------------------*/

13
src/FILES Normal file
View File

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

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

15
src/arch/FILES Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

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

View File

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

View File

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

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

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

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

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

View File

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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