mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-30 18:47:01 +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 **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
@ -64,10 +64,6 @@ namespace Net { class Dhcp_packet; }
|
|||||||
*/
|
*/
|
||||||
class Net::Dhcp_packet
|
class Net::Dhcp_packet
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
struct No_dhcp_packet : Genode::Exception { };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::uint8_t _op;
|
Genode::uint8_t _op;
|
||||||
@ -104,13 +100,6 @@ class Net::Dhcp_packet
|
|||||||
BOOTPC = 68
|
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() {
|
void default_magic_cookie() {
|
||||||
_magic_cookie = host_to_big_endian(0x63825363);
|
_magic_cookie = host_to_big_endian(0x63825363);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,6 @@ class Net::Ethernet_frame
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class No_ethernet_frame : Genode::Exception {};
|
|
||||||
|
|
||||||
enum { MIN_SIZE = 64 };
|
enum { MIN_SIZE = 64 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,11 +71,22 @@ class Net::Ethernet_frame
|
|||||||
ARP = 0x0806,
|
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 (data_size < sizeof(T)) {
|
||||||
if (size < sizeof(Ethernet_frame))
|
throw Bad_data_type();
|
||||||
throw No_ethernet_frame();
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,8 +97,6 @@ class Net::Ethernet_frame
|
|||||||
Mac_address dst() const { return Mac_address((void *)_dst); }
|
Mac_address dst() const { return Mac_address((void *)_dst); }
|
||||||
Mac_address src() const { return Mac_address((void *)_src); }
|
Mac_address src() const { return Mac_address((void *)_src); }
|
||||||
Type type() const { return (Type)host_to_big_endian(_type); }
|
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); }
|
|
||||||
|
|
||||||
void dst(Mac_address v) { v.copy(&_dst); }
|
void dst(Mac_address v) { v.copy(&_dst); }
|
||||||
void src(Mac_address v) { v.copy(&_src); }
|
void src(Mac_address v) { v.copy(&_src); }
|
||||||
|
@ -148,16 +148,22 @@ class Net::Ipv4_packet
|
|||||||
MORE_FRAGMENTS = 0x4
|
MORE_FRAGMENTS = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Bad_data_type : Genode::Exception { };
|
||||||
|
|
||||||
/**
|
template <typename T> T const *data(Genode::size_t data_size) const
|
||||||
* Exception used to indicate protocol violation.
|
{
|
||||||
*/
|
if (data_size < sizeof(T)) {
|
||||||
class No_ip_packet : Genode::Exception {};
|
throw Bad_data_type();
|
||||||
|
}
|
||||||
|
return (T const *)(_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void validate_size(Genode::size_t size) {
|
template <typename T> T *data(Genode::size_t data_size)
|
||||||
/* ip header needs to fit in */
|
{
|
||||||
if (size < sizeof(Ipv4_packet))
|
if (data_size < sizeof(T)) {
|
||||||
throw No_ip_packet();
|
throw Bad_data_type();
|
||||||
|
}
|
||||||
|
return (T *)(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,8 +184,6 @@ class Net::Ipv4_packet
|
|||||||
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); }
|
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); }
|
||||||
Ipv4_address src() const { return Ipv4_address((void *)&_src); }
|
Ipv4_address src() const { return Ipv4_address((void *)&_src); }
|
||||||
Ipv4_address dst() const { return Ipv4_address((void *)&_dst); }
|
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); }
|
|
||||||
|
|
||||||
void header_length(Genode::size_t v) { _header_length = v; }
|
void header_length(Genode::size_t v) { _header_length = v; }
|
||||||
void version(Genode::uint8_t v) { _version = v; }
|
void version(Genode::uint8_t v) { _version = v; }
|
||||||
|
@ -70,12 +70,6 @@ class Net::Tcp_packet
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class No_tcp_packet : Exception {};
|
|
||||||
|
|
||||||
static void validate_size(Genode::size_t size) {
|
|
||||||
if (size < sizeof(Tcp_packet)) { throw No_tcp_packet(); } }
|
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
@ -51,15 +51,22 @@ class Net::Udp_packet
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
struct Bad_data_type : Genode::Exception { };
|
||||||
* Exception used to indicate protocol violation.
|
|
||||||
*/
|
|
||||||
class No_udp_packet : Genode::Exception {};
|
|
||||||
|
|
||||||
static void validate_size(Genode::size_t size) {
|
template <typename T> T const *data(Genode::size_t data_size) const
|
||||||
/* Udp header needs to fit in */
|
{
|
||||||
if (size < sizeof(Udp_packet))
|
if (data_size < sizeof(T)) {
|
||||||
throw No_udp_packet();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,8 +78,6 @@ class Net::Udp_packet
|
|||||||
Port dst_port() const { return Port(host_to_big_endian(_dst_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 length() const { return host_to_big_endian(_length); }
|
||||||
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); }
|
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); }
|
|
||||||
|
|
||||||
void length(Genode::uint16_t v) { _length = host_to_big_endian(v); }
|
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); }
|
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(), " ");
|
Genode::print(output, "\033[32mETH\033[0m ", src(), " > ", dst(), " ");
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case Ethernet_frame::Type::ARP:
|
case Ethernet_frame::Type::ARP:
|
||||||
Genode::print(output,
|
Genode::print(output, *reinterpret_cast<Arp_packet const *>(_data));
|
||||||
*reinterpret_cast<Arp_packet const *>(data<void>()));
|
|
||||||
break;
|
break;
|
||||||
case Ethernet_frame::Type::IPV4:
|
case Ethernet_frame::Type::IPV4:
|
||||||
Genode::print(output,
|
Genode::print(output, *reinterpret_cast<Ipv4_packet const *>(_data));
|
||||||
*reinterpret_cast<Ipv4_packet const *>(data<void>()));
|
|
||||||
break;
|
break;
|
||||||
default: ; }
|
default: ; }
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,10 @@ void Net::Ipv4_packet::print(Genode::Output &output) const
|
|||||||
Genode::print(output, "\033[32mIPV4\033[0m ", src(), " > ", dst(), " ");
|
Genode::print(output, "\033[32mIPV4\033[0m ", src(), " > ", dst(), " ");
|
||||||
switch (protocol()) {
|
switch (protocol()) {
|
||||||
case Protocol::TCP:
|
case Protocol::TCP:
|
||||||
Genode::print(output,
|
Genode::print(output, *reinterpret_cast<Tcp_packet const *>(_data));
|
||||||
*reinterpret_cast<Tcp_packet const *>(data<void>()));
|
|
||||||
break;
|
break;
|
||||||
case Protocol::UDP:
|
case Protocol::UDP:
|
||||||
Genode::print(output,
|
Genode::print(output, *reinterpret_cast<Udp_packet const *>(_data));
|
||||||
*reinterpret_cast<Udp_packet const *>(data<void>()));
|
|
||||||
break;
|
break;
|
||||||
default: ; }
|
default: ; }
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ void Net::Udp_packet::print(Genode::Output &output) const
|
|||||||
Genode::print(output, "\033[32mUDP\033[0m ", src_port(),
|
Genode::print(output, "\033[32mUDP\033[0m ", src_port(),
|
||||||
" > ", dst_port(), " ");
|
" > ", dst_port(), " ");
|
||||||
if (Dhcp_packet::is_dhcp(this)) {
|
if (Dhcp_packet::is_dhcp(this)) {
|
||||||
Genode::print(output,
|
Genode::print(output, *reinterpret_cast<Dhcp_packet const *>(_data));
|
||||||
*reinterpret_cast<Dhcp_packet const *>(data<void>()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,7 @@ using namespace Net;
|
|||||||
|
|
||||||
bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
|
bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
|
||||||
{
|
{
|
||||||
Arp_packet *arp = eth->data<Arp_packet>();
|
Arp_packet *arp = eth->data<Arp_packet>(size - sizeof(Ethernet_frame));
|
||||||
Arp_packet::validate_size(size - sizeof(Ethernet_frame));
|
|
||||||
if (arp->ethernet_ipv4() &&
|
if (arp->ethernet_ipv4() &&
|
||||||
arp->opcode() == Arp_packet::REQUEST) {
|
arp->opcode() == Arp_packet::REQUEST) {
|
||||||
|
|
||||||
@ -51,17 +50,14 @@ bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
|
|||||||
|
|
||||||
bool Session_component::handle_ip(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 *ip = eth->data<Ipv4_packet>(size - sizeof(Ethernet_frame));
|
||||||
Ipv4_packet::validate_size(size - sizeof(Ethernet_frame));
|
|
||||||
|
|
||||||
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
||||||
{
|
{
|
||||||
Udp_packet *udp = ip->data<Udp_packet>();
|
Udp_packet *udp = ip->data<Udp_packet>(size - sizeof(Ethernet_frame)
|
||||||
Udp_packet::validate_size(size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet));
|
- sizeof(Ipv4_packet));
|
||||||
if (Dhcp_packet::is_dhcp(udp)) {
|
if (Dhcp_packet::is_dhcp(udp)) {
|
||||||
Dhcp_packet *dhcp = udp->data<Dhcp_packet>();
|
Dhcp_packet *dhcp = udp->data<Dhcp_packet>(size - sizeof(Ethernet_frame)
|
||||||
Dhcp_packet::validate_size(size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet)
|
- sizeof(Ipv4_packet)
|
||||||
- sizeof(Udp_packet));
|
- sizeof(Udp_packet));
|
||||||
if (dhcp->op() == Dhcp_packet::REQUEST) {
|
if (dhcp->op() == Dhcp_packet::REQUEST) {
|
||||||
|
@ -24,8 +24,7 @@ using namespace Net;
|
|||||||
|
|
||||||
|
|
||||||
bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
|
bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
|
||||||
Arp_packet *arp = eth->data<Arp_packet>();
|
Arp_packet *arp = eth->data<Arp_packet>(size - sizeof(Ethernet_frame));
|
||||||
Arp_packet::validate_size(size - sizeof(Ethernet_frame));
|
|
||||||
|
|
||||||
/* ignore broken packets */
|
/* ignore broken packets */
|
||||||
if (!arp->ethernet_ipv4())
|
if (!arp->ethernet_ipv4())
|
||||||
@ -66,20 +65,17 @@ bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
|
|||||||
|
|
||||||
|
|
||||||
bool Net::Nic::handle_ip(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 *ip = eth->data<Ipv4_packet>(size - sizeof(Ethernet_frame));
|
||||||
Ipv4_packet::validate_size(size - sizeof(Ethernet_frame));
|
|
||||||
|
|
||||||
/* is it an UDP packet ? */
|
/* is it an UDP packet ? */
|
||||||
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
if (ip->protocol() == Ipv4_packet::Protocol::UDP)
|
||||||
{
|
{
|
||||||
Udp_packet *udp = ip->data<Udp_packet>();
|
Udp_packet *udp = ip->data<Udp_packet>(size - sizeof(Ethernet_frame)
|
||||||
Udp_packet::validate_size(size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet));
|
- sizeof(Ipv4_packet));
|
||||||
|
|
||||||
/* is it a DHCP packet ? */
|
/* is it a DHCP packet ? */
|
||||||
if (Dhcp_packet::is_dhcp(udp)) {
|
if (Dhcp_packet::is_dhcp(udp)) {
|
||||||
Dhcp_packet *dhcp = udp->data<Dhcp_packet>();
|
Dhcp_packet *dhcp = udp->data<Dhcp_packet>(size - sizeof(Ethernet_frame)
|
||||||
Dhcp_packet::validate_size(size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet)
|
- sizeof(Ipv4_packet)
|
||||||
- sizeof(Udp_packet));
|
- sizeof(Udp_packet));
|
||||||
|
|
||||||
|
@ -80,7 +80,6 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size)
|
|||||||
try {
|
try {
|
||||||
/* parse ethernet frame header */
|
/* parse ethernet frame header */
|
||||||
Ethernet_frame *eth = reinterpret_cast<Ethernet_frame *>(src);
|
Ethernet_frame *eth = reinterpret_cast<Ethernet_frame *>(src);
|
||||||
Ethernet_frame::validate_size(size);
|
|
||||||
switch (eth->type()) {
|
switch (eth->type()) {
|
||||||
case Ethernet_frame::Type::ARP:
|
case Ethernet_frame::Type::ARP:
|
||||||
if (!handle_arp(eth, size)) return;
|
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);
|
broadcast_to_clients(eth, size);
|
||||||
finalize_packet(eth, size);
|
finalize_packet(eth, size);
|
||||||
} catch(Arp_packet::No_arp_packet) {
|
} catch(Ethernet_frame::Bad_data_type) {
|
||||||
Genode::warning("Invalid ARP packet!");
|
Genode::warning("Invalid Ethernet frame!");
|
||||||
} catch(Ethernet_frame::No_ethernet_frame) {
|
} catch(Ipv4_packet::Bad_data_type) {
|
||||||
Genode::warning("Invalid ethernet frame");
|
|
||||||
} catch(Dhcp_packet::No_dhcp_packet) {
|
|
||||||
Genode::warning("Invalid IPv4 packet!");
|
Genode::warning("Invalid IPv4 packet!");
|
||||||
} catch(Ipv4_packet::No_ip_packet) {
|
} catch(Udp_packet::Bad_data_type) {
|
||||||
Genode::warning("Invalid IPv4 packet!");
|
|
||||||
} catch(Udp_packet::No_udp_packet) {
|
|
||||||
Genode::warning("Invalid UDP packet!");
|
Genode::warning("Invalid UDP packet!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ void Net::Interface::_handle_eth(void *const eth_base,
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Ethernet_frame ð = *reinterpret_cast<Ethernet_frame *>(eth_base);
|
Ethernet_frame ð = *reinterpret_cast<Ethernet_frame *>(eth_base);
|
||||||
Ethernet_frame::validate_size(eth_size);
|
|
||||||
Interface &remote = _remote.deref();
|
Interface &remote = _remote.deref();
|
||||||
Packet_log_config log_cfg;
|
Packet_log_config log_cfg;
|
||||||
|
|
||||||
@ -47,9 +46,6 @@ void Net::Interface::_handle_eth(void *const eth_base,
|
|||||||
}
|
}
|
||||||
remote._send(eth, eth_size);
|
remote._send(eth, eth_size);
|
||||||
}
|
}
|
||||||
catch (Ethernet_frame::No_ethernet_frame) {
|
|
||||||
error("invalid ethernet frame"); }
|
|
||||||
|
|
||||||
catch (Pointer<Interface>::Invalid) {
|
catch (Pointer<Interface>::Invalid) {
|
||||||
error("no remote interface set"); }
|
error("no remote interface set"); }
|
||||||
}
|
}
|
||||||
|
@ -157,12 +157,12 @@ void Packet_log<Ethernet_frame>::print(Output &output) const
|
|||||||
switch (_pkt.type()) {
|
switch (_pkt.type()) {
|
||||||
case Ethernet_frame::Type::ARP:
|
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;
|
break;
|
||||||
|
|
||||||
case Ethernet_frame::Type::IPV4:
|
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;
|
break;
|
||||||
|
|
||||||
default: ;
|
default: ;
|
||||||
@ -212,12 +212,12 @@ void Packet_log<Ipv4_packet>::print(Output &output) const
|
|||||||
switch (_pkt.protocol()) {
|
switch (_pkt.protocol()) {
|
||||||
case Ipv4_packet::Protocol::TCP:
|
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;
|
break;
|
||||||
|
|
||||||
case Ipv4_packet::Protocol::UDP:
|
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;
|
break;
|
||||||
|
|
||||||
default: ; }
|
default: ; }
|
||||||
@ -292,6 +292,6 @@ void Packet_log<Udp_packet>::print(Output &output) const
|
|||||||
}
|
}
|
||||||
/* print encapsulated packet */
|
/* print encapsulated packet */
|
||||||
if (Dhcp_packet::is_dhcp(&_pkt)) {
|
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,21 +93,18 @@ void Dhcp_client::handle_ip(Ethernet_frame ð, size_t eth_size)
|
|||||||
{
|
{
|
||||||
throw Drop_packet_inform("DHCP client expects Ethernet targeting the router");
|
throw Drop_packet_inform("DHCP client expects Ethernet targeting the router");
|
||||||
}
|
}
|
||||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
Ipv4_packet &ip = *eth.data<Ipv4_packet>(eth_size - sizeof(Ethernet_frame));
|
||||||
Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame));
|
|
||||||
|
|
||||||
if (ip.protocol() != Ipv4_packet::Protocol::UDP) {
|
if (ip.protocol() != Ipv4_packet::Protocol::UDP) {
|
||||||
throw Drop_packet_inform("DHCP client expects UDP packet");
|
throw Drop_packet_inform("DHCP client expects UDP packet");
|
||||||
}
|
}
|
||||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
Udp_packet &udp = *ip.data<Udp_packet>(eth_size - sizeof(Ethernet_frame)
|
||||||
Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet));
|
- sizeof(Ipv4_packet));
|
||||||
|
|
||||||
if (!Dhcp_packet::is_dhcp(&udp)) {
|
if (!Dhcp_packet::is_dhcp(&udp)) {
|
||||||
throw Drop_packet_inform("DHCP client expects DHCP packet");
|
throw Drop_packet_inform("DHCP client expects DHCP packet");
|
||||||
}
|
}
|
||||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(eth_size - sizeof(Ethernet_frame)
|
||||||
Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet)
|
- sizeof(Ipv4_packet)
|
||||||
- sizeof(Udp_packet));
|
- sizeof(Udp_packet));
|
||||||
|
|
||||||
@ -187,8 +184,8 @@ void Dhcp_client::_send(Message_type msg_type,
|
|||||||
/* create IP header of the request */
|
/* create IP header of the request */
|
||||||
enum { IPV4_TIME_TO_LIVE = 64 };
|
enum { IPV4_TIME_TO_LIVE = 64 };
|
||||||
size_t const ip_off = size.curr();
|
size_t const ip_off = size.curr();
|
||||||
|
Ipv4_packet &ip = *eth.data<Ipv4_packet>(size.left());
|
||||||
size.add(sizeof(Ipv4_packet));
|
size.add(sizeof(Ipv4_packet));
|
||||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
|
||||||
ip.header_length(sizeof(Ipv4_packet) / 4);
|
ip.header_length(sizeof(Ipv4_packet) / 4);
|
||||||
ip.version(4);
|
ip.version(4);
|
||||||
ip.diff_service(0);
|
ip.diff_service(0);
|
||||||
@ -202,15 +199,15 @@ void Dhcp_client::_send(Message_type msg_type,
|
|||||||
|
|
||||||
/* create UDP header of the request */
|
/* create UDP header of the request */
|
||||||
size_t const udp_off = size.curr();
|
size_t const udp_off = size.curr();
|
||||||
|
Udp_packet &udp = *ip.data<Udp_packet>(size.left());
|
||||||
size.add(sizeof(Udp_packet));
|
size.add(sizeof(Udp_packet));
|
||||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
|
||||||
udp.src_port(Port(Dhcp_packet::BOOTPC));
|
udp.src_port(Port(Dhcp_packet::BOOTPC));
|
||||||
udp.dst_port(Port(Dhcp_packet::BOOTPS));
|
udp.dst_port(Port(Dhcp_packet::BOOTPS));
|
||||||
|
|
||||||
/* create mandatory DHCP fields of the request */
|
/* create mandatory DHCP fields of the request */
|
||||||
size_t const dhcp_off = size.curr();
|
size_t const dhcp_off = size.curr();
|
||||||
|
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(size.left());
|
||||||
size.add(sizeof(Dhcp_packet));
|
size.add(sizeof(Dhcp_packet));
|
||||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
|
||||||
dhcp.op(Dhcp_packet::REQUEST);
|
dhcp.op(Dhcp_packet::REQUEST);
|
||||||
dhcp.htype(Dhcp_packet::Htype::ETH);
|
dhcp.htype(Dhcp_packet::Htype::ETH);
|
||||||
dhcp.hlen(sizeof(Mac_address));
|
dhcp.hlen(sizeof(Mac_address));
|
||||||
|
@ -143,12 +143,8 @@ static void *_prot_base(L3_protocol const prot,
|
|||||||
Ipv4_packet &ip)
|
Ipv4_packet &ip)
|
||||||
{
|
{
|
||||||
switch (prot) {
|
switch (prot) {
|
||||||
case L3_protocol::TCP:
|
case L3_protocol::TCP: return ip.data<Tcp_packet>(prot_size);
|
||||||
Tcp_packet::validate_size(prot_size);
|
case L3_protocol::UDP: return ip.data<Udp_packet>(prot_size);
|
||||||
return ip.data<Tcp_packet>();
|
|
||||||
case L3_protocol::UDP:
|
|
||||||
Udp_packet::validate_size(prot_size);
|
|
||||||
return ip.data<Udp_packet>();
|
|
||||||
default: throw Interface::Bad_transport_protocol(); }
|
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 */
|
/* create IP header of the reply */
|
||||||
enum { IPV4_TIME_TO_LIVE = 64 };
|
enum { IPV4_TIME_TO_LIVE = 64 };
|
||||||
size_t const ip_off = size.curr();
|
size_t const ip_off = size.curr();
|
||||||
|
Ipv4_packet &ip = *eth.data<Ipv4_packet>(size.left());
|
||||||
size.add(sizeof(Ipv4_packet));
|
size.add(sizeof(Ipv4_packet));
|
||||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
|
||||||
ip.header_length(sizeof(Ipv4_packet) / 4);
|
ip.header_length(sizeof(Ipv4_packet) / 4);
|
||||||
ip.version(4);
|
ip.version(4);
|
||||||
ip.diff_service(0);
|
ip.diff_service(0);
|
||||||
@ -330,14 +326,14 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv,
|
|||||||
|
|
||||||
/* create UDP header of the reply */
|
/* create UDP header of the reply */
|
||||||
size_t const udp_off = size.curr();
|
size_t const udp_off = size.curr();
|
||||||
|
Udp_packet &udp = *ip.data<Udp_packet>(size.left());
|
||||||
size.add(sizeof(Udp_packet));
|
size.add(sizeof(Udp_packet));
|
||||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
|
||||||
udp.src_port(Port(Dhcp_packet::BOOTPS));
|
udp.src_port(Port(Dhcp_packet::BOOTPS));
|
||||||
udp.dst_port(Port(Dhcp_packet::BOOTPC));
|
udp.dst_port(Port(Dhcp_packet::BOOTPC));
|
||||||
|
|
||||||
/* create mandatory DHCP fields of the reply */
|
/* create mandatory DHCP fields of the reply */
|
||||||
|
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(size.left());
|
||||||
size.add(sizeof(Dhcp_packet));
|
size.add(sizeof(Dhcp_packet));
|
||||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
|
||||||
dhcp.op(Dhcp_packet::REPLY);
|
dhcp.op(Dhcp_packet::REPLY);
|
||||||
dhcp.htype(Dhcp_packet::Htype::ETH);
|
dhcp.htype(Dhcp_packet::Htype::ETH);
|
||||||
dhcp.hlen(sizeof(Mac_address));
|
dhcp.hlen(sizeof(Mac_address));
|
||||||
@ -538,8 +534,7 @@ void Interface::_handle_ip(Ethernet_frame ð,
|
|||||||
Packet_descriptor const &pkt)
|
Packet_descriptor const &pkt)
|
||||||
{
|
{
|
||||||
/* read packet information */
|
/* read packet information */
|
||||||
Ipv4_packet &ip = *eth.data<Ipv4_packet>();
|
Ipv4_packet &ip = *eth.data<Ipv4_packet>(eth_size - sizeof(Ethernet_frame));
|
||||||
Ipv4_packet::validate_size(eth_size - sizeof(Ethernet_frame));
|
|
||||||
|
|
||||||
/* try handling subnet-local IP packets */
|
/* try handling subnet-local IP packets */
|
||||||
if (_ip_config().interface.prefix_matches(ip.dst()) &&
|
if (_ip_config().interface.prefix_matches(ip.dst()) &&
|
||||||
@ -561,16 +556,12 @@ void Interface::_handle_ip(Ethernet_frame ð,
|
|||||||
|
|
||||||
/* try handling DHCP requests before trying any routing */
|
/* try handling DHCP requests before trying any routing */
|
||||||
if (prot == L3_protocol::UDP) {
|
if (prot == L3_protocol::UDP) {
|
||||||
Udp_packet &udp = *ip.data<Udp_packet>();
|
Udp_packet &udp = *ip.data<Udp_packet>(eth_size - sizeof(Ipv4_packet));
|
||||||
Udp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet));
|
|
||||||
|
|
||||||
if (Dhcp_packet::is_dhcp(&udp)) {
|
if (Dhcp_packet::is_dhcp(&udp)) {
|
||||||
|
|
||||||
/* get DHCP packet */
|
/* get DHCP packet */
|
||||||
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>();
|
Dhcp_packet &dhcp = *udp.data<Dhcp_packet>(eth_size - sizeof(Ipv4_packet)
|
||||||
Dhcp_packet::validate_size(eth_size - sizeof(Ethernet_frame)
|
|
||||||
- sizeof(Ipv4_packet)
|
|
||||||
- sizeof(Udp_packet));
|
- sizeof(Udp_packet));
|
||||||
|
|
||||||
if (dhcp.op() == Dhcp_packet::REQUEST) {
|
if (dhcp.op() == Dhcp_packet::REQUEST) {
|
||||||
@ -696,7 +687,7 @@ void Interface::_broadcast_arp_request(Ipv4_address const &ip)
|
|||||||
eth.type(Ethernet_frame::Type::ARP);
|
eth.type(Ethernet_frame::Type::ARP);
|
||||||
|
|
||||||
/* write ARP header */
|
/* 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.hardware_address_type(Arp_packet::ETHERNET);
|
||||||
arp.protocol_address_type(Arp_packet::IPV4);
|
arp.protocol_address_type(Arp_packet::IPV4);
|
||||||
arp.hardware_address_size(sizeof(Mac_address));
|
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)
|
void Interface::_handle_arp(Ethernet_frame ð, size_t const eth_size)
|
||||||
{
|
{
|
||||||
/* ignore ARP regarding protocols other than IPv4 via ethernet */
|
/* 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>(eth_size - sizeof(Ethernet_frame));
|
||||||
Arp_packet &arp = *eth.data<Arp_packet>();
|
|
||||||
Arp_packet::validate_size(arp_size);
|
|
||||||
if (!arp.ethernet_ipv4()) {
|
if (!arp.ethernet_ipv4()) {
|
||||||
error("ARP for unknown protocol"); }
|
error("ARP for unknown protocol"); }
|
||||||
|
|
||||||
@ -890,7 +879,6 @@ void Interface::_handle_eth(void *const eth_base,
|
|||||||
/* inspect and handle ethernet frame */
|
/* inspect and handle ethernet frame */
|
||||||
try {
|
try {
|
||||||
Ethernet_frame *const eth = reinterpret_cast<Ethernet_frame *>(eth_base);
|
Ethernet_frame *const eth = reinterpret_cast<Ethernet_frame *>(eth_base);
|
||||||
Ethernet_frame::validate_size(eth_size);
|
|
||||||
if (_config().verbose()) {
|
if (_config().verbose()) {
|
||||||
log("(router <- ", _domain, ") ", *eth); }
|
log("(router <- ", _domain, ") ", *eth); }
|
||||||
|
|
||||||
@ -908,12 +896,9 @@ void Interface::_handle_eth(void *const eth_base,
|
|||||||
default: throw Bad_network_protocol(); }
|
default: throw Bad_network_protocol(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Ethernet_frame::No_ethernet_frame) { warning("malformed Ethernet frame"); }
|
catch (Ethernet_frame::Bad_data_type) { warning("malformed Ethernet frame"); }
|
||||||
catch (Ipv4_packet::No_ip_packet) { warning("malformed IPv4 packet" ); }
|
catch (Ipv4_packet::Bad_data_type) { warning("malformed IPv4 packet" ); }
|
||||||
catch (Tcp_packet::No_tcp_packet) { warning("malformed TCP packet" ); }
|
catch (Udp_packet::Bad_data_type) { warning("malformed UDP 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 (Bad_network_protocol) {
|
catch (Bad_network_protocol) {
|
||||||
if (_config().verbose()) {
|
if (_config().verbose()) {
|
||||||
|
@ -40,6 +40,7 @@ class Genode::Size_guard_tpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t curr() const { return _curr; }
|
size_t curr() const { return _curr; }
|
||||||
|
size_t left() const { return MAX - _curr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SIZE_GUARD_H_ */
|
#endif /* _SIZE_GUARD_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user