nic_router: handle ARP requests for foreign IPs

If the router has no gateway attribute for a domain (means that the router
itself is the gateway), and it gets an ARP request for a foreign IP, it shall
answer with its own IP.

Ref #2490
This commit is contained in:
Martin Stein 2017-09-25 17:40:35 +02:00 committed by Christian Helmuth
parent ee88d4d2d5
commit 215937ff0f
2 changed files with 26 additions and 15 deletions

View File

@ -128,17 +128,18 @@ class Net::Domain : public Domain_base
** Accessors **
***************/
Domain_name const &name() { return _name; }
Ip_rule_list &ip_rules() { return _ip_rules; }
Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; }
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Ipv4_address_prefix &interface_attr() { return _interface_attr; }
Pointer<Interface> &interface() { return _interface; }
Configuration &config() const { return _config; }
Domain_avl_member &avl_member() { return _avl_member; }
bool gateway_valid() const { return _gateway_valid; }
Domain_name const &name() { return _name; }
Ip_rule_list &ip_rules() { return _ip_rules; }
Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; }
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Ipv4_address_prefix &interface_attr() { return _interface_attr; }
Pointer<Interface> &interface() { return _interface; }
Configuration &config() const { return _config; }
Domain_avl_member &avl_member() { return _avl_member; }
};

View File

@ -462,18 +462,28 @@ void Interface::_handle_arp_request(Ethernet_frame &eth,
size_t const eth_size,
Arp_packet &arp)
{
/* ignore packets that do not target the router */
if (arp.dst_ip() != _router_ip()) {
/*
* We handle ARP only if it asks for the routers IP or if the router
* shall forward an ARP to a foreign address as gateway. The second
* is the case if no gateway attribute is specified (so we're the
* gateway) and the address is not of the same subnet like the interface
* attribute.
*/
if (arp.dst_ip() != _router_ip() &&
(_domain.gateway_valid() ||
_domain.interface_attr().prefix_matches(arp.dst_ip())))
{
if (_config().verbose()) {
log("ARP request for unknown IP"); }
log("Ignore ARP request"); }
return;
}
/* interchange source and destination MAC and IP addresses */
Ipv4_address dst_ip = arp.dst_ip();
arp.dst_ip(arp.src_ip());
arp.dst_mac(arp.src_mac());
eth.dst(eth.src());
arp.src_ip(_router_ip());
arp.src_ip(dst_ip);
arp.src_mac(_router_mac);
eth.src(_router_mac);