From f4a2d932e395fa8c80c04e6e8fcf8a272f4ced95 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 8 Jan 2018 14:11:29 +0100 Subject: [PATCH] net: check packet data size in accessor Instead of having a method validate_size in each packet class, check sizes in the data accessor of the surrounding packet class. This packet accessor is the one that casts the data pointer to the desired data type so it is sensible that it also checks whether the desired type would exceed the available RAM before doing the cast. This also fits nicely the fact that for the top-level packet-class of a packet, the size must not be checked (which was previously done). Issue #465 --- repos/os/include/net/arp.h | 12 ----- repos/os/include/net/dhcp.h | 11 ---- repos/os/include/net/ethernet.h | 29 +++++++---- repos/os/include/net/ipv4.h | 50 ++++++++++--------- repos/os/include/net/tcp.h | 6 --- repos/os/include/net/udp.h | 33 ++++++------ repos/os/src/lib/net/ethernet.cc | 6 +-- repos/os/src/lib/net/ipv4.cc | 6 +-- repos/os/src/lib/net/udp.cc | 3 +- repos/os/src/server/nic_bridge/component.cc | 18 +++---- repos/os/src/server/nic_bridge/nic.cc | 18 +++---- .../src/server/nic_bridge/packet_handler.cc | 13 ++--- repos/os/src/server/nic_dump/interface.cc | 4 -- repos/os/src/server/nic_dump/packet_log.cc | 10 ++-- repos/os/src/server/nic_router/dhcp_client.cc | 21 ++++---- repos/os/src/server/nic_router/interface.cc | 43 ++++++---------- repos/os/src/server/nic_router/size_guard.h | 1 + 17 files changed, 116 insertions(+), 168 deletions(-) diff --git a/repos/os/include/net/arp.h b/repos/os/include/net/arp.h index adc795bfb8..f292f801cf 100644 --- a/repos/os/include/net/arp.h +++ b/repos/os/include/net/arp.h @@ -145,18 +145,6 @@ class Net::Arp_packet }; - /** - * Exception used to indicate protocol violation. - */ - class No_arp_packet : Genode::Exception {}; - - static void validate_size(Genode::size_t size) { - /* arp packet needs to fit in */ - if (size < sizeof(Arp_packet)) - throw No_arp_packet(); - } - - /*************** ** Accessors ** ***************/ diff --git a/repos/os/include/net/dhcp.h b/repos/os/include/net/dhcp.h index a9e7ceb550..09674069d9 100644 --- a/repos/os/include/net/dhcp.h +++ b/repos/os/include/net/dhcp.h @@ -64,10 +64,6 @@ namespace Net { class Dhcp_packet; } */ class Net::Dhcp_packet { - public: - - struct No_dhcp_packet : Genode::Exception { }; - private: Genode::uint8_t _op; @@ -104,13 +100,6 @@ class Net::Dhcp_packet BOOTPC = 68 }; - - static void validate_size(Genode::size_t size) { - /* dhcp packet needs to fit in */ - if (size < sizeof(Dhcp_packet)) - throw No_dhcp_packet(); - } - void default_magic_cookie() { _magic_cookie = host_to_big_endian(0x63825363); } diff --git a/repos/os/include/net/ethernet.h b/repos/os/include/net/ethernet.h index eceb0b7f15..39e4172c40 100644 --- a/repos/os/include/net/ethernet.h +++ b/repos/os/include/net/ethernet.h @@ -61,8 +61,6 @@ class Net::Ethernet_frame public: - class No_ethernet_frame : Genode::Exception {}; - enum { MIN_SIZE = 64 }; /** @@ -73,11 +71,22 @@ class Net::Ethernet_frame ARP = 0x0806, }; - static void validate_size(Genode::size_t size) + struct Bad_data_type : Genode::Exception { }; + + template T const *data(Genode::size_t data_size) const { - /* at least, frame header needs to fit in */ - if (size < sizeof(Ethernet_frame)) - throw No_ethernet_frame(); + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T const *)(_data); + } + + template T *data(Genode::size_t data_size) + { + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T *)(_data); } @@ -85,11 +94,9 @@ class Net::Ethernet_frame ** Accessors ** ***************/ - Mac_address dst() const { return Mac_address((void *)_dst); } - Mac_address src() const { return Mac_address((void *)_src); } - Type type() const { return (Type)host_to_big_endian(_type); } - template T const *data() const { return (T const *)(_data); } - template T *data() { return (T *)(_data); } + Mac_address dst() const { return Mac_address((void *)_dst); } + Mac_address src() const { return Mac_address((void *)_src); } + Type type() const { return (Type)host_to_big_endian(_type); } void dst(Mac_address v) { v.copy(&_dst); } void src(Mac_address v) { v.copy(&_src); } diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h index 7098400312..045bb3f44a 100644 --- a/repos/os/include/net/ipv4.h +++ b/repos/os/include/net/ipv4.h @@ -148,16 +148,22 @@ class Net::Ipv4_packet MORE_FRAGMENTS = 0x4 }; + struct Bad_data_type : Genode::Exception { }; - /** - * Exception used to indicate protocol violation. - */ - class No_ip_packet : Genode::Exception {}; + template T const *data(Genode::size_t data_size) const + { + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T const *)(_data); + } - static void validate_size(Genode::size_t size) { - /* ip header needs to fit in */ - if (size < sizeof(Ipv4_packet)) - throw No_ip_packet(); + template T *data(Genode::size_t data_size) + { + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T *)(_data); } @@ -165,21 +171,19 @@ class Net::Ipv4_packet ** Accessors ** ***************/ - Genode::size_t header_length() const { return _header_length; } - Genode::uint8_t version() const { return _version; } - Genode::uint8_t diff_service() const { return _diff_service; } - Genode::uint8_t ecn() const { return _ecn; } - Genode::size_t total_length() const { return host_to_big_endian(_total_length); } - Genode::uint16_t identification() const { return host_to_big_endian(_identification); } - Genode::uint8_t flags() const { return _flags; } - Genode::size_t fragment_offset() const { return _fragment_offset; } - Genode::uint8_t time_to_live() const { return _time_to_live; } - Protocol protocol() const { return (Protocol)_protocol; } - Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); } - Ipv4_address src() const { return Ipv4_address((void *)&_src); } - Ipv4_address dst() const { return Ipv4_address((void *)&_dst); } - template T const * data() const { return (T const *)(_data); } - template T * data() { return (T *)(_data); } + Genode::size_t header_length() const { return _header_length; } + Genode::uint8_t version() const { return _version; } + Genode::uint8_t diff_service() const { return _diff_service; } + Genode::uint8_t ecn() const { return _ecn; } + Genode::size_t total_length() const { return host_to_big_endian(_total_length); } + Genode::uint16_t identification() const { return host_to_big_endian(_identification); } + Genode::uint8_t flags() const { return _flags; } + Genode::size_t fragment_offset() const { return _fragment_offset; } + Genode::uint8_t time_to_live() const { return _time_to_live; } + Protocol protocol() const { return (Protocol)_protocol; } + Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); } + Ipv4_address src() const { return Ipv4_address((void *)&_src); } + Ipv4_address dst() const { return Ipv4_address((void *)&_dst); } void header_length(Genode::size_t v) { _header_length = v; } void version(Genode::uint8_t v) { _version = v; } diff --git a/repos/os/include/net/tcp.h b/repos/os/include/net/tcp.h index b138de1e34..7c1b84bf5e 100644 --- a/repos/os/include/net/tcp.h +++ b/repos/os/include/net/tcp.h @@ -70,12 +70,6 @@ class Net::Tcp_packet public: - class No_tcp_packet : Exception {}; - - static void validate_size(Genode::size_t size) { - if (size < sizeof(Tcp_packet)) { throw No_tcp_packet(); } } - - /*************** ** Accessors ** ***************/ diff --git a/repos/os/include/net/udp.h b/repos/os/include/net/udp.h index 272fb9cf4c..3d72452137 100644 --- a/repos/os/include/net/udp.h +++ b/repos/os/include/net/udp.h @@ -51,15 +51,22 @@ class Net::Udp_packet public: - /** - * Exception used to indicate protocol violation. - */ - class No_udp_packet : Genode::Exception {}; + struct Bad_data_type : Genode::Exception { }; - static void validate_size(Genode::size_t size) { - /* Udp header needs to fit in */ - if (size < sizeof(Udp_packet)) - throw No_udp_packet(); + template T const *data(Genode::size_t data_size) const + { + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T const *)(_data); + } + + template T *data(Genode::size_t data_size) + { + if (data_size < sizeof(T)) { + throw Bad_data_type(); + } + return (T *)(_data); } @@ -67,12 +74,10 @@ class Net::Udp_packet ** Accessors ** ***************/ - Port src_port() const { return Port(host_to_big_endian(_src_port)); } - Port dst_port() const { return Port(host_to_big_endian(_dst_port)); } - Genode::uint16_t length() const { return host_to_big_endian(_length); } - Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); } - template T const * data() const { return (T const *)(_data); } - template T * data() { return (T *)(_data); } + Port src_port() const { return Port(host_to_big_endian(_src_port)); } + Port dst_port() const { return Port(host_to_big_endian(_dst_port)); } + Genode::uint16_t length() const { return host_to_big_endian(_length); } + Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); } void length(Genode::uint16_t v) { _length = host_to_big_endian(v); } void src_port(Port p) { _src_port = host_to_big_endian(p.value); } diff --git a/repos/os/src/lib/net/ethernet.cc b/repos/os/src/lib/net/ethernet.cc index 7946a0b776..1c9c635ba0 100644 --- a/repos/os/src/lib/net/ethernet.cc +++ b/repos/os/src/lib/net/ethernet.cc @@ -25,12 +25,10 @@ void Net::Ethernet_frame::print(Genode::Output &output) const Genode::print(output, "\033[32mETH\033[0m ", src(), " > ", dst(), " "); switch (type()) { case Ethernet_frame::Type::ARP: - Genode::print(output, - *reinterpret_cast(data())); + Genode::print(output, *reinterpret_cast(_data)); break; case Ethernet_frame::Type::IPV4: - Genode::print(output, - *reinterpret_cast(data())); + Genode::print(output, *reinterpret_cast(_data)); break; default: ; } } diff --git a/repos/os/src/lib/net/ipv4.cc b/repos/os/src/lib/net/ipv4.cc index 78e82ed0f1..a8060e75e2 100644 --- a/repos/os/src/lib/net/ipv4.cc +++ b/repos/os/src/lib/net/ipv4.cc @@ -27,12 +27,10 @@ void Net::Ipv4_packet::print(Genode::Output &output) const Genode::print(output, "\033[32mIPV4\033[0m ", src(), " > ", dst(), " "); switch (protocol()) { case Protocol::TCP: - Genode::print(output, - *reinterpret_cast(data())); + Genode::print(output, *reinterpret_cast(_data)); break; case Protocol::UDP: - Genode::print(output, - *reinterpret_cast(data())); + Genode::print(output, *reinterpret_cast(_data)); break; default: ; } } diff --git a/repos/os/src/lib/net/udp.cc b/repos/os/src/lib/net/udp.cc index 37c1877301..c69544a4f7 100644 --- a/repos/os/src/lib/net/udp.cc +++ b/repos/os/src/lib/net/udp.cc @@ -22,7 +22,6 @@ void Net::Udp_packet::print(Genode::Output &output) const Genode::print(output, "\033[32mUDP\033[0m ", src_port(), " > ", dst_port(), " "); if (Dhcp_packet::is_dhcp(this)) { - Genode::print(output, - *reinterpret_cast(data())); + Genode::print(output, *reinterpret_cast(_data)); } } diff --git a/repos/os/src/server/nic_bridge/component.cc b/repos/os/src/server/nic_bridge/component.cc index 25235323ac..86dbbf7afd 100644 --- a/repos/os/src/server/nic_bridge/component.cc +++ b/repos/os/src/server/nic_bridge/component.cc @@ -22,8 +22,7 @@ using namespace Net; bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size) { - Arp_packet *arp = eth->data(); - Arp_packet::validate_size(size - sizeof(Ethernet_frame)); + Arp_packet *arp = eth->data(size - sizeof(Ethernet_frame)); if (arp->ethernet_ipv4() && arp->opcode() == Arp_packet::REQUEST) { @@ -51,19 +50,16 @@ bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size) bool Session_component::handle_ip(Ethernet_frame *eth, Genode::size_t size) { - Ipv4_packet *ip = eth->data(); - Ipv4_packet::validate_size(size - sizeof(Ethernet_frame)); + Ipv4_packet *ip = eth->data(size - sizeof(Ethernet_frame)); if (ip->protocol() == Ipv4_packet::Protocol::UDP) { - Udp_packet *udp = ip->data(); - Udp_packet::validate_size(size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet)); + Udp_packet *udp = ip->data(size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet)); if (Dhcp_packet::is_dhcp(udp)) { - Dhcp_packet *dhcp = udp->data(); - Dhcp_packet::validate_size(size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet) - - sizeof(Udp_packet)); + Dhcp_packet *dhcp = udp->data(size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet) + - sizeof(Udp_packet)); if (dhcp->op() == Dhcp_packet::REQUEST) { dhcp->broadcast(true); udp->update_checksum(ip->src(), ip->dst()); diff --git a/repos/os/src/server/nic_bridge/nic.cc b/repos/os/src/server/nic_bridge/nic.cc index 76755f6fa3..8626d1ec4a 100644 --- a/repos/os/src/server/nic_bridge/nic.cc +++ b/repos/os/src/server/nic_bridge/nic.cc @@ -24,8 +24,7 @@ using namespace Net; bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) { - Arp_packet *arp = eth->data(); - Arp_packet::validate_size(size - sizeof(Ethernet_frame)); + Arp_packet *arp = eth->data(size - sizeof(Ethernet_frame)); /* ignore broken packets */ if (!arp->ethernet_ipv4()) @@ -66,22 +65,19 @@ bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) { bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) { - Ipv4_packet *ip = eth->data(); - Ipv4_packet::validate_size(size - sizeof(Ethernet_frame)); + Ipv4_packet *ip = eth->data(size - sizeof(Ethernet_frame)); /* is it an UDP packet ? */ if (ip->protocol() == Ipv4_packet::Protocol::UDP) { - Udp_packet *udp = ip->data(); - Udp_packet::validate_size(size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet)); + Udp_packet *udp = ip->data(size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet)); /* is it a DHCP packet ? */ if (Dhcp_packet::is_dhcp(udp)) { - Dhcp_packet *dhcp = udp->data(); - Dhcp_packet::validate_size(size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet) - - sizeof(Udp_packet)); + Dhcp_packet *dhcp = udp->data(size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet) + - sizeof(Udp_packet)); /* check for DHCP ACKs containing new client ips */ if (dhcp->op() == Dhcp_packet::REPLY) { diff --git a/repos/os/src/server/nic_bridge/packet_handler.cc b/repos/os/src/server/nic_bridge/packet_handler.cc index 984b93daf7..60904df0e7 100644 --- a/repos/os/src/server/nic_bridge/packet_handler.cc +++ b/repos/os/src/server/nic_bridge/packet_handler.cc @@ -80,7 +80,6 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size) try { /* parse ethernet frame header */ Ethernet_frame *eth = reinterpret_cast(src); - Ethernet_frame::validate_size(size); switch (eth->type()) { case Ethernet_frame::Type::ARP: if (!handle_arp(eth, size)) return; @@ -94,15 +93,11 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size) broadcast_to_clients(eth, size); finalize_packet(eth, size); - } catch(Arp_packet::No_arp_packet) { - Genode::warning("Invalid ARP packet!"); - } catch(Ethernet_frame::No_ethernet_frame) { - Genode::warning("Invalid ethernet frame"); - } catch(Dhcp_packet::No_dhcp_packet) { + } catch(Ethernet_frame::Bad_data_type) { + Genode::warning("Invalid Ethernet frame!"); + } catch(Ipv4_packet::Bad_data_type) { Genode::warning("Invalid IPv4 packet!"); - } catch(Ipv4_packet::No_ip_packet) { - Genode::warning("Invalid IPv4 packet!"); - } catch(Udp_packet::No_udp_packet) { + } catch(Udp_packet::Bad_data_type) { Genode::warning("Invalid UDP packet!"); } } diff --git a/repos/os/src/server/nic_dump/interface.cc b/repos/os/src/server/nic_dump/interface.cc index 8edd0eddfc..685df92e48 100644 --- a/repos/os/src/server/nic_dump/interface.cc +++ b/repos/os/src/server/nic_dump/interface.cc @@ -28,7 +28,6 @@ void Net::Interface::_handle_eth(void *const eth_base, { try { Ethernet_frame ð = *reinterpret_cast(eth_base); - Ethernet_frame::validate_size(eth_size); Interface &remote = _remote.deref(); Packet_log_config log_cfg; @@ -47,9 +46,6 @@ void Net::Interface::_handle_eth(void *const eth_base, } remote._send(eth, eth_size); } - catch (Ethernet_frame::No_ethernet_frame) { - error("invalid ethernet frame"); } - catch (Pointer::Invalid) { error("no remote interface set"); } } diff --git a/repos/os/src/server/nic_dump/packet_log.cc b/repos/os/src/server/nic_dump/packet_log.cc index 74a99dda5a..41fd8febd7 100644 --- a/repos/os/src/server/nic_dump/packet_log.cc +++ b/repos/os/src/server/nic_dump/packet_log.cc @@ -157,12 +157,12 @@ void Packet_log::print(Output &output) const switch (_pkt.type()) { case Ethernet_frame::Type::ARP: - print(output, " ", packet_log(*_pkt.data(), _cfg)); + print(output, " ", packet_log(*_pkt.data(~0UL), _cfg)); break; case Ethernet_frame::Type::IPV4: - print(output, " ", packet_log(*_pkt.data(), _cfg)); + print(output, " ", packet_log(*_pkt.data(~0UL), _cfg)); break; default: ; @@ -212,12 +212,12 @@ void Packet_log::print(Output &output) const switch (_pkt.protocol()) { case Ipv4_packet::Protocol::TCP: - print(output, " ", packet_log(*_pkt.data(), _cfg)); + print(output, " ", packet_log(*_pkt.data(~0UL), _cfg)); break; case Ipv4_packet::Protocol::UDP: - print(output, " ", packet_log(*_pkt.data(), _cfg)); + print(output, " ", packet_log(*_pkt.data(~0UL), _cfg)); break; default: ; } @@ -292,6 +292,6 @@ void Packet_log::print(Output &output) const } /* print encapsulated packet */ if (Dhcp_packet::is_dhcp(&_pkt)) { - print(output, " ", packet_log(*_pkt.data(), _cfg)); + print(output, " ", packet_log(*_pkt.data(~0UL), _cfg)); } } diff --git a/repos/os/src/server/nic_router/dhcp_client.cc b/repos/os/src/server/nic_router/dhcp_client.cc index bfb36d6628..8497d07329 100644 --- a/repos/os/src/server/nic_router/dhcp_client.cc +++ b/repos/os/src/server/nic_router/dhcp_client.cc @@ -93,23 +93,20 @@ void Dhcp_client::handle_ip(Ethernet_frame ð, size_t eth_size) { throw Drop_packet_inform("DHCP client expects Ethernet targeting the router"); } - Ipv4_packet &ip = *eth.data(); - Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame)); + Ipv4_packet &ip = *eth.data(eth_size - sizeof(Ethernet_frame)); if (ip.protocol() != Ipv4_packet::Protocol::UDP) { throw Drop_packet_inform("DHCP client expects UDP packet"); } - Udp_packet &udp = *ip.data(); - Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet)); + Udp_packet &udp = *ip.data(eth_size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet)); if (!Dhcp_packet::is_dhcp(&udp)) { throw Drop_packet_inform("DHCP client expects DHCP packet"); } - Dhcp_packet &dhcp = *udp.data(); - Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet) - - sizeof(Udp_packet)); + Dhcp_packet &dhcp = *udp.data(eth_size - sizeof(Ethernet_frame) + - sizeof(Ipv4_packet) + - sizeof(Udp_packet)); if (dhcp.op() != Dhcp_packet::REPLY) { throw Drop_packet_inform("DHCP client expects DHCP reply"); @@ -187,8 +184,8 @@ void Dhcp_client::_send(Message_type msg_type, /* create IP header of the request */ enum { IPV4_TIME_TO_LIVE = 64 }; size_t const ip_off = size.curr(); + Ipv4_packet &ip = *eth.data(size.left()); size.add(sizeof(Ipv4_packet)); - Ipv4_packet &ip = *eth.data(); ip.header_length(sizeof(Ipv4_packet) / 4); ip.version(4); ip.diff_service(0); @@ -202,15 +199,15 @@ void Dhcp_client::_send(Message_type msg_type, /* create UDP header of the request */ size_t const udp_off = size.curr(); + Udp_packet &udp = *ip.data(size.left()); size.add(sizeof(Udp_packet)); - Udp_packet &udp = *ip.data(); udp.src_port(Port(Dhcp_packet::BOOTPC)); udp.dst_port(Port(Dhcp_packet::BOOTPS)); /* create mandatory DHCP fields of the request */ size_t const dhcp_off = size.curr(); + Dhcp_packet &dhcp = *udp.data(size.left()); size.add(sizeof(Dhcp_packet)); - Dhcp_packet &dhcp = *udp.data(); dhcp.op(Dhcp_packet::REQUEST); dhcp.htype(Dhcp_packet::Htype::ETH); dhcp.hlen(sizeof(Mac_address)); diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 7441bd512c..cf7d904ad0 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -143,12 +143,8 @@ static void *_prot_base(L3_protocol const prot, Ipv4_packet &ip) { switch (prot) { - case L3_protocol::TCP: - Tcp_packet::validate_size(prot_size); - return ip.data(); - case L3_protocol::UDP: - Udp_packet::validate_size(prot_size); - return ip.data(); + case L3_protocol::TCP: return ip.data(prot_size); + case L3_protocol::UDP: return ip.data(prot_size); default: throw Interface::Bad_transport_protocol(); } } @@ -315,8 +311,8 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv, /* create IP header of the reply */ enum { IPV4_TIME_TO_LIVE = 64 }; size_t const ip_off = size.curr(); + Ipv4_packet &ip = *eth.data(size.left()); size.add(sizeof(Ipv4_packet)); - Ipv4_packet &ip = *eth.data(); ip.header_length(sizeof(Ipv4_packet) / 4); ip.version(4); ip.diff_service(0); @@ -330,14 +326,14 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv, /* create UDP header of the reply */ size_t const udp_off = size.curr(); + Udp_packet &udp = *ip.data(size.left()); size.add(sizeof(Udp_packet)); - Udp_packet &udp = *ip.data(); udp.src_port(Port(Dhcp_packet::BOOTPS)); udp.dst_port(Port(Dhcp_packet::BOOTPC)); /* create mandatory DHCP fields of the reply */ + Dhcp_packet &dhcp = *udp.data(size.left()); size.add(sizeof(Dhcp_packet)); - Dhcp_packet &dhcp = *udp.data(); dhcp.op(Dhcp_packet::REPLY); dhcp.htype(Dhcp_packet::Htype::ETH); dhcp.hlen(sizeof(Mac_address)); @@ -538,8 +534,7 @@ void Interface::_handle_ip(Ethernet_frame ð, Packet_descriptor const &pkt) { /* read packet information */ - Ipv4_packet &ip = *eth.data(); - Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame)); + Ipv4_packet &ip = *eth.data(eth_size - sizeof(Ethernet_frame)); /* try handling subnet-local IP packets */ if (_ip_config().interface.prefix_matches(ip.dst()) && @@ -561,17 +556,13 @@ void Interface::_handle_ip(Ethernet_frame ð, /* try handling DHCP requests before trying any routing */ if (prot == L3_protocol::UDP) { - Udp_packet &udp = *ip.data(); - Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet)); + Udp_packet &udp = *ip.data(eth_size - sizeof(Ipv4_packet)); if (Dhcp_packet::is_dhcp(&udp)) { /* get DHCP packet */ - Dhcp_packet &dhcp = *udp.data(); - Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame) - - sizeof(Ipv4_packet) - - sizeof(Udp_packet)); + Dhcp_packet &dhcp = *udp.data(eth_size - sizeof(Ipv4_packet) + - sizeof(Udp_packet)); if (dhcp.op() == Dhcp_packet::REQUEST) { try { @@ -696,7 +687,7 @@ void Interface::_broadcast_arp_request(Ipv4_address const &ip) eth.type(Ethernet_frame::Type::ARP); /* write ARP header */ - Arp_packet &arp = *eth.data(); + Arp_packet &arp = *eth.data(PKT_SIZE - sizeof(Ethernet_frame)); arp.hardware_address_type(Arp_packet::ETHERNET); arp.protocol_address_type(Arp_packet::IPV4); arp.hardware_address_size(sizeof(Mac_address)); @@ -817,9 +808,7 @@ void Interface::_handle_arp_request(Ethernet_frame ð, void Interface::_handle_arp(Ethernet_frame ð, size_t const eth_size) { /* ignore ARP regarding protocols other than IPv4 via ethernet */ - size_t const arp_size = eth_size - sizeof(Ethernet_frame); - Arp_packet &arp = *eth.data(); - Arp_packet::validate_size(arp_size); + Arp_packet &arp = *eth.data(eth_size - sizeof(Ethernet_frame)); if (!arp.ethernet_ipv4()) { error("ARP for unknown protocol"); } @@ -890,7 +879,6 @@ void Interface::_handle_eth(void *const eth_base, /* inspect and handle ethernet frame */ try { Ethernet_frame *const eth = reinterpret_cast(eth_base); - Ethernet_frame::validate_size(eth_size); if (_config().verbose()) { log("(router <- ", _domain, ") ", *eth); } @@ -908,12 +896,9 @@ void Interface::_handle_eth(void *const eth_base, default: throw Bad_network_protocol(); } } } - catch (Ethernet_frame::No_ethernet_frame) { warning("malformed Ethernet frame"); } - catch (Ipv4_packet::No_ip_packet) { warning("malformed IPv4 packet" ); } - catch (Tcp_packet::No_tcp_packet) { warning("malformed TCP packet" ); } - catch (Udp_packet::No_udp_packet) { warning("malformed UDP packet" ); } - catch (Dhcp_packet::No_dhcp_packet) { warning("malformed DHCP packet" ); } - catch (Arp_packet::No_arp_packet) { warning("malformed ARP packet" ); } + catch (Ethernet_frame::Bad_data_type) { warning("malformed Ethernet frame"); } + catch (Ipv4_packet::Bad_data_type) { warning("malformed IPv4 packet" ); } + catch (Udp_packet::Bad_data_type) { warning("malformed UDP packet" ); } catch (Bad_network_protocol) { if (_config().verbose()) { diff --git a/repos/os/src/server/nic_router/size_guard.h b/repos/os/src/server/nic_router/size_guard.h index c9c2b4ee93..b409c27e0e 100644 --- a/repos/os/src/server/nic_router/size_guard.h +++ b/repos/os/src/server/nic_router/size_guard.h @@ -40,6 +40,7 @@ class Genode::Size_guard_tpl } size_t curr() const { return _curr; } + size_t left() const { return MAX - _curr; } }; #endif /* _SIZE_GUARD_H_ */