mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
Remove legacy lwIP plugins
Now that the lwIP VFS plugin has become a first class IP stack it is time to remove the lwIP 1.x library and the associated libc plugins. Fix #2958
This commit is contained in:
parent
1370fa7631
commit
fcbe060096
@ -13,6 +13,7 @@ set build_components {
|
|||||||
drivers/timer drivers/usb
|
drivers/timer drivers/usb
|
||||||
server/tcp_terminal
|
server/tcp_terminal
|
||||||
test/terminal_echo
|
test/terminal_echo
|
||||||
|
lib/vfs/lwip
|
||||||
}
|
}
|
||||||
|
|
||||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
||||||
@ -66,8 +67,11 @@ set config {
|
|||||||
<provides> <service name="Terminal"/> </provides>
|
<provides> <service name="Terminal"/> </provides>
|
||||||
<config>
|
<config>
|
||||||
<policy label_prefix="test-terminal_echo" port="8888"/>
|
<policy label_prefix="test-terminal_echo" port="8888"/>
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log"/>
|
<dir name="dev"> <log/> </dir>
|
||||||
|
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" socket="/socket"/>
|
||||||
</config>
|
</config>
|
||||||
<route>
|
<route>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
@ -103,6 +107,7 @@ set boot_modules {
|
|||||||
libc.lib.so vfs.lib.so libc_pipe.lib.so lwip_legacy.lib.so pthread.lib.so
|
libc.lib.so vfs.lib.so libc_pipe.lib.so lwip_legacy.lib.so pthread.lib.so
|
||||||
tcp_terminal
|
tcp_terminal
|
||||||
test-terminal_echo
|
test-terminal_echo
|
||||||
|
vfs_lwip.lib.so
|
||||||
}
|
}
|
||||||
|
|
||||||
append_platform_drv_boot_modules
|
append_platform_drv_boot_modules
|
||||||
|
@ -48,7 +48,7 @@ append config {
|
|||||||
<provides> <service name="Terminal"/> </provides>
|
<provides> <service name="Terminal"/> </provides>
|
||||||
<config ld_verbose="yes">
|
<config ld_verbose="yes">
|
||||||
<policy label="test-terminal_echo" port="8888"/>
|
<policy label="test-terminal_echo" port="8888"/>
|
||||||
<libc stdout="/dev/log">
|
<libc stdout="/dev/log" socket="/socket"/>
|
||||||
<vfs>
|
<vfs>
|
||||||
<dir name="dev"> <log/> </dir>
|
<dir name="dev"> <log/> </dir>
|
||||||
<dir name="socket">
|
<dir name="socket">
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Automated testing of http_blk
|
|
||||||
# \author Stefan Kalkowski
|
|
||||||
# \date 2013-11-29
|
|
||||||
#
|
|
||||||
|
|
||||||
if {[have_spec odroid_xu]} {
|
|
||||||
puts "Run script does not support this platform."
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
|
||||||
set use_nic_driver [expr !$use_usb_driver && ![have_spec imx53]]
|
|
||||||
|
|
||||||
if {[expr !$use_usb_driver && !$use_nic_driver]} {
|
|
||||||
puts "\n Run script is not supported on this platform. \n"; exit 0 }
|
|
||||||
|
|
||||||
if {$use_usb_driver} { set network_driver "usb_drv" }
|
|
||||||
if {$use_nic_driver} { set network_driver "nic_drv" }
|
|
||||||
|
|
||||||
set build_components {
|
|
||||||
core init
|
|
||||||
drivers/timer
|
|
||||||
server/nic_bridge
|
|
||||||
server/http_blk
|
|
||||||
app/lighttpd
|
|
||||||
test/rom_blk
|
|
||||||
}
|
|
||||||
|
|
||||||
# platform-specific modules
|
|
||||||
lappend_if $use_usb_driver build_components drivers/usb
|
|
||||||
lappend_if $use_nic_driver build_components drivers/nic
|
|
||||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
|
||||||
|
|
||||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
|
||||||
append_platform_drv_build_components
|
|
||||||
|
|
||||||
build $build_components
|
|
||||||
|
|
||||||
create_boot_directory
|
|
||||||
|
|
||||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
|
||||||
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
|
|
||||||
return gpio_drv }
|
|
||||||
|
|
||||||
append config {
|
|
||||||
<config>
|
|
||||||
<parent-provides>
|
|
||||||
<service name="ROM"/>
|
|
||||||
<service name="LOG"/>
|
|
||||||
<service name="RM"/>
|
|
||||||
<service name="CPU"/>
|
|
||||||
<service name="PD"/>
|
|
||||||
<service name="IRQ"/>
|
|
||||||
<service name="IO_PORT"/>
|
|
||||||
<service name="IO_MEM"/>
|
|
||||||
</parent-provides>
|
|
||||||
<default-route>
|
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
|
||||||
</default-route>
|
|
||||||
<start name="timer">
|
|
||||||
<resource name="RAM" quantum="1M"/>
|
|
||||||
<provides><service name="Timer"/></provides>
|
|
||||||
</start>}
|
|
||||||
|
|
||||||
append_if [have_spec gpio] config "
|
|
||||||
<start name=\"[gpio_drv]\">
|
|
||||||
<resource name=\"RAM\" quantum=\"4M\"/>
|
|
||||||
<provides><service name=\"Gpio\"/></provides>
|
|
||||||
<config/>
|
|
||||||
</start>"
|
|
||||||
|
|
||||||
append_if $use_usb_driver config {
|
|
||||||
<start name="usb_drv" caps="120">
|
|
||||||
<resource name="RAM" quantum="12M"/>
|
|
||||||
<provides>
|
|
||||||
<service name="Nic"/>
|
|
||||||
</provides>
|
|
||||||
<config ehci="yes">
|
|
||||||
<nic mac="02:00:00:00:01:01"/>
|
|
||||||
</config>
|
|
||||||
</start>}
|
|
||||||
|
|
||||||
append_if $use_nic_driver config {
|
|
||||||
<start name="nic_drv">
|
|
||||||
<binary name="} [nic_drv_binary] {"/>
|
|
||||||
<resource name="RAM" quantum="4M"/>
|
|
||||||
<provides><service name="Nic"/></provides>
|
|
||||||
</start>}
|
|
||||||
|
|
||||||
append_platform_drv_config
|
|
||||||
|
|
||||||
append config {
|
|
||||||
<start name="nic_bridge">
|
|
||||||
<resource name="RAM" quantum="4M"/>
|
|
||||||
<provides><service name="Nic"/></provides>
|
|
||||||
<config>
|
|
||||||
<policy label_prefix="lighttpd" ip_addr="10.0.1.1"/>
|
|
||||||
<policy label_prefix="http_blk" ip_addr="10.0.1.2"/>
|
|
||||||
</config>
|
|
||||||
<route>
|
|
||||||
<service name="Nic">}
|
|
||||||
append config " <child name=\"$network_driver\"/>"
|
|
||||||
append config {
|
|
||||||
</service>
|
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
|
||||||
</route>
|
|
||||||
</start>
|
|
||||||
<start name="http_blk">
|
|
||||||
<resource name="RAM" quantum="2M" />
|
|
||||||
<provides><service name="Block"/></provides>
|
|
||||||
<config block_size="512" uri="http://10.0.1.1/index.bin">
|
|
||||||
<libc ip_addr="10.0.1.2" gateway="10.0.1.5" netmask="255.255.255.0"/>
|
|
||||||
</config>
|
|
||||||
<route>
|
|
||||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
|
||||||
<service name="ROM"> <parent/> </service>
|
|
||||||
<any-service> <any-child /> <parent/> </any-service>
|
|
||||||
</route>
|
|
||||||
</start>
|
|
||||||
<start name="test-rom_blk">
|
|
||||||
<resource name="RAM" quantum="3M"/>
|
|
||||||
<config file="index.bin"/>
|
|
||||||
</start>
|
|
||||||
<start name="lighttpd">
|
|
||||||
<resource name="RAM" quantum="1G" />
|
|
||||||
<config>
|
|
||||||
<arg value="lighttpd" />
|
|
||||||
<arg value="-f" />
|
|
||||||
<arg value="/etc/lighttpd/lighttpd.conf" />
|
|
||||||
<arg value="-D" />
|
|
||||||
<vfs>
|
|
||||||
<dir name="dev">
|
|
||||||
<log/>
|
|
||||||
<null/>
|
|
||||||
</dir>
|
|
||||||
<dir name="etc">
|
|
||||||
<dir name="lighttpd">
|
|
||||||
<inline name="lighttpd.conf">
|
|
||||||
# lighttpd configuration
|
|
||||||
server.port = 80
|
|
||||||
server.document-root = "/website"
|
|
||||||
server.event-handler = "select"
|
|
||||||
server.network-backend = "write"
|
|
||||||
index-file.names = (
|
|
||||||
"index.xhtml", "index.html", "index.htm"
|
|
||||||
)
|
|
||||||
mimetype.assign = (
|
|
||||||
".html" => "text/html",
|
|
||||||
".htm" => "text/html"
|
|
||||||
)
|
|
||||||
</inline>
|
|
||||||
</dir>
|
|
||||||
</dir>
|
|
||||||
<dir name="website">
|
|
||||||
<rom name="index.bin" as="index.bin" />
|
|
||||||
</dir>
|
|
||||||
</vfs>
|
|
||||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
|
|
||||||
ip_addr="10.0.1.1" gateway="10.0.1.5"
|
|
||||||
netmask="255.255.255.0"/>
|
|
||||||
</config>
|
|
||||||
<route>
|
|
||||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
|
||||||
<service name="ROM"> <parent/> </service>
|
|
||||||
<any-service> <any-child /> <parent/> </any-service>
|
|
||||||
</route>
|
|
||||||
</start>
|
|
||||||
</config>}
|
|
||||||
|
|
||||||
install_config $config
|
|
||||||
|
|
||||||
catch { exec dd if=/dev/zero of=bin/index.bin bs=512 count=400 }
|
|
||||||
|
|
||||||
#
|
|
||||||
# Boot modules
|
|
||||||
#
|
|
||||||
|
|
||||||
# generic modules
|
|
||||||
set boot_modules {
|
|
||||||
core ld.lib.so init timer
|
|
||||||
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
|
|
||||||
lwip_legacy.lib.so zlib.lib.so
|
|
||||||
lighttpd nic_bridge http_blk index.bin test-rom_blk
|
|
||||||
}
|
|
||||||
|
|
||||||
# platform-specific modules
|
|
||||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
|
||||||
lappend_if $use_usb_driver boot_modules usb_drv
|
|
||||||
lappend_if $use_nic_driver boot_modules [nic_drv_binary]
|
|
||||||
|
|
||||||
append_platform_drv_boot_modules
|
|
||||||
|
|
||||||
build_boot_image $boot_modules
|
|
||||||
|
|
||||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
|
|
||||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
|
|
||||||
|
|
||||||
append qemu_args " -net user -redir tcp:5555::80 "
|
|
||||||
append qemu_args " -nographic -serial mon:stdio "
|
|
||||||
|
|
||||||
run_genode_until {.*all done, finished!.*} 120
|
|
||||||
exec rm -f bin/index.bin
|
|
@ -20,6 +20,7 @@ set build_components {
|
|||||||
drivers/timer drivers/nic
|
drivers/timer drivers/nic
|
||||||
server/tcp_terminal
|
server/tcp_terminal
|
||||||
test/terminal_echo
|
test/terminal_echo
|
||||||
|
lib/vfs/lwip
|
||||||
}
|
}
|
||||||
|
|
||||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||||
@ -58,12 +59,15 @@ set config {
|
|||||||
<provides> <service name="Nic"/> </provides>
|
<provides> <service name="Nic"/> </provides>
|
||||||
</start>
|
</start>
|
||||||
<start name="tcp_terminal" caps="200">
|
<start name="tcp_terminal" caps="200">
|
||||||
<resource name="RAM" quantum="2560K"/>
|
<resource name="RAM" quantum="8M"/>
|
||||||
<provides> <service name="Terminal"/> </provides>
|
<provides> <service name="Terminal"/> </provides>
|
||||||
<config>
|
<config>
|
||||||
<policy label_prefix="test-terminal_echo" port="8888"/>
|
<policy label_prefix="test-terminal_echo" port="8888"/>
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log"/>
|
<dir name="dev"> <log/> </dir>
|
||||||
|
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" socket="/socket"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
<start name="test-terminal_echo">
|
<start name="test-terminal_echo">
|
||||||
@ -89,6 +93,7 @@ set boot_modules {
|
|||||||
libc.lib.so vfs.lib.so pthread.lib.so lwip_legacy.lib.so libc_pipe.lib.so
|
libc.lib.so vfs.lib.so pthread.lib.so lwip_legacy.lib.so libc_pipe.lib.so
|
||||||
tcp_terminal
|
tcp_terminal
|
||||||
test-terminal_echo
|
test-terminal_echo
|
||||||
|
vfs_lwip.lib.so
|
||||||
}
|
}
|
||||||
|
|
||||||
# platform-specific modules
|
# platform-specific modules
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#include <base/child.h>
|
#include <base/child.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
#include <nic/packet_allocator.h>
|
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
TARGET = http_blk
|
TARGET = http_blk
|
||||||
SRC_CC = main.cc http.cc
|
SRC_CC = main.cc http.cc
|
||||||
LIBS = libc libc_lwip_nic_dhcp
|
LIBS = libc
|
||||||
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = tcp_terminal
|
TARGET = tcp_terminal
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = libc pthread libc_lwip_nic_dhcp libc_pipe
|
LIBS = libc pthread libc_pipe
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Some size definitions and macros needed by LwIP.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__ARCH__CC_H__
|
|
||||||
#define __LWIP__ARCH__CC_H__
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <base/fixed_stdint.h>
|
|
||||||
|
|
||||||
typedef genode_uint8_t u8_t;
|
|
||||||
typedef genode_int8_t s8_t;
|
|
||||||
typedef genode_uint16_t u16_t;
|
|
||||||
typedef genode_int16_t s16_t;
|
|
||||||
typedef genode_uint32_t u32_t;
|
|
||||||
typedef genode_int32_t s32_t;
|
|
||||||
|
|
||||||
typedef unsigned long mem_ptr_t;
|
|
||||||
|
|
||||||
/* Define (sn)printf formatters */
|
|
||||||
#define U16_F "u" // we don't have hu
|
|
||||||
#define S16_F "d" // we don't have hd
|
|
||||||
#define X16_F "x" // we don't have hx
|
|
||||||
#define U32_F "u"
|
|
||||||
#define S32_F "d"
|
|
||||||
#define X32_F "x"
|
|
||||||
|
|
||||||
void lwip_printf(const char *format, ...);
|
|
||||||
void lwip_sleep_forever(void);
|
|
||||||
|
|
||||||
#define LWIP_PLATFORM_DIAG(x) do { lwip_printf x; } while(0)
|
|
||||||
|
|
||||||
#ifdef GENODE_RELEASE
|
|
||||||
#define LWIP_PLATFORM_ASSERT(x)
|
|
||||||
#else /* GENODE_RELEASE */
|
|
||||||
#define LWIP_PLATFORM_ASSERT(x) \
|
|
||||||
do { \
|
|
||||||
lwip_printf("Assertion \"%s\" failed at %s:%u\n", \
|
|
||||||
x, __FILE__, __LINE__); \
|
|
||||||
lwip_sleep_forever(); \
|
|
||||||
} while (0)
|
|
||||||
#endif /* GENODE_RELEASE */
|
|
||||||
|
|
||||||
#define PACK_STRUCT_FIELD(x) x
|
|
||||||
#define PACK_STRUCT_STRUCT
|
|
||||||
#define PACK_STRUCT_BEGIN
|
|
||||||
#define PACK_STRUCT_END
|
|
||||||
|
|
||||||
#ifndef BYTE_ORDER
|
|
||||||
#define BYTE_ORDER LITTLE_ENDIAN
|
|
||||||
#endif /* BYTE_ORDER */
|
|
||||||
|
|
||||||
#define mem_realloc realloc
|
|
||||||
|
|
||||||
#endif /* __LWIP__ARCH__CC_H__ */
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Header file with macros needed by LwIP.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__ARCH__PERF_H__
|
|
||||||
#define __LWIP__ARCH__PERF_H__
|
|
||||||
|
|
||||||
#define PERF_START
|
|
||||||
#define PERF_STOP(x)
|
|
||||||
|
|
||||||
#endif /* __LWIP__ARCH__PERF_H__ */
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Platform definitions for certain types in LwIP.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__ARCH__SYS_ARCH_H__
|
|
||||||
#define __LWIP__ARCH__SYS_ARCH_H__
|
|
||||||
|
|
||||||
#include <arch/cc.h>
|
|
||||||
|
|
||||||
struct _sys_sem_t {
|
|
||||||
void* ptr;
|
|
||||||
};
|
|
||||||
typedef struct _sys_sem_t sys_sem_t;
|
|
||||||
|
|
||||||
struct _sys_mbox_t {
|
|
||||||
void* ptr;
|
|
||||||
};
|
|
||||||
typedef struct _sys_mbox_t sys_mbox_t;
|
|
||||||
|
|
||||||
typedef mem_ptr_t sys_thread_t;
|
|
||||||
typedef mem_ptr_t sys_prot_t;
|
|
||||||
|
|
||||||
#define SYS_MBOX_NULL 0
|
|
||||||
#define SYS_SEM_NULL 0
|
|
||||||
|
|
||||||
sys_prot_t sys_arch_protect(void);
|
|
||||||
void sys_arch_unprotect(sys_prot_t pval);
|
|
||||||
|
|
||||||
#endif /* __LWIP__ARCH__SYS_ARCH_H__ */
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Genode-specific lwIP API
|
|
||||||
* \author Christian Helmuth
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2010-02-22
|
|
||||||
*
|
|
||||||
* This header is included from C sources.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__GENODE_H__
|
|
||||||
#define __LWIP__GENODE_H__
|
|
||||||
|
|
||||||
#include <base/fixed_stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Initialize the TCP/IP stack */
|
|
||||||
void lwip_tcpip_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize lwIP for NIC session
|
|
||||||
*
|
|
||||||
* \param ip_addr IPv4 address in network byte order, or zero when requesting
|
|
||||||
* DHCP
|
|
||||||
* \param netmask IPv4 network mask in network byte order
|
|
||||||
* \param gateway IPv4 network-gateway address in network byte order
|
|
||||||
* \param tx_buf_size packet stream buffer size for TX direction
|
|
||||||
* \param rx_buf_size packet stream buffer size for RX direction
|
|
||||||
*
|
|
||||||
* \return 0 on success, or 1 if DHCP failed.
|
|
||||||
*
|
|
||||||
* This function initializes Genode's nic_drv and does optionally send DHCP
|
|
||||||
* requests.
|
|
||||||
*/
|
|
||||||
int lwip_nic_init(genode_int32_t ip_addr,
|
|
||||||
genode_int32_t netmask,
|
|
||||||
genode_int32_t gateway,
|
|
||||||
unsigned long tx_buf_size,
|
|
||||||
unsigned long rx_buf_size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass on link-state changes to lwIP
|
|
||||||
*
|
|
||||||
* \param state current link-state
|
|
||||||
*/
|
|
||||||
void lwip_nic_link_state_changed(int state);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __LWIP__GENODE_H__ */
|
|
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Configuration file for LwIP, adapt it to your needs.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__LWIPOPTS_H__
|
|
||||||
#define __LWIP__LWIPOPTS_H__
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define NO_SYS 0 /* single-threaded? do not touch! */
|
|
||||||
#define SYS_LIGHTWEIGHT_PROT 1 /* do we provide lightweight protection */
|
|
||||||
#define LWIP_ARP 1 /* ARP support */
|
|
||||||
#define LWIP_RAW 0 /* LwIP raw API */
|
|
||||||
#define LWIP_UDP 1 /* UDP support */
|
|
||||||
#define LWIP_TCP 1 /* TCP support */
|
|
||||||
#define LWIP_ICMP 1 /* ICMP support */
|
|
||||||
#define LWIP_DNS 1 /* DNS support */
|
|
||||||
#define LWIP_DHCP 1 /* DHCP support */
|
|
||||||
#define LWIP_SOCKET 1 /* LwIP socket API */
|
|
||||||
#define LWIP_COMPAT_SOCKETS 0 /* Libc compatibility layer */
|
|
||||||
#define LWIP_COMPAT_MUTEX 1 /* use binary semaphore instead of mutex */
|
|
||||||
#define LWIP_NETIF_API 1 /* Network interface API */
|
|
||||||
#define LWIP_NETIF_LOOPBACK 1 /* Looping back to same address? */
|
|
||||||
#define LWIP_HAVE_LOOPIF 1 /* 127.0.0.1 support ? */
|
|
||||||
#define LWIP_STATS 0 /* disable stating */
|
|
||||||
#define LWIP_STATS_DISPLAY 0 /* disable stating display function */
|
|
||||||
#define LWIP_SO_RCVTIMEO 1 /* support timeouts for socket recv */
|
|
||||||
#define LWIP_SO_SNDTIMEO 1 /* support timeouts for socket send */
|
|
||||||
#define LWIP_TCP_TIMESTAMPS 1
|
|
||||||
#define LWIP_SO_RCVBUF 1 /* enable SO_RCVBUF */
|
|
||||||
#define SO_REUSE 1 /* enable SO_REUSE */
|
|
||||||
#define LWIP_WND_SCALE 1 /* enable window scaling */
|
|
||||||
#define TCP_RCV_SCALE 2 /* receive scale factor IETF RFC 1323 */
|
|
||||||
|
|
||||||
#if LWIP_DHCP
|
|
||||||
#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used for interface changes */
|
|
||||||
#define LWIP_NETIF_LINK_CALLBACK 1 /* callback function used for link-state changes */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************
|
|
||||||
** Checksum calculation settings **
|
|
||||||
***********************************/
|
|
||||||
|
|
||||||
/* checksum calculation for outgoing packets can be disabled if the hardware supports it */
|
|
||||||
#define CHECKSUM_GEN_IP 1 /* calculate checksum for outgoing IP packets */
|
|
||||||
#define CHECKSUM_GEN_TCP 1 /* calculate checksum for outgoing TCP packets */
|
|
||||||
|
|
||||||
#define CHECKSUM_CHECK_IP 1 /* check checksum of incoming IP packets */
|
|
||||||
#define CHECKSUM_CHECK_TCP 1 /* check checksum of incoming TCP packets */
|
|
||||||
|
|
||||||
#define LWIP_CHECKSUM_ON_COPY 1 /* calculate checksum during memcpy */
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
** Memory settings **
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#define MEM_LIBC_MALLOC 1
|
|
||||||
#define MEMP_MEM_MALLOC 1
|
|
||||||
/* MEM_ALIGNMENT > 4 e.g. for x86_64 are not supported, see Genode issue #817 */
|
|
||||||
#define MEM_ALIGNMENT 4
|
|
||||||
|
|
||||||
#define DEFAULT_ACCEPTMBOX_SIZE 128
|
|
||||||
#define TCPIP_MBOX_SIZE 128
|
|
||||||
|
|
||||||
#define TCP_MSS 1460
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The TCP window scaling is implemented for servers only, while the client
|
|
||||||
* implementation just uses the lower 16 bits of the TCP_WND configuration
|
|
||||||
* value. We, therefore, maximize the TCP_WND value to ~64K.
|
|
||||||
*/
|
|
||||||
#define TCP_WND ((96 * TCP_MSS) & 0xffff)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The window scale option (http://tools.ietf.org/html/rfc1323) patch of lwIP
|
|
||||||
* definitely works solely for the receive window, not for the send window.
|
|
||||||
* Setting the send window size to the maximum of an 16bit value, 65535,
|
|
||||||
* or multiple of it (x * 65536 - 1) results in the same performance.
|
|
||||||
* Everything else decrease performance.
|
|
||||||
*/
|
|
||||||
#define TCP_SND_BUF (65535)
|
|
||||||
|
|
||||||
#define TCP_SND_QUEUELEN ((32 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
|
|
||||||
|
|
||||||
#define RECV_BUFSIZE_DEFAULT (512*1024)
|
|
||||||
|
|
||||||
#define PBUF_POOL_SIZE 96
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We reduce the maximum segment lifetime from one minute to one second to
|
|
||||||
* avoid queuing up PCBs in TIME-WAIT state. This is the state, PCBs end up
|
|
||||||
* after closing a TCP connection socket at the server side. The number of PCBs
|
|
||||||
* in this state is apparently not limited by the value of 'MEMP_NUM_TCP_PCB'.
|
|
||||||
* One allocation costs around 160 bytes. If clients connect to the server at a
|
|
||||||
* high rate, those allocations accumulate quickly and thereby may exhaust the
|
|
||||||
* memory of the server. By reducing the segment lifetime, PCBs in TIME-WAIT
|
|
||||||
* state are cleaned up from the 'tcp_tw_pcbs' queue in a more timely fashion
|
|
||||||
* (by 'tcp_slowtmr()').
|
|
||||||
*/
|
|
||||||
#define TCP_MSL 1000UL
|
|
||||||
|
|
||||||
#define MEMP_NUM_SYS_TIMEOUT 16
|
|
||||||
#define MEMP_NUM_TCP_PCB 128
|
|
||||||
#define MEMP_NUM_NETCONN (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_RAW_PCB + MEMP_NUM_TCP_PCB_LISTEN - 1)
|
|
||||||
|
|
||||||
void genode_memcpy(void * dst, const void *src, unsigned long size);
|
|
||||||
#define MEMCPY(dst,src,len) genode_memcpy(dst,src,len)
|
|
||||||
|
|
||||||
/********************
|
|
||||||
** Debug settings **
|
|
||||||
********************/
|
|
||||||
|
|
||||||
/* #define LWIP_DEBUG */
|
|
||||||
/* #define DHCP_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define ETHARP_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define NETIF_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define PBUF_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define API_LIB_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define API_MSG_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define SOCKETS_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define ICMP_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define INET_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define IP_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define IP_REASS_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define RAW_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define MEM_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define MEMP_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define SYS_DEBUG LWIP_DBG_ON */
|
|
||||||
/* #define TCP_DEBUG LWIP_DBG_ON */
|
|
||||||
|
|
||||||
#endif /* __LWIP__LWIPOPTS_H__ */
|
|
@ -1,2 +0,0 @@
|
|||||||
INC_DIR += $(call select_from_ports,lwip_legacy)/include/lwip_legacy
|
|
||||||
INC_DIR += $(call select_from_repositories,include/lwip_legacy)
|
|
@ -1,7 +0,0 @@
|
|||||||
SRC_CC = init.cc plugin.cc
|
|
||||||
|
|
||||||
vpath %.cc $(REP_DIR)/src/lib/libc_lwip
|
|
||||||
|
|
||||||
LIBS += lwip_legacy libc
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
|
@ -1,7 +0,0 @@
|
|||||||
SRC_CC = init.cc
|
|
||||||
|
|
||||||
vpath %.cc $(REP_DIR)/src/lib/libc_lwip_loopback
|
|
||||||
|
|
||||||
LIBS += lwip_legacy libc libc_lwip
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
|
@ -1,7 +0,0 @@
|
|||||||
SRC_CC = plugin.cc
|
|
||||||
|
|
||||||
vpath %.cc $(REP_DIR)/src/lib/libc_lwip_nic_dhcp
|
|
||||||
|
|
||||||
LIBS += lwip_legacy libc libc_lwip
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
|
@ -1,51 +0,0 @@
|
|||||||
#
|
|
||||||
# lwIP TCP/IP library
|
|
||||||
#
|
|
||||||
# The library implementes TCP and UDP as well as DNS and DHCP.
|
|
||||||
#
|
|
||||||
|
|
||||||
LWIP_PORT_DIR := $(call select_from_ports,lwip_legacy)
|
|
||||||
LWIP_DIR := $(LWIP_PORT_DIR)/src/lib/lwip_legacy
|
|
||||||
|
|
||||||
# Genode platform files
|
|
||||||
SRC_CC = nic.cc printf.cc sys_arch.cc
|
|
||||||
|
|
||||||
# Core files
|
|
||||||
SRC_C = init.c mem.c memp.c netif.c pbuf.c stats.c udp.c raw.c sys.c \
|
|
||||||
tcp.c tcp_in.c tcp_out.c dhcp.c dns.c timers.c def.c inet_chksum.c
|
|
||||||
|
|
||||||
# IPv4 files
|
|
||||||
SRC_C += icmp.c igmp.c ip4_addr.c ip4.c ip_frag.c
|
|
||||||
|
|
||||||
# API files
|
|
||||||
SRC_C += err.c api_lib.c api_msg.c netbuf.c netdb.c netifapi.c sockets.c \
|
|
||||||
tcpip.c
|
|
||||||
|
|
||||||
# Network interface files
|
|
||||||
SRC_C += etharp.c
|
|
||||||
|
|
||||||
LIBS = alarm libc timed_semaphore
|
|
||||||
|
|
||||||
D_OPTS = ERRNO
|
|
||||||
D_OPTS := $(addprefix -D,$(D_OPTS))
|
|
||||||
CC_DEF += $(D_OPTS)
|
|
||||||
|
|
||||||
LD_OPT += --version-script=$(REP_DIR)/src/lib/lwip_legacy/symbol.map
|
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/include/lwip_legacy \
|
|
||||||
$(LWIP_PORT_DIR)/include/lwip_legacy \
|
|
||||||
$(LWIP_DIR)/src/include \
|
|
||||||
$(LWIP_DIR)/src/include/ipv4 \
|
|
||||||
$(LWIP_DIR)/src/include/api \
|
|
||||||
$(LWIP_DIR)/src/include/netif \
|
|
||||||
$(REP_DIR)/src/lib/lwip_legacy/include
|
|
||||||
|
|
||||||
vpath %.cc $(REP_DIR)/src/lib/lwip_legacy/platform
|
|
||||||
vpath %.c $(LWIP_DIR)/src/core
|
|
||||||
vpath %.c $(LWIP_DIR)/src/core/ipv4
|
|
||||||
vpath %.c $(LWIP_DIR)/src/api
|
|
||||||
vpath %.c $(LWIP_DIR)/src/netif
|
|
||||||
|
|
||||||
SHARED_LIB = yes
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
|
@ -1 +0,0 @@
|
|||||||
7f5610426ed8c4c64903136122d9ba58836cdc89
|
|
@ -1,30 +0,0 @@
|
|||||||
LICENSE := BSD
|
|
||||||
VERSION := git
|
|
||||||
DOWNLOADS := lwip.git window_scaling_patch.file
|
|
||||||
|
|
||||||
URL(lwip) := git://git.savannah.nongnu.org/lwip.git
|
|
||||||
REV(lwip) := fe63f36656bd66b4051bdfab93e351a584337d7c
|
|
||||||
DIR(lwip) := src/lib/lwip_legacy
|
|
||||||
|
|
||||||
URL(window_scaling_patch) := https://savannah.nongnu.org/patch/download.php?file_id=28026
|
|
||||||
NAME(window_scaling_patch) := src/lib/lwip_legacy/window_scaling.patch
|
|
||||||
SHA(window_scaling_patch) := b8dcaa2e0508208222e3e84a42cbe3eba6f6bfc728a5ba62d0d6c4c0c548e46f
|
|
||||||
|
|
||||||
PATCHES := $(addprefix src/lib/lwip_legacy/,window_scaling.patch \
|
|
||||||
errno.patch \
|
|
||||||
libc_select_notify.patch \
|
|
||||||
sockets_c_errno.patch \
|
|
||||||
sol_socket_definition.patch \
|
|
||||||
remove_warnings.patch \
|
|
||||||
api_msg.patch \
|
|
||||||
nonblocking_connect.patch)
|
|
||||||
|
|
||||||
PATCH_OPT := -p1 -d src/lib/lwip_legacy
|
|
||||||
|
|
||||||
DIRS := include/lwip_legacy/lwip include/lwip_legacy/netif
|
|
||||||
|
|
||||||
DIR_CONTENT(include/lwip_legacy/lwip) := src/lib/lwip_legacy/src/include/lwip/*.h \
|
|
||||||
src/lib/lwip_legacy/src/include/ipv4/lwip/*.h \
|
|
||||||
src/lib/lwip_legacy/src/include/ipv6/lwip/*.h
|
|
||||||
|
|
||||||
DIR_CONTENT(include/lwip_legacy/netif) := src/lib/lwip_legacy/src/include/netif/*.h
|
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief lwip plugin creation
|
|
||||||
* \author Christian Prochaska
|
|
||||||
* \date 2010-02-12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void create_lwip_plugin();
|
|
||||||
|
|
||||||
void __attribute__((constructor)) init_libc_lwip(void)
|
|
||||||
{
|
|
||||||
create_lwip_plugin();
|
|
||||||
}
|
|
@ -1,548 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Lwip plugin implementation
|
|
||||||
* \author Christian Prochaska
|
|
||||||
* \author Norman Feske
|
|
||||||
* \date 2010-02-12
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <base/env.h>
|
|
||||||
#include <base/log.h>
|
|
||||||
|
|
||||||
#define LWIP_COMPAT_SOCKETS 0
|
|
||||||
|
|
||||||
/* rename lwip functions that have the same name in the libc to lwip_*() */
|
|
||||||
#define addrinfo lwip_addrinfo
|
|
||||||
#define fd_set lwip_fd_set
|
|
||||||
#define hostent lwip_hostent
|
|
||||||
#define linger lwip_linger
|
|
||||||
#define sockaddr lwip_sockaddr
|
|
||||||
#define timeval lwip_timeval
|
|
||||||
|
|
||||||
/* the extern "C" declaration is missing in lwip/netdb.h */
|
|
||||||
extern "C" {
|
|
||||||
#include <lwip/netdb.h>
|
|
||||||
}
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
#include <lwip/sockets.h>
|
|
||||||
|
|
||||||
/* lwip and libc have different definitions for the FD_* macros and renaming
|
|
||||||
* of the macros is not possible, so wrapper functions are needed at this
|
|
||||||
* place */
|
|
||||||
|
|
||||||
static inline void lwip_FD_ZERO(lwip_fd_set *set)
|
|
||||||
{
|
|
||||||
FD_ZERO(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lwip_FD_ISSET(int lwip_fd, lwip_fd_set *set)
|
|
||||||
{
|
|
||||||
return FD_ISSET(lwip_fd, set);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void lwip_FD_SET(int lwip_fd, lwip_fd_set *set)
|
|
||||||
{
|
|
||||||
FD_SET(lwip_fd, set);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr long lwip_FIONBIO = FIONBIO;
|
|
||||||
static constexpr long lwip_FIONREAD = FIONREAD;
|
|
||||||
static constexpr int lwip_O_NONBLOCK = O_NONBLOCK;
|
|
||||||
|
|
||||||
/* undefine lwip type names that are also defined in libc headers and have
|
|
||||||
* been renamed to lwip_*() */
|
|
||||||
#undef addrinfo
|
|
||||||
#undef fd_set
|
|
||||||
#undef hostent
|
|
||||||
#undef linger
|
|
||||||
#undef sockaddr
|
|
||||||
#undef timeval
|
|
||||||
|
|
||||||
/* undefine lwip macros that are also defined in libc headers and cannot be
|
|
||||||
* renamed */
|
|
||||||
#undef AF_INET6
|
|
||||||
#undef BIG_ENDIAN
|
|
||||||
#undef BYTE_ORDER
|
|
||||||
#undef FD_CLR
|
|
||||||
#undef FD_ISSET
|
|
||||||
#undef FD_SET
|
|
||||||
#undef FD_ZERO
|
|
||||||
#undef FIONBIO
|
|
||||||
#undef FIONREAD
|
|
||||||
#undef O_NDELAY
|
|
||||||
#undef O_NONBLOCK
|
|
||||||
#undef HOST_NOT_FOUND
|
|
||||||
#undef IOCPARM_MASK
|
|
||||||
#undef IOC_VOID
|
|
||||||
#undef IOC_OUT
|
|
||||||
#undef IOC_IN
|
|
||||||
#undef _IO
|
|
||||||
#undef _IOR
|
|
||||||
#undef _IOW
|
|
||||||
#undef LITTLE_ENDIAN
|
|
||||||
#undef MSG_DONTWAIT
|
|
||||||
#undef MSG_OOB
|
|
||||||
#undef MSG_PEEK
|
|
||||||
#undef MSG_WAITALL
|
|
||||||
#undef NO_DATA
|
|
||||||
#undef NO_RECOVERY
|
|
||||||
#undef EAI_FAIL
|
|
||||||
#undef EAI_MEMORY
|
|
||||||
#undef EAI_NONAME
|
|
||||||
#undef EAI_SERVICE
|
|
||||||
#undef SIOCATMARK
|
|
||||||
#undef SIOCGHIWAT
|
|
||||||
#undef SIOCGLOWAT
|
|
||||||
#undef SIOCSHIWAT
|
|
||||||
#undef SIOCSLOWAT
|
|
||||||
#undef SOL_SOCKET
|
|
||||||
#undef TRY_AGAIN
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
** Plugin interface **
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
#include <libc-plugin/fd_alloc.h>
|
|
||||||
#include <libc-plugin/plugin_registry.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the lwip plugin, we only use the lwip file descriptor as context
|
|
||||||
*/
|
|
||||||
class Plugin_context : public Libc::Plugin_context
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
int _lwip_fd;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* \param lwip_fd file descriptor used for interacting with the
|
|
||||||
* socket API of lwip
|
|
||||||
*/
|
|
||||||
Plugin_context(int lwip_fd) : _lwip_fd(lwip_fd) { }
|
|
||||||
|
|
||||||
int lwip_fd() const { return _lwip_fd; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static inline Plugin_context *context(Libc::File_descriptor *fd)
|
|
||||||
{
|
|
||||||
return static_cast<Plugin_context *>(fd->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int get_lwip_fd(Libc::File_descriptor *sockfdo)
|
|
||||||
{
|
|
||||||
return context(sockfdo)->lwip_fd();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct Plugin : Libc::Plugin
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Plugin();
|
|
||||||
|
|
||||||
bool supports_select(int nfds,
|
|
||||||
fd_set *readfds,
|
|
||||||
fd_set *writefds,
|
|
||||||
fd_set *exceptfds,
|
|
||||||
struct timeval *timeout) override;
|
|
||||||
bool supports_socket(int domain, int type, int protocol) override;
|
|
||||||
|
|
||||||
Libc::File_descriptor *accept(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr,
|
|
||||||
socklen_t *addrlen) override;
|
|
||||||
int bind(Libc::File_descriptor *sockfdo,
|
|
||||||
const struct sockaddr *addr,
|
|
||||||
socklen_t addrlen) override;
|
|
||||||
int close(Libc::File_descriptor *fdo) override;
|
|
||||||
int connect(Libc::File_descriptor *sockfdo,
|
|
||||||
const struct sockaddr *addr,
|
|
||||||
socklen_t addrlen) override;
|
|
||||||
int fcntl(Libc::File_descriptor *sockfdo, int cmd, long val) override;
|
|
||||||
int getpeername(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr,
|
|
||||||
socklen_t *addrlen) override;
|
|
||||||
int getsockname(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr,
|
|
||||||
socklen_t *addrlen) override;
|
|
||||||
int getsockopt(Libc::File_descriptor *sockfdo, int level,
|
|
||||||
int optname, void *optval,
|
|
||||||
socklen_t *optlen) override;
|
|
||||||
int ioctl(Libc::File_descriptor *sockfdo, int request, char *argp) override;
|
|
||||||
int listen(Libc::File_descriptor *sockfdo, int backlog) override;
|
|
||||||
ssize_t read(Libc::File_descriptor *fdo, void *buf, ::size_t count) override;
|
|
||||||
int shutdown(Libc::File_descriptor *fdo, int) override;
|
|
||||||
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
|
||||||
fd_set *exceptfds, struct timeval *timeout) override;
|
|
||||||
ssize_t send(Libc::File_descriptor *, const void *buf, ::size_t len, int flags) override;
|
|
||||||
ssize_t sendto(Libc::File_descriptor *, const void *buf,
|
|
||||||
::size_t len, int flags,
|
|
||||||
const struct sockaddr *dest_addr,
|
|
||||||
socklen_t addrlen) override;
|
|
||||||
ssize_t recv(Libc::File_descriptor *, void *buf, ::size_t len, int flags) override;
|
|
||||||
ssize_t recvfrom(Libc::File_descriptor *, void *buf, ::size_t len, int flags,
|
|
||||||
struct sockaddr *src_addr, socklen_t *addrlen) override;
|
|
||||||
int setsockopt(Libc::File_descriptor *sockfdo, int level,
|
|
||||||
int optname, const void *optval,
|
|
||||||
socklen_t optlen) override;
|
|
||||||
Libc::File_descriptor *socket(int domain, int type, int protocol) override;
|
|
||||||
ssize_t write(Libc::File_descriptor *fdo, const void *buf, ::size_t count) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Plugin::Plugin()
|
|
||||||
{
|
|
||||||
Genode::log("using the lwIP libc plugin");
|
|
||||||
|
|
||||||
lwip_tcpip_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Plugin::supports_select(int nfds,
|
|
||||||
fd_set *readfds,
|
|
||||||
fd_set *writefds,
|
|
||||||
fd_set *exceptfds,
|
|
||||||
struct timeval *timeout)
|
|
||||||
{
|
|
||||||
Libc::File_descriptor *fdo;
|
|
||||||
/* return true if any file descriptor which is marked set in one of
|
|
||||||
* the sets belongs to this plugin */
|
|
||||||
for (int libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
|
||||||
if (FD_ISSET(libc_fd, readfds)
|
|
||||||
|| FD_ISSET(libc_fd, writefds) || FD_ISSET(libc_fd, exceptfds)) {
|
|
||||||
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
if (fdo && (fdo->plugin == this)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Plugin::supports_socket(int domain, int, int)
|
|
||||||
{
|
|
||||||
if (domain == AF_INET)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Libc::File_descriptor *Plugin::accept(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr, socklen_t *addrlen)
|
|
||||||
{
|
|
||||||
int lwip_fd = lwip_accept(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
|
|
||||||
|
|
||||||
if (lwip_fd == -1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(lwip_fd);
|
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
|
||||||
|
|
||||||
if (!fd)
|
|
||||||
Genode::error("could not allocate file descriptor");
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::bind(Libc::File_descriptor *sockfdo, const struct sockaddr *addr,
|
|
||||||
socklen_t addrlen)
|
|
||||||
{
|
|
||||||
return lwip_bind(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::close(Libc::File_descriptor *fdo)
|
|
||||||
{
|
|
||||||
int result = lwip_close(get_lwip_fd(fdo));
|
|
||||||
|
|
||||||
if (context(fdo))
|
|
||||||
Genode::destroy(Genode::env()->heap(), context(fdo));
|
|
||||||
Libc::file_descriptor_allocator()->free(fdo);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::connect(Libc::File_descriptor *sockfdo,
|
|
||||||
const struct sockaddr *addr,
|
|
||||||
socklen_t addrlen)
|
|
||||||
{
|
|
||||||
return lwip_connect(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::fcntl(Libc::File_descriptor *sockfdo, int cmd, long val)
|
|
||||||
{
|
|
||||||
int s = get_lwip_fd(sockfdo);
|
|
||||||
int result = -1;
|
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case F_GETFL:
|
|
||||||
/* lwip_fcntl() supports only the 'O_NONBLOCK' flag */
|
|
||||||
result = lwip_fcntl(s, cmd, val);
|
|
||||||
if (result == lwip_O_NONBLOCK)
|
|
||||||
result = O_NONBLOCK;
|
|
||||||
break;
|
|
||||||
case F_SETFL:
|
|
||||||
/*
|
|
||||||
* lwip_fcntl() supports only the 'O_NONBLOCK' flag and only if
|
|
||||||
* no other flag is set.
|
|
||||||
*/
|
|
||||||
result = lwip_fcntl(s, cmd, (val & O_NONBLOCK) ? lwip_O_NONBLOCK : 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Genode::error("libc_lwip: unsupported fcntl() request: ", cmd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::getpeername(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr,
|
|
||||||
socklen_t *addrlen)
|
|
||||||
{
|
|
||||||
return lwip_getpeername(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::getsockname(Libc::File_descriptor *sockfdo,
|
|
||||||
struct sockaddr *addr,
|
|
||||||
socklen_t *addrlen)
|
|
||||||
{
|
|
||||||
return lwip_getsockname(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::getsockopt(Libc::File_descriptor *sockfdo, int level,
|
|
||||||
int optname, void *optval, socklen_t *optlen)
|
|
||||||
{
|
|
||||||
return lwip_getsockopt(get_lwip_fd(sockfdo), level, optname, optval, optlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Plugin::ioctl(Libc::File_descriptor *sockfdo, int request, char *argp)
|
|
||||||
{
|
|
||||||
switch (request) {
|
|
||||||
case FIONBIO:
|
|
||||||
return lwip_ioctl(get_lwip_fd(sockfdo), lwip_FIONBIO, argp);
|
|
||||||
break;
|
|
||||||
case FIONREAD:
|
|
||||||
return lwip_ioctl(get_lwip_fd(sockfdo), lwip_FIONREAD, argp);;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Genode::error("unsupported ioctl() request");
|
|
||||||
errno = ENOSYS;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::listen(Libc::File_descriptor *sockfdo, int backlog)
|
|
||||||
{
|
|
||||||
return lwip_listen(get_lwip_fd(sockfdo), backlog);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::read(Libc::File_descriptor *fdo, void *buf, ::size_t count)
|
|
||||||
{
|
|
||||||
return lwip_read(get_lwip_fd(fdo), buf, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::shutdown(Libc::File_descriptor *sockfdo, int how)
|
|
||||||
{
|
|
||||||
return lwip_shutdown(get_lwip_fd(sockfdo), how);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::select(int nfds,
|
|
||||||
fd_set *readfds,
|
|
||||||
fd_set *writefds,
|
|
||||||
fd_set *exceptfds,
|
|
||||||
struct timeval *timeout)
|
|
||||||
{
|
|
||||||
Libc::File_descriptor *fdo;
|
|
||||||
lwip_fd_set lwip_readfds;
|
|
||||||
lwip_fd_set lwip_writefds;
|
|
||||||
lwip_fd_set lwip_exceptfds;
|
|
||||||
int libc_fd;
|
|
||||||
int lwip_fd;
|
|
||||||
int highest_lwip_fd = -2;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
lwip_FD_ZERO(&lwip_readfds);
|
|
||||||
lwip_FD_ZERO(&lwip_writefds);
|
|
||||||
lwip_FD_ZERO(&lwip_exceptfds);
|
|
||||||
|
|
||||||
for (libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
|
||||||
|
|
||||||
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
|
|
||||||
/* handle only libc_fds that belong to this plugin */
|
|
||||||
if (!fdo || (fdo->plugin != this))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (FD_ISSET(libc_fd, readfds) ||
|
|
||||||
FD_ISSET(libc_fd, writefds) ||
|
|
||||||
FD_ISSET(libc_fd, exceptfds)) {
|
|
||||||
|
|
||||||
lwip_fd = get_lwip_fd(fdo);
|
|
||||||
|
|
||||||
if (lwip_fd > highest_lwip_fd) {
|
|
||||||
highest_lwip_fd = lwip_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_ISSET(libc_fd, readfds)) {
|
|
||||||
lwip_FD_SET(lwip_fd, &lwip_readfds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_ISSET(libc_fd, writefds)) {
|
|
||||||
lwip_FD_SET(lwip_fd, &lwip_writefds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_ISSET(libc_fd, exceptfds)) {
|
|
||||||
lwip_FD_SET(lwip_fd, &lwip_exceptfds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = lwip_select(highest_lwip_fd + 1,
|
|
||||||
&lwip_readfds,
|
|
||||||
&lwip_writefds,
|
|
||||||
&lwip_exceptfds,
|
|
||||||
(struct lwip_timeval*)timeout);
|
|
||||||
|
|
||||||
if (result > 0) {
|
|
||||||
|
|
||||||
/* clear result sets */
|
|
||||||
FD_ZERO(readfds);
|
|
||||||
FD_ZERO(writefds);
|
|
||||||
FD_ZERO(exceptfds);
|
|
||||||
|
|
||||||
for (lwip_fd = 0; lwip_fd <= highest_lwip_fd; lwip_fd++) {
|
|
||||||
|
|
||||||
/* find an lwip_fd which is in the set */
|
|
||||||
|
|
||||||
if (lwip_FD_ISSET(lwip_fd, &lwip_readfds) ||
|
|
||||||
lwip_FD_ISSET(lwip_fd, &lwip_writefds) ||
|
|
||||||
lwip_FD_ISSET(lwip_fd, &lwip_exceptfds)) {
|
|
||||||
|
|
||||||
/* find matching libc_fd for lwip_fd */
|
|
||||||
for (libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
|
||||||
|
|
||||||
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
|
|
||||||
if (fdo && (fdo->plugin == this) &&
|
|
||||||
(get_lwip_fd(fdo) == lwip_fd)) {
|
|
||||||
|
|
||||||
if (lwip_FD_ISSET(lwip_fd, &lwip_readfds)) {
|
|
||||||
FD_SET(libc_fd, readfds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lwip_FD_ISSET(lwip_fd, &lwip_writefds)) {
|
|
||||||
FD_SET(libc_fd, writefds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lwip_FD_ISSET(lwip_fd, &lwip_exceptfds)) {
|
|
||||||
FD_SET(libc_fd, exceptfds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::recv(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags)
|
|
||||||
{
|
|
||||||
return lwip_recv(get_lwip_fd(sockfdo), buf, len, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::recvfrom(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags,
|
|
||||||
struct sockaddr *src_addr, socklen_t *addrlen)
|
|
||||||
{
|
|
||||||
return lwip_recvfrom(get_lwip_fd(sockfdo), buf, len, flags,
|
|
||||||
(struct lwip_sockaddr *)src_addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::send(Libc::File_descriptor *sockfdo, const void *buf, ::size_t len, int flags)
|
|
||||||
{
|
|
||||||
return lwip_send(get_lwip_fd(sockfdo), buf, len, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::sendto(Libc::File_descriptor *sockfdo, const void *buf,
|
|
||||||
::size_t len, int flags,
|
|
||||||
const struct sockaddr *dest_addr, socklen_t addrlen)
|
|
||||||
{
|
|
||||||
return lwip_sendto(get_lwip_fd(sockfdo), buf, len, flags,
|
|
||||||
(struct lwip_sockaddr *)dest_addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Plugin::setsockopt(Libc::File_descriptor *sockfdo, int level,
|
|
||||||
int optname, const void *optval,
|
|
||||||
socklen_t optlen)
|
|
||||||
{
|
|
||||||
return lwip_setsockopt(get_lwip_fd(sockfdo), level, optname, optval, optlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol)
|
|
||||||
{
|
|
||||||
int lwip_fd = lwip_socket(domain, type, protocol);
|
|
||||||
|
|
||||||
if (lwip_fd == -1) {
|
|
||||||
Genode::error("lwip_socket() failed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(lwip_fd);
|
|
||||||
return Libc::file_descriptor_allocator()->alloc(this, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t Plugin::write(Libc::File_descriptor *fdo, const void *buf, ::size_t count)
|
|
||||||
{
|
|
||||||
return lwip_write(get_lwip_fd(fdo), buf, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} /* unnamed namespace */
|
|
||||||
|
|
||||||
|
|
||||||
void create_lwip_plugin()
|
|
||||||
{
|
|
||||||
static Plugin lwip_plugin;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief lwip loopback interface initialization
|
|
||||||
* \author Christian Prochaska
|
|
||||||
* \date 2010-04-29
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <base/log.h>
|
|
||||||
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
|
|
||||||
extern void create_lwip_plugin();
|
|
||||||
|
|
||||||
void __attribute__((constructor)) init_loopback(void)
|
|
||||||
{
|
|
||||||
Genode::log(__func__);
|
|
||||||
|
|
||||||
/* make sure the libc_lwip plugin has been created */
|
|
||||||
create_lwip_plugin();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As of lwip-1.4.x this is not needed anymore because lwip
|
|
||||||
* now always creates a loopback device. This plug-in will
|
|
||||||
* be removed in the future but for now keep it around so
|
|
||||||
* we currently do not need to update the other targets that
|
|
||||||
* depend on it.
|
|
||||||
*
|
|
||||||
* lwip_loopback_init();
|
|
||||||
*/
|
|
||||||
}
|
|
@ -1,353 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Libc plugin providing lwIP's DNS server address in the
|
|
||||||
* '/socket/nameserver' file
|
|
||||||
* \author Christian Prochaska
|
|
||||||
* \date 2013-05-02
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* lwip includes */
|
|
||||||
#include <lwip/err.h>
|
|
||||||
#include <lwip/ip_addr.h>
|
|
||||||
#include <lwip/dns.h>
|
|
||||||
|
|
||||||
/* fix redefinition warnings */
|
|
||||||
#undef LITTLE_ENDIAN
|
|
||||||
#undef BIG_ENDIAN
|
|
||||||
#undef BYTE_ORDER
|
|
||||||
|
|
||||||
/* libc plugin interface */
|
|
||||||
#include <libc-plugin/plugin.h>
|
|
||||||
#include <libc-plugin/fd_alloc.h>
|
|
||||||
|
|
||||||
/* libc includes */
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <base/attached_rom_dataspace.h>
|
|
||||||
#include <base/env.h>
|
|
||||||
#include <base/heap.h>
|
|
||||||
#include <util/misc_math.h>
|
|
||||||
|
|
||||||
#include <base/log.h>
|
|
||||||
#include <parent/parent.h>
|
|
||||||
|
|
||||||
#include <nic/packet_allocator.h>
|
|
||||||
#include <util/string.h>
|
|
||||||
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
|
|
||||||
#undef AF_INET6
|
|
||||||
#undef MSG_PEEK
|
|
||||||
#undef MSG_WAITALL
|
|
||||||
#undef MSG_OOB
|
|
||||||
#undef MSG_DONTWAIT
|
|
||||||
|
|
||||||
namespace Lwip {
|
|
||||||
extern "C" {
|
|
||||||
#include <lwip/sockets.h>
|
|
||||||
#include <lwip/api.h>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void create_lwip_plugin();
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class Plugin_context : public Libc::Plugin_context
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
int _status_flags;
|
|
||||||
off_t _seek_offset;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Plugin_context() : _status_flags(0), _seek_offset(0) { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set/get file status status flags
|
|
||||||
*/
|
|
||||||
void status_flags(int flags) { _status_flags = flags; }
|
|
||||||
int status_flags() { return _status_flags; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set seek offset
|
|
||||||
*/
|
|
||||||
void seek_offset(size_t seek_offset) { _seek_offset = seek_offset; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return seek offset
|
|
||||||
*/
|
|
||||||
off_t seek_offset() const { return _seek_offset; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advance current seek position by 'incr' number of bytes
|
|
||||||
*/
|
|
||||||
void advance_seek_offset(size_t incr)
|
|
||||||
{
|
|
||||||
_seek_offset += incr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void infinite_seek_offset()
|
|
||||||
{
|
|
||||||
_seek_offset = ~0;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static inline Plugin_context *context(Libc::File_descriptor *fd)
|
|
||||||
{
|
|
||||||
return static_cast<Plugin_context *>(fd->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin : public Libc::Plugin
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Genode::Constructible<Genode::Heap> _heap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File name this plugin feels responsible for
|
|
||||||
*/
|
|
||||||
static char const *_file_name() { return "/socket/nameserver"; }
|
|
||||||
|
|
||||||
const char *_file_content()
|
|
||||||
{
|
|
||||||
static char result[32];
|
|
||||||
ip_addr_t nameserver_ip = dns_getserver(0);
|
|
||||||
snprintf(result, sizeof(result), "%s\n",
|
|
||||||
ipaddr_ntoa(&nameserver_ip));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
::off_t _file_size(Libc::File_descriptor *fd)
|
|
||||||
{
|
|
||||||
struct stat stat_buf;
|
|
||||||
if (fstat(fd, &stat_buf) == -1)
|
|
||||||
return -1;
|
|
||||||
return stat_buf.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Plugin() { }
|
|
||||||
|
|
||||||
bool supports_stat(const char *path)
|
|
||||||
{
|
|
||||||
return (Genode::strcmp(path, "/socket") == 0) ||
|
|
||||||
(Genode::strcmp(path, _file_name()) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool supports_open(const char *path, int flags)
|
|
||||||
{
|
|
||||||
return (Genode::strcmp(path, _file_name()) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Libc::File_descriptor *open(const char *pathname, int flags)
|
|
||||||
{
|
|
||||||
Plugin_context *context = new (*_heap) Plugin_context;
|
|
||||||
context->status_flags(flags);
|
|
||||||
return Libc::file_descriptor_allocator()->alloc(this, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
int close(Libc::File_descriptor *fd)
|
|
||||||
{
|
|
||||||
Genode::destroy(*_heap, context(fd));
|
|
||||||
Libc::file_descriptor_allocator()->free(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stat(const char *path, struct stat *buf)
|
|
||||||
{
|
|
||||||
if (buf) {
|
|
||||||
Genode::memset(buf, 0, sizeof(struct stat));
|
|
||||||
if (Genode::strcmp(path, "/socket") == 0)
|
|
||||||
buf->st_mode = S_IFDIR;
|
|
||||||
else if (Genode::strcmp(path, _file_name()) == 0) {
|
|
||||||
buf->st_mode = S_IFREG;
|
|
||||||
buf->st_size = strlen(_file_content()) + 1;
|
|
||||||
} else {
|
|
||||||
errno = ENOENT;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fstat(Libc::File_descriptor *fd, struct stat *buf)
|
|
||||||
{
|
|
||||||
if (buf) {
|
|
||||||
Genode::memset(buf, 0, sizeof(struct stat));
|
|
||||||
buf->st_mode = S_IFREG;
|
|
||||||
buf->st_size = strlen(_file_content()) + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence)
|
|
||||||
{
|
|
||||||
switch (whence) {
|
|
||||||
|
|
||||||
case SEEK_SET:
|
|
||||||
context(fd)->seek_offset(offset);
|
|
||||||
return offset;
|
|
||||||
|
|
||||||
case SEEK_CUR:
|
|
||||||
context(fd)->advance_seek_offset(offset);
|
|
||||||
return context(fd)->seek_offset();
|
|
||||||
|
|
||||||
case SEEK_END:
|
|
||||||
if (offset != 0) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
context(fd)->infinite_seek_offset();
|
|
||||||
return _file_size(fd);
|
|
||||||
|
|
||||||
default:
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count)
|
|
||||||
{
|
|
||||||
::off_t seek_offset = context(fd)->seek_offset();
|
|
||||||
|
|
||||||
if (seek_offset >= _file_size(fd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const char *content = _file_content();
|
|
||||||
count = Genode::min((::off_t)count, _file_size(fd) - seek_offset);
|
|
||||||
|
|
||||||
memcpy(buf, &content[seek_offset], count);
|
|
||||||
|
|
||||||
context(fd)->advance_seek_offset(count);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
|
||||||
{
|
|
||||||
switch (cmd) {
|
|
||||||
case F_GETFL: return context(fd)->status_flags();
|
|
||||||
default: Genode::error("fcntl(): command ", cmd, " not supported", cmd); return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(Libc::Env &env) override
|
|
||||||
{
|
|
||||||
_heap.construct(env.ram(), env.rm());
|
|
||||||
|
|
||||||
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
|
|
||||||
|
|
||||||
Genode::log(__func__);
|
|
||||||
|
|
||||||
char ip_addr_str[16] = {0};
|
|
||||||
char netmask_str[16] = {0};
|
|
||||||
char gateway_str[16] = {0};
|
|
||||||
|
|
||||||
genode_int32_t ip_addr = 0;
|
|
||||||
genode_int32_t netmask = 0;
|
|
||||||
genode_int32_t gateway = 0;
|
|
||||||
Genode::Number_of_bytes tx_buf_size(BUF_SIZE);
|
|
||||||
Genode::Number_of_bytes rx_buf_size(BUF_SIZE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Genode::Attached_rom_dataspace config(env, "config");
|
|
||||||
Genode::Xml_node libc_node = config.xml().sub_node("libc");
|
|
||||||
|
|
||||||
try {
|
|
||||||
libc_node.attribute("ip_addr").value(ip_addr_str, sizeof(ip_addr_str));
|
|
||||||
} catch(...) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
libc_node.attribute("netmask").value(netmask_str, sizeof(netmask_str));
|
|
||||||
} catch(...) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
libc_node.attribute("gateway").value(gateway_str, sizeof(gateway_str));
|
|
||||||
} catch(...) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
libc_node.attribute("tx_buf_size").value(&tx_buf_size);
|
|
||||||
} catch(...) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
libc_node.attribute("rx_buf_size").value(&rx_buf_size);
|
|
||||||
} catch(...) { }
|
|
||||||
|
|
||||||
/* either none or all 3 interface attributes must exist */
|
|
||||||
if ((strlen(ip_addr_str) != 0) ||
|
|
||||||
(strlen(netmask_str) != 0) ||
|
|
||||||
(strlen(gateway_str) != 0)) {
|
|
||||||
if (strlen(ip_addr_str) == 0) {
|
|
||||||
Genode::error("missing \"ip_addr\" attribute. Ignoring network interface config.");
|
|
||||||
throw Genode::Xml_node::Nonexistent_attribute();
|
|
||||||
} else if (strlen(netmask_str) == 0) {
|
|
||||||
Genode::error("missing \"netmask\" attribute. Ignoring network interface config.");
|
|
||||||
throw Genode::Xml_node::Nonexistent_attribute();
|
|
||||||
} else if (strlen(gateway_str) == 0) {
|
|
||||||
Genode::error("missing \"gateway\" attribute. Ignoring network interface config.");
|
|
||||||
throw Genode::Xml_node::Nonexistent_attribute();
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
Genode::log("static network interface: "
|
|
||||||
"ip_addr=", Genode::Cstring(ip_addr_str), " "
|
|
||||||
"netmask=", Genode::Cstring(netmask_str), " "
|
|
||||||
"gateway=", Genode::Cstring(gateway_str));
|
|
||||||
|
|
||||||
genode_uint32_t ip, nm, gw;
|
|
||||||
|
|
||||||
ip = inet_addr(ip_addr_str);
|
|
||||||
nm = inet_addr(netmask_str);
|
|
||||||
gw = inet_addr(gateway_str);
|
|
||||||
|
|
||||||
if (ip == INADDR_NONE || nm == INADDR_NONE || gw == INADDR_NONE) {
|
|
||||||
Genode::error("invalid network interface config");
|
|
||||||
throw -1;
|
|
||||||
} else {
|
|
||||||
ip_addr = ip;
|
|
||||||
netmask = nm;
|
|
||||||
gateway = gw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
Genode::log("Using DHCP for interface configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the libc_lwip plugin has been created */
|
|
||||||
create_lwip_plugin();
|
|
||||||
|
|
||||||
try {
|
|
||||||
lwip_nic_init(ip_addr, netmask, gateway,
|
|
||||||
(Genode::size_t)tx_buf_size, (Genode::size_t)rx_buf_size);
|
|
||||||
}
|
|
||||||
catch (Genode::Service_denied) { /* ignore for now */ }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} /* unnamed namespace */
|
|
||||||
|
|
||||||
|
|
||||||
void __attribute__((constructor)) init_libc_lwip_dhcp(void)
|
|
||||||
{
|
|
||||||
static Plugin plugin;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
The write offset was not always reset after a write finished resulting in the
|
|
||||||
failed assertion "already writing or closing".
|
|
||||||
|
|
||||||
--- a/src/api/api_msg.c
|
|
||||||
+++ b/src/api/api_msg.c
|
|
||||||
@@ -1340,6 +1340,7 @@ err_mem:
|
|
||||||
and back to application task */
|
|
||||||
conn->current_msg->err = err;
|
|
||||||
conn->current_msg = NULL;
|
|
||||||
+ conn->write_offset = 0;
|
|
||||||
conn->state = NETCONN_NONE;
|
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
|
||||||
if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)
|
|
@ -1,15 +0,0 @@
|
|||||||
--- a/src/include/lwip/arch.h
|
|
||||||
+++ b/src/include/lwip/arch.h
|
|
||||||
@@ -208,6 +208,12 @@ extern "C" {
|
|
||||||
extern int errno;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#else
|
|
||||||
+
|
|
||||||
+#include <errno.h>
|
|
||||||
+/* errno codes which are not defined in Genode libc's errno.h */
|
|
||||||
+#define ENSRNOTFOUND 163 /* Domain name not found */
|
|
||||||
+
|
|
||||||
#endif /* LWIP_PROVIDE_ERRNO */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief LwIP Genode ethernet interface
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-05
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LWIP__NIC_H_
|
|
||||||
#define _LWIP__NIC_H_
|
|
||||||
|
|
||||||
struct netif_buf_sizes {
|
|
||||||
__SIZE_TYPE__ tx_buf_size;
|
|
||||||
__SIZE_TYPE__ rx_buf_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the genode nic backend.
|
|
||||||
*
|
|
||||||
* \param netif pointer to struct, where nic related stuff is registered.
|
|
||||||
*/
|
|
||||||
err_t genode_netif_init(struct netif *netif);
|
|
||||||
|
|
||||||
#endif //_LWIP__NIC_H_
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Ring buffer implementation.
|
|
||||||
* \author Norman Feske
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-10-29
|
|
||||||
*
|
|
||||||
* This ring buffer implementation is taken from the os repository.
|
|
||||||
* In contrast to the original implementation this one lets pass
|
|
||||||
* timeouts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__INCLUDE__RING_BUFFER_H__
|
|
||||||
#define __LWIP__INCLUDE__RING_BUFFER_H__
|
|
||||||
|
|
||||||
#include <base/exception.h>
|
|
||||||
#include <util/string.h>
|
|
||||||
|
|
||||||
#include <os/timed_semaphore.h>
|
|
||||||
|
|
||||||
namespace Lwip {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ring buffer
|
|
||||||
*
|
|
||||||
* The ring buffer manages its elements as values.
|
|
||||||
* When inserting an element, a copy of the element is
|
|
||||||
* stored in the buffer. Hence, the ring buffer is suited
|
|
||||||
* for simple plain-data element types.
|
|
||||||
*/
|
|
||||||
class Ring_buffer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
enum Constants { QUEUE_SIZE=128 };
|
|
||||||
|
|
||||||
int _head;
|
|
||||||
int _tail;
|
|
||||||
Genode::Timed_semaphore _sem; /* element counter */
|
|
||||||
Genode::Lock _head_lock; /* synchronize add */
|
|
||||||
|
|
||||||
void* _queue[QUEUE_SIZE];
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
class Overflow : public Genode::Exception { };
|
|
||||||
|
|
||||||
static const Genode::Alarm::Time NO_BLOCK = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Ring_buffer() : _head(0), _tail(0)
|
|
||||||
{
|
|
||||||
Genode::memset(_queue, 0, sizeof(_queue));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place element into ring buffer
|
|
||||||
*
|
|
||||||
* If the ring buffer is full, this function
|
|
||||||
* throws an Overflow exception.
|
|
||||||
*/
|
|
||||||
void add(void* ev)
|
|
||||||
{
|
|
||||||
Genode::Lock::Guard lock_guard(_head_lock);
|
|
||||||
|
|
||||||
if ((_head + 1)%QUEUE_SIZE != _tail) {
|
|
||||||
_queue[_head] = ev;
|
|
||||||
_head = (_head + 1)%QUEUE_SIZE;
|
|
||||||
_sem.up();
|
|
||||||
} else
|
|
||||||
throw Overflow();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take element from ring buffer
|
|
||||||
*
|
|
||||||
* \return element
|
|
||||||
*
|
|
||||||
* If the ring buffer is empty, this function
|
|
||||||
* blocks until an element gets available.
|
|
||||||
*/
|
|
||||||
Genode::Alarm::Time get(void* *ev, Genode::Alarm::Time t)
|
|
||||||
{
|
|
||||||
Genode::Alarm::Time time;
|
|
||||||
|
|
||||||
if (t == NO_BLOCK) {
|
|
||||||
time = _sem.down(0);
|
|
||||||
} else if (t == 0) {
|
|
||||||
time = Genode::Timeout_thread::alarm_timer()->time();
|
|
||||||
_sem.down();
|
|
||||||
time = Genode::Timeout_thread::alarm_timer()->time() - time;
|
|
||||||
} else {
|
|
||||||
time = _sem.down(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::Lock::Guard lock_guard(_head_lock);
|
|
||||||
|
|
||||||
*ev = _queue[_tail];
|
|
||||||
_tail = (_tail + 1)%QUEUE_SIZE;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if ring buffer is empty
|
|
||||||
*/
|
|
||||||
bool empty() { return _tail == _head; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //__LWIP__INCLUDE__RING_BUFFER_H_
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Thread implementation for LwIP threads.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-14
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LWIP__INCLUDE__THREAD_H__
|
|
||||||
#define __LWIP__INCLUDE__THREAD_H__
|
|
||||||
|
|
||||||
#include <base/thread.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <lwip/sys.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Lwip {
|
|
||||||
|
|
||||||
class Lwip_thread : public Genode::Thread_deprecated<16384>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
void (*_thread)(void *arg);
|
|
||||||
void *_arg;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Lwip_thread(const char *name,
|
|
||||||
void (* thread)(void *arg),
|
|
||||||
void *arg)
|
|
||||||
: Genode::Thread_deprecated<16384>(name), _thread(thread), _arg(arg) { }
|
|
||||||
|
|
||||||
void entry() { _thread(_arg); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //__LWIP__INCLUDE__THREAD_H__
|
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Enable debugging output
|
|
||||||
* \author Sebastian Sumpf
|
|
||||||
* \date 2012-09-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LWIP__VERBOSE_H_
|
|
||||||
#define _LWIP__VERBOSE_H_
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set to one for more output
|
|
||||||
*/
|
|
||||||
static int verbose = 0;
|
|
||||||
|
|
||||||
#endif //_LWIP__VERBOSE_H_
|
|
@ -1,39 +0,0 @@
|
|||||||
--- a/src/api/sockets.c
|
|
||||||
+++ b/src/api/sockets.c
|
|
||||||
@@ -243,6 +243,9 @@ static const int err_to_errno_table[] = {
|
|
||||||
set_errno(sk->err); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
+/* function to notify libc about a socket event */
|
|
||||||
+extern void (*libc_select_notify)();
|
|
||||||
+
|
|
||||||
/* Forward delcaration of some functions */
|
|
||||||
static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
|
|
||||||
static void lwip_getsockopt_internal(void *arg);
|
|
||||||
@@ -1316,7 +1319,7 @@ return_copy_fdsets:
|
|
||||||
* Processes recvevent (data available) and wakes up tasks waiting for select.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|
||||||
+orig_event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|
||||||
{
|
|
||||||
int s;
|
|
||||||
struct lwip_sock *sock;
|
|
||||||
@@ -1431,6 +1434,17 @@ again:
|
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Wrapper for the original event_callback() function that additionally calls
|
|
||||||
+ * libc_select_notify()
|
|
||||||
+ */
|
|
||||||
+static void
|
|
||||||
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|
||||||
+{
|
|
||||||
+ orig_event_callback(conn, evt, len);
|
|
||||||
+ if (libc_select_notify)
|
|
||||||
+ libc_select_notify();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* Unimplemented: Close one end of a full-duplex connection.
|
|
||||||
* Currently, the full connection is closed.
|
|
@ -1,26 +0,0 @@
|
|||||||
Avoid assertion on nonblocking connect()
|
|
||||||
|
|
||||||
From: Christian Prochaska <christian.prochaska@genode-labs.com>
|
|
||||||
|
|
||||||
When calling 'connect()' in nonblocking mode and the connection has been
|
|
||||||
established, don't call 'tcp_connect()' again, which would trigger an
|
|
||||||
assertion with the message 'tcp_connect: can only connect from state
|
|
||||||
CLOSED'.
|
|
||||||
---
|
|
||||||
src/api/api_msg.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/api/api_msg.c b/src/api/api_msg.c
|
|
||||||
index c00222c..d05a5ae 100644
|
|
||||||
--- a/src/api/api_msg.c
|
|
||||||
+++ b/src/api/api_msg.c
|
|
||||||
@@ -1008,7 +1008,8 @@ lwip_netconn_do_connect(struct api_msg_msg *msg)
|
|
||||||
#if LWIP_TCP
|
|
||||||
case NETCONN_TCP:
|
|
||||||
/* Prevent connect while doing any other action. */
|
|
||||||
- if (msg->conn->state != NETCONN_NONE) {
|
|
||||||
+ if ((msg->conn->state != NETCONN_NONE) ||
|
|
||||||
+ ((msg->conn->pcb.tcp->state == ESTABLISHED) && netconn_is_nonblocking(msg->conn))) {
|
|
||||||
msg->err = ERR_ISCONN;
|
|
||||||
} else {
|
|
||||||
setup_tcp(msg->conn);
|
|
@ -1,339 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief LwIP ethernet interface
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-11-05
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* LwIP includes */
|
|
||||||
extern "C" {
|
|
||||||
#include <lwip/opt.h>
|
|
||||||
#include <lwip/def.h>
|
|
||||||
#include <lwip/mem.h>
|
|
||||||
#include <lwip/pbuf.h>
|
|
||||||
#include <lwip/sys.h>
|
|
||||||
#include <lwip/stats.h>
|
|
||||||
#include <lwip/snmp.h>
|
|
||||||
#include <netif/etharp.h>
|
|
||||||
#include <netif/ppp_oe.h>
|
|
||||||
#include <nic.h>
|
|
||||||
#include <verbose.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <base/thread.h>
|
|
||||||
#include <base/log.h>
|
|
||||||
#include <nic/packet_allocator.h>
|
|
||||||
#include <nic_session/connection.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
static void genode_netif_input(struct netif *netif);
|
|
||||||
|
|
||||||
void lwip_nic_link_state_changed(int state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Thread, that receives packets by the nic-session interface.
|
|
||||||
*/
|
|
||||||
class Nic_receiver_thread : public Genode::Thread_deprecated<8192>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef Nic::Packet_descriptor Packet_descriptor;
|
|
||||||
|
|
||||||
Nic::Connection *_nic; /* nic-session */
|
|
||||||
Packet_descriptor _rx_packet; /* actual packet received */
|
|
||||||
struct netif *_netif; /* LwIP network interface structure */
|
|
||||||
|
|
||||||
Genode::Signal_receiver _sig_rec;
|
|
||||||
|
|
||||||
Genode::Io_signal_dispatcher<Nic_receiver_thread> _link_state_dispatcher;
|
|
||||||
Genode::Io_signal_dispatcher<Nic_receiver_thread> _rx_packet_avail_dispatcher;
|
|
||||||
Genode::Io_signal_dispatcher<Nic_receiver_thread> _rx_ready_to_ack_dispatcher;
|
|
||||||
|
|
||||||
void _handle_rx_packet_avail(unsigned)
|
|
||||||
{
|
|
||||||
while (_nic->rx()->packet_avail() && _nic->rx()->ready_to_ack()) {
|
|
||||||
_rx_packet = _nic->rx()->get_packet();
|
|
||||||
genode_netif_input(_netif);
|
|
||||||
_nic->rx()->acknowledge_packet(_rx_packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handle_rx_read_to_ack(unsigned) { _handle_rx_packet_avail(0); }
|
|
||||||
|
|
||||||
void _handle_link_state(unsigned)
|
|
||||||
{
|
|
||||||
lwip_nic_link_state_changed(_nic->link_state());
|
|
||||||
}
|
|
||||||
|
|
||||||
void _tx_ack(bool block = false)
|
|
||||||
{
|
|
||||||
/* check for acknowledgements */
|
|
||||||
while (nic()->tx()->ack_avail() || block) {
|
|
||||||
Packet_descriptor acked_packet = nic()->tx()->get_acked_packet();
|
|
||||||
nic()->tx()->release_packet(acked_packet);
|
|
||||||
block = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
|
|
||||||
:
|
|
||||||
Genode::Thread_deprecated<8192>("nic-recv"), _nic(nic), _netif(netif),
|
|
||||||
_link_state_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_link_state),
|
|
||||||
_rx_packet_avail_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_packet_avail),
|
|
||||||
_rx_ready_to_ack_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_read_to_ack)
|
|
||||||
{
|
|
||||||
_nic->link_state_sigh(_link_state_dispatcher);
|
|
||||||
_nic->rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher);
|
|
||||||
_nic->rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
void entry();
|
|
||||||
Nic::Connection *nic() { return _nic; };
|
|
||||||
Packet_descriptor rx_packet() { return _rx_packet; };
|
|
||||||
|
|
||||||
Packet_descriptor alloc_tx_packet(Genode::size_t size)
|
|
||||||
{
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
Packet_descriptor packet = nic()->tx()->alloc_packet(size);
|
|
||||||
return packet;
|
|
||||||
} catch(Nic::Session::Tx::Source::Packet_alloc_failed) {
|
|
||||||
/* packet allocator exhausted, wait for acknowledgements */
|
|
||||||
_tx_ack(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void submit_tx_packet(Packet_descriptor packet)
|
|
||||||
{
|
|
||||||
nic()->tx()->submit_packet(packet);
|
|
||||||
/* check for acknowledgements */
|
|
||||||
_tx_ack();
|
|
||||||
}
|
|
||||||
|
|
||||||
char *content(Packet_descriptor packet) {
|
|
||||||
return nic()->tx()->packet_content(packet); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* C-interface
|
|
||||||
*/
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function 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.
|
|
||||||
*
|
|
||||||
* @param netif the lwip network interface structure for this genode_netif
|
|
||||||
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
|
|
||||||
* @return ERR_OK if the packet could be sent
|
|
||||||
* an err_t value if the packet couldn't be sent
|
|
||||||
*
|
|
||||||
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
|
|
||||||
* strange results. You might consider waiting for space in the DMA queue
|
|
||||||
* to become availale since the stack doesn't retry to send a packet
|
|
||||||
* dropped because of memory failure (except for the TCP timers).
|
|
||||||
*/
|
|
||||||
static err_t
|
|
||||||
low_level_output(struct netif *netif, struct pbuf *p)
|
|
||||||
{
|
|
||||||
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
|
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
|
||||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
|
||||||
#endif
|
|
||||||
Nic::Packet_descriptor tx_packet = th->alloc_tx_packet(p->tot_len);
|
|
||||||
char *tx_content = th->content(tx_packet);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterate through all pbufs and
|
|
||||||
* copy payload into packet's payload
|
|
||||||
*/
|
|
||||||
for(struct pbuf *q = p; q != NULL; q = q->next) {
|
|
||||||
char *src = (char*) q->payload;
|
|
||||||
Genode::memcpy(tx_content, src, q->len);
|
|
||||||
tx_content += q->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Submit packet */
|
|
||||||
th->submit_tx_packet(tx_packet);
|
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
|
||||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
|
||||||
#endif
|
|
||||||
LINK_STATS_INC(link.xmit);
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
|
||||||
* packet from the interface into the pbuf.
|
|
||||||
*
|
|
||||||
* @param netif the lwip network interface structure for this genode_netif
|
|
||||||
* @return a pbuf filled with the received packet (including MAC header)
|
|
||||||
* NULL on memory error
|
|
||||||
*/
|
|
||||||
static struct pbuf *
|
|
||||||
low_level_input(struct netif *netif)
|
|
||||||
{
|
|
||||||
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
|
|
||||||
Nic::Connection *nic = th->nic();
|
|
||||||
Nic::Packet_descriptor rx_packet = th->rx_packet();
|
|
||||||
char *rx_content = nic->rx()->packet_content(rx_packet);
|
|
||||||
u16_t len = rx_packet.size();
|
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
|
||||||
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
|
||||||
struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
|
||||||
if (p) {
|
|
||||||
#if ETH_PAD_SIZE
|
|
||||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We iterate over the pbuf chain until we have read the entire
|
|
||||||
* packet into the pbuf.
|
|
||||||
*/
|
|
||||||
for(struct pbuf *q = p; q != 0; q = q->next) {
|
|
||||||
char *dst = (char*)q->payload;
|
|
||||||
Genode::memcpy(dst, rx_content, q->len);
|
|
||||||
rx_content += q->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ETH_PAD_SIZE
|
|
||||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
|
||||||
#endif
|
|
||||||
LINK_STATS_INC(link.recv);
|
|
||||||
} else {
|
|
||||||
LINK_STATS_INC(link.memerr);
|
|
||||||
LINK_STATS_INC(link.drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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. Then the type of the received packet is determined and
|
|
||||||
* the appropriate input function is called.
|
|
||||||
*
|
|
||||||
* @param netif the lwip network interface structure for this genode_netif
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
genode_netif_input(struct netif *netif)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Move received packet into a new pbuf,
|
|
||||||
* if something went wrong, return silently
|
|
||||||
*/
|
|
||||||
struct pbuf *p = low_level_input(netif);
|
|
||||||
|
|
||||||
/* No packet could be read, silently ignore this */
|
|
||||||
if (p == NULL) return;
|
|
||||||
|
|
||||||
if (netif->input(p, netif) != ERR_OK) {
|
|
||||||
if (verbose)
|
|
||||||
Genode::error("genode_netif_input: input error");
|
|
||||||
pbuf_free(p);
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* This function should be passed as a parameter to netif_add().
|
|
||||||
*
|
|
||||||
* @param netif the lwip network interface structure for this genode_netif
|
|
||||||
* @return ERR_OK if the loopif is initialized
|
|
||||||
* ERR_MEM if private data couldn't be allocated
|
|
||||||
* any other err_t on error
|
|
||||||
*/
|
|
||||||
err_t genode_netif_init(struct netif *netif)
|
|
||||||
{
|
|
||||||
using namespace Genode;
|
|
||||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
|
||||||
|
|
||||||
/* Initialize nic-session */
|
|
||||||
Nic::Packet_allocator *tx_block_alloc = new (env()->heap())
|
|
||||||
Nic::Packet_allocator(env()->heap());
|
|
||||||
|
|
||||||
struct netif_buf_sizes *nbs = (struct netif_buf_sizes *) netif->state;
|
|
||||||
Nic::Connection *nic = 0;
|
|
||||||
try {
|
|
||||||
nic = new (env()->heap()) Nic::Connection(tx_block_alloc,
|
|
||||||
nbs->tx_buf_size,
|
|
||||||
nbs->rx_buf_size);
|
|
||||||
}
|
|
||||||
catch (Service_denied) {
|
|
||||||
destroy(env()->heap(), tx_block_alloc);
|
|
||||||
return ERR_IF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup receiver thread */
|
|
||||||
Nic_receiver_thread *th = new (env()->heap())
|
|
||||||
Nic_receiver_thread(nic, netif);
|
|
||||||
|
|
||||||
/* Store receiver thread address in user-defined netif struct part */
|
|
||||||
netif->state = (void*) th;
|
|
||||||
#if LWIP_NETIF_HOSTNAME
|
|
||||||
netif->hostname = "lwip";
|
|
||||||
#endif /* LWIP_NETIF_HOSTNAME */
|
|
||||||
netif->name[0] = 'e';
|
|
||||||
netif->name[1] = 'n';
|
|
||||||
netif->output = etharp_output;
|
|
||||||
netif->linkoutput = low_level_output;
|
|
||||||
netif->mtu = 1500;
|
|
||||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
|
||||||
netif->flags = NETIF_FLAG_BROADCAST |
|
|
||||||
NETIF_FLAG_ETHARP |
|
|
||||||
NETIF_FLAG_LINK_UP;
|
|
||||||
|
|
||||||
/* Get MAC address from nic-session and set it accordingly */
|
|
||||||
Nic::Mac_address _mac = nic->mac_address();
|
|
||||||
for(int i=0; i<6; ++i)
|
|
||||||
netif->hwaddr[i] = _mac.addr[i];
|
|
||||||
|
|
||||||
th->start();
|
|
||||||
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
} /* extern "C" */
|
|
||||||
|
|
||||||
|
|
||||||
void Nic_receiver_thread::entry()
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
Genode::Signal sig = _sig_rec.wait_for_signal();
|
|
||||||
int num = sig.num();
|
|
||||||
|
|
||||||
Genode::Signal_dispatcher_base *dispatcher;
|
|
||||||
dispatcher = dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context());
|
|
||||||
dispatcher->dispatch(num);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Print function for debugging functionality of lwIP.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-10-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <base/printf.h>
|
|
||||||
#include <base/console.h>
|
|
||||||
#include <base/lock.h>
|
|
||||||
#include <base/env.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
/* LwIP includes */
|
|
||||||
#include <arch/cc.h>
|
|
||||||
|
|
||||||
/* Simply map to Genode's printf implementation */
|
|
||||||
void lwip_printf(const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list list;
|
|
||||||
va_start(list, format);
|
|
||||||
|
|
||||||
Genode::vprintf(format, list);
|
|
||||||
|
|
||||||
va_end(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,660 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Platform dependent function implementations for lwIP.
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-10-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is part of the Genode OS framework, which is distributed
|
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Genode includes */
|
|
||||||
#include <base/log.h>
|
|
||||||
#include <base/env.h>
|
|
||||||
#include <base/lock.h>
|
|
||||||
#include <base/sleep.h>
|
|
||||||
#include <parent/parent.h>
|
|
||||||
#include <os/timed_semaphore.h>
|
|
||||||
|
|
||||||
/* LwIP includes */
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
#include <ring_buffer.h>
|
|
||||||
#include <thread.h>
|
|
||||||
#include <verbose.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Lwip {
|
|
||||||
|
|
||||||
class Mutex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Genode::Lock lock;
|
|
||||||
int counter;
|
|
||||||
Genode::Thread *thread;
|
|
||||||
|
|
||||||
Mutex() : counter(0), thread((Genode::Thread*)-1) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* LwIP's so called mailboxes map to a ring buffer in our case */
|
|
||||||
typedef Ring_buffer Mailbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns lock used to synchronize with tcpip thread's startup.
|
|
||||||
*/
|
|
||||||
static Genode::Lock *startup_lock()
|
|
||||||
{
|
|
||||||
static Genode::Lock _startup_lock(Genode::Lock::LOCKED);
|
|
||||||
return &_startup_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns global mutex for lightweight protection mechanisms in LwIP.
|
|
||||||
*/
|
|
||||||
static Lwip::Mutex *global_mutex()
|
|
||||||
{
|
|
||||||
static Lwip::Mutex _mutex;
|
|
||||||
return &_mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for startup synchronization by the tcpip thread.
|
|
||||||
*/
|
|
||||||
static void startup_done(void *arg)
|
|
||||||
{
|
|
||||||
startup_lock()->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Lwip;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
/* LwIP includes */
|
|
||||||
#include <lwip/opt.h>
|
|
||||||
#include <lwip/tcpip.h>
|
|
||||||
#include <lwip/err.h>
|
|
||||||
#include <lwip/sys.h>
|
|
||||||
#include <lwip/dhcp.h>
|
|
||||||
#include <arch/sys_arch.h>
|
|
||||||
#include <arch/cc.h>
|
|
||||||
#include <nic.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sanitize check, whether somebody tries to use our LwIP backend,
|
|
||||||
* without the tcpip thread and synchronization primitives,
|
|
||||||
* we use LwIP multi-threaded anyway.
|
|
||||||
*/
|
|
||||||
#if NO_SYS
|
|
||||||
#error "You cannot use the Genode LwIP backend with NO_SYS!"
|
|
||||||
#endif //NO_SYS
|
|
||||||
|
|
||||||
#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
|
|
||||||
#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
|
|
||||||
|
|
||||||
static struct netif netif;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback function used when changing the interface state.
|
|
||||||
*/
|
|
||||||
static void status_callback(struct netif *netif)
|
|
||||||
{
|
|
||||||
static ip_addr_t ip_addr = { 0 };
|
|
||||||
|
|
||||||
if (ip_addr.addr != netif->ip_addr.addr) {
|
|
||||||
Genode::log("got IP address ",
|
|
||||||
ip4_addr1(&(netif->ip_addr)), ".",
|
|
||||||
ip4_addr2(&(netif->ip_addr)), ".",
|
|
||||||
ip4_addr3(&(netif->ip_addr)), ".",
|
|
||||||
ip4_addr4(&(netif->ip_addr)));
|
|
||||||
ip_addr.addr = netif->ip_addr.addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Callback function used when doing a link-state change.
|
|
||||||
*/
|
|
||||||
static void link_callback(struct netif *netif)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We call the status callback at this point to print
|
|
||||||
* the IP address because we may have got a new one,
|
|
||||||
* e.h., we joined another wireless network.
|
|
||||||
*/
|
|
||||||
status_callback(netif);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/********************
|
|
||||||
** Initialization **
|
|
||||||
********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function needed by LwIP.
|
|
||||||
*/
|
|
||||||
void sys_init(void) {}
|
|
||||||
|
|
||||||
|
|
||||||
void lwip_tcpip_init()
|
|
||||||
{
|
|
||||||
/* call the tcpip initialization code and block, until it's initialized */
|
|
||||||
tcpip_init(startup_done, 0);
|
|
||||||
startup_lock()->lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* in lwip/genode.h */
|
|
||||||
int lwip_nic_init(Genode::int32_t ip_addr,
|
|
||||||
Genode::int32_t netmask,
|
|
||||||
Genode::int32_t gateway,
|
|
||||||
Genode::size_t tx_buf_size,
|
|
||||||
Genode::size_t rx_buf_size)
|
|
||||||
{
|
|
||||||
struct ip_addr ip, nm, gw;
|
|
||||||
static struct netif_buf_sizes nbs;
|
|
||||||
nbs.tx_buf_size = tx_buf_size;
|
|
||||||
nbs.rx_buf_size = rx_buf_size;
|
|
||||||
ip.addr = ip_addr;
|
|
||||||
nm.addr = netmask;
|
|
||||||
gw.addr = gateway;
|
|
||||||
|
|
||||||
class Nic_not_availble { };
|
|
||||||
|
|
||||||
try {
|
|
||||||
/**
|
|
||||||
* Add Genode's nic, which uses the nic-session interface.
|
|
||||||
*
|
|
||||||
* LwIP recommends to use ethernet_input as packet pushing function
|
|
||||||
* for ethernet cards and ip_input for everything else.
|
|
||||||
* Nevertheless, when we use the tcpip synchronization subsystem,
|
|
||||||
* we should use tcpip_input anyway
|
|
||||||
*
|
|
||||||
* See: http://lwip.wikia.com/wiki/Writing_a_device_driver
|
|
||||||
*/
|
|
||||||
err_t ret = netifapi_netif_add(&netif, &ip, &nm, &gw, &nbs,
|
|
||||||
genode_netif_init, tcpip_input);
|
|
||||||
if (ret != ERR_OK)
|
|
||||||
throw Nic_not_availble();
|
|
||||||
|
|
||||||
/* Set Genode's nic as the default nic */
|
|
||||||
netifapi_netif_set_default(&netif);
|
|
||||||
|
|
||||||
/* If no static ip was set, we do dhcp */
|
|
||||||
if (!ip_addr) {
|
|
||||||
#if LWIP_DHCP
|
|
||||||
/* Register callback functions. */
|
|
||||||
netif.status_callback = status_callback;
|
|
||||||
netif.link_callback = link_callback;
|
|
||||||
|
|
||||||
netifapi_dhcp_start(&netif);
|
|
||||||
#else
|
|
||||||
/* no IP address - no networking */
|
|
||||||
return 1;
|
|
||||||
#endif /* LWIP_DHCP */
|
|
||||||
} else {
|
|
||||||
netifapi_netif_set_up(&netif);
|
|
||||||
}
|
|
||||||
} catch (Nic_not_availble) {
|
|
||||||
Genode::warning("NIC not available, loopback is used as default");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void lwip_nic_link_state_changed(int state)
|
|
||||||
{
|
|
||||||
if (state)
|
|
||||||
netifapi_netif_set_link_up(&netif);
|
|
||||||
else
|
|
||||||
netifapi_netif_set_link_down(&netif);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************
|
|
||||||
** Semaphore **
|
|
||||||
***************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns a new semaphore.
|
|
||||||
*
|
|
||||||
* \param count specifies the initial state of the semaphore.
|
|
||||||
* \return the semaphore, or SYS_SEM_NULL on error.
|
|
||||||
*/
|
|
||||||
err_t sys_sem_new(sys_sem_t* sem, u8_t count)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Genode::Timed_semaphore *_sem = new (Genode::env()->heap())
|
|
||||||
Genode::Timed_semaphore(count);
|
|
||||||
sem->ptr = _sem;
|
|
||||||
return ERR_OK;
|
|
||||||
} catch (Genode::Allocator::Out_of_memory) {
|
|
||||||
Genode::warning(__func__, ": out of memory");
|
|
||||||
return ERR_MEM;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
/* we just use a arbitrary value that is
|
|
||||||
* not defined in err.h */
|
|
||||||
return -32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees a semaphore
|
|
||||||
*
|
|
||||||
* \param sem the semaphore to free
|
|
||||||
*/
|
|
||||||
void sys_sem_free(sys_sem_t* sem)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Genode::Timed_semaphore *_sem =
|
|
||||||
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
|
|
||||||
if (_sem)
|
|
||||||
destroy(Genode::env()->heap(), _sem);
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signals (or releases) a semaphore.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void sys_sem_signal(sys_sem_t* sem)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Genode::Timed_semaphore *_sem =
|
|
||||||
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
|
|
||||||
if (!_sem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_sem->up();
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a semaphore is valid
|
|
||||||
*
|
|
||||||
* \param sem semaphore to check
|
|
||||||
*
|
|
||||||
* \return 1 if semaphore is valid, 0 otherwise.
|
|
||||||
*/
|
|
||||||
int sys_sem_valid(sys_sem_t* sem)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Genode::Timed_semaphore *_sem =
|
|
||||||
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
|
|
||||||
|
|
||||||
if (_sem)
|
|
||||||
return 1;
|
|
||||||
} catch (...) { }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a semaphore to invalid
|
|
||||||
*
|
|
||||||
* \param sem semaphore to set invalid
|
|
||||||
*/
|
|
||||||
void sys_sem_set_invalid(sys_sem_t* sem)
|
|
||||||
{
|
|
||||||
sem->ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blocks the thread while waiting for the semaphore to be signaled.
|
|
||||||
*
|
|
||||||
* \param sem semaphore used to block on
|
|
||||||
* \param timeout specifies how many milliseconds the function should block.
|
|
||||||
* If timeout=0, then the function should block indefinitely.
|
|
||||||
* \return SYS_ARCH_TIMEOUT if the function times out. If the function
|
|
||||||
* acquires the semaphore, it should return how many
|
|
||||||
* milliseconds expired while waiting for the semaphore.
|
|
||||||
*/
|
|
||||||
u32_t sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout)
|
|
||||||
{
|
|
||||||
using namespace Genode;
|
|
||||||
try {
|
|
||||||
Timed_semaphore *_sem = reinterpret_cast<Timed_semaphore*>(sem->ptr);
|
|
||||||
if (!_sem) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no timeout is requested, we have to track the time ourself */
|
|
||||||
if (!timeout) {
|
|
||||||
Alarm::Time starttime = Timeout_thread::alarm_timer()->time();
|
|
||||||
_sem->down();
|
|
||||||
return Timeout_thread::alarm_timer()->time() - starttime;
|
|
||||||
} else {
|
|
||||||
return _sem->down(timeout);
|
|
||||||
}
|
|
||||||
} catch (Timeout_exception) {
|
|
||||||
return SYS_ARCH_TIMEOUT;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter critical section
|
|
||||||
*/
|
|
||||||
sys_prot_t sys_arch_protect(void)
|
|
||||||
{
|
|
||||||
if (global_mutex()->thread == Genode::Thread::myself())
|
|
||||||
return ++global_mutex()->counter;
|
|
||||||
global_mutex()->lock.lock();
|
|
||||||
global_mutex()->thread = Genode::Thread::myself();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Leave critical section.
|
|
||||||
*/
|
|
||||||
void sys_arch_unprotect(sys_prot_t pval)
|
|
||||||
{
|
|
||||||
if (global_mutex()->thread != Genode::Thread::myself())
|
|
||||||
return;
|
|
||||||
if (global_mutex()->counter > 1)
|
|
||||||
global_mutex()->counter--;
|
|
||||||
else {
|
|
||||||
global_mutex()->counter = 0;
|
|
||||||
global_mutex()->thread = (Genode::Thread*)-1;
|
|
||||||
global_mutex()->lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************
|
|
||||||
** Mailboxes **
|
|
||||||
***************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a new mailbox.
|
|
||||||
*
|
|
||||||
* \param size size of the mailbox
|
|
||||||
* \return a new mailbox, or SYS_MBOX_NULL on error.
|
|
||||||
*/
|
|
||||||
err_t sys_mbox_new(sys_mbox_t *mbox, int size) {
|
|
||||||
LWIP_UNUSED_ARG(size);
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = new (Genode::env()->heap()) Mailbox();
|
|
||||||
mbox->ptr = _mbox;
|
|
||||||
return ERR_OK;
|
|
||||||
} catch (Genode::Allocator::Out_of_memory) {
|
|
||||||
Genode::warning(__func__, ": out of memory");
|
|
||||||
return ERR_MEM;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
return -32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free a mailbox.
|
|
||||||
*
|
|
||||||
* \param mbox mailbox to free
|
|
||||||
*/
|
|
||||||
void sys_mbox_free(sys_mbox_t* mbox)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
|
|
||||||
if (_mbox)
|
|
||||||
destroy(Genode::env()->heap(), _mbox);
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a mailbox is valid.
|
|
||||||
*
|
|
||||||
* \param mbox mailbox to check
|
|
||||||
*
|
|
||||||
* \return 1 if mailbox is valid, 0 otherwise.
|
|
||||||
*/
|
|
||||||
int sys_mbox_valid(sys_mbox_t* mbox)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
|
|
||||||
if (_mbox) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} catch (...) { }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate a mailbox
|
|
||||||
*
|
|
||||||
* Afterwards sys_mbox_valid() returns 0.
|
|
||||||
* ATTENTION: This does NOT mean that the mailbox shall be deallocated:
|
|
||||||
* sys_mbox_free() is always called before calling this function!
|
|
||||||
*
|
|
||||||
* \param mbox mailbox to set invalid
|
|
||||||
*/
|
|
||||||
void sys_mbox_set_invalid(sys_mbox_t* mbox)
|
|
||||||
{
|
|
||||||
mbox->ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Posts the "msg" to the mailbox.
|
|
||||||
*
|
|
||||||
* \param mbox target mailbox
|
|
||||||
* \param msg message to post
|
|
||||||
*/
|
|
||||||
void sys_mbox_post(sys_mbox_t* mbox, void *msg)
|
|
||||||
{
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
|
|
||||||
if (!_mbox) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_mbox->add(msg);
|
|
||||||
return;
|
|
||||||
} catch (Mailbox::Overflow) {
|
|
||||||
if (verbose)
|
|
||||||
Genode::warning(__func__, ": overflow exception!");
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Posts the "msg" to the mailbox, returns when it is full.
|
|
||||||
*
|
|
||||||
* \param mbox target mailbox
|
|
||||||
* \param msg message to post
|
|
||||||
*/
|
|
||||||
err_t sys_mbox_trypost(sys_mbox_t* mbox, void *msg)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
|
|
||||||
if (!_mbox) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
_mbox->add(msg);
|
|
||||||
return ERR_OK;
|
|
||||||
} catch (Mailbox::Overflow) {
|
|
||||||
if (verbose)
|
|
||||||
Genode::warning(__func__, ": overflow exception!");
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
}
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch a "msg" from the mailbox.
|
|
||||||
*
|
|
||||||
* \param mbox target mailbox
|
|
||||||
* \param msg pointer to message buffer
|
|
||||||
* \param timeout how long will it block, if no message is available
|
|
||||||
*/
|
|
||||||
u32_t sys_arch_mbox_fetch(sys_mbox_t* mbox, void **msg, u32_t timeout)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The mailbox might be invalid to indicate,
|
|
||||||
* that the message should be dropped
|
|
||||||
*/
|
|
||||||
if (!mbox)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u32_t ret = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Mailbox* _mbox = reinterpret_cast<Mailbox *>(mbox->ptr);
|
|
||||||
if (!_mbox)
|
|
||||||
return 0;
|
|
||||||
ret = _mbox->get(msg, timeout);
|
|
||||||
} catch (Genode::Timeout_exception) {
|
|
||||||
ret = SYS_ARCH_TIMEOUT;
|
|
||||||
} catch (Genode::Nonblocking_exception) {
|
|
||||||
ret = SYS_MBOX_EMPTY;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
ret = SYS_ARCH_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to fetch a "msg" from the mailbox.
|
|
||||||
*
|
|
||||||
* \param mbox target mailbox
|
|
||||||
* \param msg pointer to message buffer
|
|
||||||
* \return on success 0 is returned.
|
|
||||||
*
|
|
||||||
* This is similar to sys_arch_mbox_fetch, however if a message is not present
|
|
||||||
* in the mailbox, it immediately returns with the code SYS_MBOX_EMPTY.
|
|
||||||
*/
|
|
||||||
u32_t sys_arch_mbox_tryfetch(sys_mbox_t* mbox, void **msg)
|
|
||||||
{
|
|
||||||
return sys_arch_mbox_fetch(mbox, msg, Mailbox::NO_BLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************
|
|
||||||
** Threads **
|
|
||||||
*************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and run a new thread.
|
|
||||||
*
|
|
||||||
* \param name name of the new thread
|
|
||||||
* \param thread pointer to thread's entry function
|
|
||||||
* \param arg arguments to the entry function
|
|
||||||
* \param stacksize size of the thread's stack
|
|
||||||
* \param prio priority of new thread
|
|
||||||
*/
|
|
||||||
sys_thread_t sys_thread_new(const char *name, void (* thread)(void *arg),
|
|
||||||
void *arg, int stacksize, int prio)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
LWIP_UNUSED_ARG(stacksize);
|
|
||||||
LWIP_UNUSED_ARG(prio);
|
|
||||||
Lwip_thread *_th = new (Genode::env()->heap())
|
|
||||||
Lwip_thread(name, thread, arg);
|
|
||||||
_th->start();
|
|
||||||
return (sys_thread_t) _th;
|
|
||||||
} catch (Genode::Allocator::Out_of_memory) {
|
|
||||||
Genode::warning(__func__, ": out of memory");
|
|
||||||
return 0;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown Exception occured!");
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32_t sys_now() {
|
|
||||||
return Genode::Timeout_thread::alarm_timer()->time(); }
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**************
|
|
||||||
** Timeouts **
|
|
||||||
**************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns linked list of timeout for a thread created within LwIP
|
|
||||||
* (by now this is only the tcpip thread)
|
|
||||||
*/
|
|
||||||
struct sys_timeouts *sys_arch_timeouts(void)
|
|
||||||
{
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
struct Thread_timeout
|
|
||||||
{
|
|
||||||
sys_timeouts timeouts;
|
|
||||||
Thread *thread;
|
|
||||||
Thread_timeout *next;
|
|
||||||
|
|
||||||
Thread_timeout(Thread *t = 0)
|
|
||||||
: thread(t), next(0) { timeouts.next = 0; }
|
|
||||||
};
|
|
||||||
static Lock mutex;
|
|
||||||
static Thread_timeout thread_timeouts;
|
|
||||||
|
|
||||||
Lock::Guard lock_guard(mutex);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread *thread = Thread::myself();
|
|
||||||
|
|
||||||
/* check available timeout heads */
|
|
||||||
for (Thread_timeout *tt = &thread_timeouts; tt; tt = tt->next)
|
|
||||||
if (tt->thread == thread)
|
|
||||||
return &tt->timeouts;
|
|
||||||
|
|
||||||
/* we have to add a new one */
|
|
||||||
Thread_timeout *tt = new (env()->heap()) Thread_timeout(thread);
|
|
||||||
tt->next = thread_timeouts.next;
|
|
||||||
thread_timeouts.next = tt;
|
|
||||||
|
|
||||||
return &tt->timeouts;
|
|
||||||
} catch (...) {
|
|
||||||
Genode::error(__func__, ": unknown exception occured!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void genode_memcpy(void * dst, const void *src, unsigned long size) {
|
|
||||||
Genode::memcpy(dst, src, size);
|
|
||||||
}
|
|
||||||
} /* extern "C" */
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void lwip_sleep_forever()
|
|
||||||
{
|
|
||||||
int dummy = 1;
|
|
||||||
Genode::log(__func__, ": thread ", (unsigned)(((Genode::addr_t)&dummy)>>20)&0xff);
|
|
||||||
Genode::sleep_forever();
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
diff --git a/src/core/dhcp.c b/src/core/dhcp.c
|
|
||||||
index 21fd784..d85d86c 100644
|
|
||||||
--- a/src/core/dhcp.c
|
|
||||||
+++ b/src/core/dhcp.c
|
|
||||||
@@ -982,7 +982,7 @@ dhcp_bind(struct netif *netif)
|
|
||||||
|
|
||||||
ip_addr_copy(gw_addr, dhcp->offered_gw_addr);
|
|
||||||
/* gateway address not given? */
|
|
||||||
- if (ip_addr_isany(&gw_addr)) {
|
|
||||||
+ if (gw_addr.addr == IPADDR_ANY) {
|
|
||||||
/* copy network address */
|
|
||||||
ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
|
|
||||||
/* use first host address on network as gateway */
|
|
||||||
diff --git a/src/include/ipv4/lwip/ip4_addr.h b/src/include/ipv4/lwip/ip4_addr.h
|
|
||||||
index b05ae53..dc0d9a8 100644
|
|
||||||
--- a/src/include/ipv4/lwip/ip4_addr.h
|
|
||||||
+++ b/src/include/ipv4/lwip/ip4_addr.h
|
|
||||||
@@ -210,7 +210,7 @@ u8_t ip4_addr_netmask_valid(u32_t netmask);
|
|
||||||
#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
|
|
||||||
|
|
||||||
#define ip_addr_debug_print(debug, ipaddr) \
|
|
||||||
- LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
|
|
||||||
+ LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, \
|
|
||||||
ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \
|
|
||||||
ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \
|
|
||||||
ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \
|
|
@ -1,16 +0,0 @@
|
|||||||
This patch is necessary because lwip always returns EALREADY if the
|
|
||||||
connection is established but never EISCONN. So most programs will
|
|
||||||
fail to connect because they at one point while connecting expect to
|
|
||||||
get EISCONN.
|
|
||||||
|
|
||||||
--- a/src/api/sockets.c
|
|
||||||
+++ b/src/api/sockets.c
|
|
||||||
@@ -214,7 +214,7 @@ static const int err_to_errno_table[] = {
|
|
||||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
|
||||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
|
||||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
|
||||||
- EALREADY, /* ERR_ISCONN -9 Already connected. */
|
|
||||||
+ EISCONN, /* ERR_ISCONN -9 Already connected. */
|
|
||||||
ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
|
|
||||||
ECONNRESET, /* ERR_RST -11 Connection reset. */
|
|
||||||
ENOTCONN, /* ERR_CLSD -12 Connection closed. */
|
|
@ -1,15 +0,0 @@
|
|||||||
Our FreeBSD libc based libc defines SOL_SOCKET as 0xffff. We change
|
|
||||||
lwip's definition from 0xfff to match ours. This prevents us from
|
|
||||||
converting the level when we call {g,s}etsockopt.
|
|
||||||
|
|
||||||
--- a/src/include/lwip/sockets.h
|
|
||||||
+++ b/src/include/lwip/sockets.h
|
|
||||||
@@ -131,7 +131,7 @@ struct linger {
|
|
||||||
/*
|
|
||||||
* Level number for (get/set)sockopt() to apply to socket itself.
|
|
||||||
*/
|
|
||||||
-#define SOL_SOCKET 0xfff /* options for socket level */
|
|
||||||
+#define SOL_SOCKET 0xffff /* options for socket level */
|
|
||||||
|
|
||||||
|
|
||||||
#define AF_UNSPEC 0
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
global:
|
|
||||||
|
|
||||||
lwip_*;
|
|
||||||
ipaddr_addr;
|
|
||||||
dns_getserver;
|
|
||||||
ipaddr_ntoa;
|
|
||||||
|
|
||||||
local:
|
|
||||||
|
|
||||||
*;
|
|
||||||
};
|
|
@ -21,8 +21,9 @@ virtual network between the lighttpd web server and the Arora web browser, both
|
|||||||
running as Genode processes without real network connectivity.
|
running as Genode processes without real network connectivity.
|
||||||
|
|
||||||
The static IP can be configured per client of the NIC bridge using a '<policy>'
|
The static IP can be configured per client of the NIC bridge using a '<policy>'
|
||||||
node of the configuration. For example, the following policy assigns a static
|
node of the configuration. Of course, the client needs to configure its TCP/IP
|
||||||
address to a client with the session label "lighttpd".
|
stack to use the assigned IP address. As an example, the following policy assigns
|
||||||
|
a static address to a client with the session label "lighttpd".
|
||||||
|
|
||||||
!<start name="nic_bridge">
|
!<start name="nic_bridge">
|
||||||
! ...
|
! ...
|
||||||
@ -31,18 +32,6 @@ address to a client with the session label "lighttpd".
|
|||||||
! </config>
|
! </config>
|
||||||
!</start>
|
!</start>
|
||||||
|
|
||||||
Of course, the client needs to configure its TCP/IP stack to use the assigned
|
|
||||||
IP address. This can be done via configuration arguments examined by the
|
|
||||||
'lwip_nic_dhcp' libc plugin. For the given example, the configuration for the
|
|
||||||
lighttpd process would look as follows.
|
|
||||||
|
|
||||||
!<start name="lighttpd">
|
|
||||||
! <config>
|
|
||||||
! <interface ip_addr="10.0.2.55"
|
|
||||||
! netmask="255.255.255.0"
|
|
||||||
! gateway="10.0.2.1"/>
|
|
||||||
! </config>
|
|
||||||
!</start>
|
|
||||||
|
|
||||||
The verbosity mode of the NIC bridge can be toggled with the verbose attribute
|
The verbosity mode of the NIC bridge can be toggled with the verbose attribute
|
||||||
(default value shown):
|
(default value shown):
|
||||||
|
@ -18,6 +18,7 @@ set build_components {
|
|||||||
core init
|
core init
|
||||||
drivers/timer
|
drivers/timer
|
||||||
app/lighttpd
|
app/lighttpd
|
||||||
|
lib/vfs/lwip
|
||||||
}
|
}
|
||||||
|
|
||||||
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
||||||
@ -102,9 +103,12 @@ append config {
|
|||||||
<log/>
|
<log/>
|
||||||
<null/>
|
<null/>
|
||||||
</dir>
|
</dir>
|
||||||
|
<dir name="socket">
|
||||||
|
<lwip dhcp="yes"/> </dir>
|
||||||
<tar name="genode_org.tar"/>
|
<tar name="genode_org.tar"/>
|
||||||
</vfs>
|
</vfs>
|
||||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
|
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
|
||||||
|
socket="/socket" />
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
@ -160,8 +164,8 @@ exec tar cfv bin/genode_org.tar -h -C bin/genode_org .
|
|||||||
# generic modules
|
# generic modules
|
||||||
set boot_modules {
|
set boot_modules {
|
||||||
core init timer ld.lib.so
|
core init timer ld.lib.so
|
||||||
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
|
libc.lib.so libm.lib.so posix.lib.so
|
||||||
lwip_legacy.lib.so zlib.lib.so
|
vfs.lib.so vfs_lwip.lib.so zlib.lib.so
|
||||||
lighttpd genode_org.tar
|
lighttpd genode_org.tar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ append config {
|
|||||||
<log/>
|
<log/>
|
||||||
<null/>
|
<null/>
|
||||||
</dir>
|
</dir>
|
||||||
|
<dir name="socket">
|
||||||
|
<lwip dhcp="yes"/> </dir>
|
||||||
<dir name="etc">
|
<dir name="etc">
|
||||||
<dir name="lighttpd">
|
<dir name="lighttpd">
|
||||||
<inline name="lighttpd.conf">
|
<inline name="lighttpd.conf">
|
||||||
@ -91,7 +93,8 @@ mimetype.assign = (
|
|||||||
</inline>
|
</inline>
|
||||||
</dir>
|
</dir>
|
||||||
</vfs>
|
</vfs>
|
||||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
|
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
|
||||||
|
socket="/socket" />
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
@ -108,8 +111,8 @@ install_config $config
|
|||||||
# generic modules
|
# generic modules
|
||||||
append boot_modules {
|
append boot_modules {
|
||||||
core init timer ld.lib.so } [nic_drv_binary] {
|
core init timer ld.lib.so } [nic_drv_binary] {
|
||||||
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
|
libc.lib.so libm.lib.so posix.lib.so
|
||||||
lwip_legacy.lib.so zlib.lib.so
|
vfs.lib.so vfs_lwip.lib.so zlib.lib.so
|
||||||
lighttpd
|
lighttpd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ set build_components {
|
|||||||
server/ram_fs server/report_rom
|
server/ram_fs server/report_rom
|
||||||
server/tcp_terminal drivers/nic
|
server/tcp_terminal drivers/nic
|
||||||
lib/libc_noux
|
lib/libc_noux
|
||||||
|
lib/vfs/lwip
|
||||||
noux
|
noux
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ foreach pkg {bash coreutils} {
|
|||||||
set boot_modules {
|
set boot_modules {
|
||||||
ram_fs
|
ram_fs
|
||||||
noux libc_noux.lib.so posix.lib.so bash.tar coreutils.tar
|
noux libc_noux.lib.so posix.lib.so bash.tar coreutils.tar
|
||||||
tcp_terminal lwip_legacy.lib.so nic_drv report_rom
|
tcp_terminal vfs_lwip.lib.so nic_drv report_rom
|
||||||
input_merger
|
input_merger
|
||||||
test.bin template.bat
|
test.bin template.bat
|
||||||
}
|
}
|
||||||
@ -136,8 +137,11 @@ set config_of_app {
|
|||||||
<provides> <service name="Terminal"/> </provides>
|
<provides> <service name="Terminal"/> </provides>
|
||||||
<config>
|
<config>
|
||||||
<policy label_prefix="noux" port="8888"/>
|
<policy label_prefix="noux" port="8888"/>
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log"/>
|
<dir name="dev"> <log/> </dir>
|
||||||
|
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" socket="/socket" />
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@ TARGET = lighttpd
|
|||||||
|
|
||||||
include $(REP_DIR)/src/app/lighttpd/target.inc
|
include $(REP_DIR)/src/app/lighttpd/target.inc
|
||||||
|
|
||||||
LIBS += libc libm libc_lwip_nic_dhcp
|
LIBS += libc libm
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
TARGET = openvpn
|
TARGET = openvpn
|
||||||
|
|
||||||
LIBS += libc libc_pipe libc_lwip_nic_dhcp \
|
LIBS += libc libc_pipe libcrypto libssl
|
||||||
libcrypto libssl
|
|
||||||
|
|
||||||
OPENVPN_PORT_DIR := $(call select_from_ports,openvpn)
|
OPENVPN_PORT_DIR := $(call select_from_ports,openvpn)
|
||||||
OPENVPN_DIR := $(OPENVPN_PORT_DIR)/src/app/openvpn
|
OPENVPN_DIR := $(OPENVPN_PORT_DIR)/src/app/openvpn
|
||||||
|
Loading…
Reference in New Issue
Block a user