diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index 93eba51a3..c6875bad7 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 3040e3526..629c94fef 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);