From 215937ff0f37efcd18def54ed4f0a22a5c29e493 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 25 Sep 2017 17:40:35 +0200 Subject: [PATCH] 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 --- repos/os/src/server/nic_router/domain.h | 23 +++++++++++---------- repos/os/src/server/nic_router/interface.cc | 18 ++++++++++++---- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index 93eba51a3e..c6875bad71 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -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() { 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() { return _interface; } + Configuration &config() const { return _config; } + Domain_avl_member &avl_member() { return _avl_member; } }; diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 3040e35264..629c94fef3 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -462,18 +462,28 @@ void Interface::_handle_arp_request(Ethernet_frame ð, 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);