diff --git a/repos/libports/run/nic_router.run b/repos/libports/run/nic_router.run index 643df8ac78..97a4783a44 100644 --- a/repos/libports/run/nic_router.run +++ b/repos/libports/run/nic_router.run @@ -34,9 +34,8 @@ proc nic_drv_build { } { proc gpio_drv_build { } { if {[gpio_drv] != ""} { return drivers/gpio } } build "core init drivers/timer server/nic_router server/nic_bridge - test/lwip/http_srv_static test/lwip/http_clnt test/lxip/udp_echo - test/lxip/udp_client [nic_drv_build] [gpio_drv_build] - [platform_drv_build_components]" + test/lwip/http_srv_static test/lwip/http_clnt test/lwip/udp + [nic_drv_build] [gpio_drv_build] [platform_drv_build_components]" create_boot_directory @@ -81,23 +80,18 @@ proc nic_drv_config { } { } proc client_bin { prot } { - if {$prot == "udp"} { return "test-lxip_udp_client" } + if {$prot == "udp"} { return "test-lwip-udp-client" } if {$prot == "http"} { return "test-http_clnt" } } proc server_bin { prot } { - if {$prot == "udp"} { return "test-lxip_udp_echo" } + if {$prot == "udp"} { return "test-lwip-udp-server" } if {$prot == "http"} { return "test-lwip_httpsrv_static" } } -proc ram_quota { prot } { - if {$prot == "udp"} { return 29M } - if {$prot == "http"} { return 12M } -} - proc client_config { prot index ip_addr gateway netmask nic srv_port srv_ip } { append result { - + @@ -115,7 +109,7 @@ proc server_config { prot index ip_addr gateway netmask nic port } { append result { - + @@ -276,9 +270,9 @@ install_config $config build_boot_image " core init timer nic_router nic_bridge ld.lib.so libc.lib.so libm.lib.so - lwip.lib.so lxip.lib.so posix.lib.so test-http_clnt - test-lwip_httpsrv_static test-lxip_udp_echo test-lxip_udp_client - [nic_drv_binary] [gpio_drv] [platform_drv_boot_modules]" + lwip.lib.so posix.lib.so test-http_clnt test-lwip_httpsrv_static + test-lwip-udp-client test-lwip-udp-server [nic_drv_binary] [gpio_drv] + [platform_drv_boot_modules]" proc nic_qemu_args { } { if {[have_spec x86]} { return "-net nic,model=e1000" } diff --git a/repos/libports/src/test/lwip/udp/client/main.cc b/repos/libports/src/test/lwip/udp/client/main.cc new file mode 100644 index 0000000000..db385748f2 --- /dev/null +++ b/repos/libports/src/test/lwip/udp/client/main.cc @@ -0,0 +1,87 @@ +/* + * \brief Simple UDP test client + * \author Martin Stein + * \date 2017-10-18 + */ + +/* + * Copyright (C) 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 +#include +#include +#include +#include + +/* libc includes */ +#include +#include +#include +#include + +using namespace Genode; +using Ipv4_addr_str = Genode::String<16>; + +struct Socket_failed : Genode::Exception { }; +struct Send_failed : Genode::Exception { }; +struct Receive_failed : Genode::Exception { }; + +struct Read_server_port_attr_failed : Exception { }; +struct Read_server_ip_attr_failed : Exception { }; + + +void Libc::Component::construct(Libc::Env &env) +{ + /* wait a while for the server to come up */ + Timer::Connection timer(env); + timer.msleep(3000); + + /* create socket */ + int s = socket(AF_INET, SOCK_DGRAM, 0 ); + if (s < 0) { + throw Socket_failed(); + } + /* try to send and receive a message multiple times */ + for (int j = 0; j != 5; ++j) { + timer.msleep(1000); + + /* read server IP address and port */ + Ipv4_addr_str serv_addr; + unsigned port = 0; + Attached_rom_dataspace config(env, "config"); + Xml_node config_node = config.xml(); + try { config_node.attribute("server_ip").value(&serv_addr); } + catch (...) { + throw Read_server_port_attr_failed(); + } + try { config_node.attribute("server_port").value(&port); } + catch (...) { + throw Read_server_port_attr_failed(); + } + /* create server socket address */ + struct sockaddr_in addr; + socklen_t addr_sz = sizeof(addr); + addr.sin_port = htons(port); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(serv_addr.string()); + + /* send test message */ + enum { BUF_SZ = 1024 }; + char buf[BUF_SZ]; + ::snprintf(buf, BUF_SZ, "UDP server at %s:%u", serv_addr.string(), port); + if (sendto(s, buf, BUF_SZ, 0, (struct sockaddr*)&addr, addr_sz) != BUF_SZ) { + throw Send_failed(); + } + /* receive and print what has been received */ + if (recvfrom(s, buf, BUF_SZ, 0, (struct sockaddr*)&addr, &addr_sz) != BUF_SZ) { + throw Receive_failed(); + } + log("Received \"", String<64>(buf), " ...\""); + } + log("Test done"); +} diff --git a/repos/libports/src/test/lwip/udp/client/target.mk b/repos/libports/src/test/lwip/udp/client/target.mk new file mode 100644 index 0000000000..f8c8639781 --- /dev/null +++ b/repos/libports/src/test/lwip/udp/client/target.mk @@ -0,0 +1,5 @@ +TARGET = test-lwip-udp-client +LIBS = posix libc_lwip_nic_dhcp libc_lwip lwip +SRC_CC = main.cc + +INC_DIR += $(REP_DIR)/src/lib/lwip/include diff --git a/repos/libports/src/test/lwip/udp/server/main.cc b/repos/libports/src/test/lwip/udp/server/main.cc new file mode 100644 index 0000000000..e007b521ac --- /dev/null +++ b/repos/libports/src/test/lwip/udp/server/main.cc @@ -0,0 +1,80 @@ +/* + * \brief Simple UDP test server + * \author Martin Stein + * \date 2017-10-18 + */ + +/* + * Copyright (C) 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 +#include +#include +#include + +/* libc includes */ +#include +#include +#include +#include + +using namespace Genode; +using Ipv4_addr_str = Genode::String<16>; + +struct Socket_failed : Genode::Exception { }; +struct Send_failed : Genode::Exception { }; +struct Receive_failed : Genode::Exception { }; +struct Bind_failed : Genode::Exception { }; + +struct Read_port_attr_failed : Genode::Exception { }; + + +void Libc::Component::construct(Libc::Env & env) +{ + /* create socket */ + int s = socket(AF_INET, SOCK_DGRAM, 0 ); + if (s < 0) { + throw Socket_failed(); + } + /* read server port */ + unsigned port = 0; + Attached_rom_dataspace config(env, "config"); + Xml_node config_node = config.xml(); + try { config_node.attribute("port").value(&port); } + catch (...) { + throw Read_port_attr_failed(); + } + /* create server socket address */ + struct sockaddr_in in_addr; + in_addr.sin_family = AF_INET; + in_addr.sin_port = htons(port); + in_addr.sin_addr.s_addr = INADDR_ANY; + + /* bind server socket address to socket */ + if (bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) { + throw Bind_failed(); + } + /* prepare client socket address */ + struct sockaddr_in addr; + addr.sin_family = AF_INET; + socklen_t addr_sz = sizeof(addr); + + while (true) { + + /* receive and send back one message without any modifications */ + char buf[4096]; + ::memset(buf, 0, sizeof(buf)); + ssize_t rcv_sz = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addr_sz); + if (rcv_sz < 0) { + throw Receive_failed(); + } + if (sendto(s, buf, rcv_sz, 0, (struct sockaddr*)&addr, addr_sz) != rcv_sz) { + throw Send_failed(); + } + } +} diff --git a/repos/libports/src/test/lwip/udp/server/target.mk b/repos/libports/src/test/lwip/udp/server/target.mk new file mode 100644 index 0000000000..3cee67dbeb --- /dev/null +++ b/repos/libports/src/test/lwip/udp/server/target.mk @@ -0,0 +1,5 @@ +TARGET = test-lwip-udp-server +LIBS = posix libc_lwip_nic_dhcp libc_lwip lwip +SRC_CC = main.cc + +INC_DIR += $(REP_DIR)/src/lib/lwip/include