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
This commit is contained in:
Martin Stein 2018-04-06 11:56:33 +02:00 committed by Christian Helmuth
parent fed42e1742
commit ed13a0a262
8 changed files with 106 additions and 50 deletions

View File

@ -59,7 +59,16 @@ append config {
<start name="nic_dump" priority="-1">
<resource name="RAM" quantum="6M"/>
<provides><service name="Nic"/></provides>
<config uplink="bridge" downlink="router" time="yes"/>
<config uplink="bridge"
downlink="router"
time="yes"
eth="name"
arp="all"
ipv4="default"
dhcp="no"
udp="no"
icmp="all"
tcp="default" />
<route>
<service name="Nic"> <child name="nic_bridge"/> </service>
<any-service> <parent/> <any-child/> </any-service>

View File

@ -7,14 +7,31 @@ ARP, IPv4, TCP, UDP, and DHCP.
Basics
~~~~~~
The component knows three configuration attributes:
this is an example configuration of the component showing all attributes with
their default values (except config.uplink and config.downlink):
! <config uplink="karl" downlink="olivia" time="yes"/>
! <config uplink="uplink"
! downlink="downlink"
! time="no"
! eth="default"
! arp="default"
! ipv4="default"
! dhcp="default"
! udp="default"
! icmp="default"
! tcp="default" />
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.
the log. The third attribute 'time' defines wether to print timing information
or not. Furthemore, as you can see, each supported protocol 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
An example output snippet of the component might be:

View File

@ -68,7 +68,7 @@ Net::Session_component::Session_component(Allocator &alloc,
env.ep().rpc_ep()),
Interface(env.ep(), config.attribute_value("downlink", Interface_label()),
timer, curr_time, config.attribute_value("time", false),
_guarded_alloc),
_guarded_alloc, config),
_uplink(env, config, timer, curr_time, alloc),
_link_state_handler(env.ep(), *this, &Session_component::_handle_link_state)
{

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <net/ethernet.h>
#include <packet_log.h>
#include <util/xml_node.h>
using namespace Net;
using namespace Genode;
@ -29,7 +30,6 @@ void Net::Interface::_handle_eth(void *const eth_base,
try {
Ethernet_frame &eth = *reinterpret_cast<Ethernet_frame *>(eth_base);
Interface &remote = _remote.deref();
Packet_log_config log_cfg;
if (_log_time) {
Genode::Duration const new_time = _timer.curr_time();
@ -37,12 +37,13 @@ void Net::Interface::_handle_eth(void *const eth_base,
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,
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));
log("\033[33m(", remote._label, " <- ", _label, ")\033[0m ",
packet_log(eth, _log_cfg));
}
remote._send(eth, eth_size);
}
@ -95,12 +96,23 @@ Net::Interface::Interface(Entrypoint &ep,
Timer::Connection &timer,
Duration &curr_time,
bool log_time,
Allocator &alloc)
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)
_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) }
{ }

View File

@ -16,12 +16,15 @@
/* local includes */
#include <pointer.h>
#include <packet_log.h>
/* Genode includes */
#include <nic_session/nic_session.h>
#include <util/string.h>
#include <timer_session/connection.h>
namespace Genode { class Xml_node; }
namespace Net {
using Packet_descriptor = ::Nic::Packet_descriptor;
@ -46,12 +49,13 @@ class Net::Interface
private:
Genode::Allocator &_alloc;
Pointer<Interface> _remote { };
Interface_label _label;
Timer::Connection &_timer;
Genode::Duration &_curr_time;
bool _log_time;
Genode::Allocator &_alloc;
Pointer<Interface> _remote { };
Interface_label _label;
Timer::Connection &_timer;
Genode::Duration &_curr_time;
bool _log_time;
Packet_log_config const _log_cfg;
void _send(Ethernet_frame &eth, Genode::size_t const eth_size);
@ -80,7 +84,8 @@ class Net::Interface
Timer::Connection &timer,
Genode::Duration &curr_time,
bool log_time,
Genode::Allocator &alloc);
Genode::Allocator &alloc,
Genode::Xml_node config);
virtual ~Interface() { }

View File

@ -25,7 +25,7 @@ void Packet_log<Dhcp_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.dhcp) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mDHCP\033[0m");
print(output, " op ", _pkt.op());
@ -49,13 +49,13 @@ void Packet_log<Dhcp_packet>::print(Output &output) const
});
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mDHCP\033[0m ", _pkt.client_mac(), " > ",
_pkt.siaddr(), " cmd ", _pkt.op());
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mDHCP\033[0m");
break;
@ -87,7 +87,7 @@ void Packet_log<Arp_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.arp) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mARP\033[0m");
print(output, " hw ", _pkt.hardware_address_type());
@ -108,14 +108,14 @@ void Packet_log<Arp_packet>::print(Output &output) const
}
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mARP\033[0m ", _pkt.src_mac(), " ",
_pkt.src_ip(), " > ", _pkt.dst_mac(), " ", _pkt.dst_ip(),
" cmd ", _pkt.opcode());
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mARP\033[0m");
break;
@ -132,7 +132,7 @@ void Packet_log<Ethernet_frame>::print(Output &output) const
/* print header attributes */
switch (_cfg.eth) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mETH\033[0m");
print(output, " src ", _pkt.src());
@ -140,13 +140,13 @@ void Packet_log<Ethernet_frame>::print(Output &output) const
print(output, " typ ", (Genode::uint16_t)_pkt.type());
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mETH\033[0m ", _pkt.src(), " > ", _pkt.dst(),
" ");
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mETH\033[0m");
break;
@ -177,7 +177,7 @@ void Packet_log<Ipv4_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.ipv4) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mIPV4\033[0m");
print(output, " hdrlen ", _pkt.header_length());
@ -195,13 +195,13 @@ void Packet_log<Ipv4_packet>::print(Output &output) const
print(output, " dst ", _pkt.dst());
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mIPV4\033[0m ", _pkt.src(), " > ", _pkt.dst(),
" ");
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mIPV4\033[0m");
break;
@ -236,7 +236,7 @@ void Packet_log<Tcp_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.tcp) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mTCP\033[0m");
print(output, " src ", _pkt.src_port());
@ -250,13 +250,13 @@ void Packet_log<Tcp_packet>::print(Output &output) const
print(output, " urgp ", _pkt.urgent_ptr());
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mTCP\033[0m ", _pkt.src_port(), " > ",
_pkt.dst_port(), " flags '");
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mTCP\033[0m");
break;
@ -273,7 +273,7 @@ void Packet_log<Udp_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.udp) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mUDP\033[0m");
print(output, " src ", _pkt.src_port());
@ -282,13 +282,13 @@ void Packet_log<Udp_packet>::print(Output &output) const
print(output, " crc ", _pkt.checksum());
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mUDP\033[0m ", _pkt.src_port(), " > ",
_pkt.dst_port(), " ");
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mUDP\033[0m");
break;
@ -309,7 +309,7 @@ void Packet_log<Icmp_packet>::print(Output &output) const
/* print header attributes */
switch (_cfg.icmp) {
case Packet_log_style::COMPREHENSIVE:
case Packet_log_style::ALL:
print(output, "\033[32mICMP\033[0m");
print(output, " typ ", (unsigned)_pkt.type());
@ -318,13 +318,13 @@ void Packet_log<Icmp_packet>::print(Output &output) const
print(output, " roh ", _pkt.rest_of_header());
break;
case Packet_log_style::COMPACT:
case Packet_log_style::DEFAULT:
print(output, "\033[32mICMP\033[0m ", (unsigned)_pkt.type(), " ",
(unsigned)_pkt.code());
break;
case Packet_log_style::SHORT:
case Packet_log_style::NAME:
print(output, "\033[32mICMP\033[0m");
break;

View File

@ -29,7 +29,7 @@ namespace Net {
enum class Packet_log_style : Genode::uint8_t
{
NONE, SHORT, COMPACT, COMPREHENSIVE,
NO, NAME, DEFAULT, ALL,
};
struct Packet_log_config;
@ -38,6 +38,18 @@ namespace Net {
struct Packet_log;
}
namespace Genode
{
inline size_t ascii_to(char const *s, Net::Packet_log_style &result)
{
if (!strcmp(s, "no", 2)) { result = Net::Packet_log_style::NO; return 2; }
if (!strcmp(s, "name", 4)) { result = Net::Packet_log_style::NAME; return 4; }
if (!strcmp(s, "default", 7)) { result = Net::Packet_log_style::DEFAULT; return 7; }
if (!strcmp(s, "all", 3)) { result = Net::Packet_log_style::ALL; return 3; }
return 0;
}
}
/**
* Configuration for the print functionality of network packets
@ -48,7 +60,7 @@ struct Net::Packet_log_config
Style eth, arp, ipv4, dhcp, udp, icmp, tcp;
Packet_log_config(Style def = Style::COMPACT)
Packet_log_config(Style def = Style::DEFAULT)
: eth(def), arp(def), ipv4(def), dhcp(def), udp(def), icmp(def), tcp(def) { }
Packet_log_config(Style eth,

View File

@ -28,10 +28,11 @@ Net::Uplink::Uplink(Env &env,
Duration &curr_time,
Allocator &alloc)
:
Nic::Packet_allocator(&alloc),
Nic::Connection(env, this, BUF_SIZE, BUF_SIZE),
Net::Interface(env.ep(), config.attribute_value("uplink", Interface_label()),
timer, curr_time, config.attribute_value("time", false), alloc)
Nic::Packet_allocator { &alloc },
Nic::Connection { env, this, BUF_SIZE, BUF_SIZE },
Net::Interface { env.ep(), config.attribute_value("uplink", Interface_label()),
timer, curr_time, config.attribute_value("time", false),
alloc, config }
{
rx_channel()->sigh_ready_to_ack(_sink_ack);
rx_channel()->sigh_packet_avail(_sink_submit);