mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
nic_router: better warnings on bad DHCP requests
Be more descriptive about why the NIC router thinks that a DHCP request sent to him is bad. Issue #2534
This commit is contained in:
parent
b32f2d126a
commit
70c5c31ec9
@ -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<T *>(ptr);
|
||||
|
@ -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<void>())
|
||||
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<void>())
|
||||
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<void>())
|
||||
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<Dhcp_packet::Ip_lease_time>().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<Dhcp_packet::Ip_lease_time>().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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Interface>::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"); }
|
||||
|
||||
|
@ -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 <typename... ARGS>
|
||||
Drop_packet_inform(ARGS... args) : msg({args...}) { }
|
||||
};
|
||||
|
||||
struct Drop_packet_warn : Genode::Exception
|
||||
{
|
||||
Genode::String<128> msg;
|
||||
|
||||
template <typename... ARGS>
|
||||
Drop_packet_warn(ARGS... args) : msg({args...}) { }
|
||||
};
|
||||
|
||||
Interface(Genode::Entrypoint &ep,
|
||||
|
Loading…
x
Reference in New Issue
Block a user