LwIP 2.2.1在STM32F407VET6平台 移植

This commit is contained in:
冯佳
2026-01-29 17:26:04 +08:00
parent ffd33c4644
commit e7e10a8328
2207 changed files with 409723 additions and 165 deletions

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>
#
# Architecture specific files.
LWIPARCH?=$(CONTRIBDIR)/ports/unix/port
SYSARCH?=$(LWIPARCH)/sys_arch.c
ARCHFILES=$(LWIPARCH)/perf.c \
$(SYSARCH) \
$(LWIPARCH)/netif/tapif.c \
$(LWIPARCH)/netif/list.c \
$(LWIPARCH)/netif/sio.c \
$(LWIPARCH)/netif/fifo.c
UNIX_COMMON_MK_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(UNIX_COMMON_MK_DIR)../Common.allports.mk
LDFLAGS+=-lutil
UNAME_S:= $(shell uname -s)
ifneq ($(UNAME_S),Darwin)
# Darwin doesn't have pthreads or POSIX real-time extensions libs
LDFLAGS+=-pthread -lrt
endif

View File

@ -0,0 +1,44 @@
# This file is indended to be included in end-user CMakeLists.txt
# include(/path/to/Filelists.cmake)
# It assumes the variable LWIP_CONTRIB_DIR is defined pointing to the
# root path of lwIP/contrib sources.
#
# This file is NOT designed (on purpose) to be used as cmake
# subdir via add_subdirectory()
# The intention is to provide greater flexibility to users to
# create their own targets using the *_SRCS variables.
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
include_guard(GLOBAL)
endif()
set(lwipcontribportunix_SRCS
${LWIP_CONTRIB_DIR}/ports/unix/port/sys_arch.c
${LWIP_CONTRIB_DIR}/ports/unix/port/perf.c
)
set(lwipcontribportunixnetifs_SRCS
${LWIP_CONTRIB_DIR}/ports/unix/port/netif/tapif.c
${LWIP_CONTRIB_DIR}/ports/unix/port/netif/list.c
${LWIP_CONTRIB_DIR}/ports/unix/port/netif/sio.c
${LWIP_CONTRIB_DIR}/ports/unix/port/netif/fifo.c
)
add_library(lwipcontribportunix EXCLUDE_FROM_ALL ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
target_include_directories(lwipcontribportunix PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
target_compile_options(lwipcontribportunix PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwipcontribportunix PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_link_libraries(lwipcontribportunix PUBLIC ${LWIP_MBEDTLS_LINK_LIBRARIES})
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_library(LIBUTIL util)
find_library(LIBPTHREAD pthread)
find_library(LIBRT rt)
target_link_libraries(lwipcontribportunix PUBLIC ${LIBUTIL} ${LIBPTHREAD} ${LIBRT})
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# Darwin doesn't have pthreads or POSIX real-time extensions libs
find_library(LIBUTIL util)
target_link_libraries(lwipcontribportunix PUBLIC ${LIBUTIL})
endif()

View File

@ -0,0 +1,25 @@
This port contains infrastructure and examples for running lwIP on Unix-like
operating systems (Linux, OpenBSD, cygwin). Much of this is targeted towards
testing lwIP applications.
* port/sys_arch.c, port/perf.c, port/include/arch/: Generic platform porting,
for both states of NO_SYS. (Mapping debugging to printf, providing
sys_now & co from the system time etc.)
* check: Runs the unit tests shipped with main lwIP on the Unix port.
* port/netif, port/include/netif: Various network interface implementations and
their helpers, some explicitly for Unix infrastructure, some generic (but most
useful on an easy to debug system):
* fifo: Helper for sio
* list: Helper for unixif
* pcapif: Network interface that replays packages from a PCAP dump file, and
discards packages sent out from it
* sio: Mapping Unix character devices to lwIP's sio mechanisms
* tapif: Network interface that is mapped to a tap interface (Unix user
space layer 2 network device). Uses lwIP threads.

View File

@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 3.8)
set (CMAKE_CONFIGURATION_TYPES "Debug;Release")
project(lwipunittests C)
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
message(FATAL_ERROR "Unit test are currently only working on Linux, Darwin or Hurd")
endif()
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
if (NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
set(LWIP_USE_SANITIZERS true)
endif()
include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
list(LWIP_COMPILER_FLAGS APPEND -Wno-gnu-zero-variadic-macro-arguments)
endif()
set (LWIP_DEFINITIONS -DLWIP_DEBUG -DLWIP_NOASSERT_ON_ERROR)
set (LWIP_INCLUDE_DIRS
"${LWIP_DIR}/test/unit"
"${LWIP_DIR}/src/include"
"${LWIP_CONTRIB_DIR}/"
"${LWIP_CONTRIB_DIR}/ports/unix/port/include"
"${CMAKE_CURRENT_SOURCE_DIR}/"
)
include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
include(${LWIP_DIR}/src/Filelists.cmake)
include(${LWIP_DIR}/test/unit/Filelists.cmake)
add_executable(lwip_unittests ${LWIP_TESTFILES})
target_include_directories(lwip_unittests PRIVATE ${LWIP_INCLUDE_DIRS})
target_compile_options(lwip_unittests PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwip_unittests PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
find_library(LIBCHECK check)
find_library(LIBM m)
target_link_libraries(lwip_unittests ${LWIP_SANITIZER_LIBS} lwipallapps lwipcore ${LIBCHECK} ${LIBM})
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
find_library(LIBSUBUNIT subunit)
target_link_libraries(lwip_unittests ${LIBSUBUNIT})
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "GNU")
find_library(LIBUTIL util)
find_library(LIBPTHREAD pthread)
find_library(LIBRT rt)
target_link_libraries(lwip_unittests ${LIBUTIL} ${LIBPTHREAD} ${LIBRT})
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# Darwin doesn't have pthreads or POSIX real-time extensions libs
find_library(LIBUTIL util)
target_link_libraries(lwip_unittests ${LIBUTIL})
endif()

View File

@ -0,0 +1,94 @@
#
# 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>
#
all compile: lwip_unittests
.PHONY: all clean check
LWIPDIR=../../../../src
# The include path to sys_arch.h and lwipopts.h must be first, so this must be before Common.mk
CFLAGS=-DLWIP_NOASSERT_ON_ERROR -I/usr/include/check -I$(LWIPDIR)/../test/unit
# Ignore 'too many arguments for format' warnings which happen with GCCs
# from check 0.15.2 on fail_if/fail_unless macros with text.
# See https://github.com/libcheck/check/pull/298/commits/82540c5428d3818b64d
CFLAGS+=-Wno-error=format-extra-args
ifeq (clang,$(findstring clang,$(CC)))
# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
CFLAGS+=-Wno-gnu-zero-variadic-macro-arguments
endif
# Prevent compiling sys_arch.c of unix port because unit test provide their own port
SYSARCH?=
include ../Common.mk
LDFLAGS:=-lcheck -lm $(LDFLAGS)
ifneq ($(UNAME_S),Darwin)
# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
LDFLAGS+=-lsubunit
endif
TESTDIR=$(LWIPDIR)/../test/unit
include $(TESTDIR)/Filelists.mk
TESTOBJS=$(notdir $(TESTFILES:.c=.o))
DEPFILES=.depend_test .depend_lwip .depend_app
clean:
@rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) lwip_unittests *.s $(DEPFILES) *.core core lwip_unittests.xml
depend dep: $(DEPFILES)
@true
ifneq ($(MAKECMDGOALS),clean)
include $(DEPFILES)
endif
.depend_test: $(TESTFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend_test || rm -f .depend_test
.depend_lwip: $(LWIPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend_lwip || rm -f .depend_lwip
.depend_app: $(APPFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend_app || rm -f .depend_app
ifneq ($(UNAME_S),Darwin)
# clang on Darwin doesn't support --start-group
lwip_unittests: $(DEPFILES) $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB)
$(CC) $(CFLAGS) -o lwip_unittests $(TESTOBJS) -Wl,--start-group $(LWIPLIBCOMMON) $(APPLIB) $(LDFLAGS) -Wl,--end-group
else
lwip_unittests: $(DEPFILES) $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB)
$(CC) $(CFLAGS) -o lwip_unittests $(TESTOBJS) $(LWIPLIBCOMMON) $(APPLIB) $(LDFLAGS)
endif
check: lwip_unittests
@./lwip_unittests

View File

@ -0,0 +1,8 @@
Helper files to run lwIP unit tests on unix-like systems.
1. Install the check library, through a package manager or from https://libcheck.github.io/check/
2. Put the lwip code in a directory called 'lwip'
3. Run `make check`
4. Make sure all tests pass

View File

@ -0,0 +1,2 @@
/* Enable this to simplify debugging */
/* #define LWIP_UNITTESTS_NOFORK */

View File

@ -0,0 +1,27 @@
include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
set (LWIP_INCLUDE_DIRS
"${LWIP_DIR}/src/include"
"${LWIP_DIR}/contrib/"
"${LWIP_DIR}/contrib/ports/unix/port/include"
"${LWIP_DIR}/contrib/examples/example_app"
)
include(${LWIP_DIR}/src/Filelists.cmake)
include(${LWIP_DIR}/contrib/Filelists.cmake)
include(${LWIP_DIR}/contrib/ports/unix/Filelists.cmake)
if(NOT EXISTS ${LWIP_DIR}/contrib/examples/example_app/lwipcfg.h)
message(WARNING "${LWIP_DIR}/contrib/examples/example_app is missing lwipcfg.h
Copy ${LWIP_DIR}/contrib/examples/example_app/lwipcfg.h.example to ${LWIP_DIR}/contrib/examples/example_app/lwipcfg.h and edit appropriately")
endif()
add_executable(example_app ${LWIP_DIR}/contrib/examples/example_app/test.c default_netif.c)
target_include_directories(example_app PRIVATE ${LWIP_INCLUDE_DIRS})
target_compile_options(example_app PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(example_app PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_link_libraries(example_app ${LWIP_SANITIZER_LIBS} lwipcontribexamples lwipcontribapps lwipcontribaddons lwipallapps lwipcontribportunix lwipcore lwipmbedtls)
add_executable(makefsdata ${lwipmakefsdata_SRCS})
target_compile_options(makefsdata PRIVATE ${LWIP_COMPILER_FLAGS})
target_include_directories(makefsdata PRIVATE ${LWIP_INCLUDE_DIRS})
target_link_libraries(makefsdata ${LWIP_SANITIZER_LIBS})

View File

@ -0,0 +1,60 @@
#
# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# This file is part of the lwIP TCP/IP stack.
#
# Author: Adam Dunkels <adam@sics.se>
#
all compile: example_app makefsdata
.PHONY: all
LWIPDIR=../../../../src
include ../Common.mk
CFLAGS+=-I$(CONTRIBDIR)/examples/example_app
TESTFLAGS?=
CFLAGS+=$(TESTFLAGS)
MAKEFSDATAOBJS=$(notdir $(MAKEFSDATAFILES:.c=.o))
clean:
rm -f *.o $(LWIPLIBCOMMON) $(APPLIB) example_app makefsdata *.s .depend* *.core core
depend dep: .depend
include .depend
.depend: $(CONTRIBDIR)/examples/example_app/test.c default_netif.c $(LWIPFILES) $(APPFILES) $(MAKEFSDATAFILES)
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
example_app: .depend $(LWIPLIBCOMMON) $(APPLIB) default_netif.o test.o
$(CC) $(CFLAGS) -o example_app test.o default_netif.o -Wl,--start-group $(APPLIB) $(LWIPLIBCOMMON) -Wl,--end-group $(LDFLAGS)
makefsdata: .depend $(MAKEFSDATAOBJS)
$(CC) $(CFLAGS) -o makefsdata $(MAKEFSDATAOBJS)

View File

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

View File

@ -0,0 +1,34 @@
#!/bin/bash
LOGFILE=iteropts.log
EXAPPDIR=../../../examples/example_app
RETVAL=0
pushd `dirname "$0"`
pwd
echo Starting Iteropts run >> $LOGFILE
for f in $EXAPPDIR/test_configs/*.h
do
echo Cleaning...
make clean > /dev/null
BUILDLOG=$(basename "$f" ".h").log
echo testing $f
echo testing $f >> $LOGFILE
rm -f $EXAPPDIR/lwipopts_test.h
# cat the file to update its timestamp
cat $f > $EXAPPDIR/lwipopts_test.h
make TESTFLAGS="-DLWIP_OPTTEST_FILE -Wno-documentation" -j 4 1> $BUILDLOG 2>&1
ERR=$?
if [ $ERR != 0 ]; then
cat $BUILDLOG
echo file $f failed with $ERR >> $LOGFILE
echo ++++++++ $f FAILED +++++++
RETVAL=1
fi
echo test $f done >> $LOGFILE
done
echo done, cleaning
make clean > /dev/null
popd
echo Exit value: $RETVAL
exit $RETVAL

View File

@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.8)
project(lwip C)
set (BUILD_SHARED_LIBS ON)
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT CMAKE_SYSTEM_NAME STREQUAL "GNU")
message(FATAL_ERROR "Lwip shared library is only working on Linux or the Hurd")
endif()
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
set (LWIP_DEFINITIONS -DLWIP_DEBUG)
set (LWIP_INCLUDE_DIRS
"${LWIP_DIR}/src/include"
"${LWIP_CONTRIB_DIR}/"
"${LWIP_CONTRIB_DIR}/ports/unix/port/include"
"${CMAKE_CURRENT_SOURCE_DIR}/"
)
set (LWIP_EXCLUDE_SLIPIF TRUE)
include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
include(${LWIP_DIR}/src/Filelists.cmake)
add_library(lwip ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
target_compile_options(lwip PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwip PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_include_directories(lwip PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
target_link_libraries(lwip ${LWIP_SANITIZER_LIBS})
find_library(LIBPTHREAD pthread)
target_link_libraries(lwip ${LIBPTHREAD})

View File

@ -0,0 +1,28 @@
This directory contains an example of how to compile lwIP as a shared library
on Linux.
Some brief instructions:
* Compile the code:
> mkdir build
> cd build
> cmake ..
> make clean all
This should produce liblwip.so. This is the shared library.
* Link an application against the shared library
If you're using gcc you can do this by including -llwip in your link command.
* Run your application
Ensure that LD_LIBRARY_PATH includes the directory that contains liblwip.so
(ie. this directory)
If you are unsure about shared libraries and libraries on linux in
general, you might find this HOWTO useful:
<http://www.tldp.org/HOWTO/Program-Library-HOWTO/>

View File

@ -0,0 +1,435 @@
/**
* @file
*
* lwIP Options Configuration
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_LWIPOPTS_H
#define LWIP_LWIPOPTS_H
/*
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you don't like!
*/
#include "lwipopts.h"
#include "lwip/debug.h"
/*
-----------------------------------------------
---------- Platform specific locking ----------
-----------------------------------------------
*/
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 0
/**
* NO_SYS==1: Provides VERY minimal functionality. Otherwise,
* use lwIP facilities.
*/
#define NO_SYS 0
/*
------------------------------------
---------- Memory options ----------
------------------------------------
*/
/**
* MEM_ALIGNMENT: should be set to the alignment of the CPU
* 4 byte alignment -> #define MEM_ALIGNMENT 4
* 2 byte alignment -> #define MEM_ALIGNMENT 2
*/
#define MEM_ALIGNMENT 1U
/**
* MEM_SIZE: the size of the heap memory. If the application will send
* a lot of data that needs to be copied, this should be set high.
*/
#define MEM_SIZE 1600
/*
------------------------------------------------
---------- Internal Memory Pool Sizes ----------
------------------------------------------------
*/
/**
* MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF).
* If the application sends a lot of data out of ROM (or other static memory),
* this should be set high.
*/
#define MEMP_NUM_PBUF 16
/**
* MEMP_NUM_RAW_PCB: Number of raw connection PCBs
* (requires the LWIP_RAW option)
*/
#define MEMP_NUM_RAW_PCB 4
/**
* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
* per active UDP "connection".
* (requires the LWIP_UDP option)
*/
#define MEMP_NUM_UDP_PCB 4
/**
* MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections.
* (requires the LWIP_TCP option)
*/
#define MEMP_NUM_TCP_PCB 4
/**
* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections.
* (requires the LWIP_TCP option)
*/
#define MEMP_NUM_TCP_PCB_LISTEN 4
/**
* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments.
* (requires the LWIP_TCP option)
*/
#define MEMP_NUM_TCP_SEG 16
/**
* MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for
* reassembly (whole packets, not fragments!)
*/
#define MEMP_NUM_REASSDATA 1
/**
* MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing
* packets (pbufs) that are waiting for an ARP request (to resolve
* their destination address) to finish.
* (requires the ARP_QUEUEING option)
*/
#define MEMP_NUM_ARP_QUEUE 2
/**
* MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts.
* (requires NO_SYS==0)
*/
#define MEMP_NUM_SYS_TIMEOUT 8
/**
* MEMP_NUM_NETBUF: the number of struct netbufs.
* (only needed if you use the sequential API, like api_lib.c)
*/
#define MEMP_NUM_NETBUF 2
/**
* MEMP_NUM_NETCONN: the number of struct netconns.
* (only needed if you use the sequential API, like api_lib.c)
*/
#define MEMP_NUM_NETCONN 32
/**
* MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used
* for callback/timeout API communication.
* (only needed if you use tcpip.c)
*/
#define MEMP_NUM_TCPIP_MSG_API 8
/**
* MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used
* for incoming packets.
* (only needed if you use tcpip.c)
*/
#define MEMP_NUM_TCPIP_MSG_INPKT 8
/**
* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
*/
#define PBUF_POOL_SIZE 8
/*
---------------------------------
---------- ARP options ----------
---------------------------------
*/
/**
* LWIP_ARP==1: Enable ARP functionality.
*/
#define LWIP_ARP 1
/*
--------------------------------
---------- IP options ----------
--------------------------------
*/
/**
* IP_FORWARD==1: Enables the ability to forward IP packets across network
* interfaces. If you are going to run lwIP on a device with only one network
* interface, define this to 0.
*/
#define IP_FORWARD 0
/**
* IP_OPTIONS: Defines the behavior for IP options.
* IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped.
* IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed).
*/
#define IP_OPTIONS_ALLOWED 1
/**
* IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
* this option does not affect outgoing packet sizes, which can be controlled
* via IP_FRAG.
*/
#define IP_REASSEMBLY 1
/**
* IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#define IP_FRAG 1
/**
* IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
* a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived
* in this time, the whole packet is discarded.
*/
#define IP_REASS_MAXAGE 3
/**
* IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.
* Since the received pbufs are enqueued, be sure to configure
* PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive
* packets even if the maximum amount of fragments is enqueued for reassembly!
*/
#define IP_REASS_MAX_PBUFS 4
/**
* IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP
* fragmentation. Otherwise pbufs are allocated and reference the original
* packet data to be fragmented.
*/
#define IP_FRAG_USES_STATIC_BUF 0
/**
* IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers.
*/
#define IP_DEFAULT_TTL 255
/*
----------------------------------
---------- ICMP options ----------
----------------------------------
*/
/**
* LWIP_ICMP==1: Enable ICMP module inside the IP stack.
* Be careful, disable that make your product non-compliant to RFC1122
*/
#define LWIP_ICMP 1
/*
---------------------------------
---------- RAW options ----------
---------------------------------
*/
/**
* LWIP_RAW==1: Enable application layer to hook into the IP layer itself.
*/
#define LWIP_RAW 1
/*
----------------------------------
---------- DHCP options ----------
----------------------------------
*/
/**
* LWIP_DHCP==1: Enable DHCP module.
*/
#define LWIP_DHCP 0
/*
------------------------------------
---------- AUTOIP options ----------
------------------------------------
*/
/**
* LWIP_AUTOIP==1: Enable AUTOIP module.
*/
#define LWIP_AUTOIP 0
/*
----------------------------------
---------- SNMP options ----------
----------------------------------
*/
/**
* LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP
* transport.
*/
#define LWIP_SNMP 0
/*
----------------------------------
---------- IGMP options ----------
----------------------------------
*/
/**
* LWIP_IGMP==1: Turn on IGMP module.
*/
#define LWIP_IGMP 0
/*
----------------------------------
---------- DNS options -----------
----------------------------------
*/
/**
* LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
* transport.
*/
#define LWIP_DNS 0
/*
---------------------------------
---------- UDP options ----------
---------------------------------
*/
/**
* LWIP_UDP==1: Turn on UDP.
*/
#define LWIP_UDP 1
/*
---------------------------------
---------- TCP options ----------
---------------------------------
*/
/**
* LWIP_TCP==1: Turn on TCP.
*/
#define LWIP_TCP 1
#define TCP_LISTEN_BACKLOG 0
/*
----------------------------------
---------- Pbuf options ----------
----------------------------------
*/
/**
* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
* link level header. The default is 14, the standard value for
* Ethernet.
*/
#define PBUF_LINK_HLEN 16
/**
* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is
* designed to accommodate single full size TCP frame in one pbuf, including
* TCP_MSS, IP header, and link header.
*/
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
/*
------------------------------------
---------- LOOPIF options ----------
------------------------------------
*/
/**
* LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c
*/
#define LWIP_HAVE_LOOPIF 0
/*
----------------------------------------------
---------- Sequential layer options ----------
----------------------------------------------
*/
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN 1
/*
------------------------------------
---------- Socket options ----------
------------------------------------
*/
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1
/**
* SO_REUSE==1: Enable SO_REUSEADDR
*/
#define SO_REUSE 1
/*
----------------------------------------
---------- Statistics options ----------
----------------------------------------
*/
/**
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
*/
#define LWIP_STATS 0
/*
---------------------------------
---------- PPP options ----------
---------------------------------
*/
/**
* PPP_SUPPORT==1: Enable PPP.
*/
#define PPP_SUPPORT 0
/*
---------------------------------------
---------- Threading options ----------
---------------------------------------
*/
#define LWIP_TCPIP_CORE_LOCKING 1
#if !NO_SYS
void sys_check_core_locking(void);
#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
#endif
#endif /* LWIP_LWIPOPTS_H */

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H
/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
#if defined __ANDROID__
#define LWIP_UNIX_ANDROID
#elif defined __linux__
#define LWIP_UNIX_LINUX
#elif defined __APPLE__
#define LWIP_UNIX_MACH
#elif defined __OpenBSD__
#define LWIP_UNIX_OPENBSD
#elif defined __FreeBSD__
#define LWIP_UNIX_FREEBSD
#elif defined __FreeBSD_kernel__ && __GLIBC__
#define LWIP_UNIX_KFREEBSD
#elif defined __CYGWIN__
#define LWIP_UNIX_CYGWIN
#elif defined __GNU__
#define LWIP_UNIX_HURD
#endif
#define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LWIP_ERRNO_INCLUDE <errno.h>
#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) || defined(LWIP_UNIX_KFREEBSD)
#define LWIP_ERRNO_STDINCLUDE 1
#endif
extern unsigned int lwip_port_rand(void);
#define LWIP_RAND() (lwip_port_rand())
/* different handling for unit test, normally not needed */
#ifdef LWIP_NOASSERT_ON_ERROR
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
handler;}} while(0)
#endif
#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET)
typedef __kernel_fd_set fd_set;
#endif
#if defined(LWIP_UNIX_MACH)
/* sys/types.h and signal.h bring in Darwin byte order macros. pull the
header here and disable LwIP's version so that apps still can get
the macros via LwIP headers and use system headers */
#include <sys/types.h>
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#endif
struct sio_status_s;
typedef struct sio_status_s sio_status_t;
#define sio_fd_t sio_status_t*
#define __sio_fd_t_defined
typedef unsigned int sys_prot_t;
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ARCH_CC_H */

View File

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

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_ARCH_SYS_ARCH_H
#define LWIP_ARCH_SYS_ARCH_H
#ifdef __cplusplus
extern "C" {
#endif
#define SYS_MBOX_NULL NULL
#define SYS_SEM_NULL NULL
/*typedef u32_t sys_prot_t;*/
struct sys_sem;
typedef struct sys_sem * sys_sem_t;
#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL))
#define sys_sem_valid_val(sem) ((sem) != NULL)
#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
#define sys_sem_set_invalid_val(sem) do { (sem) = NULL; }while(0)
struct sys_mutex;
typedef struct sys_mutex * sys_mutex_t;
#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
struct sys_mbox;
typedef struct sys_mbox * sys_mbox_t;
#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
#define sys_mbox_valid_val(mbox) sys_sem_valid_val(mbox)
#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox)
struct sys_thread;
typedef struct sys_thread * sys_thread_t;
#if LWIP_NETCONN_SEM_PER_THREAD
sys_sem_t* sys_arch_netconn_sem_get(void);
void sys_arch_netconn_sem_alloc(void);
void sys_arch_netconn_sem_free(void);
#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get()
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free()
#endif /* #if LWIP_NETCONN_SEM_PER_THREAD */
#define LWIP_EXAMPLE_APP_ABORT() lwip_unix_keypressed()
int lwip_unix_keypressed(void);
/*
---------------------------------------
---------- Threading options ----------
---------------------------------------
*/
void sys_mark_tcpip_thread(void);
#define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread()
#if LWIP_TCPIP_CORE_LOCKING
void sys_lock_tcpip_core(void);
#define LOCK_TCPIP_CORE() sys_lock_tcpip_core()
void sys_unlock_tcpip_core(void);
#define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core()
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ARCH_SYS_ARCH_H */

View File

@ -0,0 +1,62 @@
#ifndef FIFO_H
#define FIFO_H
#include "lwip/sys.h"
#ifdef __cplusplus
extern "C" {
#endif
/** How many bytes in fifo */
#define FIFOSIZE 2048
/** fifo data structure, this one is passed to all fifo functions */
typedef struct fifo_t {
u8_t data[FIFOSIZE+10]; /* data segment, +10 is a hack probably not needed.. FIXME! */
int dataslot; /* index to next char to be read */
int emptyslot; /* index to next empty slot */
int len; /* len probably not needed, may be calculated from dataslot and emptyslot in conjunction with FIFOSIZE */
sys_sem_t sem; /* semaphore protecting simultaneous data manipulation */
sys_sem_t getSem; /* sepaphore used to signal new data if getWaiting is set */
u8_t getWaiting; /* flag used to indicate that fifoget is waiting for data. fifoput is supposed to clear */
/* this flag prior to signaling the getSem semaphore */
} fifo_t;
/**
* Get a character from fifo
* Blocking call.
* @param fifo pointer to fifo data structure
* @return character read from fifo
*/
u8_t fifoGet(fifo_t * fifo);
/**
* Get a character from fifo
* Non blocking call.
* @param fifo pointer to fifo data structure
* @return character read from fifo, or < zero if non was available
*/
s16_t fifoGetNonBlock(fifo_t * fifo);
/**
* fifoput is called by the signalhandler when new data has arrived (or some other event is indicated)
* fifoput reads directly from the serialport and is thus highly dependent on unix arch at this moment
* @param fifo pointer to fifo data structure
* @param fd unix file descriptor
*/
void fifoPut(fifo_t * fifo, int fd);
/**
* fifoinit initiate fifo
* @param fifo pointer to fifo data structure, allocated by the user
*/
void fifoInit(fifo_t * fifo);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,34 @@
#ifndef LWIP_LIST_H
#define LWIP_LIST_H
#ifdef __cplusplus
extern "C" {
#endif
struct elem;
struct list {
struct elem *first, *last;
int size, elems;
};
struct elem {
struct elem *next;
void *data;
};
struct list *list_new(int size);
int list_push(struct list *list, void *data);
void *list_pop(struct list *list);
void *list_first(struct list *list);
int list_elems(struct list *list);
void list_delete(struct list *list);
int list_remove(struct list *list, void *elem);
void list_map(struct list *list, void (* func)(void *arg));
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -0,0 +1,68 @@
#ifndef SIO_UNIX_H
#define SIO_UNIX_H
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "netif/fifo.h"
/*#include "netif/pppif.h"*/
#ifdef __cplusplus
extern "C" {
#endif
struct sio_status_s {
int fd;
fifo_t myfifo;
};
/* BAUDRATE is defined in sio.c as it is implementation specific */
/** Baudrates */
typedef enum sioBaudrates {
SIO_BAUD_9600,
SIO_BAUD_19200,
SIO_BAUD_38400,
SIO_BAUD_57600,
SIO_BAUD_115200
} sioBaudrates;
/**
* Poll for a new character from incoming data stream
* @param siostat siostatus struct, contains sio instance data, given by sio_open
* @return char read from input stream, or < 0 if no char was available
*/
s16_t sio_poll(sio_status_t * siostat);
/**
* Parse incoming characters until a string str is received, blocking call
* @param str zero terminated string to expect
* @param siostat siostatus struct, contains sio instance data, given by sio_open
*/
void sio_expect_string(u8_t *str, sio_status_t * siostat);
/**
* Write a char to output data stream
* @param str pointer to a zero terminated string
* @param siostat siostatus struct, contains sio instance data, given by sio_open
*/
void sio_send_string(u8_t *str, sio_status_t * siostat);
/**
* Flush outbuffer (send everything in buffer now), useful if some layer below is
* holding on to data, waitng to fill a buffer
* @param siostat siostatus struct, contains sio instance data, given by sio_open
*/
void sio_flush( sio_status_t * siostat );
/**
* Change baudrate of port, may close and reopen port
* @param baud new baudrate
* @param siostat siostatus struct, contains sio instance data, given by sio_open
*/
void sio_change_baud( sioBaudrates baud, sio_status_t * siostat );
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

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

View File

@ -0,0 +1,139 @@
/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
/* ---------------------------------------------- */
/* --- fifo 4 unix ------------------------------ */
/* ---------------------------------------------- */
#include "lwip/err.h"
#include "netif/fifo.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/arch.h"
#include <unistd.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef SIO_FIFO_DEBUG
#define SIO_FIFO_DEBUG LWIP_DBG_OFF
#endif
u8_t fifoGet(fifo_t * fifo)
{
u8_t c;
sys_sem_wait(&fifo->sem); /* enter critical section */
if (fifo->dataslot == fifo->emptyslot)
{
fifo->getWaiting = TRUE; /* tell putFifo to signal us when data is available */
sys_sem_signal(&fifo->sem); /* leave critical section (allow input from serial port..) */
sys_sem_wait(&fifo->getSem); /* wait 4 data */
sys_sem_wait(&fifo->sem); /* reenter critical section */
}
c = fifo->data[fifo->dataslot++];
fifo->len--;
if (fifo->dataslot == FIFOSIZE)
{
fifo->dataslot = 0;
}
sys_sem_signal(&fifo->sem); /* leave critical section */
return c;
}
s16_t fifoGetNonBlock(fifo_t * fifo)
{
u16_t c;
sys_sem_wait(&fifo->sem); /* enter critical section */
if (fifo->dataslot == fifo->emptyslot)
{
/* empty fifo */
c = -1;
}
else
{
c = fifo->data[fifo->dataslot++];
fifo->len--;
if (fifo->dataslot == FIFOSIZE)
{
fifo->dataslot = 0;
}
}
sys_sem_signal(&fifo->sem); /* leave critical section */
return c;
}
void fifoPut(fifo_t * fifo, int fd)
{
/* FIXME: mutex around struct data.. */
int cnt=0;
sys_sem_wait(&fifo->sem ); /* enter critical */
LWIP_DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) );
if ( fifo->emptyslot < fifo->dataslot )
{
cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot );
}
else
{
cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot );
}
fifo->emptyslot += cnt;
fifo->len += cnt;
LWIP_DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) );
if ( fifo->len > FIFOSIZE )
{
printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len );
fifo->dataslot = 0;
fifo->emptyslot = 0;
fifo->len = 0;
}
if ( fifo->emptyslot == FIFOSIZE )
{
fifo->emptyslot = 0;
LWIP_DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") );
sys_sem_signal(&fifo->sem ); /* leave critical */
fifoPut( fifo, fd );
return;
}
if ( fifo->getWaiting )
{
fifo->getWaiting = FALSE;
sys_sem_signal(&fifo->getSem );
}
sys_sem_signal(&fifo->sem ); /* leave critical */
return;
}
void fifoInit(fifo_t * fifo)
{
fifo->dataslot = 0;
fifo->emptyslot = 0;
fifo->len = 0;
if(sys_sem_new(&fifo->sem, 1) != ERR_OK) { /* critical section 1=free to enter */
LWIP_ASSERT("Failed to create semaphore", 0);
}
if(sys_sem_new(&fifo->getSem, 0) != ERR_OK) { /* 0 = no one waiting */
LWIP_ASSERT("Failed to create semaphore", 0);
}
fifo->getWaiting = FALSE;
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <stdlib.h>
#include <netif/list.h>
/*-----------------------------------------------------------------------------------*/
struct list *
list_new(int size)
{
struct list *list;
list = (struct 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 = (struct 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,207 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <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 "lwip/sys.h"
#include "lwip/ip.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,
ip_addr_t *ipaddr)
{
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static void
timeout(void *arg)
{
struct netif *netif;
struct pcapif *pcapif;
struct pbuf *p;
struct eth_hdr *ethhdr;
netif = (struct netif *)arg;
pcapif = netif->state;
ethhdr = (struct eth_hdr *)pcapif->pkt;
if (lwip_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) {
pbuf_take(p, pcapif->pkt, pcapif->len);
ethhdr = p->payload;
switch (lwip_htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
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);
}
}
}
/*-----------------------------------------------------------------------------------*/
err_t
pcapif_init(struct netif *netif)
{
struct pcapif *p;
p = malloc(sizeof(struct pcapif));
if (p == NULL)
return ERR_MEM;
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 ERR_IF;
}
if(sys_sem_new(&p->sem, 0) != ERR_OK) {
LWIP_ASSERT("Failed to create semaphore", 0);
}
p->p = NULL;
p->lasttime = 0;
sys_thread_new("pcapif_thread", pcapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
#endif /* linux */

View File

@ -0,0 +1,490 @@
/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
/* to get rid of implicit function declarations */
#ifndef __FreeBSD__
/* defining this on FreeBSD hides non-standard defines that sio.c depends on */
#define _XOPEN_SOURCE 600
#endif
#define _GNU_SOURCE
/* build with Darwin C extensions not part of POSIX, i.e. FASYNC, SIGIO.
we can't use LWIP_UNIX_MACH because extensions need to be turned
on before any system headers (which are pulled in through cc.h)
are included */
#if defined(__APPLE__)
#define _DARWIN_C_SOURCE
#endif
#include "netif/sio.h"
#include "netif/fifo.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/arch.h"
#include "lwip/sio.h"
#include "netif/ppp/ppp_opts.h"
/* Following #undefs are here to keep compiler from issuing warnings
about them being double defined. (They are defined in lwip/inet.h
as well as the Unix #includes below.) */
#undef htonl
#undef ntohl
#undef htons
#undef ntohs
#undef HTONL
#undef NTOHL
#undef HTONS
#undef NTOHS
#include <stdlib.h>
#include <stdio.h>
#if defined(LWIP_UNIX_OPENBSD) || defined(LWIP_UNIX_MACH)
#include <util.h>
#elif defined(LWIP_UNIX_FREEBSD)
#include <libutil.h>
#endif
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#ifndef LWIP_HAVE_SLIPIF
#define LWIP_HAVE_SLIPIF 0
#endif
#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF) && defined(LWIP_UNIX_LINUX)
#include <pty.h>
#endif
/*#define BAUDRATE B19200 */
/*#define BAUDRATE B57600 */
#define BAUDRATE B115200
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* for all of you who don't define SIO_DEBUG in debug.h */
#ifndef SIO_DEBUG
#define SIO_DEBUG 0
#endif
/* typedef struct siostruct_t */
/* { */
/* sio_status_t *sio; */
/* } siostruct_t; */
/** array of ((siostruct*)netif->state)->sio structs */
static sio_status_t statusar[4];
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
/* --private-functions----------------------------------------------------------------- */
/**
* Signal handler for ttyXX0 to indicate bytes received
* one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
*/
static void signal_handler_IO_0( int status )
{
LWIP_UNUSED_ARG(status);
LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 0\n"));
fifoPut( &statusar[0].myfifo, statusar[0].fd );
}
/**
* Signal handler for ttyXX1 to indicate bytes received
* one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
*/
static void signal_handler_IO_1( int status )
{
LWIP_UNUSED_ARG(status);
LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 1\n"));
fifoPut( &statusar[1].myfifo, statusar[1].fd );
}
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
/**
* Initiation of serial device
* @param device string with the device name and path, eg. "/dev/ttyS0"
* @param devnum device number
* @param siostat status
* @return file handle to serial dev.
*/
static int sio_init( char * device, int devnum, sio_status_t * siostat )
{
struct termios oldtio,newtio;
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
struct sigaction saio; /* definition of signal action */
#endif
int fd;
LWIP_UNUSED_ARG(siostat);
LWIP_UNUSED_ARG(devnum);
/* open the device to be non-blocking (read will return immediately) */
fd = open( device, O_RDWR | O_NOCTTY | O_NONBLOCK );
if ( fd < 0 )
{
perror( device );
exit( -1 );
}
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
memset(&saio, 0, sizeof(struct sigaction));
/* install the signal handler before making the device asynchronous */
switch ( devnum )
{
case 0:
LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_0\n") );
saio.sa_handler = signal_handler_IO_0;
break;
case 1:
LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_1\n") );
saio.sa_handler = signal_handler_IO_1;
break;
default:
LWIP_DEBUGF( SIO_DEBUG,("sioinit, devnum not allowed\n") );
break;
}
sigaction( SIGIO,&saio,NULL );
/* allow the process to receive SIGIO */
if ( fcntl( fd, F_SETOWN, getpid( ) ) != 0)
{
perror( device );
exit( -1 );
}
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
if ( fcntl( fd, F_SETFL, FASYNC ) != 0)
{
perror( device );
exit( -1 );
}
#else
if ( fcntl( fd, F_SETFL, 0 ) != 0)
{
perror( device );
exit( -1 );
}
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
tcgetattr( fd,&oldtio ); /* save current port settings */
/* set new port settings */
/* see 'man termios' for further settings */
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
newtio.c_iflag = 0;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /*ECHO; */
newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
newtio.c_cc[VTIME] = 0;
tcsetattr( fd,TCSANOW,&newtio );
tcflush( fd, TCIOFLUSH );
return fd;
}
/**
*
*/
static void sio_speed( int fd, int speed )
{
struct termios oldtio,newtio;
/* int fd; */
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: baudcode:%d enter\n", fd, speed));
if ( fd < 0 )
{
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: fd ERROR\n", fd));
exit( -1 );
}
tcgetattr( fd,&oldtio ); /* get current port settings */
/* set new port settings
* see 'man termios' for further settings */
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = speed | CS8 | CLOCAL | CREAD; /* | CRTSCTS; */
newtio.c_iflag = 0;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /*ECHO; */
newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
newtio.c_cc[VTIME] = 0;
tcsetattr( fd,TCSANOW,&newtio );
tcflush( fd, TCIOFLUSH );
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: leave\n", fd));
}
/* --public-functions----------------------------------------------------------------------------- */
void sio_send( u8_t c, sio_status_t * siostat )
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
if ( write( siostat->fd, &c, 1 ) <= 0 )
{
LWIP_DEBUGF(SIO_DEBUG, ("sio_send[%d]: write refused\n", siostat->fd));
}
}
void sio_send_string( u8_t *str, sio_status_t * siostat )
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
int len = strlen( (const char *)str );
if ( write( siostat->fd, str, len ) <= 0 )
{
LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: write refused\n", siostat->fd));
}
LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: sent: %s\n", siostat->fd, str));
}
void sio_flush( sio_status_t * siostat )
{
LWIP_UNUSED_ARG(siostat);
/* not implemented in unix as it is not needed */
/*sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
}
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
/*u8_t sio_recv( struct netif * netif )*/
u8_t sio_recv( sio_status_t * siostat )
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
return fifoGet( &(siostat->myfifo) );
}
s16_t sio_poll(sio_status_t * siostat)
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
return fifoGetNonBlock( &(siostat->myfifo) );
}
void sio_expect_string( u8_t *str, sio_status_t * siostat )
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
u8_t c;
int finger=0;
LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: %s\n", siostat->fd, str));
while ( 1 )
{
c=fifoGet( &(siostat->myfifo) );
LWIP_DEBUGF(SIO_DEBUG, ("_%c", c));
if ( c==str[finger] )
{
finger++;
} else if ( finger > 0 )
{
/*it might fit in the beginning? */
if ( str[0] == c )
{
finger = 1;
}
}
if ( 0 == str[finger] )
break; /* done, we have a match */
}
LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: [match]\n", siostat->fd));
}
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
u32_t sio_write(sio_status_t * siostat, const u8_t *buf, u32_t size)
{
ssize_t wsz = write( siostat->fd, buf, size );
return wsz < 0 ? 0 : wsz;
}
u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
{
ssize_t rsz = read( siostat->fd, buf, size );
return rsz < 0 ? 0 : rsz;
}
void sio_read_abort(sio_status_t * siostat)
{
LWIP_UNUSED_ARG(siostat);
printf("sio_read_abort[%d]: not yet implemented for unix\n", siostat->fd);
}
#endif /* (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
sio_fd_t sio_open(u8_t devnum)
{
char dev[20];
/* would be nice with dynamic memory alloc */
sio_status_t * siostate = &statusar[ devnum ];
/* siostruct_t * tmp; */
/* tmp = (siostruct_t*)(netif->state); */
/* tmp->sio = siostate; */
/* tmp = (siostruct_t*)(netif->state); */
/* ((sio_status_t*)(tmp->sio))->fd = 0; */
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: for devnum %d\n", devnum));
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
fifoInit( &siostate->myfifo );
#endif /* ! PPP_SUPPORT */
snprintf( dev, sizeof(dev), "/dev/ttyS%d", devnum );
if ( (devnum == 1) || (devnum == 0) )
{
if ( ( siostate->fd = sio_init( dev, devnum, siostate ) ) == 0 )
{
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: ERROR opening serial device dev=%s\n", dev));
abort( );
return NULL;
}
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: dev=%s open.\n", siostate->fd, dev));
}
#if PPP_SUPPORT
else if (devnum == 2) {
pid_t childpid;
char name[256];
childpid = forkpty(&siostate->fd, name, NULL, NULL);
if(childpid < 0) {
perror("forkpty");
exit (1);
}
if(childpid == 0) {
execl("/usr/sbin/pppd", "pppd",
"ms-dns", "198.168.100.7",
"local", "crtscts",
"debug",
#ifdef LWIP_PPP_CHAP_TEST
"auth",
"require-chap",
"remotename", "lwip",
#else
"noauth",
#endif
#if LWIP_IPV6
"+ipv6",
#endif
"192.168.1.1:192.168.1.2",
NULL);
perror("execl pppd");
exit (1);
} else {
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned pppd pid %d on %s\n",
siostate->fd, childpid, name));
}
}
#endif
#if LWIP_HAVE_SLIPIF
else if (devnum == 3) {
pid_t childpid;
/* create PTY pair */
siostate->fd = posix_openpt(O_RDWR | O_NOCTTY);
if (siostate->fd < 0) {
perror("open pty master");
exit (1);
}
if (grantpt(siostate->fd) != 0) {
perror("grant pty master");
exit (1);
}
if (unlockpt(siostate->fd) != 0) {
perror("unlock pty master");
exit (1);
}
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: for %s\n",
siostate->fd, ptsname(siostate->fd)));
/* fork for slattach */
childpid = fork();
if(childpid < 0) {
perror("fork");
exit (1);
}
if(childpid == 0) {
/* esteblish SLIP interface on host side connected to PTY slave */
execl("/sbin/slattach", "slattach",
"-d", "-v", "-L", "-p", "slip",
ptsname(siostate->fd),
NULL);
perror("execl slattach");
exit (1);
} else {
int ret;
char buf[1024];
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned slattach pid %d on %s\n",
siostate->fd, childpid, ptsname(siostate->fd)));
/* wait a moment for slattach startup */
sleep(1);
/* configure SLIP interface on host side as P2P interface */
snprintf(buf, sizeof(buf),
"/sbin/ifconfig sl0 mtu %d %s pointopoint %s up",
SLIP_MAX_SIZE, "192.168.2.1", "192.168.2.2");
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: system(\"%s\");\n", siostate->fd, buf));
ret = system(buf);
if (ret < 0) {
perror("ifconfig failed");
exit(1);
}
}
}
#endif /* LWIP_HAVE_SLIPIF */
else
{
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: device %s (%d) is not supported\n", dev, devnum));
return NULL;
}
return siostate;
}
/**
*
*/
void sio_change_baud( sioBaudrates baud, sio_status_t * siostat )
{
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]\n", siostat->fd));
switch ( baud )
{
case SIO_BAUD_9600:
sio_speed( siostat->fd, B9600 );
break;
case SIO_BAUD_19200:
sio_speed( siostat->fd, B19200 );
break;
case SIO_BAUD_38400:
sio_speed( siostat->fd, B38400 );
break;
case SIO_BAUD_57600:
sio_speed( siostat->fd, B57600 );
break;
case SIO_BAUD_115200:
sio_speed( siostat->fd, B115200 );
break;
default:
LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]: Unknown baudrate, code:%d\n",
siostat->fd, baud));
break;
}
}

View File

@ -0,0 +1,432 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <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>
#include "lwip/opt.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "netif/tapif.h"
#define IFCONFIG_BIN "/sbin/ifconfig "
#if defined(LWIP_UNIX_LINUX)
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
/*
* Creating a tap interface requires special privileges. If the interfaces
* is created in advance with `tunctl -u <user>` it can be opened as a regular
* user. The network must already be configured. If DEVTAP_IF is defined it
* will be opened instead of creating a new tap device.
*
* You can also use PRECONFIGURED_TAPIF environment variable to do so.
*/
#ifndef DEVTAP_DEFAULT_IF
#define DEVTAP_DEFAULT_IF "tap0"
#endif
#ifndef DEVTAP
#define DEVTAP "/dev/net/tun"
#endif
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
#elif defined(LWIP_UNIX_OPENBSD)
#define DEVTAP "/dev/tun0"
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
#define IFCONFIG_ARGS "tun0 inet %d.%d.%d.%d " NETMASK_ARGS " link0"
#else /* others */
#define DEVTAP "/dev/tap0"
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
#endif
/* Define those to better describe your network interface. */
#define IFNAME0 't'
#define IFNAME1 'p'
#ifndef TAPIF_DEBUG
#define TAPIF_DEBUG LWIP_DBG_OFF
#endif
struct tapif {
/* Add whatever per-interface state that is needed here. */
int fd;
};
/* Forward declarations. */
static void tapif_input(struct netif *netif);
#if !NO_SYS
static void tapif_thread(void *arg);
#endif /* !NO_SYS */
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif)
{
struct tapif *tapif;
#if LWIP_IPV4
int ret;
char buf[1024];
#endif /* LWIP_IPV4 */
char *preconfigured_tapif = getenv("PRECONFIGURED_TAPIF");
tapif = (struct tapif *)netif->state;
/* Obtain MAC address from network interface. */
/* (We just fake an address...) */
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x12;
netif->hwaddr[2] = 0x34;
netif->hwaddr[3] = 0x56;
netif->hwaddr[4] = 0x78;
netif->hwaddr[5] = 0xab;
netif->hwaddr_len = 6;
/* device capabilities */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
tapif->fd = open(DEVTAP, O_RDWR);
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: fd %d\n", tapif->fd));
if (tapif->fd == -1) {
#ifdef LWIP_UNIX_LINUX
perror("tapif_init: try running \"modprobe tun\" or rebuilding your kernel with CONFIG_TUN; cannot open "DEVTAP);
#else /* LWIP_UNIX_LINUX */
perror("tapif_init: cannot open "DEVTAP);
#endif /* LWIP_UNIX_LINUX */
exit(1);
}
#ifdef LWIP_UNIX_LINUX
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
if (preconfigured_tapif) {
strncpy(ifr.ifr_name, preconfigured_tapif, sizeof(ifr.ifr_name) - 1);
} else {
strncpy(ifr.ifr_name, DEVTAP_DEFAULT_IF, sizeof(ifr.ifr_name) - 1);
}
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0; /* ensure \0 termination */
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
perror("tapif_init: "DEVTAP" ioctl TUNSETIFF");
exit(1);
}
}
#endif /* LWIP_UNIX_LINUX */
netif_set_link_up(netif);
if (preconfigured_tapif == NULL) {
#if LWIP_IPV4
snprintf(buf, 1024, IFCONFIG_BIN IFCONFIG_ARGS,
ip4_addr1(netif_ip4_gw(netif)),
ip4_addr2(netif_ip4_gw(netif)),
ip4_addr3(netif_ip4_gw(netif)),
ip4_addr4(netif_ip4_gw(netif))
#ifdef NETMASK_ARGS
,
ip4_addr1(netif_ip4_netmask(netif)),
ip4_addr2(netif_ip4_netmask(netif)),
ip4_addr3(netif_ip4_netmask(netif)),
ip4_addr4(netif_ip4_netmask(netif))
#endif /* NETMASK_ARGS */
);
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
ret = system(buf);
if (ret < 0) {
perror("ifconfig failed");
exit(1);
}
if (ret != 0) {
printf("ifconfig returned %d\n", ret);
}
#else /* LWIP_IPV4 */
perror("todo: support IPv6 support for non-preconfigured tapif");
exit(1);
#endif /* LWIP_IPV4 */
}
#if !NO_SYS
sys_thread_new("tapif_thread", tapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
#endif /* !NO_SYS */
}
/*-----------------------------------------------------------------------------------*/
/*
* 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 tapif *tapif = (struct tapif *)netif->state;
char buf[1518]; /* max packet size including VLAN excluding CRC */
ssize_t written;
#if 0
if (((double)rand()/(double)RAND_MAX) < 0.2) {
printf("drop output\n");
return ERR_OK; /* ERR_OK because we simulate packet loss on cable */
}
#endif
if (p->tot_len > sizeof(buf)) {
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
perror("tapif: packet too large");
return ERR_IF;
}
/* initiate transfer(); */
pbuf_copy_partial(p, buf, p->tot_len, 0);
/* signal that packet should be sent(); */
written = write(tapif->fd, buf, p->tot_len);
if (written < p->tot_len) {
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
perror("tapif: write");
return ERR_IF;
} else {
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, (u32_t)written);
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 netif *netif)
{
struct pbuf *p;
u16_t len;
ssize_t readlen;
char buf[1518]; /* max packet size including VLAN excluding CRC */
struct tapif *tapif = (struct tapif *)netif->state;
/* Obtain the size of the packet and put it into the "len"
variable. */
readlen = read(tapif->fd, buf, sizeof(buf));
if (readlen < 0) {
perror("read returned -1");
exit(1);
}
len = (u16_t)readlen;
MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
#if 0
if (((double)rand()/(double)RAND_MAX) < 0.2) {
printf("drop\n");
return NULL;
}
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
pbuf_take(p, buf, len);
/* acknowledge that packet has been read(); */
} else {
/* drop packet(); */
MIB2_STATS_NETIF_INC(netif, ifindiscards);
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: could not allocate pbuf\n"));
}
return p;
}
/*-----------------------------------------------------------------------------------*/
/*
* 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 pbuf *p = low_level_input(netif);
if (p == NULL) {
#if LINK_STATS
LINK_STATS_INC(link.recv);
#endif /* LINK_STATS */
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_input: low_level_input returned NULL\n"));
return;
}
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: netif input error\n"));
pbuf_free(p);
}
}
/*-----------------------------------------------------------------------------------*/
/*
* 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.
*
*/
/*-----------------------------------------------------------------------------------*/
err_t
tapif_init(struct netif *netif)
{
struct tapif *tapif = (struct tapif *)mem_malloc(sizeof(struct tapif));
if (tapif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_init: out of memory for tapif\n"));
return ERR_MEM;
}
netif->state = tapif;
MIB2_INIT_NETIF(netif, snmp_ifType_other, 100000000);
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#if LWIP_IPV4
netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = low_level_output;
netif->mtu = 1500;
low_level_init(netif);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
tapif_poll(struct netif *netif)
{
tapif_input(netif);
}
#if NO_SYS
int
tapif_select(struct netif *netif)
{
fd_set fdset;
int ret;
struct timeval tv;
struct tapif *tapif;
u32_t msecs = sys_timeouts_sleeptime();
tapif = (struct tapif *)netif->state;
tv.tv_sec = msecs / 1000;
tv.tv_usec = (msecs % 1000) * 1000;
FD_ZERO(&fdset);
FD_SET(tapif->fd, &fdset);
ret = select(tapif->fd + 1, &fdset, NULL, NULL, &tv);
if (ret > 0) {
tapif_input(netif);
}
return ret;
}
#else /* NO_SYS */
static void
tapif_thread(void *arg)
{
struct netif *netif;
struct tapif *tapif;
fd_set fdset;
int ret;
netif = (struct netif *)arg;
tapif = (struct 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");
}
}
}
#endif /* NO_SYS */

View File

@ -0,0 +1,344 @@
/*
* VDE (virtual distributed ethernet) interface for ale4net
* (based on tapif interface Adam Dunkels <adam@sics.se>)
* 2005,2010,2011,2023 Renzo Davoli University of Bologna - Italy
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <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>
#include "lwip/opt.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include <libvdeplug.h>
#include "netif/vdeif.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'v'
#define IFNAME1 'd'
#ifndef VDEIF_DEBUG
#define VDEIF_DEBUG LWIP_DBG_OFF
#endif
static char vdedescr[] = "lwip";
struct vdeif {
VDECONN *vdeconn;
};
/* Forward declarations. */
static void vdeif_input(struct netif *netif);
#if !NO_SYS
static void vdeif_thread(void *arg);
#endif /* !NO_SYS */
/*-----------------------------------------------------------------------------------*/
static void
low_level_init(struct netif *netif, char *vderl)
{
struct vdeif *vdeif;
int randaddr;
struct timeval now;
vdeif = (struct vdeif *)netif->state;
gettimeofday(&now, NULL);
srand(now.tv_sec + now.tv_usec);
randaddr = rand();
/* Obtain MAC address from network interface. */
/* (We just fake an address...) */
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x2;
netif->hwaddr[2] = randaddr >> 24;
netif->hwaddr[3] = randaddr >> 16;
netif->hwaddr[4] = randaddr >> 8;
netif->hwaddr[5] = randaddr;
netif->hwaddr_len = 6;
/* device capabilities */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
vdeif->vdeconn = vde_open(vderl, vdedescr, NULL);
LWIP_DEBUGF(VDEIF_DEBUG, ("vdeif_init: ok = %d\n", !!vdeif->vdeconn));
if (vdeif->vdeconn == NULL) {
perror("vdeif_init: cannot open vde net");
exit(1);
}
netif_set_link_up(netif);
#if !NO_SYS
sys_thread_new("vdeif_thread", vdeif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
#endif /* !NO_SYS */
}
/*-----------------------------------------------------------------------------------*/
/*
* 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 vdeif *vdeif = (struct vdeif *)netif->state;
char buf[1518]; /* max packet size including VLAN excluding CRC */
ssize_t written;
if (p->tot_len > sizeof(buf)) {
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
perror("vdeif: packet too large");
return ERR_IF;
}
/* initiate transfer(); */
pbuf_copy_partial(p, buf, p->tot_len, 0);
/* signal that packet should be sent(); */
written = vde_send(vdeif->vdeconn, buf, p->tot_len, 0);
if (written < p->tot_len) {
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
perror("vdeif: write");
return ERR_IF;
} else {
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, (u32_t)written);
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 netif *netif)
{
struct pbuf *p;
u16_t len;
ssize_t readlen;
char buf[1518]; /* max packet size including VLAN excluding CRC */
struct vdeif *vdeif = (struct vdeif *)netif->state;
/* Obtain the size of the packet and put it into the "len"
variable. */
readlen = vde_recv(vdeif->vdeconn, buf, sizeof(buf), 0);
if (readlen < 0) {
perror("read returned -1");
exit(1);
}
len = (u16_t)readlen;
MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
pbuf_take(p, buf, len);
/* acknowledge that packet has been read(); */
} else {
/* drop packet(); */
MIB2_STATS_NETIF_INC(netif, ifindiscards);
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_input: could not allocate pbuf\n"));
}
return p;
}
/*-----------------------------------------------------------------------------------*/
/*
* vdeif_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
vdeif_input(struct netif *netif)
{
struct pbuf *p = low_level_input(netif);
if (p == NULL) {
#if LINK_STATS
LINK_STATS_INC(link.recv);
#endif /* LINK_STATS */
LWIP_DEBUGF(VDEIF_DEBUG, ("vdeif_input: low_level_input returned NULL\n"));
return;
}
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_input: netif input error\n"));
pbuf_free(p);
}
}
/*-----------------------------------------------------------------------------------*/
/*
* vdeif_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.
*
*/
/*-----------------------------------------------------------------------------------*/
err_t
vdeif_init(struct netif *netif)
{
char *vderl = (char *) netif->state;
struct vdeif *vdeif = (struct vdeif *)mem_malloc(sizeof(struct vdeif));
if (vdeif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_init: out of memory for vdeif\n"));
return ERR_MEM;
}
netif->state = vdeif;
MIB2_INIT_NETIF(netif, snmp_ifType_other, 100000000);
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#if LWIP_IPV4
netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = low_level_output;
netif->mtu = 1500;
low_level_init(netif, vderl);
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
vdeif_poll(struct netif *netif)
{
vdeif_input(netif);
}
#if NO_SYS
int
vdeif_select(struct netif *netif)
{
fd_set fdset;
int ret;
struct timeval tv;
struct vdeif *vdeif;
u32_t msecs = sys_timeouts_sleeptime();
int datafd;
vdeif = (struct vdeif *)netif->state;
datafd = vde_datafd(vdeif->vdeconn);
tv.tv_sec = msecs / 1000;
tv.tv_usec = (msecs % 1000) * 1000;
FD_ZERO(&fdset);
FD_SET(datafd, &fdset);
ret = select(datafd + 1, &fdset, NULL, NULL, &tv);
if (ret > 0) {
vdeif_input(netif);
}
return ret;
}
#else /* NO_SYS */
static void
vdeif_thread(void *arg)
{
struct netif *netif;
struct vdeif *vdeif;
fd_set fdset;
int ret;
int datafd;
netif = (struct netif *)arg;
vdeif = (struct vdeif *)netif->state;
datafd = vde_datafd(vdeif->vdeconn);
while(1) {
FD_ZERO(&fdset);
FD_SET(datafd, &fdset);
/* Wait for a packet to arrive. */
ret = select(datafd + 1, &fdset, NULL, NULL, NULL);
if(ret == 1) {
/* Handle incoming packet. */
vdeif_input(netif);
} else if(ret == -1) {
perror("vdeif_thread: select");
}
}
}
#endif /* NO_SYS */

View File

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

View File

@ -0,0 +1,840 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <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.
*/
#define _GNU_SOURCE /* pull in pthread_setname_np() on Linux */
#include "lwip/debug.h"
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include "lwip/def.h"
#ifdef LWIP_UNIX_MACH
#include <mach/mach.h>
#include <mach/mach_time.h>
#endif
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#if LWIP_NETCONN_SEM_PER_THREAD
/* pthread key to *our* thread local storage entry */
static pthread_key_t sys_thread_sem_key;
#endif
/* Return code for an interrupted timed wait */
#define SYS_ARCH_INTR 0xfffffffeUL
u32_t
lwip_port_rand(void)
{
return (u32_t)rand();
}
static void
get_monotonic_time(struct timespec *ts)
{
#ifdef LWIP_UNIX_MACH
/* darwin impl (no CLOCK_MONOTONIC) */
u64_t t = mach_absolute_time();
mach_timebase_info_data_t timebase_info = {0, 0};
mach_timebase_info(&timebase_info);
u64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
u64_t sec = nano/1000000000L;
nano -= sec * 1000000000L;
ts->tv_sec = sec;
ts->tv_nsec = nano;
#else
clock_gettime(CLOCK_MONOTONIC, ts);
#endif
}
#if SYS_LIGHTWEIGHT_PROT
static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t lwprot_thread = (pthread_t)0xDEAD;
static int lwprot_count = 0;
#endif /* SYS_LIGHTWEIGHT_PROT */
#if !NO_SYS
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 *not_empty;
struct sys_sem *not_full;
struct sys_sem *mutex;
int wait_send;
};
struct sys_sem {
unsigned int c;
pthread_condattr_t condattr;
pthread_cond_t cond;
pthread_mutex_t mutex;
};
struct sys_mutex {
pthread_mutex_t mutex;
};
struct sys_thread {
struct sys_thread *next;
pthread_t pthread;
};
static struct sys_sem *sys_sem_new_internal(u8_t count);
static void sys_sem_free_internal(struct sys_sem *sem);
static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
u32_t timeout);
/*-----------------------------------------------------------------------------------*/
/* Threads */
static struct sys_thread *
introduce_thread(pthread_t id)
{
struct sys_thread *thread;
thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
if (thread != NULL) {
pthread_mutex_lock(&threads_mutex);
thread->next = threads;
thread->pthread = id;
threads = thread;
pthread_mutex_unlock(&threads_mutex);
}
return thread;
}
struct thread_wrapper_data
{
lwip_thread_fn function;
void *arg;
};
static void *
thread_wrapper(void *arg)
{
struct thread_wrapper_data *thread_data = (struct thread_wrapper_data *)arg;
thread_data->function(thread_data->arg);
/* we should never get here */
free(arg);
return NULL;
}
sys_thread_t
sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
{
int code;
pthread_t tmp;
struct sys_thread *st = NULL;
struct thread_wrapper_data *thread_data;
LWIP_UNUSED_ARG(name);
LWIP_UNUSED_ARG(stacksize);
LWIP_UNUSED_ARG(prio);
thread_data = (struct thread_wrapper_data *)malloc(sizeof(struct thread_wrapper_data));
thread_data->arg = arg;
thread_data->function = function;
code = pthread_create(&tmp,
NULL,
thread_wrapper,
thread_data);
#ifdef LWIP_UNIX_LINUX
pthread_setname_np(tmp, name);
#endif
if (0 == code) {
st = introduce_thread(tmp);
}
if (NULL == st) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx\n",
code, (unsigned long)st));
abort();
}
return st;
}
#if LWIP_TCPIP_CORE_LOCKING
static pthread_t lwip_core_lock_holder_thread_id;
void sys_lock_tcpip_core(void)
{
sys_mutex_lock(&lock_tcpip_core);
lwip_core_lock_holder_thread_id = pthread_self();
}
void sys_unlock_tcpip_core(void)
{
lwip_core_lock_holder_thread_id = 0;
sys_mutex_unlock(&lock_tcpip_core);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
static pthread_t lwip_tcpip_thread_id;
void sys_mark_tcpip_thread(void)
{
lwip_tcpip_thread_id = pthread_self();
}
void sys_check_core_locking(void)
{
/* Embedded systems should check we are NOT in an interrupt context here */
if (lwip_tcpip_thread_id != 0) {
pthread_t current_thread_id = pthread_self();
#if LWIP_TCPIP_CORE_LOCKING
LWIP_ASSERT("Function called without core lock", current_thread_id == lwip_core_lock_holder_thread_id);
#else /* LWIP_TCPIP_CORE_LOCKING */
LWIP_ASSERT("Function called from wrong thread", current_thread_id == lwip_tcpip_thread_id);
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
}
/*-----------------------------------------------------------------------------------*/
/* Mailbox */
err_t
sys_mbox_new(struct sys_mbox **mb, int size)
{
struct sys_mbox *mbox;
LWIP_UNUSED_ARG(size);
mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
if (mbox == NULL) {
return ERR_MEM;
}
mbox->first = mbox->last = 0;
mbox->not_empty = sys_sem_new_internal(0);
mbox->not_full = sys_sem_new_internal(0);
mbox->mutex = sys_sem_new_internal(1);
mbox->wait_send = 0;
SYS_STATS_INC_USED(mbox);
*mb = mbox;
return ERR_OK;
}
void
sys_mbox_free(struct sys_mbox **mb)
{
if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
struct sys_mbox *mbox = *mb;
SYS_STATS_DEC(mbox.used);
sys_arch_sem_wait(&mbox->mutex, 0);
sys_sem_free_internal(mbox->not_empty);
sys_sem_free_internal(mbox->not_full);
sys_sem_free_internal(mbox->mutex);
mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
/* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
free(mbox);
}
}
err_t
sys_mbox_trypost(struct sys_mbox **mb, void *msg)
{
u8_t first;
struct sys_mbox *mbox;
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
mbox = *mb;
sys_arch_sem_wait(&mbox->mutex, 0);
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
(void *)mbox, (void *)msg));
if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
sys_sem_signal(&mbox->mutex);
return ERR_MEM;
}
mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
if (mbox->last == mbox->first) {
first = 1;
} else {
first = 0;
}
mbox->last++;
if (first) {
sys_sem_signal(&mbox->not_empty);
}
sys_sem_signal(&mbox->mutex);
return ERR_OK;
}
err_t
sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
{
return sys_mbox_trypost(q, msg);
}
void
sys_mbox_post(struct sys_mbox **mb, void *msg)
{
u8_t first;
struct sys_mbox *mbox;
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
mbox = *mb;
sys_arch_sem_wait(&mbox->mutex, 0);
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
mbox->wait_send++;
sys_sem_signal(&mbox->mutex);
sys_arch_sem_wait(&mbox->not_full, 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->not_empty);
}
sys_sem_signal(&mbox->mutex);
}
u32_t
sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
{
struct sys_mbox *mbox;
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
mbox = *mb;
sys_arch_sem_wait(&mbox->mutex, 0);
if (mbox->first == mbox->last) {
sys_sem_signal(&mbox->mutex);
return SYS_MBOX_EMPTY;
}
if (msg != NULL) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
}
else{
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
}
mbox->first++;
if (mbox->wait_send) {
sys_sem_signal(&mbox->not_full);
}
sys_sem_signal(&mbox->mutex);
return 0;
}
u32_t
sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
{
u32_t time_needed = 0;
struct sys_mbox *mbox;
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
mbox = *mb;
/* 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_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
if (time_needed == SYS_ARCH_TIMEOUT) {
return SYS_ARCH_TIMEOUT;
}
} else {
sys_arch_sem_wait(&mbox->not_empty, 0);
}
sys_arch_sem_wait(&mbox->mutex, 0);
}
if (msg != NULL) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
}
else{
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
}
mbox->first++;
if (mbox->wait_send) {
sys_sem_signal(&mbox->not_full);
}
sys_sem_signal(&mbox->mutex);
return time_needed;
}
/*-----------------------------------------------------------------------------------*/
/* Semaphore */
static struct sys_sem *
sys_sem_new_internal(u8_t count)
{
struct sys_sem *sem;
sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
if (sem != NULL) {
sem->c = count;
pthread_condattr_init(&(sem->condattr));
#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21))
pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
#endif
pthread_cond_init(&(sem->cond), &(sem->condattr));
pthread_mutex_init(&(sem->mutex), NULL);
}
return sem;
}
err_t
sys_sem_new(struct sys_sem **sem, u8_t count)
{
SYS_STATS_INC_USED(sem);
*sem = sys_sem_new_internal(count);
if (*sem == NULL) {
return ERR_MEM;
}
return ERR_OK;
}
static u32_t
cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
{
struct timespec rtime1, rtime2, ts;
int ret;
#ifdef LWIP_UNIX_HURD
#define pthread_cond_wait pthread_hurd_cond_wait_np
#define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
#endif
if (timeout == 0) {
ret = pthread_cond_wait(cond, mutex);
return
#ifdef LWIP_UNIX_HURD
/* On the Hurd, ret == 1 means the RPC has been cancelled.
* The thread is awakened (not terminated) and execution must continue */
ret == 1 ? SYS_ARCH_INTR :
#endif
(u32_t)ret;
}
/* Get a timestamp and add the timeout value. */
get_monotonic_time(&rtime1);
#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
ts.tv_sec = timeout / 1000L;
ts.tv_nsec = (timeout % 1000L) * 1000000L;
ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
#else
ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
if (ts.tv_nsec >= 1000000000L) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000L;
}
ret = pthread_cond_timedwait(cond, mutex, &ts);
#endif
if (ret == ETIMEDOUT) {
return SYS_ARCH_TIMEOUT;
#ifdef LWIP_UNIX_HURD
/* On the Hurd, ret == 1 means the RPC has been cancelled.
* The thread is awakened (not terminated) and execution must continue */
} else if (ret == EINTR) {
return SYS_ARCH_INTR;
#endif
}
/* Calculate for how long we waited for the cond. */
get_monotonic_time(&rtime2);
ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
if (ts.tv_nsec < 0) {
ts.tv_sec--;
ts.tv_nsec += 1000000000L;
}
return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
}
u32_t
sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
{
u32_t time_needed = 0;
struct sys_sem *sem;
LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
sem = *s;
pthread_mutex_lock(&(sem->mutex));
while (sem->c <= 0) {
if (timeout > 0) {
time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
if (time_needed == SYS_ARCH_TIMEOUT) {
pthread_mutex_unlock(&(sem->mutex));
return SYS_ARCH_TIMEOUT;
#ifdef LWIP_UNIX_HURD
} else if(time_needed == SYS_ARCH_INTR) {
pthread_mutex_unlock(&(sem->mutex));
return 0;
#endif
}
/* pthread_mutex_unlock(&(sem->mutex));
return time_needed; */
} else if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
/* Some error happened or the thread has been awakened but not by lwip */
pthread_mutex_unlock(&(sem->mutex));
return 0;
}
}
sem->c--;
pthread_mutex_unlock(&(sem->mutex));
return (u32_t)time_needed;
}
void
sys_sem_signal(struct sys_sem **s)
{
struct sys_sem *sem;
LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
sem = *s;
pthread_mutex_lock(&(sem->mutex));
sem->c++;
if (sem->c > 1) {
sem->c = 1;
}
pthread_cond_broadcast(&(sem->cond));
pthread_mutex_unlock(&(sem->mutex));
}
static void
sys_sem_free_internal(struct sys_sem *sem)
{
pthread_cond_destroy(&(sem->cond));
pthread_condattr_destroy(&(sem->condattr));
pthread_mutex_destroy(&(sem->mutex));
free(sem);
}
void
sys_sem_free(struct sys_sem **sem)
{
if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
SYS_STATS_DEC(sem.used);
sys_sem_free_internal(*sem);
}
}
/*-----------------------------------------------------------------------------------*/
/* Mutex */
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t
sys_mutex_new(struct sys_mutex **mutex)
{
struct sys_mutex *mtx;
mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
if (mtx != NULL) {
pthread_mutex_init(&(mtx->mutex), NULL);
*mutex = mtx;
return ERR_OK;
}
else {
return ERR_MEM;
}
}
/** Lock a mutex
* @param mutex the mutex to lock */
void
sys_mutex_lock(struct sys_mutex **mutex)
{
pthread_mutex_lock(&((*mutex)->mutex));
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void
sys_mutex_unlock(struct sys_mutex **mutex)
{
pthread_mutex_unlock(&((*mutex)->mutex));
}
/** Delete a mutex
* @param mutex the mutex to delete */
void
sys_mutex_free(struct sys_mutex **mutex)
{
pthread_mutex_destroy(&((*mutex)->mutex));
free(*mutex);
}
#endif /* !NO_SYS */
#if LWIP_NETCONN_SEM_PER_THREAD
/*-----------------------------------------------------------------------------------*/
/* Semaphore per thread located TLS */
static void
sys_thread_sem_free(void* data)
{
sys_sem_t *sem = (sys_sem_t*)(data);
if (sem) {
sys_sem_free(sem);
free(sem);
}
}
static sys_sem_t*
sys_thread_sem_alloc(void)
{
sys_sem_t *sem;
err_t err;
int ret;
sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
LWIP_ASSERT("failed to allocate memory for TLS semaphore", sem != NULL);
err = sys_sem_new(sem, 0);
LWIP_ASSERT("failed to initialise TLS semaphore", err == ERR_OK);
ret = pthread_setspecific(sys_thread_sem_key, sem);
LWIP_ASSERT("failed to initialise TLS semaphore storage", ret == 0);
return sem;
}
sys_sem_t*
sys_arch_netconn_sem_get(void)
{
sys_sem_t* sem = (sys_sem_t*)pthread_getspecific(sys_thread_sem_key);
if (!sem) {
sem = sys_thread_sem_alloc();
}
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_sem_get s=%p\n", (void*)sem));
return sem;
}
void
sys_arch_netconn_sem_alloc(void)
{
sys_sem_t* sem = sys_thread_sem_alloc();
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_sem created s=%p\n", (void*)sem));
}
void
sys_arch_netconn_sem_free(void)
{
int ret;
sys_sem_t *sem = (sys_sem_t *)pthread_getspecific(sys_thread_sem_key);
sys_thread_sem_free(sem);
ret = pthread_setspecific(sys_thread_sem_key, NULL);
LWIP_ASSERT("failed to de-init TLS semaphore storage", ret == 0);
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
/*-----------------------------------------------------------------------------------*/
/* Time */
u32_t
sys_now(void)
{
struct timespec ts;
u32_t now;
get_monotonic_time(&ts);
now = (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
#ifdef LWIP_FUZZ_SYS_NOW
now += sys_now_offset;
#endif
return now;
}
u32_t
sys_jiffies(void)
{
struct timespec ts;
get_monotonic_time(&ts);
return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
}
/*-----------------------------------------------------------------------------------*/
/* Init */
void
sys_init(void)
{
#if LWIP_NETCONN_SEM_PER_THREAD
pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free);
#endif
}
/*-----------------------------------------------------------------------------------*/
/* Critical section */
#if SYS_LIGHTWEIGHT_PROT
/** sys_prot_t sys_arch_protect(void)
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
sys_prot_t
sys_arch_protect(void)
{
/* Note that for the UNIX port, we are using a lightweight mutex, and our
* own counter (which is locked by the mutex). The return code is not actually
* used. */
if (lwprot_thread != pthread_self())
{
/* We are locking the mutex where it has not been locked before *
* or is being locked by another thread */
pthread_mutex_lock(&lwprot_mutex);
lwprot_thread = pthread_self();
lwprot_count = 1;
}
else
/* It is already locked by THIS thread */
lwprot_count++;
return 0;
}
/** void sys_arch_unprotect(sys_prot_t pval)
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
void
sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
if (lwprot_thread == pthread_self())
{
lwprot_count--;
if (lwprot_count == 0)
{
lwprot_thread = (pthread_t) 0xDEAD;
pthread_mutex_unlock(&lwprot_mutex);
}
}
}
#endif /* SYS_LIGHTWEIGHT_PROT */
#if !NO_SYS
/* get keyboard state to terminate the debug app by using select */
int
lwip_unix_keypressed(void)
{
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return select(1, &fds, NULL, NULL, &tv);
}
#endif /* !NO_SYS */

View File

@ -0,0 +1,94 @@
cmake_minimum_required(VERSION 3.8)
project(liblwip
VERSION 2.2.0
DESCRIPTION "lwip library for linux"
HOMEPAGE_URL "http://wiki.virtualsquare.org"
LANGUAGES C)
include(GNUInstallDirs)
include(CheckIncludeFile)
set (BUILD_SHARED_LIBS ON)
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(FATAL_ERROR "Lwip shared library is only working on Linux or the Hurd")
endif()
set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
find_library(LIB_VDEPLUGOK vdeplug)
check_include_file(libvdeplug.h INCLUDE_VDEPLUGOK)
if (LIB_VDEPLUGOK AND INCLUDE_VDEPLUGOK)
message(STATUS "Found libvdeplug: vde support added")
else()
message(STATUS "Libvdeplug needs to be installed to add vde support")
endif()
include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
set (LWIP_DEFINITIONS -DLWIP_DEBUG)
set (LWIP_INCLUDE_DIRS
"include"
"${LWIP_DIR}/src/include"
"${LWIP_CONTRIB_DIR}/"
"${LWIP_CONTRIB_DIR}/ports/unix/port/include"
"${CMAKE_CURRENT_SOURCE_DIR}/"
)
set (LWIP_EXCLUDE_SLIPIF TRUE)
include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
include(${LWIP_DIR}/src/Filelists.cmake)
if (LIB_VDEPLUGOK AND INCLUDE_VDEPLUGOK)
set(lwipnoapps_SRCS ${lwipnoapps_SRCS}
${LWIP_DIR}/contrib/ports/unix/port/netif/vdeif.c)
endif()
add_library(lwip ${lwipnoapps_SRCS} ${lwipcontribportunix_SRCS} ${lwipcontribportunixnetifs_SRCS})
target_compile_options(lwip PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwip PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_include_directories(lwip PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
if (LIB_VDEPLUGOK AND INCLUDE_VDEPLUGOK)
target_link_libraries(lwip ${LWIP_SANITIZER_LIBS} vdeplug)
else()
target_link_libraries(lwip ${LWIP_SANITIZER_LIBS})
endif()
find_library(LIBPTHREAD pthread)
target_link_libraries(lwip ${LIBPTHREAD})
install(TARGETS lwip
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
set_target_properties(lwip PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
install(DIRECTORY "${LWIP_DIR}/src/include/lwip"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip"
FILES_MATCHING PATTERN "*.h"
)
install(DIRECTORY "${LWIP_DIR}/src/include/netif"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip"
FILES_MATCHING PATTERN "*.h"
)
install(FILES lwipopts.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip")
install(DIRECTORY "${LWIP_DIR}/contrib/ports/unix/port/include/arch"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip"
FILES_MATCHING PATTERN "*.h"
)
install(DIRECTORY "${LWIP_DIR}/contrib/ports/unix/port/include/netif"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip"
FILES_MATCHING PATTERN "*.h"
)
install(DIRECTORY "${LWIP_DIR}/contrib/ports/unix/posixlib/include/posix"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/lwip"
FILES_MATCHING PATTERN "*.h"
)
add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/Uninstall.cmake")

View File

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.13)
set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
if(NOT EXISTS ${MANIFEST})
message(FATAL_ERROR "Cannot find install manifest: '${MANIFEST}'")
endif()
file(STRINGS ${MANIFEST} files)
foreach(file ${files})
if(EXISTS ${file} OR IS_SYMLINK ${file})
message(STATUS "Removing: ${file}")
execute_process(
COMMAND rm -f ${file}
RESULT_VARIABLE retcode
)
if(NOT "${retcode}" STREQUAL "0")
message(WARNING "Failed to remove: ${file}")
endif()
endif()
endforeach(file)

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2023 Joan Lled<65> <jlledom@member.fsf.org>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef HURD_LWIP_POSIX_INET_H
#define HURD_LWIP_POSIX_INET_H
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <net/if.h>
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_IPV4
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
#ifdef LWIP_UNIX_HURD
#define IP_PKTINFO 8
struct in_pktinfo {
unsigned int ipi_ifindex; /* Interface index */
struct in_addr ipi_addr; /* Destination (from header) address */
};
#endif /* LWIP_UNIX_HURD */
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
(target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
(target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
(target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
(target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
(target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
(target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3]; \
ip6_addr_clear_zone(target_ip6addr);}
/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
#endif /* LWIP_IPV6 */
#ifdef __cplusplus
}
#endif
#endif /* HURD_LWIP_POSIX_INET_H */

View File

@ -0,0 +1,150 @@
/*
* Copyright (C) 2023 Joan Lled<65> <jlledom@member.fsf.org>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef HURD_LWIP_POSIX_SOCKET_H
#define HURD_LWIP_POSIX_SOCKET_H
#include <sys/socket.h>
#include <poll.h>
#include <errno.h>
#include LWIP_SOCKET_EXTERNAL_HEADER_INET_H
typedef size_t msg_iovlen_t;
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _HAVE_SA_LEN
#define HAVE_SA_LEN _HAVE_SA_LEN
#else
#define HAVE_SA_LEN 0
#endif /* _HAVE_SA_LEN */
/* Address length safe read and write */
#if HAVE_SA_LEN
#define IP4ADDR_SOCKADDR_SET_LEN(sin) \
(sin)->sin_len = sizeof(struct sockaddr_in)
#define IP6ADDR_SOCKADDR_SET_LEN(sin6) \
(sin6)->sin6_len = sizeof(struct sockaddr_in6)
#define IPADDR_SOCKADDR_GET_LEN(addr) \
(addr)->sa.sa_len
#else
#define IP4ADDR_SOCKADDR_SET_LEN(addr)
#define IP6ADDR_SOCKADDR_SET_LEN(addr)
#define IPADDR_SOCKADDR_GET_LEN(addr) \
((addr)->sa.sa_family == AF_INET ? sizeof(struct sockaddr_in) \
: ((addr)->sa.sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0))
#endif /* HAVE_SA_LEN */
#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
__SOCKADDR_COMMON_SIZE - \
sizeof (in_port_t) - \
sizeof (struct in_addr)
#if !defined IOV_MAX
#define IOV_MAX 0xFFFF
#elif IOV_MAX > 0xFFFF
#error "IOV_MAX larger than supported by LwIP"
#endif /* IOV_MAX */
#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET)
#if LWIP_UDP && LWIP_UDPLITE
/*
* Options for level IPPROTO_UDPLITE
*/
#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
#endif /* LWIP_UDP && LWIP_UDPLITE*/
#if 0
void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_shutdown(int s, int how);
int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
int lwip_close(int s);
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_listen(int s, int backlog);
ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
ssize_t lwip_read(int s, void *mem, size_t len);
ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int lwip_socket(int domain, int type, int protocol);
ssize_t lwip_write(int s, const void *dataptr, size_t size);
ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
#if LWIP_SOCKET_SELECT
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
struct timeval *timeout);
#endif
#if LWIP_SOCKET_POLL
int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
int lwip_ioctl(int s, long cmd, void *argp);
int lwip_fcntl(int s, int cmd, int val);
const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
int lwip_inet_pton(int af, const char *src, void *dst);
#endif
/* Unsupported identifiers */
#ifndef SO_NO_CHECK
#define SO_NO_CHECK 0xFF
#endif
#ifndef SO_BINDTODEVICE
#define SO_BINDTODEVICE 0xFE
#endif
#ifndef MSG_MORE
#define MSG_MORE 0x0
#endif
#ifndef TCP_KEEPALIVE
#define TCP_KEEPALIVE 0xFF
#endif
#ifndef TCP_KEEPIDLE
#define TCP_KEEPIDLE 0xFE
#endif
#ifndef TCP_KEEPINTVL
#define TCP_KEEPINTVL 0xFD
#endif
#ifndef TCP_KEEPCNT
#define TCP_KEEPCNT 0xFC
#endif
#ifdef __cplusplus
}
#endif
#endif /* HURD_LWIP_POSIX_SOCKET_H */

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2023 Joan Lled<65> <jlledom@member.fsf.org>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef UNIX_LWIP_LWIPOPTS_H
#define UNIX_LWIP_LWIPOPTS_H
/* An OS is present */
#define NO_SYS 0
/* Sockets API config */
#define LWIP_COMPAT_SOCKETS 0
#define LWIP_SOCKET_OFFSET 1
#define LWIP_POLL 1
/* User posix socket headers */
#define LWIP_SOCKET_EXTERNAL_HEADERS 1
#define LWIP_SOCKET_EXTERNAL_HEADER_SOCKETS_H "posix/sockets.h"
#define LWIP_SOCKET_EXTERNAL_HEADER_INET_H "posix/inet.h"
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
/* Use Glibc malloc()/free() */
#define MEM_LIBC_MALLOC 1
#define MEMP_MEM_MALLOC 1
#define MEM_USE_POOLS 0
/* Only send complete packets to the device */
#define LWIP_NETIF_TX_SINGLE_PBUF 1
/* Randomize local ports */
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
/* Glibc sends more than one packet in a row during an ARP resolution */
#define ARP_QUEUEING 1
#define ARP_QUEUE_LEN 10
/*
* Activate loopback, but don't use lwip's default loopback interface,
* we provide our own.
*/
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_HAVE_LOOPIF 0
/* IPv4 stuff */
#define IP_FORWARD 1
/* SLAAC support and other IPv6 stuff */
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
#define LWIP_IPV6_AUTOCONFIG 1
#define LWIP_IPV6_FORWARD 1
#define MEMP_NUM_MLD6_GROUP 16
#define LWIP_IPV6_NUM_ADDRESSES 6
#define IPV6_FRAG_COPYHEADER 1
/* TCP tuning */
#define TCP_MSS 1460
#define TCP_WND 0xFFFF
#define LWIP_WND_SCALE 1
#define TCP_RCV_SCALE 0x1
#define TCP_SND_BUF TCP_WND
/* Throughput settings */
#define LWIP_CHECKSUM_ON_COPY 1
/* Disable stats */
#define LWIP_STATS 0
#define LWIP_STATS_DISPLAY 0
/* Enable all socket operations */
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_LINGER 1
#define SO_REUSE 1
#define LWIP_MULTICAST_TX_OPTIONS 1
/* Enable modules */
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_IPV4 1
#define LWIP_ICMP 1
#define LWIP_IGMP 1
#define LWIP_RAW 1
#define LWIP_UDP 1
#define LWIP_UDPLITE 1
#define LWIP_TCP 1
#define LWIP_IPV6 1
#define LWIP_ICMP6 1
#define LWIP_IPV6_MLD 1
/* Don't abort the whole stack when an error is detected */
#define LWIP_NOASSERT_ON_ERROR 1
/* Threading options */
#define LWIP_TCPIP_CORE_LOCKING 1
/* If the system is 64 bit */
#if defined __LP64__
#define MEM_ALIGNMENT 8
#else
#define MEM_ALIGNMENT 4
#endif
#if !NO_SYS
void sys_check_core_locking(void);
#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
#if 0
void sys_mark_tcpip_thread(void);
#define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread()
#if LWIP_TCPIP_CORE_LOCKING
void sys_lock_tcpip_core(void);
#define LOCK_TCPIP_CORE() sys_lock_tcpip_core()
void sys_unlock_tcpip_core(void);
#define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core()
#endif
#endif
#endif
/* Debug mode */
#ifdef LWIP_DEBUG
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TIMERS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
#define IP6_DEBUG LWIP_DBG_OFF
#endif
#endif /* UNIX_LWIP_LWIPOPTS_H */

View File

@ -0,0 +1,22 @@
#!/bin/bash
# This script needs bridge-util debian package or similar
# for other distros.
# Run using "source setup-tapif" to get exported PRECONFIGURED_TAPIF variable
# Alternatively, add "export PRECONFIGURED_TAPIF=tap0" to ~/.bashrc
# http://backreference.org/2010/03/26/tuntap-interface-tutorial/
# After executing this script, start example_app.
# Enter 192.168.1.200 or "http://lwip.local/" (Zeroconf)
# in your webbrowser to see example_app webpage.
export PRECONFIGURED_TAPIF=tap0
sudo ip tuntap add dev $PRECONFIGURED_TAPIF mode tap user `whoami`
sudo ip link set $PRECONFIGURED_TAPIF up
sudo brctl addbr lwipbridge
sudo brctl addif lwipbridge $PRECONFIGURED_TAPIF
sudo ip addr add 192.168.1.1/24 dev lwipbridge
sudo ip link set dev lwipbridge up