genode/repos/os/src/server/nic_dump/interface.cc
Martin Stein ed13a0a262 nic_dump: make protocols configurable
Each supported protocol now has an attribute with the name of the protocol in
the config tag. Each of these attributes accepts one of four possible values:

* no      - do not print out this protocol
* name    - print only the protocol name
* default - print a short summary of the most important header values
* all     - print all available header values

Example:

! <config eth="name"
!         arp="all"
!         ipv4="default"
!         dhcp="no"
!         icmp="all"
!         udp="no"
!         tcp="default"
!         ... />

Corresponding output example:

! ETH IPV4 10.0.2.212 > 10.0.2.55   time 7158 ms (Δ 11 ms)
! ETH IPV4 10.0.2.55 > 10.0.2.201  TCP 80 > 49154 flags ' time 6976 ms (Δ 5 ms)
! ETH ARP hw 1 prot 2048 hwsz 6 protsz 4 op 1 srcmac 02:02:02:02:02:01 srcip 10.0.2.212 dstmac 00:00:00:00:00:00 dstip 10.0.2.55 time 7074 ms (Δ 98 ms)

Issue #2738
2018-04-10 11:20:49 +02:00

119 lines
3.6 KiB
C++

/*
* \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 <interface.h>
/* Genode includes */
#include <net/ethernet.h>
#include <packet_log.h>
#include <util/xml_node.h>
using namespace Net;
using namespace Genode;
void Net::Interface::_handle_eth(void *const eth_base,
size_t const eth_size,
Packet_descriptor const &)
{
try {
Ethernet_frame &eth = *reinterpret_cast<Ethernet_frame *>(eth_base);
Interface &remote = _remote.deref();
if (_log_time) {
Genode::Duration const new_time = _timer.curr_time();
unsigned long const new_time_ms = new_time.trunc_to_plain_us().value / 1000;
unsigned long const old_time_ms = _curr_time.trunc_to_plain_us().value / 1000;
log("\033[33m(", remote._label, " <- ", _label, ")\033[0m ",
packet_log(eth, _log_cfg), " \033[33mtime ", new_time_ms,
" ms (Δ ", new_time_ms - old_time_ms, " ms)\033[0m");
_curr_time = new_time;
} else {
log("\033[33m(", remote._label, " <- ", _label, ")\033[0m ",
packet_log(eth, _log_cfg));
}
remote._send(eth, eth_size);
}
catch (Pointer<Interface>::Invalid) {
error("no remote interface set"); }
}
void Net::Interface::_send(Ethernet_frame &eth, 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 *)&eth, size);
_source().submit_packet(pkt);
}
catch (Packet_stream_source::Packet_alloc_failed) {
error("Failed to allocate packet"); }
}
void Net::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 Net::Interface::_ready_to_ack()
{
while (_source().ack_avail()) {
_source().release_packet(_source().get_acked_packet()); }
}
Net::Interface::Interface(Entrypoint &ep,
Interface_label label,
Timer::Connection &timer,
Duration &curr_time,
bool log_time,
Allocator &alloc,
Xml_node config)
:
_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 },
_log_cfg { config.attribute_value("eth", Packet_log_style::DEFAULT),
config.attribute_value("arp", Packet_log_style::DEFAULT),
config.attribute_value("ipv4", Packet_log_style::DEFAULT),
config.attribute_value("dhcp", Packet_log_style::DEFAULT),
config.attribute_value("udp", Packet_log_style::DEFAULT),
config.attribute_value("icmp", Packet_log_style::DEFAULT),
config.attribute_value("tcp", Packet_log_style::DEFAULT) }
{ }