mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 06:33:31 +00:00
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
This commit is contained in:
parent
89a9e88a7e
commit
f4a2d932e3
@ -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 **
|
||||
***************/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 <typename T> 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 <typename T> 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 <typename T> T const *data() const { return (T const *)(_data); }
|
||||
template <typename T> 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); }
|
||||
|
@ -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 <typename T> 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 <typename T> 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 <typename T> T const * data() const { return (T const *)(_data); }
|
||||
template <typename T> 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; }
|
||||
|
@ -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 **
|
||||
***************/
|
||||
|
@ -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 <typename T> T const *data(Genode::size_t data_size) const
|
||||
{
|
||||
if (data_size < sizeof(T)) {
|
||||
throw Bad_data_type();
|
||||
}
|
||||
return (T const *)(_data);
|
||||
}
|
||||
|
||||
template <typename T> 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 <typename T> T const * data() const { return (T const *)(_data); }
|
||||
template <typename T> 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); }
|
||||
|
@ -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<Arp_packet const *>(data<void>()));
|
||||
Genode::print(output, *reinterpret_cast<Arp_packet const *>(_data));
|
||||
break;
|
||||
case Ethernet_frame::Type::IPV4:
|
||||
Genode::print(output,
|
||||
*reinterpret_cast<Ipv4_packet const *>(data<void>()));
|
||||
Genode::print(output, *reinterpret_cast<Ipv4_packet const *>(_data));
|
||||
break;
|
||||
default: ; }
|
||||
}
|
||||
|
@ -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<Tcp_packet const *>(data<void>()));
|
||||
Genode::print(output, *reinterpret_cast<Tcp_packet const *>(_data));
|
||||
break;
|
||||
case Protocol::UDP:
|
||||
Genode::print(output,
|
||||
*reinterpret_cast<Udp_packet const *>(data<void>()));
|
||||
Genode::print(output, *reinterpret_cast<Udp_packet const *>(_data));
|
||||
break;
|
||||
default: ; }
|
||||
}
|
||||
|
@ -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<Dhcp_packet const *>(data<void>()));
|
||||
Genode::print(output, *reinterpret_cast<Dhcp_packet const *>(_data));
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
Arp_packet::validate_size(size - sizeof(Ethernet_frame));
|
||||
Arp_packet *arp = eth->data<Arp_packet>(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>();
|
||||
Ipv4_packet::validate_size(size - sizeof(Ethernet_frame));
|
||||
Ipv4_packet *ip = eth->data<Ipv4_packet>(size - sizeof(Ethernet_frame));
|
||||
|
||||
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
||||
{
|
||||
Udp_packet *udp = ip->data<Udp_packet>();
|
||||
Udp_packet::validate_size(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet));
|
||||
Udp_packet *udp = ip->data<Udp_packet>(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet));
|
||||
if (Dhcp_packet::is_dhcp(udp)) {
|
||||
Dhcp_packet *dhcp = udp->data<Dhcp_packet>();
|
||||
Dhcp_packet::validate_size(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet)
|
||||
- sizeof(Udp_packet));
|
||||
Dhcp_packet *dhcp = udp->data<Dhcp_packet>(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());
|
||||
|
@ -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>();
|
||||
Arp_packet::validate_size(size - sizeof(Ethernet_frame));
|
||||
Arp_packet *arp = eth->data<Arp_packet>(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>();
|
||||
Ipv4_packet::validate_size(size - sizeof(Ethernet_frame));
|
||||
Ipv4_packet *ip = eth->data<Ipv4_packet>(size - sizeof(Ethernet_frame));
|
||||
|
||||
/* is it an UDP packet ? */
|
||||
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
||||
{
|
||||
Udp_packet *udp = ip->data<Udp_packet>();
|
||||
Udp_packet::validate_size(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet));
|
||||
Udp_packet *udp = ip->data<Udp_packet>(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>();
|
||||
Dhcp_packet::validate_size(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet)
|
||||
- sizeof(Udp_packet));
|
||||
Dhcp_packet *dhcp = udp->data<Dhcp_packet>(size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet)
|
||||
- sizeof(Udp_packet));
|
||||
|
||||
/* check for DHCP ACKs containing new client ips */
|
||||
if (dhcp->op() == Dhcp_packet::REPLY) {
|
||||
|
@ -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<Ethernet_frame *>(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!");
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ void Net::Interface::_handle_eth(void *const eth_base,
|
||||
{
|
||||
try {
|
||||
Ethernet_frame ð = *reinterpret_cast<Ethernet_frame *>(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<Interface>::Invalid) {
|
||||
error("no remote interface set"); }
|
||||
}
|
||||
|
@ -157,12 +157,12 @@ void Packet_log<Ethernet_frame>::print(Output &output) const
|
||||
switch (_pkt.type()) {
|
||||
case Ethernet_frame::Type::ARP:
|
||||
|
||||
print(output, " ", packet_log(*_pkt.data<Arp_packet const>(), _cfg));
|
||||
print(output, " ", packet_log(*_pkt.data<Arp_packet const>(~0UL), _cfg));
|
||||
break;
|
||||
|
||||
case Ethernet_frame::Type::IPV4:
|
||||
|
||||
print(output, " ", packet_log(*_pkt.data<Ipv4_packet const>(), _cfg));
|
||||
print(output, " ", packet_log(*_pkt.data<Ipv4_packet const>(~0UL), _cfg));
|
||||
break;
|
||||
|
||||
default: ;
|
||||
@ -212,12 +212,12 @@ void Packet_log<Ipv4_packet>::print(Output &output) const
|
||||
switch (_pkt.protocol()) {
|
||||
case Ipv4_packet::Protocol::TCP:
|
||||
|
||||
print(output, " ", packet_log(*_pkt.data<Tcp_packet const>(), _cfg));
|
||||
print(output, " ", packet_log(*_pkt.data<Tcp_packet const>(~0UL), _cfg));
|
||||
break;
|
||||
|
||||
case Ipv4_packet::Protocol::UDP:
|
||||
|
||||
print(output, " ", packet_log(*_pkt.data<Udp_packet const>(), _cfg));
|
||||
print(output, " ", packet_log(*_pkt.data<Udp_packet const>(~0UL), _cfg));
|
||||
break;
|
||||
|
||||
default: ; }
|
||||
@ -292,6 +292,6 @@ void Packet_log<Udp_packet>::print(Output &output) const
|
||||
}
|
||||
/* print encapsulated packet */
|
||||
if (Dhcp_packet::is_dhcp(&_pkt)) {
|
||||
print(output, " ", packet_log(*_pkt.data<Dhcp_packet const>(), _cfg));
|
||||
print(output, " ", packet_log(*_pkt.data<Dhcp_packet const>(~0UL), _cfg));
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame));
|
||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>(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>();
|
||||
Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet));
|
||||
Udp_packet &udp = *ip.data<Udp_packet>(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>();
|
||||
Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet)
|
||||
- sizeof(Udp_packet));
|
||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(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<Ipv4_packet>(size.left());
|
||||
size.add(sizeof(Ipv4_packet));
|
||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
||||
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<Udp_packet>(size.left());
|
||||
size.add(sizeof(Udp_packet));
|
||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
||||
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<Dhcp_packet>(size.left());
|
||||
size.add(sizeof(Dhcp_packet));
|
||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
||||
dhcp.op(Dhcp_packet::REQUEST);
|
||||
dhcp.htype(Dhcp_packet::Htype::ETH);
|
||||
dhcp.hlen(sizeof(Mac_address));
|
||||
|
@ -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<Tcp_packet>();
|
||||
case L3_protocol::UDP:
|
||||
Udp_packet::validate_size(prot_size);
|
||||
return ip.data<Udp_packet>();
|
||||
case L3_protocol::TCP: return ip.data<Tcp_packet>(prot_size);
|
||||
case L3_protocol::UDP: return ip.data<Udp_packet>(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<Ipv4_packet>(size.left());
|
||||
size.add(sizeof(Ipv4_packet));
|
||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
||||
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<Udp_packet>(size.left());
|
||||
size.add(sizeof(Udp_packet));
|
||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
||||
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<Dhcp_packet>(size.left());
|
||||
size.add(sizeof(Dhcp_packet));
|
||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
||||
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>();
|
||||
Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame));
|
||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>(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>();
|
||||
Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet));
|
||||
Udp_packet &udp = *ip.data<Udp_packet>(eth_size - sizeof(Ipv4_packet));
|
||||
|
||||
if (Dhcp_packet::is_dhcp(&udp)) {
|
||||
|
||||
/* get DHCP packet */
|
||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
||||
Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
||||
- sizeof(Ipv4_packet)
|
||||
- sizeof(Udp_packet));
|
||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(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_packet &arp = *eth.data<Arp_packet>(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>();
|
||||
Arp_packet::validate_size(arp_size);
|
||||
Arp_packet &arp = *eth.data<Arp_packet>(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<Ethernet_frame *>(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()) {
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user