2016-09-12 12:55:12 +02:00
|
|
|
/*
|
|
|
|
* \brief Rule for doing NAT from one given interface to another
|
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2016-09-13
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2016-2017 Genode Labs GmbH
|
2016-09-12 12:55:12 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2016-09-12 12:55:12 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <util/xml_node.h>
|
|
|
|
#include <base/log.h>
|
|
|
|
#include <net/tcp.h>
|
|
|
|
#include <net/udp.h>
|
|
|
|
|
|
|
|
/* local includes */
|
2019-10-03 20:30:26 +02:00
|
|
|
#include "nat_rule.h"
|
|
|
|
#include "domain.h"
|
|
|
|
#include "interface.h"
|
2016-09-12 12:55:12 +02:00
|
|
|
|
|
|
|
using namespace Net;
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
2018-05-27 01:10:52 +02:00
|
|
|
Domain &Nat_rule::_find_domain(Domain_tree &domains,
|
|
|
|
Xml_node const node)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return domains.find_by_name(
|
|
|
|
node.attribute_value("domain", Domain_name()));
|
|
|
|
}
|
|
|
|
catch (Domain_tree::No_match) { throw Invalid(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
bool Nat_rule::higher(Nat_rule *rule)
|
|
|
|
{
|
|
|
|
return (addr_t)&rule->domain() > (addr_t)&_domain;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Nat_rule::Nat_rule(Domain_tree &domains,
|
|
|
|
Port_allocator &tcp_port_alloc,
|
|
|
|
Port_allocator &udp_port_alloc,
|
2018-03-28 02:49:44 +02:00
|
|
|
Port_allocator &icmp_port_alloc,
|
2016-12-06 14:39:17 +01:00
|
|
|
Xml_node const node)
|
2016-09-12 12:55:12 +02:00
|
|
|
:
|
2018-05-27 01:10:52 +02:00
|
|
|
_domain(_find_domain(domains, node)),
|
2018-03-28 02:49:44 +02:00
|
|
|
_tcp_port_alloc (tcp_port_alloc, node.attribute_value("tcp-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))
|
2016-09-12 12:55:12 +02:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
Nat_rule &Nat_rule::find_by_domain(Domain &domain)
|
|
|
|
{
|
|
|
|
if (&domain == &_domain) {
|
|
|
|
return *this; }
|
|
|
|
|
|
|
|
bool const side = (addr_t)&domain > (addr_t)&_domain;
|
|
|
|
Nat_rule *const rule = Avl_node<Nat_rule>::child(side);
|
|
|
|
if (!rule) {
|
|
|
|
throw Nat_rule_tree::No_match(); }
|
|
|
|
|
|
|
|
return rule->find_by_domain(domain);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Nat_rule &Nat_rule_tree::find_by_domain(Domain &domain)
|
|
|
|
{
|
|
|
|
Nat_rule *const rule = first();
|
|
|
|
if (!rule) {
|
|
|
|
throw No_match(); }
|
|
|
|
|
|
|
|
return rule->find_by_domain(domain);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Nat_rule::print(Output &output) const
|
|
|
|
{
|
|
|
|
Genode::print(output, "domain ", _domain,
|
2018-03-28 02:49:44 +02:00
|
|
|
" tcp-ports ", _tcp_port_alloc.max(),
|
|
|
|
" udp-ports ", _udp_port_alloc.max(),
|
2018-04-13 13:09:48 +02:00
|
|
|
" icmp-ids ", _icmp_port_alloc.max());
|
2016-09-12 12:55:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-09-14 15:10:32 +02:00
|
|
|
Port_allocator_guard &Nat_rule::port_alloc(L3_protocol const prot)
|
2016-09-12 12:55:12 +02:00
|
|
|
{
|
|
|
|
switch (prot) {
|
2018-03-28 02:49:44 +02:00
|
|
|
case L3_protocol::TCP: return _tcp_port_alloc;
|
|
|
|
case L3_protocol::UDP: return _udp_port_alloc;
|
|
|
|
case L3_protocol::ICMP: return _icmp_port_alloc;
|
2016-09-12 12:55:12 +02:00
|
|
|
default: throw Interface::Bad_transport_protocol(); }
|
|
|
|
}
|