From 35cc020e9c22460ce9175b09cdb6dbd60a23cc25 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 8 Mar 2017 15:40:18 +0100 Subject: [PATCH] os/server: nic_dump A tiny bump-in-the-wire tool for dumping NIC packet information. Ref #2314 --- repos/libports/run/nic_dump.run | 258 ++++++++++++++++++++++ repos/os/src/server/nic_dump/README | 44 ++++ repos/os/src/server/nic_dump/component.cc | 150 +++++++++++++ repos/os/src/server/nic_dump/component.h | 143 ++++++++++++ repos/os/src/server/nic_dump/interface.cc | 102 +++++++++ repos/os/src/server/nic_dump/interface.h | 88 ++++++++ repos/os/src/server/nic_dump/main.cc | 58 +++++ repos/os/src/server/nic_dump/pointer.h | 55 +++++ repos/os/src/server/nic_dump/target.mk | 7 + repos/os/src/server/nic_dump/uplink.cc | 40 ++++ repos/os/src/server/nic_dump/uplink.h | 54 +++++ 11 files changed, 999 insertions(+) create mode 100644 repos/libports/run/nic_dump.run create mode 100644 repos/os/src/server/nic_dump/README create mode 100644 repos/os/src/server/nic_dump/component.cc create mode 100644 repos/os/src/server/nic_dump/component.h create mode 100644 repos/os/src/server/nic_dump/interface.cc create mode 100644 repos/os/src/server/nic_dump/interface.h create mode 100644 repos/os/src/server/nic_dump/main.cc create mode 100644 repos/os/src/server/nic_dump/pointer.h create mode 100644 repos/os/src/server/nic_dump/target.mk create mode 100644 repos/os/src/server/nic_dump/uplink.cc create mode 100644 repos/os/src/server/nic_dump/uplink.h diff --git a/repos/libports/run/nic_dump.run b/repos/libports/run/nic_dump.run new file mode 100644 index 0000000000..32f14bc655 --- /dev/null +++ b/repos/libports/run/nic_dump.run @@ -0,0 +1,258 @@ +# +# Build components +# + +proc enable_test_1 { } { return 1 } +proc enable_test_2 { } { return 1 } + +source ${genode_dir}/repos/base/run/platform_drv.inc + +proc nic_drv { } { + if {[have_spec omap4] || [have_spec arndale] || [have_spec rpi]} { return usb_drv } + if {!([have_spec imx53] || [have_spec riscv] || [have_spec odroid_xu] || [have_spec wand_quad])} { return nic_drv } +} + +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 } + if {[have_spec gpio]} { return gpio_drv } +} + +if {[nic_drv] == ""} { + puts "\n Run script is not supported on this platform. \n"; exit 0 } + +proc nic_drv_build { } { + if {[nic_drv] == "nic_drv"} { return drivers/nic } + if {[nic_drv] == "usb_drv"} { return drivers/usb } +} + +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 server/nic_dump [nic_drv_build] [gpio_drv_build] + [platform_drv_build_components]" + +create_boot_directory + +# +# Generate config +# + +proc gpio_drv_config { } { + if {[have_spec gpio]} { + append result { + + + + } + return $result + } +} + +proc nic_drv_config { } { + if {[nic_drv] == "nic_drv"} { + append result { + + + + } + return $result + } + if {[nic_drv] == "usb_drv"} { + append result { + + + + + + + + + } + return $result + } +} + +proc client_bin { prot } { + if {$prot == "udp"} { return "test-lxip_udp_client" } + if {$prot == "http"} { return "test-http_clnt" } } + +proc server_bin { prot } { + if {$prot == "udp"} { return "test-lxip_udp_echo" } + if {$prot == "http"} { return "test-lwip_httpsrv_static" } } + +proc client_config { prot index ip_addr gateway netmask nic srv_port srv_ip } { + append result { + + + + + + + + + + + + } + return $result +} + +proc server_config { prot index ip_addr gateway netmask nic port } { + append result { + + + + + + + + + + + + } + return $result +} + +proc test_1_config { } { + if {[enable_test_1]} { return " + [client_config udp 2 10.0.2.212 10.0.2.1 255.255.255.0 nic_bridge 1 10.0.2.55] + [server_config udp 2 18.17.16.15 18.17.16.14 255.255.0.0 nic_router 1 ]" } +} + +proc test_2_config { } { + if {[enable_test_2]} { return " + [client_config http 1 10.0.2.201 10.0.2.1 255.255.255.0 nic_bridge 80 10.0.2.55] + [server_config http 1 192.168.1.18 192.168.1.1 255.255.255.0 nic_router 80 ]" } +} + +append config { + + + + + + + + + + + + + + + + + + } [gpio_drv_config] { + } [nic_drv_config] { + } [platform_drv_config] { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } [test_1_config] { + } [test_2_config] { + + } + +install_config $config + +# +# Create single image and execute +# + + +build_boot_image " + core init timer nic_router nic_bridge ld.lib.so libc.lib.so libm.lib.so + libc_resolv.lib.so lwip.lib.so lxip.lib.so test-http_clnt + test-lwip_httpsrv_static nic_dump test-lxip_udp_echo test-lxip_udp_client + [nic_drv] [gpio_drv] [platform_drv_boot_modules]" + +proc nic_qemu_args { } { + if {[have_spec x86]} { return "-net nic,model=e1000" } + if {[have_spec lan9118]} { return "-net nic,model=lan9118" } } + +append qemu_args "-m 384 -nographic -net user -redir udp:5555::1337 [nic_qemu_args]" + +run_genode_until {.*Test done.*\n.*Test done.*\n} 60 diff --git a/repos/os/src/server/nic_dump/README b/repos/os/src/server/nic_dump/README new file mode 100644 index 0000000000..4da4feaf01 --- /dev/null +++ b/repos/os/src/server/nic_dump/README @@ -0,0 +1,44 @@ + + ================================== + Component for tracking NIC traffic + ================================== + + +Brief +##### + +The 'nic_dump' component is a bump-in-the-wire component for the NIC service +that does deep packet inspection for each passing packet and dumps the +gathered information to the log. This includes information about Ethernet, +ARP, IPv4, TCP, UDP, and DHCP. + + +Basics +###### + +The component knows three configuration attributes: + +! + +The values of the 'uplink' and 'downlink' attributes are used as log labels +for the two NIC peers. These labels are only relevant for the readability of +the log. The third attribute 'time' defines wether to print timing +information or not. + +An example output snippet of the component might be: + +! (olivia <- karl) ETH ... ARP ... time 4626 (15) +! (karl <- olivia) ETH ... ARP ... time 4639 (7) +! (olivia <- karl) ETH ... IPV4 ... TCP ... time 4644 (5) +! (karl <- olivia) ETH ... IPV4 ... TCP ... time 4660 (6) + +After the NIC peer labels and the traffic direction, the unfolding of the +protocols and their information follows. The printing order is from the lowest +to the highest networking layer. At the end of each line there is the word +'time' followed by two numbers if you have enabled timing information. The +first number is the packet-arrival time (the milliseconds since 'nic_dump' was +started). The second number is the time from the last packet that passed till +this one (milliseconds). + +A comprehensive example of how to use the NIC dump can be found in the test +script 'libports/run/nic_dump.run'. diff --git a/repos/os/src/server/nic_dump/component.cc b/repos/os/src/server/nic_dump/component.cc new file mode 100644 index 0000000000..1351bcf826 --- /dev/null +++ b/repos/os/src/server/nic_dump/component.cc @@ -0,0 +1,150 @@ +/* + * \brief Downlink interface in form of a NIC session component + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 + +/* local includes */ +#include +#include + +using namespace Net; +using namespace Genode; + + +/************************** + ** Communication_buffer ** + **************************/ + +Communication_buffer::Communication_buffer(Ram_session &ram, + Genode::size_t const size) +: + Ram_dataspace_capability(ram.alloc(size)), _ram(ram) +{ } + + +/**************************** + ** Session_component_base ** + ****************************/ + +Session_component_base:: +Session_component_base(Allocator &guarded_alloc_backing, + size_t const guarded_alloc_amount, + Ram_session &buf_ram, + size_t const tx_buf_size, + size_t const rx_buf_size) +: + _guarded_alloc(&guarded_alloc_backing, guarded_alloc_amount), + _range_alloc(&_guarded_alloc), _tx_buf(buf_ram, tx_buf_size), + _rx_buf(buf_ram, rx_buf_size) +{ } + + +/*********************** + ** Session_component ** + ***********************/ + +Net::Session_component::Session_component(Allocator &alloc, + size_t const amount, + Ram_session &buf_ram, + size_t const tx_buf_size, + size_t const rx_buf_size, + Region_map ®ion_map, + Uplink &uplink, + Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Entrypoint &ep) +: + Session_component_base(alloc, amount, buf_ram, tx_buf_size, rx_buf_size), + Session_rpc_object(region_map, _tx_buf, _rx_buf, &_range_alloc, ep.rpc_ep()), + Interface(ep, config.attribute_value("downlink", Interface_label()), + timer, curr_time, config.attribute_value("time", false), + _guarded_alloc), + _mac(uplink.mac_address()) +{ + _tx.sigh_ready_to_ack(_sink_ack); + _tx.sigh_packet_avail(_sink_submit); + _rx.sigh_ack_avail(_source_ack); + _rx.sigh_ready_to_submit(_source_submit); + Interface::remote(uplink); + uplink.Interface::remote(*this); +} + + +bool Session_component::link_state() +{ + warning("Session_component::link_state not implemented"); + return false; +} + + +void Session_component::link_state_sigh(Signal_context_capability sigh) +{ + warning("Session_component::link_state_sigh not implemented"); +} + + +/********** + ** Root ** + **********/ + +Net::Root::Root(Entrypoint &ep, + Allocator &alloc, + Uplink &uplink, + Ram_session &buf_ram, + Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Region_map ®ion_map) +: + Root_component(&ep.rpc_ep(), + &alloc), + _ep(ep), _uplink(uplink), _buf_ram(buf_ram), + _region_map(region_map), _config(config), _timer(timer), + _curr_time(curr_time) +{ } + + +Session_component *Net::Root::_create_session(char const *args) +{ + try { + size_t const ram_quota = + Arg_string::find_arg(args, "ram_quota").ulong_value(0); + + size_t const tx_buf_size = + Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); + + size_t const rx_buf_size = + Arg_string::find_arg(args, "rx_buf_size").ulong_value(0); + + size_t const session_size = + max((size_t)4096, sizeof(Session_component)); + + if (ram_quota < session_size) { + throw Root::Quota_exceeded(); } + + if (tx_buf_size > ram_quota - session_size || + rx_buf_size > ram_quota - session_size || + tx_buf_size + rx_buf_size > ram_quota - session_size) + { + error("insufficient 'ram_quota' for session creation"); + throw Root::Quota_exceeded(); + } + return new (md_alloc()) + Session_component(*md_alloc(), ram_quota - session_size, + _buf_ram, tx_buf_size, rx_buf_size, _region_map, + _uplink, _config, _timer, _curr_time, _ep); + } catch (...) { + throw Root::Unavailable(); } +} diff --git a/repos/os/src/server/nic_dump/component.h b/repos/os/src/server/nic_dump/component.h new file mode 100644 index 0000000000..9e08745c39 --- /dev/null +++ b/repos/os/src/server/nic_dump/component.h @@ -0,0 +1,143 @@ +/* + * \brief Downlink interface in form of a NIC session component + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 _COMPONENT_H_ +#define _COMPONENT_H_ + +/* Genode includes */ +#include +#include +#include +#include + +/* local includes */ +#include + +namespace Net { + + class Communication_buffer; + class Session_component_base; + class Session_component; + class Root; + class Uplink; +} + + +class Net::Communication_buffer : public Genode::Ram_dataspace_capability +{ + private: + + Genode::Ram_session &_ram; + + public: + + Communication_buffer(Genode::Ram_session &ram, + Genode::size_t const size); + + ~Communication_buffer() { _ram.free(*this); } +}; + + +class Net::Session_component_base +{ + protected: + + Genode::Allocator_guard _guarded_alloc; + Nic::Packet_allocator _range_alloc; + Communication_buffer _tx_buf; + Communication_buffer _rx_buf; + + public: + + Session_component_base(Genode::Allocator &guarded_alloc_backing, + Genode::size_t const guarded_alloc_amount, + Genode::Ram_session &buf_ram, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size); +}; + + +class Net::Session_component : public Session_component_base, + public ::Nic::Session_rpc_object, + public Interface +{ + private: + + Mac_address _mac; + + + /******************** + ** Net::Interface ** + ********************/ + + Packet_stream_sink &_sink() { return *_tx.sink(); } + Packet_stream_source &_source() { return *_rx.source(); } + + public: + + Session_component(Genode::Allocator &alloc, + Genode::size_t const amount, + Genode::Ram_session &buf_ram, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size, + Genode::Region_map ®ion_map, + Uplink &uplink, + Genode::Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Genode::Entrypoint &ep); + + + /****************** + ** Nic::Session ** + ******************/ + + Mac_address mac_address() { return _mac; } + bool link_state(); + void link_state_sigh(Genode::Signal_context_capability sigh); +}; + + +class Net::Root : public Genode::Root_component +{ + private: + + Genode::Entrypoint &_ep; + Uplink &_uplink; + Genode::Ram_session &_buf_ram; + Genode::Region_map &_region_map; + Genode::Xml_node _config; + Genode::Timer &_timer; + unsigned &_curr_time; + + + /******************** + ** Root_component ** + ********************/ + + Session_component *_create_session(char const *args); + + public: + + Root(Genode::Entrypoint &ep, + Genode::Allocator &alloc, + Uplink &uplink, + Genode::Ram_session &buf_ram, + Genode::Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Genode::Region_map ®ion_map); +}; + +#endif /* _COMPONENT_H_ */ diff --git a/repos/os/src/server/nic_dump/interface.cc b/repos/os/src/server/nic_dump/interface.cc new file mode 100644 index 0000000000..92e069574e --- /dev/null +++ b/repos/os/src/server/nic_dump/interface.cc @@ -0,0 +1,102 @@ +/* + * \brief A net interface in form of a signal-driven NIC-packet handler + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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. + */ + +/* local includes */ +#include + +/* Genode includes */ +#include + +using namespace Net; +using namespace Genode; + + +void Interface::_handle_eth(void *const eth_base, + size_t const eth_size, + Packet_descriptor const &pkt) +{ + try { + Ethernet_frame ð = *new (eth_base) Ethernet_frame(eth_size); + Interface &remote = _remote.deref(); + unsigned new_time = _timer.curr_time().value / 1000; + if (_log_time) { + log("\033[33m(", remote._label, " <- ", _label, ")\033[0m ", eth, + " \033[33mtime ", new_time, " (", new_time - _curr_time, + ")\033[0m"); + } else { + log("\033[33m(", remote._label, " <- ", _label, ")\033[0m ", eth); + } + _curr_time = new_time; + remote._send(eth, eth_size); + } + catch (Ethernet_frame::No_ethernet_frame) { + error("invalid ethernet frame"); } + + catch (Pointer::Invalid) { + error("no remote interface set"); } +} + + +void Interface::_send(Ethernet_frame ð, Genode::size_t const size) +{ + try { + Packet_descriptor const pkt = _source().alloc_packet(size); + char *content = _source().packet_content(pkt); + Genode::memcpy((void *)content, (void *)ð, size); + _source().submit_packet(pkt); + } + catch (Packet_stream_source::Packet_alloc_failed) { + error("Failed to allocate packet"); } +} + + +void Interface::_ready_to_submit() +{ + while (_sink().packet_avail()) { + + Packet_descriptor const pkt = _sink().get_packet(); + if (!pkt.size()) { + continue; } + + _handle_eth(_sink().packet_content(pkt), pkt.size(), pkt); + + if (!_sink().ready_to_ack()) { + error("ack state FULL"); + return; + } + _sink().acknowledge_packet(pkt); + } +} + + +void Interface::_ready_to_ack() +{ + while (_source().ack_avail()) { + _source().release_packet(_source().get_acked_packet()); } +} + + +Interface::Interface(Entrypoint &ep, + Interface_label label, + Genode::Timer &timer, + unsigned &curr_time, + bool log_time, + Allocator &alloc) +: + _sink_ack (ep, *this, &Interface::_ack_avail), + _sink_submit (ep, *this, &Interface::_ready_to_submit), + _source_ack (ep, *this, &Interface::_ready_to_ack), + _source_submit(ep, *this, &Interface::_packet_avail), + _alloc(alloc), _label(label), _timer(timer), _curr_time(curr_time), + _log_time(log_time) +{ } diff --git a/repos/os/src/server/nic_dump/interface.h b/repos/os/src/server/nic_dump/interface.h new file mode 100644 index 0000000000..9d7efca78f --- /dev/null +++ b/repos/os/src/server/nic_dump/interface.h @@ -0,0 +1,88 @@ +/* + * \brief A net interface in form of a signal-driven NIC-packet handler + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 _INTERFACE_H_ +#define _INTERFACE_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include +#include + +namespace Net { + + using Packet_descriptor = ::Nic::Packet_descriptor; + using Packet_stream_sink = ::Nic::Packet_stream_sink< ::Nic::Session::Policy>; + using Packet_stream_source = ::Nic::Packet_stream_source< ::Nic::Session::Policy>; + class Ethernet_frame; + class Interface; + using Interface_label = Genode::String<64>; +} + + +class Net::Interface +{ + protected: + + using Signal_handler = Genode::Signal_handler; + + Signal_handler _sink_ack; + Signal_handler _sink_submit; + Signal_handler _source_ack; + Signal_handler _source_submit; + + private: + + Genode::Allocator &_alloc; + Pointer _remote; + Interface_label _label; + Genode::Timer &_timer; + unsigned &_curr_time; + bool _log_time; + + void _send(Ethernet_frame ð, Genode::size_t const eth_size); + + void _handle_eth(void *const eth_base, + Genode::size_t const eth_size, + Packet_descriptor const &pkt); + + virtual Packet_stream_sink &_sink() = 0; + + virtual Packet_stream_source &_source() = 0; + + + /*********************************** + ** Packet-stream signal handlers ** + ***********************************/ + + void _ready_to_submit(); + void _ack_avail() { } + void _ready_to_ack(); + void _packet_avail() { } + + public: + + Interface(Genode::Entrypoint &ep, + Interface_label label, + Genode::Timer &timer, + unsigned &curr_time, + bool log_time, + Genode::Allocator &alloc); + + void remote(Interface &remote) { _remote.set(remote); } +}; + +#endif /* _INTERFACE_H_ */ diff --git a/repos/os/src/server/nic_dump/main.cc b/repos/os/src/server/nic_dump/main.cc new file mode 100644 index 0000000000..4334f85d59 --- /dev/null +++ b/repos/os/src/server/nic_dump/main.cc @@ -0,0 +1,58 @@ +/* + * \brief Bump-in-the-wire component to dump NIC traffic info to the log + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 */ +#include +#include +#include +#include + +/* local includes */ +#include +#include + +using namespace Net; +using namespace Genode; + + +class Main +{ + private: + + Genode::Attached_rom_dataspace _config; + Timer::Connection _timer_connection; + Genode::Timer _timer; + unsigned _curr_time { 0 }; + Genode::Heap _heap; + Uplink _uplink; + Net::Root _root; + + public: + + Main(Env &env); +}; + + +Main::Main(Env &env) +: + _config(env, "config"), _timer_connection(env), + _timer(_timer_connection, env.ep()), _heap(&env.ram(), &env.rm()), + _uplink(env, _config.xml(), _timer, _curr_time, _heap), + _root(env.ep(), _heap, _uplink, env.ram(), _config.xml(), _timer, + _curr_time, env.rm()) +{ + env.parent().announce(env.ep().manage(_root)); +} + + +void Component::construct(Env &env) { static Main main(env); } diff --git a/repos/os/src/server/nic_dump/pointer.h b/repos/os/src/server/nic_dump/pointer.h new file mode 100644 index 0000000000..5265e46c5b --- /dev/null +++ b/repos/os/src/server/nic_dump/pointer.h @@ -0,0 +1,55 @@ +/* + * \brief Pointer that can be dereferenced only when valid + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 _POINTER_H_ +#define _POINTER_H_ + +/* Genode includes */ +#include + +namespace Net { template class Pointer; } + +template +class Net::Pointer +{ + private: + + T *_ptr; + + public: + + struct Valid : Genode::Exception { }; + struct Invalid : Genode::Exception { }; + + Pointer() : _ptr(nullptr) { } + + T &deref() const + { + if (_ptr == nullptr) { + throw Invalid(); } + + return *_ptr; + } + + void set(T &ptr) + { + if (_ptr != nullptr) { + throw Valid(); } + + _ptr = &ptr; + } + + void unset() { _ptr = nullptr; } +}; + +#endif /* _POINTER_H_ */ diff --git a/repos/os/src/server/nic_dump/target.mk b/repos/os/src/server/nic_dump/target.mk new file mode 100644 index 0000000000..a8e7ae9f8d --- /dev/null +++ b/repos/os/src/server/nic_dump/target.mk @@ -0,0 +1,7 @@ +TARGET = nic_dump + +LIBS += base net config timeout + +SRC_CC += component.cc main.cc uplink.cc interface.cc + +INC_DIR += $(PRG_DIR) diff --git a/repos/os/src/server/nic_dump/uplink.cc b/repos/os/src/server/nic_dump/uplink.cc new file mode 100644 index 0000000000..2d92f669b5 --- /dev/null +++ b/repos/os/src/server/nic_dump/uplink.cc @@ -0,0 +1,40 @@ +/* + * \brief Uplink interface in form of a NIC session component + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 + +/* local includes */ +#include + +using namespace Net; +using namespace Genode; + + +Net::Uplink::Uplink(Env &env, + Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Allocator &alloc) +: + Nic::Packet_allocator(&alloc), + Nic::Connection(env, this, BUF_SIZE, BUF_SIZE), + Interface(env.ep(), config.attribute_value("uplink", Interface_label()), + timer, curr_time, config.attribute_value("time", false), alloc) +{ + rx_channel()->sigh_ready_to_ack(_sink_ack); + rx_channel()->sigh_packet_avail(_sink_submit); + tx_channel()->sigh_ack_avail(_source_ack); + tx_channel()->sigh_ready_to_submit(_source_submit); +} diff --git a/repos/os/src/server/nic_dump/uplink.h b/repos/os/src/server/nic_dump/uplink.h new file mode 100644 index 0000000000..ec6687057c --- /dev/null +++ b/repos/os/src/server/nic_dump/uplink.h @@ -0,0 +1,54 @@ +/* + * \brief Uplink interface in form of a NIC session component + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-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 _UPLINK_H_ +#define _UPLINK_H_ + +/* Genode includes */ +#include +#include +#include + +/* local includes */ +#include + +namespace Net { class Uplink; } + +class Net::Uplink : public Nic::Packet_allocator, + public Nic::Connection, + public Interface +{ + private: + + enum { + PKT_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE, + BUF_SIZE = Nic::Session::QUEUE_SIZE * PKT_SIZE, + }; + + /******************** + ** Net::Interface ** + ********************/ + + Packet_stream_sink &_sink() { return *rx(); } + Packet_stream_source &_source() { return *tx(); } + + public: + + Uplink(Genode::Env &env, + Genode::Xml_node config, + Genode::Timer &timer, + unsigned &curr_time, + Genode::Allocator &alloc); +}; + +#endif /* _UPLINK_H_ */