diff --git a/repos/os/include/net/dhcp.h b/repos/os/include/net/dhcp.h index 5fc4ccdd1..f748d74d9 100644 --- a/repos/os/include/net/dhcp.h +++ b/repos/os/include/net/dhcp.h @@ -67,7 +67,6 @@ class Net::Dhcp_packet public: struct No_dhcp_packet : Genode::Exception { }; - struct Option_not_found : Genode::Exception { }; private: @@ -178,6 +177,12 @@ class Net::Dhcp_packet } __attribute__((packed)); + struct Option_not_found : Genode::Exception + { + Option::Code const code; + + Option_not_found(Option::Code code) : code(code) { } + }; /** * DHCP option that contains a payload of type T @@ -373,7 +378,7 @@ class Net::Dhcp_packet if (opt.code() == Option::Code::INVALID || opt.code() == Option::Code::END) { - throw Option_not_found(); + throw Option_not_found(T::CODE); } if (opt.code() == T::CODE) { return *reinterpret_cast(ptr); diff --git a/repos/os/src/server/nic_router/dhcp_client.cc b/repos/os/src/server/nic_router/dhcp_client.cc index b87c8f8da..4be938277 100644 --- a/repos/os/src/server/nic_router/dhcp_client.cc +++ b/repos/os/src/server/nic_router/dhcp_client.cc @@ -20,8 +20,8 @@ using namespace Genode; using namespace Net; -using Message_type = Dhcp_packet::Message_type; -using Packet_ignored = Interface::Packet_ignored; +using Message_type = Dhcp_packet::Message_type; +using Drop_packet_inform = Interface::Drop_packet_inform; Configuration &Dhcp_client::_config() { return _domain().config(); }; @@ -91,32 +91,32 @@ void Dhcp_client::handle_ip(Ethernet_frame ð, size_t eth_size) if (eth.dst() != _interface.router_mac() && eth.dst() != Mac_address(0xff)) { - throw Packet_ignored("DHCP client expects Ethernet targeting the router"); + throw Drop_packet_inform("DHCP client expects Ethernet targeting the router"); } Ipv4_packet &ip = *new (eth.data()) Ipv4_packet(eth_size - sizeof(Ethernet_frame)); if (ip.protocol() != Ipv4_packet::Protocol::UDP) { - throw Packet_ignored("DHCP client expects UDP packet"); + throw Drop_packet_inform("DHCP client expects UDP packet"); } Udp_packet &udp = *new (ip.data()) Udp_packet(eth_size - sizeof(Ipv4_packet)); if (!Dhcp_packet::is_dhcp(&udp)) { - throw Packet_ignored("DHCP client expects DHCP packet"); + throw Drop_packet_inform("DHCP client expects DHCP packet"); } Dhcp_packet &dhcp = *new (udp.data()) Dhcp_packet(eth_size - sizeof(Ipv4_packet) - sizeof(Udp_packet)); if (dhcp.op() != Dhcp_packet::REPLY) { - throw Packet_ignored("DHCP client expects DHCP reply"); + throw Drop_packet_inform("DHCP client expects DHCP reply"); } if (dhcp.client_mac() != _interface.router_mac()) { - throw Packet_ignored("DHCP client expects DHCP targeting the router"); + throw Drop_packet_inform("DHCP client expects DHCP targeting the router"); } try { _handle_dhcp_reply(dhcp); } catch (Dhcp_packet::Option_not_found) { - throw Packet_ignored("DHCP client misses DHCP option"); + throw Drop_packet_inform("DHCP client misses DHCP option"); } } @@ -130,7 +130,7 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) case State::SELECT: if (msg_type != Message_type::OFFER) { - throw Packet_ignored("DHCP client expects an offer"); + throw Drop_packet_inform("DHCP client expects an offer"); } _set_state(State::REQUEST, _config().dhcp_request_timeout()); _send(Message_type::REQUEST, dhcp.yiaddr(), @@ -140,7 +140,7 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) case State::REQUEST: if (msg_type != Message_type::ACK) { - throw Packet_ignored("DHCP client expects an acknowledgement"); + throw Drop_packet_inform("DHCP client expects an acknowledgement"); } _lease_time_sec = dhcp.option().value(); _set_state(State::BOUND, _rerequest_timeout(1)); @@ -153,13 +153,13 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp) case State::REBIND: if (msg_type != Message_type::ACK) { - throw Packet_ignored("DHCP client expects an acknowledgement"); + throw Drop_packet_inform("DHCP client expects an acknowledgement"); } _set_state(State::BOUND, _rerequest_timeout(1)); _lease_time_sec = dhcp.option().value(); break; - default: throw Packet_ignored("DHCP client doesn't expect a packet"); + default: throw Drop_packet_inform("DHCP client doesn't expect a packet"); } } diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 5d434bceb..154f255ba 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -273,7 +273,7 @@ void Interface::_adapt_eth(Ethernet_frame ð, Interface &interface) { if (!interface.domain().ip_config().valid) { - throw Packet_ignored("target domain has yet no IP config"); + throw Drop_packet_inform("target domain has yet no IP config"); } Ipv4_address const &hop_ip = interface._domain.next_hop(ip); try { eth.dst(interface._arp_cache.find_by_ip(hop_ip).mac()); } @@ -430,7 +430,7 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, case Dhcp_packet::Message_type::DISCOVER: if (allocation.bound()) { - throw Bad_dhcp_request(); + throw Drop_packet_warn("DHCP DISCOVER from client expected to be in DHCP BOUND state"); } else { allocation.lifetime(_config().dhcp_offer_timeout()); @@ -490,10 +490,10 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, _destroy_dhcp_allocation(allocation); return; - case Dhcp_packet::Message_type::NAK: - case Dhcp_packet::Message_type::OFFER: - case Dhcp_packet::Message_type::ACK: - default: throw Bad_dhcp_request(); + case Dhcp_packet::Message_type::NAK: throw Drop_packet_warn("DHCP NAK from client"); + case Dhcp_packet::Message_type::OFFER: throw Drop_packet_warn("DHCP OFFER from client"); + case Dhcp_packet::Message_type::ACK: throw Drop_packet_warn("DHCP ACK from client"); + default: throw Drop_packet_warn("DHCP request with broken message type"); } } catch (Dhcp_allocation_tree::No_match) { @@ -517,18 +517,20 @@ void Interface::_handle_dhcp_request(Ethernet_frame ð, dhcp.xid()); return; } - case Dhcp_packet::Message_type::REQUEST: - case Dhcp_packet::Message_type::DECLINE: - case Dhcp_packet::Message_type::RELEASE: - case Dhcp_packet::Message_type::NAK: - case Dhcp_packet::Message_type::OFFER: - case Dhcp_packet::Message_type::ACK: - default: throw Bad_dhcp_request(); + case Dhcp_packet::Message_type::REQUEST: throw Drop_packet_warn("DHCP REQUEST from client without offered/acked IP"); + case Dhcp_packet::Message_type::DECLINE: throw Drop_packet_warn("DHCP DECLINE from client without offered/acked IP"); + case Dhcp_packet::Message_type::RELEASE: throw Drop_packet_warn("DHCP RELEASE from client without offered/acked IP"); + case Dhcp_packet::Message_type::NAK: throw Drop_packet_warn("DHCP NAK from client"); + case Dhcp_packet::Message_type::OFFER: throw Drop_packet_warn("DHCP OFFER from client"); + case Dhcp_packet::Message_type::ACK: throw Drop_packet_warn("DHCP ACK from client"); + default: throw Drop_packet_warn("DHCP request with broken message type"); } } } - catch (Dhcp_packet::Option_not_found) { - throw Bad_dhcp_request(); + catch (Dhcp_packet::Option_not_found exception) { + + throw Drop_packet_warn("DHCP request misses required option ", + (unsigned long)exception.code); } } @@ -844,11 +846,14 @@ void Interface::_handle_eth(void *const eth_base, log("unknown network layer protocol"); } } - catch (Packet_ignored exception) { + catch (Drop_packet_inform exception) { if (_config().verbose()) { - log("Packet ignored: ", exception.reason); + log("(", _domain, ") Drop packet: ", exception.msg); } } + catch (Drop_packet_warn exception) { + warning("(", _domain, ") Drop packet: ", exception.msg); + } catch (Ipv4_packet::No_ip_packet) { error("invalid IP packet"); } @@ -861,9 +866,6 @@ void Interface::_handle_eth(void *const eth_base, catch (Pointer::Invalid) { error("no interface connected to domain"); } - catch (Bad_dhcp_request) { - error("bad DHCP request"); } - catch (Alloc_dhcp_msg_buffer_failed) { error("failed to allocate buffer for DHCP reply"); } diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 68312e276..1db1dedd7 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -180,15 +180,23 @@ class Net::Interface struct Bad_transport_protocol : Genode::Exception { }; struct Bad_network_protocol : Genode::Exception { }; struct Packet_postponed : Genode::Exception { }; - struct Bad_dhcp_request : Genode::Exception { }; struct Alloc_dhcp_msg_buffer_failed : Genode::Exception { }; struct Dhcp_msg_buffer_too_small : Genode::Exception { }; - struct Packet_ignored : Genode::Exception + struct Drop_packet_inform : Genode::Exception { - char const *reason; + Genode::String<128> msg; - Packet_ignored(char const *reason) : reason(reason) { } + template + Drop_packet_inform(ARGS... args) : msg({args...}) { } + }; + + struct Drop_packet_warn : Genode::Exception + { + Genode::String<128> msg; + + template + Drop_packet_warn(ARGS... args) : msg({args...}) { } }; Interface(Genode::Entrypoint &ep,