ping: support reporting results

This feature simplifies automated testing. It was added to enable the creation
of the test/nic_router_uplink component.

Ref #5192
This commit is contained in:
Martin Stein 2024-06-14 05:56:20 +02:00 committed by Norman Feske
parent 24342db476
commit a935a733ab
5 changed files with 100 additions and 20 deletions

View File

@ -2,3 +2,4 @@ base
os os
net net
nic_session nic_session
report_session

View File

@ -58,6 +58,7 @@ create_boot_directory
import_from_depot [depot_user]/src/[base_src] \ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/[drivers_nic_pkg] \ [depot_user]/pkg/[drivers_nic_pkg] \
[depot_user]/src/init \ [depot_user]/src/init \
[depot_user]/src/report_rom \
[depot_user]/src/nic_router [depot_user]/src/nic_router
build { app/ping } build { app/ping }
@ -114,6 +115,15 @@ append config {
</route> </route>
</start> </start>
<start name="report_rom" caps="200">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="ROM" />
<service name="Report" />
</provides>
<config verbose="yes"/>
</start>
<start name="nic_router" caps="200"> <start name="nic_router" caps="200">
<resource name="RAM" quantum="10M"/> <resource name="RAM" quantum="10M"/>
<provides> <provides>
@ -168,9 +178,11 @@ append config {
<resource name="RAM" quantum="8M"/> <resource name="RAM" quantum="8M"/>
<config dst_ip="} [dst_ip] {" <config dst_ip="} [dst_ip] {"
period_sec="1" period_sec="1"
report="yes"
verbose="no" verbose="no"
count="3"/> count="3"/>
<route> <route>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Nic"> <child name="nic_router"/> </service> <service name="Nic"> <child name="nic_router"/> </service>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</route> </route>

View File

@ -16,6 +16,7 @@ value for each attribute except 'config.dst_ip' and 'config.interface':
! protocol="icmp" ! protocol="icmp"
! period_sec="5" ! period_sec="5"
! verbose="no" ! verbose="no"
! report="yes"
! count="5" /> ! count="5" />
This is a short description of the tags and attributes: This is a short description of the tags and attributes:
@ -36,6 +37,9 @@ This is a short description of the tags and attributes:
:config.verbose: :config.verbose:
Optional. Toggles wether the component shall log debugging information. Optional. Toggles wether the component shall log debugging information.
:config.report:
Optional. Toggles wether the component shall report results.
:config.count: :config.count:
Optional. After how many successful pings the component exits successfully. Optional. After how many successful pings the component exits successfully.
@ -46,6 +50,30 @@ This is a short description of the tags and attributes:
Optional. Protocol to ping with. Can be one of 'icmp', 'udp'. Optional. Protocol to ping with. Can be one of 'icmp', 'udp'.
Report
~~~~~~
If config attribute 'report' is set, the component generates a report named
"last_received" that looks like this if the expected reply was received:
:ICMP:
! <result id="8" type="reply" bytes="64" from="10.0.2.2" ttl="64" time_ms="3.434" icmp_seq="2"/>
:UDP:
! <result id="8" type="reply" bytes="64" from="10.0.2.2" ttl="64" time_ms="3.434"/>
When an ICMP error "destination unreachable" was received instead, the report
looks like this:
:ICMP:
! <result id="10" type="destination_unreachable" from="10.0.1.79" icmp_seq="12"/>
:UDP:
! <result id="10" type="destination_unreachable" from="10.0.1.79"/>
The id attribute in the report is incremented with each result.
Sessions Sessions
~~~~~~~~ ~~~~~~~~
@ -53,6 +81,7 @@ This is an overview of the sessions required and provided by the
component apart from the environment sessions: component apart from the environment sessions:
* Requires one Timer session. * Requires one Timer session.
* Requires one Report session if config attribute report is set.
Examples Examples

View File

@ -15,6 +15,7 @@
<xs:element name="config"> <xs:element name="config">
<xs:complexType> <xs:complexType>
<xs:attribute name="verbose" type="Boolean" /> <xs:attribute name="verbose" type="Boolean" />
<xs:attribute name="report" type="Boolean" />
<xs:attribute name="dst_ip" type="Ipv4_address" /> <xs:attribute name="dst_ip" type="Ipv4_address" />
<xs:attribute name="dst_port" type="Port" /> <xs:attribute name="dst_port" type="Port" />
<xs:attribute name="protocol" type="Protocol" /> <xs:attribute name="protocol" type="Protocol" />

View File

@ -18,6 +18,7 @@
#include <protocol.h> #include <protocol.h>
/* Genode includes */ /* Genode includes */
#include <os/reporter.h>
#include <net/ipv4.h> #include <net/ipv4.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <net/arp.h> #include <net/arp.h>
@ -67,6 +68,9 @@ class Main : public Nic_handler,
Constructible<Periodic_timeout> _period { }; Constructible<Periodic_timeout> _period { };
Heap _heap { &_env.ram(), &_env.rm() }; Heap _heap { &_env.ram(), &_env.rm() };
bool const _verbose { _config.attribute_value("verbose", false) }; bool const _verbose { _config.attribute_value("verbose", false) };
bool const _report { _config.attribute_value("report", false) };
unsigned long _report_id { 0 };
Constructible<Expanding_reporter> _reporter { };
Net::Nic _nic { _env, _heap, *this, _verbose }; Net::Nic _nic { _env, _heap, *this, _verbose };
Ipv4_address const _dst_ip { _config.attribute_value("dst_ip", Ipv4_address()) }; Ipv4_address const _dst_ip { _config.attribute_value("dst_ip", Ipv4_address()) };
Mac_address _dst_mac { }; Mac_address _dst_mac { };
@ -156,6 +160,9 @@ Main::Main(Env &env) : _env(env)
/* else, start the DHCP client for requesting an IP config */ /* else, start the DHCP client for requesting an IP config */
else { else {
_dhcp_client.construct(_timer, _nic, *this); } _dhcp_client.construct(_timer, _nic, *this); }
if (_report)
_reporter.construct(env, "result", "result");
} }
@ -281,6 +288,16 @@ void Main::_handle_icmp_echo_reply(Ipv4_packet &ip,
": icmp_seq=", icmp_seq, " ttl=", (uint64_t)IPV4_TIME_TO_LIVE, ": icmp_seq=", icmp_seq, " ttl=", (uint64_t)IPV4_TIME_TO_LIVE,
" time=", time_ms, ".", time_us ," ms"); " time=", time_ms, ".", time_us ," ms");
if (_report)
_reporter->generate([&] (Xml_generator &xml) {
xml.attribute("id", _report_id++);
xml.attribute("type", "reply");
xml.attribute("bytes", ICMP_DATA_SIZE + sizeof(Icmp_packet));
xml.attribute("from", String<32>(ip.src()));
xml.attribute("ttl", (uint64_t)IPV4_TIME_TO_LIVE);
xml.attribute("time_ms", String<32>(time_ms, ".", time_us));
xml.attribute("icmp_seq", icmp_seq); });
/* raise ICMP sequence number and check exit condition */ /* raise ICMP sequence number and check exit condition */
_icmp_seq++; _icmp_seq++;
_count--; _count--;
@ -325,6 +342,12 @@ void Main::_handle_icmp_dst_unreachbl(Ipv4_packet &ip,
return; return;
} }
log("From ", ip.src(), " icmp_seq=", embed_icmp_seq, " Destination Unreachable"); log("From ", ip.src(), " icmp_seq=", embed_icmp_seq, " Destination Unreachable");
if (_report)
_reporter->generate([&] (Xml_generator &xml) {
xml.attribute("id", _report_id++);
xml.attribute("type", "destination_unreachable");
xml.attribute("from", String<32>(ip.src()));
xml.attribute("icmp_seq", embed_icmp_seq); });
break; break;
} }
case Protocol::UDP: case Protocol::UDP:
@ -349,6 +372,11 @@ void Main::_handle_icmp_dst_unreachbl(Ipv4_packet &ip,
return; return;
} }
log("From ", ip.src(), " Destination Unreachable"); log("From ", ip.src(), " Destination Unreachable");
if (_report)
_reporter->generate([&] (Xml_generator &xml) {
xml.attribute("id", _report_id++);
xml.attribute("type", "destination_unreachable");
xml.attribute("from", String<32>(ip.src())); });
break; break;
} }
} }
@ -414,6 +442,15 @@ void Main::_handle_udp(Ipv4_packet &ip,
log(udp.length(), " bytes from ", ip.src(), " ttl=", (uint64_t)IPV4_TIME_TO_LIVE, log(udp.length(), " bytes from ", ip.src(), " ttl=", (uint64_t)IPV4_TIME_TO_LIVE,
" time=", time_ms, ".", time_us ," ms"); " time=", time_ms, ".", time_us ," ms");
if (_report)
_reporter->generate([&] (Xml_generator &xml) {
xml.attribute("id", _report_id++);
xml.attribute("type", "reply");
xml.attribute("bytes", udp.length());
xml.attribute("from", String<32>(ip.src()));
xml.attribute("ttl", (uint64_t)IPV4_TIME_TO_LIVE);
xml.attribute("time_ms", String<32>(time_ms, ".", time_us)); });
/* check exit condition */ /* check exit condition */
_count--; _count--;
if (!_count) { if (!_count) {