mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 21:57:55 +00:00
nic_router: act as ICMP Echo server
The ICMP-Echo-server functionality of the router has the following configuration attributes (default values shown): ! <config icmp_echo_server="yes"> ! <domain icmp_echo_server="yes" ... /> ! </config> The icmp_echo_server attribute configures whether the router answers ICMP Echo requests that address the router. The <config> value affects all domains without a <domain> local value. Issue #2874
This commit is contained in:
parent
a9183da87b
commit
0b8520a208
@ -10,6 +10,7 @@ these domains. This is a brief overview of the features thereby provided:
|
|||||||
* NAPT for UDP, TCP and ICMP "Echo",
|
* NAPT for UDP, TCP and ICMP "Echo",
|
||||||
* forwarding of ICMP "Destination Unreachable" according to the UDP, TCP or
|
* forwarding of ICMP "Destination Unreachable" according to the UDP, TCP or
|
||||||
ICMP "Echo" connection it refers to,
|
ICMP "Echo" connection it refers to,
|
||||||
|
* acting as ICMP echo server per domain
|
||||||
* acting as DHCP server or client per domain,
|
* acting as DHCP server or client per domain,
|
||||||
* provide per-domain network statistics via a report session,
|
* provide per-domain network statistics via a report session,
|
||||||
* print out header information for each packet received or sent,
|
* print out header information for each packet received or sent,
|
||||||
@ -361,6 +362,21 @@ Denial-of-Service attacks against the destination domain by occupying all of
|
|||||||
its ports or IDs.
|
its ports or IDs.
|
||||||
|
|
||||||
|
|
||||||
|
Configuring ICMP-Echo-server functionality
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ICMP-Echo-server functionality of the router has the following
|
||||||
|
configuration attributes (default values shown):
|
||||||
|
|
||||||
|
! <config icmp_echo_server="yes">
|
||||||
|
! <domain icmp_echo_server="yes" ... />
|
||||||
|
! </config>
|
||||||
|
|
||||||
|
The icmp_echo_server attribute configures whether the router answers ICMP Echo
|
||||||
|
requests that address the router. The <config> value affects all domains
|
||||||
|
without a <domain> local value.
|
||||||
|
|
||||||
|
|
||||||
Configuring DHCP server functionality
|
Configuring DHCP server functionality
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -151,11 +151,12 @@
|
|||||||
<xs:element name="udp-forward" type="L3_forward_rule" />
|
<xs:element name="udp-forward" type="L3_forward_rule" />
|
||||||
|
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
<xs:attribute name="name" type="Domain_name" />
|
<xs:attribute name="name" type="Domain_name" />
|
||||||
<xs:attribute name="interface" type="Ipv4_address_prefix" />
|
<xs:attribute name="interface" type="Ipv4_address_prefix" />
|
||||||
<xs:attribute name="gateway" type="Ipv4_address" />
|
<xs:attribute name="gateway" type="Ipv4_address" />
|
||||||
<xs:attribute name="verbose_packets" type="Boolean" />
|
<xs:attribute name="verbose_packets" type="Boolean" />
|
||||||
<xs:attribute name="label" type="Session_label" />
|
<xs:attribute name="label" type="Session_label" />
|
||||||
|
<xs:attribute name="icmp_echo_server" type="Boolean" />
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element><!-- domain -->
|
</xs:element><!-- domain -->
|
||||||
|
|
||||||
@ -170,6 +171,7 @@
|
|||||||
<xs:attribute name="tcp_idle_timeout_sec" type="Seconds" />
|
<xs:attribute name="tcp_idle_timeout_sec" type="Seconds" />
|
||||||
<xs:attribute name="icmp_idle_timeout_sec" type="Seconds" />
|
<xs:attribute name="icmp_idle_timeout_sec" type="Seconds" />
|
||||||
<xs:attribute name="tcp_max_segm_lifetime_sec" type="Seconds" />
|
<xs:attribute name="tcp_max_segm_lifetime_sec" type="Seconds" />
|
||||||
|
<xs:attribute name="icmp_echo_server" type="Boolean" />
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element><!-- config -->
|
</xs:element><!-- config -->
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ Configuration::Configuration(Env &env,
|
|||||||
_verbose (node.attribute_value("verbose", false)),
|
_verbose (node.attribute_value("verbose", false)),
|
||||||
_verbose_packets (node.attribute_value("verbose_packets", false)),
|
_verbose_packets (node.attribute_value("verbose_packets", false)),
|
||||||
_verbose_domain_state (node.attribute_value("verbose_domain_state", false)),
|
_verbose_domain_state (node.attribute_value("verbose_domain_state", false)),
|
||||||
|
_icmp_echo_server (node.attribute_value("icmp_echo_server", true)),
|
||||||
_dhcp_discover_timeout(read_sec_attr(node, "dhcp_discover_timeout_sec", DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC)),
|
_dhcp_discover_timeout(read_sec_attr(node, "dhcp_discover_timeout_sec", DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC)),
|
||||||
_dhcp_request_timeout (read_sec_attr(node, "dhcp_request_timeout_sec", DEFAULT_DHCP_REQUEST_TIMEOUT_SEC )),
|
_dhcp_request_timeout (read_sec_attr(node, "dhcp_request_timeout_sec", DEFAULT_DHCP_REQUEST_TIMEOUT_SEC )),
|
||||||
_dhcp_offer_timeout (read_sec_attr(node, "dhcp_offer_timeout_sec", DEFAULT_DHCP_OFFER_TIMEOUT_SEC )),
|
_dhcp_offer_timeout (read_sec_attr(node, "dhcp_offer_timeout_sec", DEFAULT_DHCP_OFFER_TIMEOUT_SEC )),
|
||||||
|
@ -37,6 +37,7 @@ class Net::Configuration
|
|||||||
bool const _verbose { false };
|
bool const _verbose { false };
|
||||||
bool const _verbose_packets { false };
|
bool const _verbose_packets { false };
|
||||||
bool const _verbose_domain_state { false };
|
bool const _verbose_domain_state { false };
|
||||||
|
bool const _icmp_echo_server { true };
|
||||||
Genode::Microseconds const _dhcp_discover_timeout { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC };
|
Genode::Microseconds const _dhcp_discover_timeout { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC };
|
||||||
Genode::Microseconds const _dhcp_request_timeout { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC };
|
Genode::Microseconds const _dhcp_request_timeout { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC };
|
||||||
Genode::Microseconds const _dhcp_offer_timeout { DEFAULT_DHCP_OFFER_TIMEOUT_SEC };
|
Genode::Microseconds const _dhcp_offer_timeout { DEFAULT_DHCP_OFFER_TIMEOUT_SEC };
|
||||||
@ -87,6 +88,7 @@ class Net::Configuration
|
|||||||
bool verbose() const { return _verbose; }
|
bool verbose() const { return _verbose; }
|
||||||
bool verbose_packets() const { return _verbose_packets; }
|
bool verbose_packets() const { return _verbose_packets; }
|
||||||
bool verbose_domain_state() const { return _verbose_domain_state; }
|
bool verbose_domain_state() const { return _verbose_domain_state; }
|
||||||
|
bool icmp_echo_server() const { return _icmp_echo_server; }
|
||||||
Genode::Microseconds dhcp_discover_timeout() const { return _dhcp_discover_timeout; }
|
Genode::Microseconds dhcp_discover_timeout() const { return _dhcp_discover_timeout; }
|
||||||
Genode::Microseconds dhcp_request_timeout() const { return _dhcp_request_timeout; }
|
Genode::Microseconds dhcp_request_timeout() const { return _dhcp_request_timeout; }
|
||||||
Genode::Microseconds dhcp_offer_timeout() const { return _dhcp_offer_timeout; }
|
Genode::Microseconds dhcp_offer_timeout() const { return _dhcp_offer_timeout; }
|
||||||
|
@ -205,6 +205,8 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
|
|||||||
Ipv4_address()),
|
Ipv4_address()),
|
||||||
_verbose_packets(_node.attribute_value("verbose_packets", false) ||
|
_verbose_packets(_node.attribute_value("verbose_packets", false) ||
|
||||||
_config.verbose_packets()),
|
_config.verbose_packets()),
|
||||||
|
_icmp_echo_server(_node.attribute_value("icmp_echo_server",
|
||||||
|
_config.icmp_echo_server())),
|
||||||
_label(_node.attribute_value("label", String<160>()).string())
|
_label(_node.attribute_value("label", String<160>()).string())
|
||||||
{
|
{
|
||||||
_log_ip_config();
|
_log_ip_config();
|
||||||
|
@ -93,6 +93,7 @@ class Net::Domain : public Domain_base,
|
|||||||
Genode::size_t _tx_bytes { 0 };
|
Genode::size_t _tx_bytes { 0 };
|
||||||
Genode::size_t _rx_bytes { 0 };
|
Genode::size_t _rx_bytes { 0 };
|
||||||
bool const _verbose_packets { false };
|
bool const _verbose_packets { false };
|
||||||
|
bool const _icmp_echo_server;
|
||||||
Genode::Session_label const _label;
|
Genode::Session_label const _label;
|
||||||
|
|
||||||
void _read_forward_rules(Genode::Cstring const &protocol,
|
void _read_forward_rules(Genode::Cstring const &protocol,
|
||||||
@ -166,26 +167,27 @@ class Net::Domain : public Domain_base,
|
|||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
bool verbose_packets() const { return _verbose_packets; }
|
bool verbose_packets() const { return _verbose_packets; }
|
||||||
Genode::Session_label const &label() const { return _label; }
|
bool icmp_echo_server() const { return _icmp_echo_server; }
|
||||||
Ipv4_config const &ip_config() const { return *_ip_config; }
|
Genode::Session_label const &label() const { return _label; }
|
||||||
List<Domain> &ip_config_dependents() { return _ip_config_dependents; }
|
Ipv4_config const &ip_config() const { return *_ip_config; }
|
||||||
Domain_name const &name() const { return _name; }
|
List<Domain> &ip_config_dependents() { return _ip_config_dependents; }
|
||||||
Ip_rule_list &ip_rules() { return _ip_rules; }
|
Domain_name const &name() const { return _name; }
|
||||||
Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; }
|
Ip_rule_list &ip_rules() { return _ip_rules; }
|
||||||
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
|
Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; }
|
||||||
Transport_rule_list &tcp_rules() { return _tcp_rules; }
|
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
|
||||||
Transport_rule_list &udp_rules() { return _udp_rules; }
|
Transport_rule_list &tcp_rules() { return _tcp_rules; }
|
||||||
Ip_rule_list &icmp_rules() { return _icmp_rules; }
|
Transport_rule_list &udp_rules() { return _udp_rules; }
|
||||||
Nat_rule_tree &nat_rules() { return _nat_rules; }
|
Ip_rule_list &icmp_rules() { return _icmp_rules; }
|
||||||
Interface_list &interfaces() { return _interfaces; }
|
Nat_rule_tree &nat_rules() { return _nat_rules; }
|
||||||
Configuration &config() const { return _config; }
|
Interface_list &interfaces() { return _interfaces; }
|
||||||
|
Configuration &config() const { return _config; }
|
||||||
Dhcp_server &dhcp_server();
|
Dhcp_server &dhcp_server();
|
||||||
Arp_cache &arp_cache() { return _arp_cache; }
|
Arp_cache &arp_cache() { return _arp_cache; }
|
||||||
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
|
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
|
||||||
Link_side_tree &tcp_links() { return _tcp_links; }
|
Link_side_tree &tcp_links() { return _tcp_links; }
|
||||||
Link_side_tree &udp_links() { return _udp_links; }
|
Link_side_tree &udp_links() { return _udp_links; }
|
||||||
Link_side_tree &icmp_links() { return _icmp_links; }
|
Link_side_tree &icmp_links() { return _icmp_links; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _DOMAIN_H_ */
|
#endif /* _DOMAIN_H_ */
|
||||||
|
@ -787,6 +787,33 @@ void Interface::handle_link_state()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Interface::_send_icmp_echo_reply(Ethernet_frame ð,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Icmp_packet &icmp,
|
||||||
|
size_t icmp_sz,
|
||||||
|
Size_guard &size_guard)
|
||||||
|
{
|
||||||
|
/* adapt Ethernet header */
|
||||||
|
Mac_address const eth_src = eth.src();
|
||||||
|
eth.src(eth.dst());
|
||||||
|
eth.dst(eth_src);
|
||||||
|
|
||||||
|
/* adapt IPv4 header */
|
||||||
|
Ipv4_address const ip_src = ip.src();
|
||||||
|
ip.src(ip.dst());
|
||||||
|
ip.dst(ip_src);
|
||||||
|
|
||||||
|
/* adapt ICMP header */
|
||||||
|
icmp.type(Icmp_packet::Type::ECHO_REPLY);
|
||||||
|
icmp.code(Icmp_packet::Code::ECHO_REPLY);
|
||||||
|
|
||||||
|
/* update checksums and send */
|
||||||
|
icmp.update_checksum(icmp_sz - sizeof(Icmp_packet));
|
||||||
|
ip.update_checksum();
|
||||||
|
send(eth, size_guard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::_handle_icmp_query(Ethernet_frame ð,
|
void Interface::_handle_icmp_query(Ethernet_frame ð,
|
||||||
Size_guard &size_guard,
|
Size_guard &size_guard,
|
||||||
Ipv4_packet &ip,
|
Ipv4_packet &ip,
|
||||||
@ -908,26 +935,38 @@ void Interface::_handle_icmp_error(Ethernet_frame ð,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::_handle_icmp(Ethernet_frame ð,
|
void Interface::_handle_icmp(Ethernet_frame ð,
|
||||||
Size_guard &size_guard,
|
Size_guard &size_guard,
|
||||||
Ipv4_packet &ip,
|
Ipv4_packet &ip,
|
||||||
Packet_descriptor const &pkt,
|
Packet_descriptor const &pkt,
|
||||||
L3_protocol prot,
|
L3_protocol prot,
|
||||||
void *prot_base,
|
void *prot_base,
|
||||||
size_t prot_size,
|
size_t prot_size,
|
||||||
Domain &local_domain)
|
Domain &local_domain,
|
||||||
|
Ipv4_address_prefix const &local_intf)
|
||||||
{
|
{
|
||||||
/* drop packet if ICMP checksum is invalid */
|
/* drop packet if ICMP checksum is invalid */
|
||||||
Icmp_packet &icmp = *reinterpret_cast<Icmp_packet *>(prot_base);
|
Icmp_packet &icmp = *reinterpret_cast<Icmp_packet *>(prot_base);
|
||||||
if (icmp.checksum_error(size_guard.unconsumed())) {
|
if (icmp.checksum_error(size_guard.unconsumed())) {
|
||||||
throw Drop_packet("bad ICMP checksum");
|
throw Drop_packet("bad ICMP checksum"); }
|
||||||
|
|
||||||
|
/* try to act as ICMP Echo server */
|
||||||
|
if (icmp.type() == Icmp_packet::Type::ECHO_REQUEST &&
|
||||||
|
ip.dst() == local_intf.address &&
|
||||||
|
local_domain.icmp_echo_server())
|
||||||
|
{
|
||||||
|
if(_config().verbose()) {
|
||||||
|
log("[", local_domain, "] act as ICMP Echo server"); }
|
||||||
|
|
||||||
|
_send_icmp_echo_reply(eth, ip, icmp, prot_size, size_guard);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
/* select ICMP message type */
|
/* try to act as ICMP router */
|
||||||
switch (icmp.type()) {
|
switch (icmp.type()) {
|
||||||
case Icmp_packet::Type::ECHO_REPLY:
|
case Icmp_packet::Type::ECHO_REPLY:
|
||||||
case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain); break;
|
case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain); break;
|
||||||
case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, pkt, local_domain, icmp, prot_size); break;
|
case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, pkt, local_domain, icmp, prot_size); break;
|
||||||
default: Drop_packet("unknown ICMP message type"); }
|
default: Drop_packet("unhandled type in ICMP"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -979,7 +1018,8 @@ void Interface::_handle_ip(Ethernet_frame ð,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (prot == L3_protocol::ICMP) {
|
else if (prot == L3_protocol::ICMP) {
|
||||||
_handle_icmp(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain);
|
_handle_icmp(eth, size_guard, ip, pkt, prot, prot_base, prot_size,
|
||||||
|
local_domain, local_intf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +140,12 @@ class Net::Interface : private Interface_list::Element
|
|||||||
Genode::uint32_t xid,
|
Genode::uint32_t xid,
|
||||||
Ipv4_address_prefix const &local_intf);
|
Ipv4_address_prefix const &local_intf);
|
||||||
|
|
||||||
|
void _send_icmp_echo_reply(Ethernet_frame ð,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Icmp_packet &icmp,
|
||||||
|
Genode::size_t icmp_sz,
|
||||||
|
Size_guard &size_guard);
|
||||||
|
|
||||||
Forward_rule_tree &_forward_rules(Domain &local_domain,
|
Forward_rule_tree &_forward_rules(Domain &local_domain,
|
||||||
L3_protocol const prot) const;
|
L3_protocol const prot) const;
|
||||||
|
|
||||||
@ -190,14 +196,15 @@ class Net::Interface : private Interface_list::Element
|
|||||||
Icmp_packet &icmp,
|
Icmp_packet &icmp,
|
||||||
Genode::size_t icmp_sz);
|
Genode::size_t icmp_sz);
|
||||||
|
|
||||||
void _handle_icmp(Ethernet_frame ð,
|
void _handle_icmp(Ethernet_frame ð,
|
||||||
Size_guard &size_guard,
|
Size_guard &size_guard,
|
||||||
Ipv4_packet &ip,
|
Ipv4_packet &ip,
|
||||||
Packet_descriptor const &pkt,
|
Packet_descriptor const &pkt,
|
||||||
L3_protocol prot,
|
L3_protocol prot,
|
||||||
void *prot_base,
|
void *prot_base,
|
||||||
Genode::size_t prot_size,
|
Genode::size_t prot_size,
|
||||||
Domain &local_domain);
|
Domain &local_domain,
|
||||||
|
Ipv4_address_prefix const &local_intf);
|
||||||
|
|
||||||
void _adapt_eth(Ethernet_frame ð,
|
void _adapt_eth(Ethernet_frame ð,
|
||||||
Ipv4_address const &dst_ip,
|
Ipv4_address const &dst_ip,
|
||||||
|
Loading…
Reference in New Issue
Block a user