mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-22 10:21:04 +00:00
nic_router: NAPT for ICMP echo messages
This follows the guidelines in RFC 5508 to enable ICMP echo through a NAPT channel of the NIC router. It serves also as blueprint for ICMP queries in general (they are merely not enabled because we don't test them by now). Issue #2732
This commit is contained in:
parent
d2adce7ba6
commit
7b3343c2dc
@ -59,6 +59,11 @@
|
|||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType><!-- Ipv4_address_prefix -->
|
</xs:simpleType><!-- Ipv4_address_prefix -->
|
||||||
|
|
||||||
|
<xs:complexType name="L2_rule">
|
||||||
|
<xs:attribute name="dst" type="Ipv4_address_prefix" />
|
||||||
|
<xs:attribute name="domain" type="Domain_name" />
|
||||||
|
</xs:complexType><!-- L2_rule -->
|
||||||
|
|
||||||
<xs:complexType name="L3_rule">
|
<xs:complexType name="L3_rule">
|
||||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
|
||||||
@ -110,15 +115,12 @@
|
|||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
|
||||||
<xs:element name="ip">
|
<xs:element name="ip" type="L2_rule" />
|
||||||
<xs:complexType>
|
<xs:element name="icmp" type="L2_rule" />
|
||||||
<xs:attribute name="dst" type="Ipv4_address_prefix" />
|
|
||||||
<xs:attribute name="domain" type="Domain_name" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element><!-- ip -->
|
|
||||||
|
|
||||||
<xs:element name="nat">
|
<xs:element name="nat">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
|
<xs:attribute name="icmp-ids" type="Nr_of_ports" />
|
||||||
<xs:attribute name="tcp-ports" type="Nr_of_ports" />
|
<xs:attribute name="tcp-ports" type="Nr_of_ports" />
|
||||||
<xs:attribute name="udp-ports" type="Nr_of_ports" />
|
<xs:attribute name="udp-ports" type="Nr_of_ports" />
|
||||||
<xs:attribute name="domain" type="Domain_name" />
|
<xs:attribute name="domain" type="Domain_name" />
|
||||||
|
@ -48,6 +48,7 @@ Configuration::Configuration(Env &env,
|
|||||||
_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 )),
|
||||||
|
_icmp_idle_timeout (read_sec_attr(node, "icmp_idle_timeout_sec", DEFAULT_ICMP_IDLE_TIMEOUT_SEC )),
|
||||||
_udp_idle_timeout (read_sec_attr(node, "udp_idle_timeout_sec", DEFAULT_UDP_IDLE_TIMEOUT_SEC )),
|
_udp_idle_timeout (read_sec_attr(node, "udp_idle_timeout_sec", DEFAULT_UDP_IDLE_TIMEOUT_SEC )),
|
||||||
_tcp_idle_timeout (read_sec_attr(node, "tcp_idle_timeout_sec", DEFAULT_TCP_IDLE_TIMEOUT_SEC )),
|
_tcp_idle_timeout (read_sec_attr(node, "tcp_idle_timeout_sec", DEFAULT_TCP_IDLE_TIMEOUT_SEC )),
|
||||||
_tcp_max_segm_lifetime(read_sec_attr(node, "tcp_max_segm_lifetime_sec", DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC)),
|
_tcp_max_segm_lifetime(read_sec_attr(node, "tcp_max_segm_lifetime_sec", DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC)),
|
||||||
|
@ -37,6 +37,7 @@ class Net::Configuration
|
|||||||
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 };
|
||||||
|
Genode::Microseconds const _icmp_idle_timeout { DEFAULT_ICMP_IDLE_TIMEOUT_SEC };
|
||||||
Genode::Microseconds const _udp_idle_timeout { DEFAULT_UDP_IDLE_TIMEOUT_SEC };
|
Genode::Microseconds const _udp_idle_timeout { DEFAULT_UDP_IDLE_TIMEOUT_SEC };
|
||||||
Genode::Microseconds const _tcp_idle_timeout { DEFAULT_TCP_IDLE_TIMEOUT_SEC };
|
Genode::Microseconds const _tcp_idle_timeout { DEFAULT_TCP_IDLE_TIMEOUT_SEC };
|
||||||
Genode::Microseconds const _tcp_max_segm_lifetime { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC };
|
Genode::Microseconds const _tcp_max_segm_lifetime { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC };
|
||||||
@ -51,6 +52,7 @@ class Net::Configuration
|
|||||||
enum { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC = 10 };
|
enum { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC = 10 };
|
||||||
enum { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC = 10 };
|
enum { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC = 10 };
|
||||||
enum { DEFAULT_DHCP_OFFER_TIMEOUT_SEC = 10 };
|
enum { DEFAULT_DHCP_OFFER_TIMEOUT_SEC = 10 };
|
||||||
|
enum { DEFAULT_ICMP_IDLE_TIMEOUT_SEC = 10 };
|
||||||
enum { DEFAULT_UDP_IDLE_TIMEOUT_SEC = 30 };
|
enum { DEFAULT_UDP_IDLE_TIMEOUT_SEC = 30 };
|
||||||
enum { DEFAULT_TCP_IDLE_TIMEOUT_SEC = 600 };
|
enum { DEFAULT_TCP_IDLE_TIMEOUT_SEC = 600 };
|
||||||
enum { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC = 30 };
|
enum { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC = 30 };
|
||||||
@ -77,6 +79,7 @@ class Net::Configuration
|
|||||||
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; }
|
||||||
|
Genode::Microseconds icmp_idle_timeout() const { return _icmp_idle_timeout; }
|
||||||
Genode::Microseconds udp_idle_timeout() const { return _udp_idle_timeout; }
|
Genode::Microseconds udp_idle_timeout() const { return _udp_idle_timeout; }
|
||||||
Genode::Microseconds tcp_idle_timeout() const { return _tcp_idle_timeout; }
|
Genode::Microseconds tcp_idle_timeout() const { return _tcp_idle_timeout; }
|
||||||
Genode::Microseconds tcp_max_segm_lifetime() const { return _tcp_max_segm_lifetime; }
|
Genode::Microseconds tcp_max_segm_lifetime() const { return _tcp_max_segm_lifetime; }
|
||||||
|
@ -136,6 +136,7 @@ Link_side_tree &Domain::links(L3_protocol const protocol)
|
|||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case L3_protocol::TCP: return _tcp_links;
|
case L3_protocol::TCP: return _tcp_links;
|
||||||
case L3_protocol::UDP: return _udp_links;
|
case L3_protocol::UDP: return _udp_links;
|
||||||
|
case L3_protocol::ICMP: return _icmp_links;
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +171,7 @@ Domain::~Domain()
|
|||||||
/* destroy rules */
|
/* destroy rules */
|
||||||
_ip_rules.destroy_each(_alloc);
|
_ip_rules.destroy_each(_alloc);
|
||||||
_nat_rules.destroy_each(_alloc);
|
_nat_rules.destroy_each(_alloc);
|
||||||
|
_icmp_rules.destroy_each(_alloc);
|
||||||
_udp_rules.destroy_each(_alloc);
|
_udp_rules.destroy_each(_alloc);
|
||||||
_tcp_rules.destroy_each(_alloc);
|
_tcp_rules.destroy_each(_alloc);
|
||||||
_udp_forward_rules.destroy_each(_alloc);
|
_udp_forward_rules.destroy_each(_alloc);
|
||||||
@ -243,10 +245,16 @@ void Domain::init(Domain_tree &domains)
|
|||||||
try {
|
try {
|
||||||
_nat_rules.insert(
|
_nat_rules.insert(
|
||||||
new (_alloc) Nat_rule(domains, _tcp_port_alloc,
|
new (_alloc) Nat_rule(domains, _tcp_port_alloc,
|
||||||
_udp_port_alloc, node));
|
_udp_port_alloc, _icmp_port_alloc,
|
||||||
|
node));
|
||||||
}
|
}
|
||||||
catch (Rule::Invalid) { warning("invalid NAT rule"); }
|
catch (Rule::Invalid) { warning("invalid NAT rule"); }
|
||||||
});
|
});
|
||||||
|
/* read ICMP rules */
|
||||||
|
_node.for_each_sub_node("icmp", [&] (Xml_node const node) {
|
||||||
|
try { _icmp_rules.insert(*new (_alloc) Ip_rule(domains, node)); }
|
||||||
|
catch (Rule::Invalid) { warning("invalid ICMP rule"); }
|
||||||
|
});
|
||||||
/* read IP rules */
|
/* read IP rules */
|
||||||
_node.for_each_sub_node("ip", [&] (Xml_node const node) {
|
_node.for_each_sub_node("ip", [&] (Xml_node const node) {
|
||||||
try { _ip_rules.insert(*new (_alloc) Ip_rule(domains, node)); }
|
try { _ip_rules.insert(*new (_alloc) Ip_rule(domains, node)); }
|
||||||
|
@ -92,8 +92,10 @@ class Net::Domain : public Domain_base,
|
|||||||
Forward_rule_tree _udp_forward_rules { };
|
Forward_rule_tree _udp_forward_rules { };
|
||||||
Transport_rule_list _tcp_rules { };
|
Transport_rule_list _tcp_rules { };
|
||||||
Transport_rule_list _udp_rules { };
|
Transport_rule_list _udp_rules { };
|
||||||
|
Ip_rule_list _icmp_rules { };
|
||||||
Port_allocator _tcp_port_alloc { };
|
Port_allocator _tcp_port_alloc { };
|
||||||
Port_allocator _udp_port_alloc { };
|
Port_allocator _udp_port_alloc { };
|
||||||
|
Port_allocator _icmp_port_alloc { };
|
||||||
Nat_rule_tree _nat_rules { };
|
Nat_rule_tree _nat_rules { };
|
||||||
Interface_list _interfaces { };
|
Interface_list _interfaces { };
|
||||||
unsigned long _interface_cnt { 0 };
|
unsigned long _interface_cnt { 0 };
|
||||||
@ -104,6 +106,7 @@ class Net::Domain : public Domain_base,
|
|||||||
Arp_waiter_list _foreign_arp_waiters { };
|
Arp_waiter_list _foreign_arp_waiters { };
|
||||||
Link_side_tree _tcp_links { };
|
Link_side_tree _tcp_links { };
|
||||||
Link_side_tree _udp_links { };
|
Link_side_tree _udp_links { };
|
||||||
|
Link_side_tree _icmp_links { };
|
||||||
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 };
|
||||||
@ -179,6 +182,7 @@ class Net::Domain : public Domain_base,
|
|||||||
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
|
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
|
||||||
Transport_rule_list &tcp_rules() { return _tcp_rules; }
|
Transport_rule_list &tcp_rules() { return _tcp_rules; }
|
||||||
Transport_rule_list &udp_rules() { return _udp_rules; }
|
Transport_rule_list &udp_rules() { return _udp_rules; }
|
||||||
|
Ip_rule_list &icmp_rules() { return _icmp_rules; }
|
||||||
Nat_rule_tree &nat_rules() { return _nat_rules; }
|
Nat_rule_tree &nat_rules() { return _nat_rules; }
|
||||||
Interface_list &interfaces() { return _interfaces; }
|
Interface_list &interfaces() { return _interfaces; }
|
||||||
Configuration &config() const { return _config; }
|
Configuration &config() const { return _config; }
|
||||||
@ -188,6 +192,7 @@ class Net::Domain : public Domain_base,
|
|||||||
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <net/udp.h>
|
#include <net/udp.h>
|
||||||
|
#include <net/icmp.h>
|
||||||
#include <net/arp.h>
|
#include <net/arp.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
@ -87,6 +88,9 @@ static void _link_packet(L3_protocol const prot,
|
|||||||
case L3_protocol::UDP:
|
case L3_protocol::UDP:
|
||||||
static_cast<Udp_link *>(&link)->packet();
|
static_cast<Udp_link *>(&link)->packet();
|
||||||
return;
|
return;
|
||||||
|
case L3_protocol::ICMP:
|
||||||
|
static_cast<Icmp_link *>(&link)->packet();
|
||||||
|
return;
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +99,8 @@ static void _update_checksum(L3_protocol const prot,
|
|||||||
void *const prot_base,
|
void *const prot_base,
|
||||||
size_t const prot_size,
|
size_t const prot_size,
|
||||||
Ipv4_address const src,
|
Ipv4_address const src,
|
||||||
Ipv4_address const dst)
|
Ipv4_address const dst,
|
||||||
|
size_t const ip_size)
|
||||||
{
|
{
|
||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP:
|
case L3_protocol::TCP:
|
||||||
@ -104,6 +109,13 @@ static void _update_checksum(L3_protocol const prot,
|
|||||||
case L3_protocol::UDP:
|
case L3_protocol::UDP:
|
||||||
((Udp_packet *)prot_base)->update_checksum(src, dst);
|
((Udp_packet *)prot_base)->update_checksum(src, dst);
|
||||||
return;
|
return;
|
||||||
|
case L3_protocol::ICMP:
|
||||||
|
{
|
||||||
|
Icmp_packet &icmp = *(Icmp_packet *)prot_base;
|
||||||
|
icmp.checksum(icmp.calc_checksum(ip_size - sizeof(Ipv4_packet) -
|
||||||
|
sizeof(Icmp_packet)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +125,7 @@ static Port _dst_port(L3_protocol const prot, void *const prot_base)
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: return (*(Tcp_packet *)prot_base).dst_port();
|
case L3_protocol::TCP: return (*(Tcp_packet *)prot_base).dst_port();
|
||||||
case L3_protocol::UDP: return (*(Udp_packet *)prot_base).dst_port();
|
case L3_protocol::UDP: return (*(Udp_packet *)prot_base).dst_port();
|
||||||
|
case L3_protocol::ICMP: return Port((*(Icmp_packet *)prot_base).query_id());
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +137,7 @@ static void _dst_port(L3_protocol const prot,
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: (*(Tcp_packet *)prot_base).dst_port(port); return;
|
case L3_protocol::TCP: (*(Tcp_packet *)prot_base).dst_port(port); return;
|
||||||
case L3_protocol::UDP: (*(Udp_packet *)prot_base).dst_port(port); return;
|
case L3_protocol::UDP: (*(Udp_packet *)prot_base).dst_port(port); return;
|
||||||
|
case L3_protocol::ICMP: (*(Icmp_packet *)prot_base).query_id(port.value); return;
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +147,7 @@ static Port _src_port(L3_protocol const prot, void *const prot_base)
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: return (*(Tcp_packet *)prot_base).src_port();
|
case L3_protocol::TCP: return (*(Tcp_packet *)prot_base).src_port();
|
||||||
case L3_protocol::UDP: return (*(Udp_packet *)prot_base).src_port();
|
case L3_protocol::UDP: return (*(Udp_packet *)prot_base).src_port();
|
||||||
|
case L3_protocol::ICMP: return Port((*(Icmp_packet *)prot_base).query_id());
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +159,7 @@ static void _src_port(L3_protocol const prot,
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: ((Tcp_packet *)prot_base)->src_port(port); return;
|
case L3_protocol::TCP: ((Tcp_packet *)prot_base)->src_port(port); return;
|
||||||
case L3_protocol::UDP: ((Udp_packet *)prot_base)->src_port(port); return;
|
case L3_protocol::UDP: ((Udp_packet *)prot_base)->src_port(port); return;
|
||||||
|
case L3_protocol::ICMP: ((Icmp_packet *)prot_base)->query_id(port.value); return;
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +171,7 @@ static void *_prot_base(L3_protocol const prot,
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: return ip.data<Tcp_packet>(prot_size);
|
case L3_protocol::TCP: return ip.data<Tcp_packet>(prot_size);
|
||||||
case L3_protocol::UDP: return ip.data<Udp_packet>(prot_size);
|
case L3_protocol::UDP: return ip.data<Udp_packet>(prot_size);
|
||||||
|
case L3_protocol::ICMP: return ip.data<Icmp_packet>(prot_size);
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +186,7 @@ void Interface::_destroy_link(Link &link)
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: ::_destroy_link<Tcp_link>(link, links(prot), _alloc); break;
|
case L3_protocol::TCP: ::_destroy_link<Tcp_link>(link, links(prot), _alloc); break;
|
||||||
case L3_protocol::UDP: ::_destroy_link<Udp_link>(link, links(prot), _alloc); break;
|
case L3_protocol::UDP: ::_destroy_link<Udp_link>(link, links(prot), _alloc); break;
|
||||||
|
case L3_protocol::ICMP: ::_destroy_link<Icmp_link>(link, links(prot), _alloc); break;
|
||||||
default: throw Bad_transport_protocol(); }
|
default: throw Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +198,7 @@ void Interface::_pass_prot(Ethernet_frame ð,
|
|||||||
void *const prot_base,
|
void *const prot_base,
|
||||||
size_t const prot_size)
|
size_t const prot_size)
|
||||||
{
|
{
|
||||||
_update_checksum(prot, prot_base, prot_size, ip.src(), ip.dst());
|
_update_checksum(prot, prot_base, prot_size, ip.src(), ip.dst(), ip.total_length());
|
||||||
_pass_ip(eth, eth_size, ip);
|
_pass_ip(eth, eth_size, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +315,7 @@ void Interface::detach_from_ip_config()
|
|||||||
/* destroy links */
|
/* destroy links */
|
||||||
_destroy_links<Tcp_link> (_tcp_links, _dissolved_tcp_links, _alloc);
|
_destroy_links<Tcp_link> (_tcp_links, _dissolved_tcp_links, _alloc);
|
||||||
_destroy_links<Udp_link> (_udp_links, _dissolved_udp_links, _alloc);
|
_destroy_links<Udp_link> (_udp_links, _dissolved_udp_links, _alloc);
|
||||||
|
_destroy_links<Icmp_link>(_icmp_links, _dissolved_icmp_links, _alloc);
|
||||||
|
|
||||||
/* destroy DHCP allocations */
|
/* destroy DHCP allocations */
|
||||||
_destroy_released_dhcp_allocations(domain);
|
_destroy_released_dhcp_allocations(domain);
|
||||||
@ -343,6 +362,10 @@ Interface::_new_link(L3_protocol const protocol,
|
|||||||
new (_alloc) Udp_link(*this, local, remote_port_alloc, remote_domain,
|
new (_alloc) Udp_link(*this, local, remote_port_alloc, remote_domain,
|
||||||
remote, _timer, _config(), protocol);
|
remote, _timer, _config(), protocol);
|
||||||
break;
|
break;
|
||||||
|
case L3_protocol::ICMP:
|
||||||
|
new (_alloc) Icmp_link(*this, local, remote_port_alloc, remote_domain,
|
||||||
|
remote, _timer, _config(), protocol);
|
||||||
|
break;
|
||||||
default: throw Bad_transport_protocol(); }
|
default: throw Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,6 +382,7 @@ Link_list &Interface::links(L3_protocol const protocol)
|
|||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case L3_protocol::TCP: return _tcp_links;
|
case L3_protocol::TCP: return _tcp_links;
|
||||||
case L3_protocol::UDP: return _udp_links;
|
case L3_protocol::UDP: return _udp_links;
|
||||||
|
case L3_protocol::ICMP: return _icmp_links;
|
||||||
default: throw Bad_transport_protocol(); }
|
default: throw Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,6 +392,7 @@ Link_list &Interface::dissolved_links(L3_protocol const protocol)
|
|||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case L3_protocol::TCP: return _dissolved_tcp_links;
|
case L3_protocol::TCP: return _dissolved_tcp_links;
|
||||||
case L3_protocol::UDP: return _dissolved_udp_links;
|
case L3_protocol::UDP: return _dissolved_udp_links;
|
||||||
|
case L3_protocol::ICMP: return _dissolved_icmp_links;
|
||||||
default: throw Bad_transport_protocol(); }
|
default: throw Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,13 +751,94 @@ void Interface::_send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf
|
|||||||
Genode::memcpy(&icmp.data<char>(~0), &req_ip, icmp_data_size);
|
Genode::memcpy(&icmp.data<char>(~0), &req_ip, icmp_data_size);
|
||||||
|
|
||||||
/* fill in header values that require the packet to be complete */
|
/* fill in header values that require the packet to be complete */
|
||||||
icmp.update_checksum(icmp_data_size);
|
icmp.checksum(icmp.calc_checksum(icmp_data_size));
|
||||||
ip.total_length(size.curr() - ip_off);
|
ip.total_length(size.curr() - ip_off);
|
||||||
ip.checksum(Ipv4_packet::calculate_checksum(ip));
|
ip.checksum(Ipv4_packet::calculate_checksum(ip));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Interface::_handle_icmp_query(Ethernet_frame ð,
|
||||||
|
size_t eth_size,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Packet_descriptor const &pkt,
|
||||||
|
L3_protocol prot,
|
||||||
|
void *prot_base,
|
||||||
|
size_t prot_size,
|
||||||
|
Domain &local_domain)
|
||||||
|
{
|
||||||
|
Link_side_id const local_id = { ip.src(), _src_port(prot, prot_base),
|
||||||
|
ip.dst(), _dst_port(prot, prot_base) };
|
||||||
|
|
||||||
|
/* try to route via existing ICMP links */
|
||||||
|
try {
|
||||||
|
Link_side const &local_side = local_domain.links(prot).find_by_id(local_id);
|
||||||
|
Link &link = local_side.link();
|
||||||
|
bool const client = local_side.is_client();
|
||||||
|
Link_side &remote_side = client ? link.server() : link.client();
|
||||||
|
Domain &remote_domain = remote_side.domain();
|
||||||
|
if (_config().verbose()) {
|
||||||
|
log("Using ", l3_protocol_name(prot), " link: ", link); }
|
||||||
|
|
||||||
|
_adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain);
|
||||||
|
ip.src(remote_side.dst_ip());
|
||||||
|
ip.dst(remote_side.src_ip());
|
||||||
|
_src_port(prot, prot_base, remote_side.dst_port());
|
||||||
|
_dst_port(prot, prot_base, remote_side.src_port());
|
||||||
|
|
||||||
|
remote_domain.interfaces().for_each([&] (Interface &interface) {
|
||||||
|
interface._pass_prot(eth, eth_size, ip, prot, prot_base, prot_size);
|
||||||
|
});
|
||||||
|
_link_packet(prot, prot_base, link, client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Link_side_tree::No_match) { }
|
||||||
|
|
||||||
|
/* try to route via ICMP rules */
|
||||||
|
try {
|
||||||
|
Ip_rule const &rule =
|
||||||
|
local_domain.icmp_rules().longest_prefix_match(ip.dst());
|
||||||
|
|
||||||
|
if(_config().verbose()) {
|
||||||
|
log("Using ICMP rule: ", rule); }
|
||||||
|
|
||||||
|
Domain &remote_domain = rule.domain();
|
||||||
|
_adapt_eth(eth, local_id.dst_ip, pkt, remote_domain);
|
||||||
|
_nat_link_and_pass(eth, eth_size, ip, prot, prot_base, prot_size,
|
||||||
|
local_id, local_domain, remote_domain);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Ip_rule_list::No_match) { }
|
||||||
|
|
||||||
|
throw Bad_transport_protocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Interface::_handle_icmp(Ethernet_frame ð,
|
||||||
|
size_t eth_size,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Packet_descriptor const &pkt,
|
||||||
|
L3_protocol prot,
|
||||||
|
void *prot_base,
|
||||||
|
size_t prot_size,
|
||||||
|
Domain &local_domain)
|
||||||
|
{
|
||||||
|
/* drop packet if ICMP checksum is invalid */
|
||||||
|
size_t const icmp_sz = ip.total_length() - sizeof(Ipv4_packet);
|
||||||
|
Icmp_packet &icmp = *ip.data<Icmp_packet>(icmp_sz);
|
||||||
|
size_t const icmp_data_sz = icmp_sz - sizeof(Icmp_packet);
|
||||||
|
if (icmp.calc_checksum(icmp_data_sz) != icmp.checksum()) {
|
||||||
|
throw Drop_packet_inform("bad ICMP checksum");
|
||||||
|
}
|
||||||
|
/* select ICMP message type */
|
||||||
|
switch (icmp.type()) {
|
||||||
|
case Icmp_packet::Type::ECHO_REPLY:
|
||||||
|
case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, eth_size, ip, pkt, prot, prot_base, prot_size, local_domain); break;
|
||||||
|
default: Drop_packet_inform("unknown ICMP message type"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::_handle_ip(Ethernet_frame ð,
|
void Interface::_handle_ip(Ethernet_frame ð,
|
||||||
Genode::size_t const eth_size,
|
Genode::size_t const eth_size,
|
||||||
Packet_descriptor const &pkt,
|
Packet_descriptor const &pkt,
|
||||||
@ -782,6 +888,11 @@ void Interface::_handle_ip(Ethernet_frame ð,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (prot == L3_protocol::ICMP) {
|
||||||
|
_handle_icmp(eth, eth_size, ip, pkt, prot, prot_base, prot_size, local_domain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Link_side_id const local_id = { ip.src(), _src_port(prot, prot_base),
|
Link_side_id const local_id = { ip.src(), _src_port(prot, prot_base),
|
||||||
ip.dst(), _dst_port(prot, prot_base) };
|
ip.dst(), _dst_port(prot, prot_base) };
|
||||||
|
|
||||||
@ -1086,6 +1197,7 @@ void Interface::_handle_eth(void *const eth_base,
|
|||||||
local_domain.raise_rx_bytes(eth_size);
|
local_domain.raise_rx_bytes(eth_size);
|
||||||
|
|
||||||
/* do garbage collection over transport-layer links and DHCP allocations */
|
/* do garbage collection over transport-layer links and DHCP allocations */
|
||||||
|
_destroy_dissolved_links<Icmp_link>(_dissolved_icmp_links, _alloc);
|
||||||
_destroy_dissolved_links<Udp_link>(_dissolved_udp_links, _alloc);
|
_destroy_dissolved_links<Udp_link>(_dissolved_udp_links, _alloc);
|
||||||
_destroy_dissolved_links<Tcp_link>(_dissolved_tcp_links, _alloc);
|
_destroy_dissolved_links<Tcp_link>(_dissolved_tcp_links, _alloc);
|
||||||
_destroy_released_dhcp_allocations(local_domain);
|
_destroy_released_dhcp_allocations(local_domain);
|
||||||
@ -1375,6 +1487,7 @@ void Interface::handle_config(Configuration &config)
|
|||||||
try {
|
try {
|
||||||
/* destroy state objects that are not needed anymore */
|
/* destroy state objects that are not needed anymore */
|
||||||
Domain &old_domain = domain();
|
Domain &old_domain = domain();
|
||||||
|
_destroy_dissolved_links<Icmp_link>(_dissolved_icmp_links, _alloc);
|
||||||
_destroy_dissolved_links<Udp_link> (_dissolved_udp_links, _alloc);
|
_destroy_dissolved_links<Udp_link> (_dissolved_udp_links, _alloc);
|
||||||
_destroy_dissolved_links<Tcp_link> (_dissolved_tcp_links, _alloc);
|
_destroy_dissolved_links<Tcp_link> (_dissolved_tcp_links, _alloc);
|
||||||
_destroy_released_dhcp_allocations(old_domain);
|
_destroy_released_dhcp_allocations(old_domain);
|
||||||
@ -1402,6 +1515,7 @@ void Interface::handle_config(Configuration &config)
|
|||||||
/* update state objects */
|
/* update state objects */
|
||||||
_update_links(L3_protocol::TCP, new_domain);
|
_update_links(L3_protocol::TCP, new_domain);
|
||||||
_update_links(L3_protocol::UDP, new_domain);
|
_update_links(L3_protocol::UDP, new_domain);
|
||||||
|
_update_links(L3_protocol::ICMP, new_domain);
|
||||||
_update_dhcp_allocations(old_domain, new_domain);
|
_update_dhcp_allocations(old_domain, new_domain);
|
||||||
_update_own_arp_waiters(new_domain);
|
_update_own_arp_waiters(new_domain);
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,10 @@ class Net::Interface : private Interface_list::Element
|
|||||||
Arp_waiter_list _own_arp_waiters { };
|
Arp_waiter_list _own_arp_waiters { };
|
||||||
Link_list _tcp_links { };
|
Link_list _tcp_links { };
|
||||||
Link_list _udp_links { };
|
Link_list _udp_links { };
|
||||||
|
Link_list _icmp_links { };
|
||||||
Link_list _dissolved_tcp_links { };
|
Link_list _dissolved_tcp_links { };
|
||||||
Link_list _dissolved_udp_links { };
|
Link_list _dissolved_udp_links { };
|
||||||
|
Link_list _dissolved_icmp_links { };
|
||||||
Dhcp_allocation_tree _dhcp_allocations { };
|
Dhcp_allocation_tree _dhcp_allocations { };
|
||||||
Dhcp_allocation_list _released_dhcp_allocations { };
|
Dhcp_allocation_list _released_dhcp_allocations { };
|
||||||
Dhcp_client _dhcp_client { _alloc, _timer, *this };
|
Dhcp_client _dhcp_client { _alloc, _timer, *this };
|
||||||
@ -158,6 +160,24 @@ class Net::Interface : private Interface_list::Element
|
|||||||
Packet_descriptor const &pkt,
|
Packet_descriptor const &pkt,
|
||||||
Domain &local_domain);
|
Domain &local_domain);
|
||||||
|
|
||||||
|
void _handle_icmp_query(Ethernet_frame ð,
|
||||||
|
Genode::size_t eth_size,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Packet_descriptor const &pkt,
|
||||||
|
L3_protocol prot,
|
||||||
|
void *prot_base,
|
||||||
|
Genode::size_t prot_size,
|
||||||
|
Domain &local_domain);
|
||||||
|
|
||||||
|
void _handle_icmp(Ethernet_frame ð,
|
||||||
|
Genode::size_t eth_size,
|
||||||
|
Ipv4_packet &ip,
|
||||||
|
Packet_descriptor const &pkt,
|
||||||
|
L3_protocol prot,
|
||||||
|
void *prot_base,
|
||||||
|
Genode::size_t prot_size,
|
||||||
|
Domain &local_domain);
|
||||||
|
|
||||||
void _adapt_eth(Ethernet_frame ð,
|
void _adapt_eth(Ethernet_frame ð,
|
||||||
Ipv4_address const &dst_ip,
|
Ipv4_address const &dst_ip,
|
||||||
Packet_descriptor const &pkt,
|
Packet_descriptor const &pkt,
|
||||||
|
@ -19,15 +19,18 @@
|
|||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <net/udp.h>
|
#include <net/udp.h>
|
||||||
|
#include <net/icmp.h>
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
static Cstring const _udp_name("UDP");
|
static Cstring const _udp_name("UDP");
|
||||||
static Cstring const _tcp_name("TCP");
|
static Cstring const _tcp_name("TCP");
|
||||||
|
static Cstring const _icmp_name("ICMP");
|
||||||
|
|
||||||
Cstring const &Net::udp_name() { return _udp_name; }
|
Cstring const &Net::udp_name() { return _udp_name; }
|
||||||
Cstring const &Net::tcp_name() { return _tcp_name; }
|
Cstring const &Net::tcp_name() { return _tcp_name; }
|
||||||
|
Cstring const &Net::icmp_name() { return _icmp_name; }
|
||||||
|
|
||||||
|
|
||||||
Cstring const &Net::l3_protocol_name(L3_protocol protocol)
|
Cstring const &Net::l3_protocol_name(L3_protocol protocol)
|
||||||
@ -35,5 +38,6 @@ Cstring const &Net::l3_protocol_name(L3_protocol protocol)
|
|||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case L3_protocol::TCP: return tcp_name();
|
case L3_protocol::TCP: return tcp_name();
|
||||||
case L3_protocol::UDP: return udp_name();
|
case L3_protocol::UDP: return udp_name();
|
||||||
|
case L3_protocol::ICMP: return icmp_name();
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace Net {
|
|||||||
|
|
||||||
Genode::Cstring const &tcp_name();
|
Genode::Cstring const &tcp_name();
|
||||||
Genode::Cstring const &udp_name();
|
Genode::Cstring const &udp_name();
|
||||||
|
Genode::Cstring const &icmp_name();
|
||||||
Genode::Cstring const &l3_protocol_name(L3_protocol protocol);
|
Genode::Cstring const &l3_protocol_name(L3_protocol protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +176,7 @@ void Link::handle_config(Domain &cln_domain,
|
|||||||
switch (_protocol) {
|
switch (_protocol) {
|
||||||
case L3_protocol::TCP: dissolve_timeout_us = config.tcp_idle_timeout(); break;
|
case L3_protocol::TCP: dissolve_timeout_us = config.tcp_idle_timeout(); break;
|
||||||
case L3_protocol::UDP: dissolve_timeout_us = config.udp_idle_timeout(); break;
|
case L3_protocol::UDP: dissolve_timeout_us = config.udp_idle_timeout(); break;
|
||||||
|
case L3_protocol::ICMP: dissolve_timeout_us = config.icmp_idle_timeout(); break;
|
||||||
default: throw Interface::Bad_transport_protocol();
|
default: throw Interface::Bad_transport_protocol();
|
||||||
}
|
}
|
||||||
_dissolve_timeout_us = dissolve_timeout_us;
|
_dissolve_timeout_us = dissolve_timeout_us;
|
||||||
@ -276,3 +277,21 @@ Udp_link::Udp_link(Interface &cln_interface,
|
|||||||
Link(cln_interface, cln_id, srv_port_alloc, srv_domain, srv_id, timer,
|
Link(cln_interface, cln_id, srv_port_alloc, srv_domain, srv_id, timer,
|
||||||
config, protocol, config.udp_idle_timeout())
|
config, protocol, config.udp_idle_timeout())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/***************
|
||||||
|
** Icmp_link **
|
||||||
|
***************/
|
||||||
|
|
||||||
|
Icmp_link::Icmp_link(Interface &cln_interface,
|
||||||
|
Link_side_id const &cln_id,
|
||||||
|
Pointer<Port_allocator_guard> srv_port_alloc,
|
||||||
|
Domain &srv_domain,
|
||||||
|
Link_side_id const &srv_id,
|
||||||
|
Timer::Connection &timer,
|
||||||
|
Configuration &config,
|
||||||
|
L3_protocol const protocol)
|
||||||
|
:
|
||||||
|
Link(cln_interface, cln_id, srv_port_alloc, srv_domain, srv_id, timer,
|
||||||
|
config, protocol, config.icmp_idle_timeout())
|
||||||
|
{ }
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* \brief State tracking for UDP/TCP connections
|
* \brief State tracking for ICMP/UDP//TCP connections
|
||||||
* \author Martin Stein
|
* \author Martin Stein
|
||||||
* \date 2016-08-19
|
* \date 2016-08-19
|
||||||
*
|
*
|
||||||
* A link is in the UDP case the state tracking of a pseudo UDP connection
|
* A link is in the UDP/ICMP case the state tracking of a pseudo UDP/ICMP
|
||||||
* (UDP hole punching) and in the TCP case the state tracking of a TCP
|
* connection (UDP/ICMP hole punching) and in the TCP case the state tracking
|
||||||
* connection. Beside the layer-3 connection state, a link also contains
|
* of a TCP connection. Beside the layer-3 connection state, a link also
|
||||||
* information about the routing and the NAT translation that correspond to
|
* contains information about the routing and the NAT translation that
|
||||||
* the connection. Link objects have three different functions:
|
* correspond to the connection. Link objects have three different functions:
|
||||||
*
|
*
|
||||||
* 1) Link objects allow the router to manage the lifetime of resources
|
* 1) Link objects allow the router to manage the lifetime of resources
|
||||||
* related to a layer-3 connection.
|
* related to a layer-3 connection.
|
||||||
@ -57,6 +57,7 @@ namespace Net {
|
|||||||
struct Link_list : List<Link> { };
|
struct Link_list : List<Link> { };
|
||||||
class Tcp_link;
|
class Tcp_link;
|
||||||
class Udp_link;
|
class Udp_link;
|
||||||
|
class Icmp_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -238,4 +239,19 @@ struct Net::Udp_link : Link
|
|||||||
void packet() { _packet(); }
|
void packet() { _packet(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Net::Icmp_link : Link
|
||||||
|
{
|
||||||
|
Icmp_link(Interface &cln_interface,
|
||||||
|
Link_side_id const &cln_id,
|
||||||
|
Pointer<Port_allocator_guard> srv_port_alloc,
|
||||||
|
Domain &srv_domain,
|
||||||
|
Link_side_id const &srv_id,
|
||||||
|
Timer::Connection &timer,
|
||||||
|
Configuration &config,
|
||||||
|
L3_protocol const protocol);
|
||||||
|
|
||||||
|
void packet() { _packet(); }
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _LINK_H_ */
|
#endif /* _LINK_H_ */
|
||||||
|
@ -35,11 +35,13 @@ bool Nat_rule::higher(Nat_rule *rule)
|
|||||||
Nat_rule::Nat_rule(Domain_tree &domains,
|
Nat_rule::Nat_rule(Domain_tree &domains,
|
||||||
Port_allocator &tcp_port_alloc,
|
Port_allocator &tcp_port_alloc,
|
||||||
Port_allocator &udp_port_alloc,
|
Port_allocator &udp_port_alloc,
|
||||||
|
Port_allocator &icmp_port_alloc,
|
||||||
Xml_node const node)
|
Xml_node const node)
|
||||||
:
|
:
|
||||||
Leaf_rule(domains, node),
|
Leaf_rule(domains, node),
|
||||||
_tcp_port_alloc (tcp_port_alloc, node.attribute_value("tcp-ports", 0UL)),
|
_tcp_port_alloc (tcp_port_alloc, node.attribute_value("tcp-ports", 0UL)),
|
||||||
_udp_port_alloc(udp_port_alloc, node.attribute_value("udp-ports", 0UL))
|
_udp_port_alloc (udp_port_alloc, node.attribute_value("udp-ports", 0UL)),
|
||||||
|
_icmp_port_alloc(icmp_port_alloc, node.attribute_value("icmp-ids", 0UL))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +73,8 @@ void Nat_rule::print(Output &output) const
|
|||||||
{
|
{
|
||||||
Genode::print(output, "domain ", _domain,
|
Genode::print(output, "domain ", _domain,
|
||||||
" tcp-ports ", _tcp_port_alloc.max(),
|
" tcp-ports ", _tcp_port_alloc.max(),
|
||||||
" udp-ports ", _udp_port_alloc.max());
|
" udp-ports ", _udp_port_alloc.max(),
|
||||||
|
" icmp-ports ", _icmp_port_alloc.max());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,5 +83,6 @@ Port_allocator_guard &Nat_rule::port_alloc(L3_protocol const prot)
|
|||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP: return _tcp_port_alloc;
|
case L3_protocol::TCP: return _tcp_port_alloc;
|
||||||
case L3_protocol::UDP: return _udp_port_alloc;
|
case L3_protocol::UDP: return _udp_port_alloc;
|
||||||
|
case L3_protocol::ICMP: return _icmp_port_alloc;
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
default: throw Interface::Bad_transport_protocol(); }
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,14 @@ class Net::Nat_rule : public Leaf_rule,
|
|||||||
|
|
||||||
Port_allocator_guard _tcp_port_alloc;
|
Port_allocator_guard _tcp_port_alloc;
|
||||||
Port_allocator_guard _udp_port_alloc;
|
Port_allocator_guard _udp_port_alloc;
|
||||||
|
Port_allocator_guard _icmp_port_alloc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Nat_rule(Domain_tree &domains,
|
Nat_rule(Domain_tree &domains,
|
||||||
Port_allocator &tcp_port_alloc,
|
Port_allocator &tcp_port_alloc,
|
||||||
Port_allocator &udp_port_alloc,
|
Port_allocator &udp_port_alloc,
|
||||||
|
Port_allocator &icmp_port_alloc,
|
||||||
Genode::Xml_node const node);
|
Genode::Xml_node const node);
|
||||||
|
|
||||||
Nat_rule &find_by_domain(Domain &domain);
|
Nat_rule &find_by_domain(Domain &domain);
|
||||||
@ -72,6 +74,7 @@ class Net::Nat_rule : public Leaf_rule,
|
|||||||
|
|
||||||
Port_allocator_guard &tcp_port_alloc() { return _tcp_port_alloc; }
|
Port_allocator_guard &tcp_port_alloc() { return _tcp_port_alloc; }
|
||||||
Port_allocator_guard &udp_port_alloc() { return _udp_port_alloc; }
|
Port_allocator_guard &udp_port_alloc() { return _udp_port_alloc; }
|
||||||
|
Port_allocator_guard &icmp_port_alloc() { return _icmp_port_alloc; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user