diff --git a/repos/os/include/net/dhcp.h b/repos/os/include/net/dhcp.h
index 457df3f0cd..2ab35b9db5 100644
--- a/repos/os/include/net/dhcp.h
+++ b/repos/os/include/net/dhcp.h
@@ -104,10 +104,6 @@ class Net::Dhcp_packet
_magic_cookie = host_to_big_endian(0x63825363);
}
- void zero_fill_sname() { Genode::memset(_sname, 0, sizeof(_sname)); }
-
- void zero_fill_file() { Genode::memset(_file, 0, sizeof(_file)); }
-
/*******************************
** Utilities for the options **
diff --git a/repos/os/include/net/ethernet.h b/repos/os/include/net/ethernet.h
index 69ecf960f0..d2283bebff 100644
--- a/repos/os/include/net/ethernet.h
+++ b/repos/os/include/net/ethernet.h
@@ -17,7 +17,7 @@
/* Genode includes */
#include
#include
-
+#include
#include
#include
@@ -72,20 +72,27 @@ class Net::Ethernet_frame
struct Bad_data_type : Genode::Exception { };
- template T const *data(Genode::size_t data_size) const
+ template T const &data(Genode::size_t data_size) const
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T const *)(_data);
+ return *(T const *)(_data);
}
- template T *data(Genode::size_t data_size)
+ template T &data(Genode::size_t data_size)
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T *)(_data);
+ return *(T *)(_data);
+ }
+
+ template
+ T &construct_at_data(SIZE_GUARD &size_guard)
+ {
+ size_guard.add(sizeof(T));
+ return *Genode::construct_at(_data);
}
diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h
index e623a35fd1..a00bc928d5 100644
--- a/repos/os/include/net/ipv4.h
+++ b/repos/os/include/net/ipv4.h
@@ -18,7 +18,7 @@
#include
#include
#include
-
+#include
#include
#include
@@ -124,20 +124,29 @@ class Net::Ipv4_packet
struct Bad_data_type : Genode::Exception { };
- template T const *data(Genode::size_t data_size) const
+ template
+ T const &data(Genode::size_t data_size) const
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T const *)(_data);
+ return *(T const *)(_data);
}
- template T *data(Genode::size_t data_size)
+ template
+ T &data(Genode::size_t data_size)
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T *)(_data);
+ return *(T *)(_data);
+ }
+
+ template
+ T &construct_at_data(SIZE_GUARD &size_guard)
+ {
+ size_guard.add(sizeof(T));
+ return *Genode::construct_at(_data);
}
diff --git a/repos/os/include/net/udp.h b/repos/os/include/net/udp.h
index e384434646..b7f92dbf84 100644
--- a/repos/os/include/net/udp.h
+++ b/repos/os/include/net/udp.h
@@ -53,20 +53,27 @@ class Net::Udp_packet
struct Bad_data_type : Genode::Exception { };
- template T const *data(Genode::size_t data_size) const
+ template T const &data(Genode::size_t data_size) const
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T const *)(_data);
+ return *(T const *)(_data);
}
- template T *data(Genode::size_t data_size)
+ template T &data(Genode::size_t data_size)
{
if (data_size < sizeof(T)) {
throw Bad_data_type();
}
- return (T *)(_data);
+ return *(T *)(_data);
+ }
+
+ template
+ T &construct_at_data(SIZE_GUARD &size_guard)
+ {
+ size_guard.add(sizeof(T));
+ return *Genode::construct_at(_data);
}
diff --git a/repos/os/src/app/ping/main.cc b/repos/os/src/app/ping/main.cc
index ffe6f219fb..7f2ddc734d 100644
--- a/repos/os/src/app/ping/main.cc
+++ b/repos/os/src/app/ping/main.cc
@@ -200,7 +200,7 @@ void Main::_handle_ip(Ethernet_frame ð,
{
/* drop packet if IP does not target us */
size_t const ip_size = eth_size - sizeof(Ethernet_frame);
- Ipv4_packet &ip = *eth.data(ip_size);
+ Ipv4_packet &ip = eth.data(ip_size);
if (ip.dst() != _src_ip &&
ip.dst() != Ipv4_packet::broadcast())
{
@@ -306,7 +306,7 @@ void Main::_handle_icmp_dst_unreachbl(Ipv4_packet &ip,
}
/* drop packet if embedded ICMP identifier is invalid */
size_t const embed_icmp_sz = embed_ip.total_length() - sizeof(Ipv4_packet);
- Icmp_packet &embed_icmp = *embed_ip.data(embed_icmp_sz);
+ Icmp_packet &embed_icmp = embed_ip.data(embed_icmp_sz);
if (embed_icmp.query_id() != ICMP_ID) {
if (_verbose) {
log("bad ICMP identifier in payload of ICMP error"); }
@@ -328,7 +328,7 @@ void Main::_handle_icmp(Ipv4_packet &ip,
{
/* drop packet if ICMP checksum is invalid */
size_t const icmp_sz = ip_size - sizeof(Ipv4_packet);
- Icmp_packet &icmp = *ip.data(icmp_sz);
+ Icmp_packet &icmp = ip.data(icmp_sz);
size_t const icmp_data_sz = icmp_sz - sizeof(Icmp_packet);
if (icmp.calc_checksum(icmp_data_sz) != icmp.checksum()) {
if (_verbose) {
@@ -351,7 +351,7 @@ void Main::_handle_arp(Ethernet_frame ð,
size_t const eth_size)
{
/* check ARP protocol- and hardware address type */
- Arp_packet &arp = *eth.data(eth_size - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth.data(eth_size - sizeof(Ethernet_frame));
if (!arp.ethernet_ipv4()) {
error("ARP for unknown protocol"); }
@@ -409,24 +409,19 @@ void Main::_ready_to_ack()
void Main::_send_arp_reply(Ethernet_frame &req_eth,
Arp_packet &req_arp)
{
- enum {
- ETH_HDR_SZ = sizeof(Ethernet_frame),
- ETH_DAT_SZ = sizeof(Arp_packet) + ETH_HDR_SZ >= Ethernet_frame::MIN_SIZE ?
- sizeof(Arp_packet) :
- Ethernet_frame::MIN_SIZE - ETH_HDR_SZ,
- ETH_CRC_SZ = sizeof(uint32_t),
- PKT_SIZE = ETH_HDR_SZ + ETH_DAT_SZ + ETH_CRC_SZ,
- };
- _send(PKT_SIZE, [&] (void *pkt_base) {
+ size_t const buf_sz = sizeof(Ethernet_frame) + sizeof(Arp_packet);
+ _send(buf_sz, [&] (void *pkt_base) {
/* write Ethernet header */
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Size_guard size(buf_sz);
+ size.add(sizeof(Ethernet_frame));
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(req_eth.src());
eth.src(_src_mac);
eth.type(Ethernet_frame::Type::ARP);
/* write ARP header */
- Arp_packet &arp = *eth.data(PKT_SIZE - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth.construct_at_data(size);
arp.hardware_address_type(Arp_packet::ETHERNET);
arp.protocol_address_type(Arp_packet::IPV4);
arp.hardware_address_size(sizeof(Mac_address));
@@ -442,24 +437,19 @@ void Main::_send_arp_reply(Ethernet_frame &req_eth,
void Main::_broadcast_arp_request()
{
- enum {
- ETH_HDR_SZ = sizeof(Ethernet_frame),
- ETH_DAT_SZ = sizeof(Arp_packet) + ETH_HDR_SZ >= Ethernet_frame::MIN_SIZE ?
- sizeof(Arp_packet) :
- Ethernet_frame::MIN_SIZE - ETH_HDR_SZ,
- ETH_CRC_SZ = sizeof(uint32_t),
- PKT_SIZE = ETH_HDR_SZ + ETH_DAT_SZ + ETH_CRC_SZ,
- };
- _send(PKT_SIZE, [&] (void *pkt_base) {
+ size_t const buf_sz = sizeof(Ethernet_frame) + sizeof(Arp_packet);
+ _send(buf_sz, [&] (void *pkt_base) {
/* write Ethernet header */
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Size_guard size(buf_sz);
+ size.add(sizeof(Ethernet_frame));
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(Mac_address(0xff));
eth.src(_src_mac);
eth.type(Ethernet_frame::Type::ARP);
/* write ARP header */
- Arp_packet &arp = *eth.data(PKT_SIZE - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth.construct_at_data(size);
arp.hardware_address_type(Arp_packet::ETHERNET);
arp.protocol_address_type(Arp_packet::IPV4);
arp.hardware_address_size(sizeof(Mac_address));
@@ -487,36 +477,30 @@ void Main::_send_ping(Duration)
/* create ETH header */
Size_guard size(buf_sz);
size.add(sizeof(Ethernet_frame));
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(_dst_mac);
eth.src(_src_mac);
eth.type(Ethernet_frame::Type::IPV4);
/* create IP header */
size_t const ip_off = size.curr();
- Ipv4_packet &ip = *eth.data(size.left());
- size.add(sizeof(Ipv4_packet));
+ Ipv4_packet &ip = eth.construct_at_data(size);
ip.header_length(sizeof(Ipv4_packet) / 4);
ip.version(4);
- ip.diff_service(0);
- ip.ecn(0);
- ip.identification(0);
- ip.flags(0);
- ip.fragment_offset(0);
ip.time_to_live(IPV4_TIME_TO_LIVE);
ip.protocol(Ipv4_packet::Protocol::ICMP);
ip.src(_src_ip);
ip.dst(_dst_ip);
/* create ICMP header */
- Icmp_packet &icmp = *ip.data(size.left());
- size.add(sizeof(Icmp_packet) + _icmp_data_sz);
+ Icmp_packet &icmp = ip.construct_at_data(size);
icmp.type(Icmp_packet::Type::ECHO_REQUEST);
icmp.code(Icmp_packet::Code::ECHO_REQUEST);
icmp.query_id(ICMP_ID);
icmp.query_seq(_icmp_seq);
- /* fill ICMP data with characters from 'a' to 'w' */
+ /* fill ICMP data with characters from 'a' to 'z' */
+ size.add(_icmp_data_sz);
struct Data { char chr[0]; };
Data &data = icmp.data(_icmp_data_sz);
char chr = 'a';
diff --git a/repos/os/src/server/nic_bridge/component.cc b/repos/os/src/server/nic_bridge/component.cc
index 86dbbf7afd..f637d030f4 100644
--- a/repos/os/src/server/nic_bridge/component.cc
+++ b/repos/os/src/server/nic_bridge/component.cc
@@ -22,9 +22,9 @@ using namespace Net;
bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
{
- Arp_packet *arp = eth->data(size - sizeof(Ethernet_frame));
- if (arp->ethernet_ipv4() &&
- arp->opcode() == Arp_packet::REQUEST) {
+ Arp_packet &arp = eth->data(size - sizeof(Ethernet_frame));
+ if (arp.ethernet_ipv4() &&
+ arp.opcode() == Arp_packet::REQUEST) {
/*
* 'Gratuitous ARP' broadcast messages are used to announce newly created
@@ -34,14 +34,14 @@ bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
* The simplest solution to this problem is to just drop those messages,
* since they are not really necessary.
*/
- if (arp->src_ip() == arp->dst_ip())
+ if (arp.src_ip() == arp.dst_ip())
return false;
Ipv4_address_node *node = vlan().ip_tree.first();
if (node)
- node = node->find_by_address(arp->dst_ip());
+ node = node->find_by_address(arp.dst_ip());
if (!node) {
- arp->src_mac(_nic.mac());
+ arp.src_mac(_nic.mac());
}
}
return true;
@@ -50,19 +50,19 @@ 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(size - sizeof(Ethernet_frame));
+ Ipv4_packet &ip = eth->data(size - sizeof(Ethernet_frame));
- if (ip->protocol() == Ipv4_packet::Protocol::UDP)
+ if (ip.protocol() == Ipv4_packet::Protocol::UDP)
{
- Udp_packet *udp = ip->data(size - sizeof(Ethernet_frame)
- - sizeof(Ipv4_packet));
- if (Dhcp_packet::is_dhcp(udp)) {
- 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());
+ Udp_packet &udp = ip.data(size - sizeof(Ethernet_frame)
+ - sizeof(Ipv4_packet));
+ if (Dhcp_packet::is_dhcp(&udp)) {
+ 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 8626d1ec4a..d5e8528a3c 100644
--- a/repos/os/src/server/nic_bridge/nic.cc
+++ b/repos/os/src/server/nic_bridge/nic.cc
@@ -24,37 +24,37 @@ using namespace Net;
bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
- Arp_packet *arp = eth->data(size - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth->data(size - sizeof(Ethernet_frame));
/* ignore broken packets */
- if (!arp->ethernet_ipv4())
+ if (!arp.ethernet_ipv4())
return true;
/* look whether the IP address is one of our client's */
Ipv4_address_node *node = vlan().ip_tree.first();
if (node)
- node = node->find_by_address(arp->dst_ip());
+ node = node->find_by_address(arp.dst_ip());
if (node) {
- if (arp->opcode() == Arp_packet::REQUEST) {
+ if (arp.opcode() == Arp_packet::REQUEST) {
/*
* The ARP packet gets re-written, we interchange source
* and destination MAC and IP addresses, and set the opcode
* to reply, and then push the packet back to the NIC driver.
*/
- Ipv4_address old_src_ip = arp->src_ip();
- arp->opcode(Arp_packet::REPLY);
- arp->dst_mac(arp->src_mac());
- arp->src_mac(mac());
- arp->src_ip(arp->dst_ip());
- arp->dst_ip(old_src_ip);
- eth->dst(arp->dst_mac());
+ Ipv4_address old_src_ip = arp.src_ip();
+ arp.opcode(Arp_packet::REPLY);
+ arp.dst_mac(arp.src_mac());
+ arp.src_mac(mac());
+ arp.src_ip(arp.dst_ip());
+ arp.dst_ip(old_src_ip);
+ eth->dst(arp.dst_mac());
/* set our MAC as sender */
eth->src(mac());
send(eth, size);
} else {
/* overwrite destination MAC */
- arp->dst_mac(node->component().mac_address().addr);
+ arp.dst_mac(node->component().mac_address().addr);
eth->dst(node->component().mac_address().addr);
node->component().send(eth, size);
}
@@ -65,26 +65,26 @@ 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(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)
+ if (ip.protocol() == Ipv4_packet::Protocol::UDP)
{
- Udp_packet *udp = ip->data(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(size - sizeof(Ethernet_frame)
- - sizeof(Ipv4_packet)
- - sizeof(Udp_packet));
+ if (Dhcp_packet::is_dhcp(&udp)) {
+ 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) {
+ if (dhcp.op() == Dhcp_packet::REPLY) {
try {
Dhcp_packet::Message_type const msg_type =
- dhcp->option().value();
+ dhcp.option().value();
/*
* Extract the IP address and set it in the client's
@@ -94,9 +94,9 @@ bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) {
Mac_address_node *node =
vlan().mac_tree.first();
if (node)
- node = node->find_by_address(dhcp->client_mac());
+ node = node->find_by_address(dhcp.client_mac());
if (node)
- node->component().set_ipv4_address(dhcp->yiaddr());
+ node->component().set_ipv4_address(dhcp.yiaddr());
}
}
catch (Dhcp_packet::Option_not_found) { }
@@ -108,7 +108,7 @@ bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) {
if (eth->dst() == mac()) {
Ipv4_address_node *node = vlan().ip_tree.first();
if (node) {
- node = node->find_by_address(ip->dst());
+ node = node->find_by_address(ip.dst());
if (node) {
/* overwrite destination MAC */
eth->dst(node->component().mac_address().addr);
diff --git a/repos/os/src/server/nic_dump/packet_log.cc b/repos/os/src/server/nic_dump/packet_log.cc
index 394ff89643..a10c0ada09 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(~0UL), _cfg));
+ print(output, " ", packet_log(_pkt.data(~0UL), _cfg));
break;
case Ethernet_frame::Type::IPV4:
- print(output, " ", packet_log(*_pkt.data(~0UL), _cfg));
+ print(output, " ", packet_log(_pkt.data(~0UL), _cfg));
break;
default: ;
@@ -212,17 +212,17 @@ void Packet_log::print(Output &output) const
switch (_pkt.protocol()) {
case Ipv4_packet::Protocol::TCP:
- print(output, " ", packet_log(*_pkt.data(~0UL), _cfg));
+ print(output, " ", packet_log(_pkt.data(~0UL), _cfg));
break;
case Ipv4_packet::Protocol::UDP:
- print(output, " ", packet_log(*_pkt.data(~0UL), _cfg));
+ print(output, " ", packet_log(_pkt.data(~0UL), _cfg));
break;
case Ipv4_packet::Protocol::ICMP:
- print(output, " ", packet_log(*_pkt.data(~0UL), _cfg));
+ print(output, " ", packet_log(_pkt.data(~0UL), _cfg));
break;
default: ; }
@@ -297,7 +297,7 @@ void Packet_log::print(Output &output) const
}
/* print encapsulated packet */
if (Dhcp_packet::is_dhcp(&_pkt)) {
- print(output, " ", packet_log(*_pkt.data(~0UL), _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 8a6c020365..33ec8c3434 100644
--- a/repos/os/src/server/nic_router/dhcp_client.cc
+++ b/repos/os/src/server/nic_router/dhcp_client.cc
@@ -119,20 +119,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(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(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(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");
@@ -206,7 +206,7 @@ void Dhcp_client::_send(Message_type msg_type,
/* create ETH header of the request */
Size_guard size;
size.add(sizeof(Ethernet_frame));
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(Mac_address(0xff));
eth.src(client_mac);
eth.type(Ethernet_frame::Type::IPV4);
@@ -214,15 +214,9 @@ 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.construct_at_data(size);
ip.header_length(sizeof(Ipv4_packet) / 4);
ip.version(4);
- ip.diff_service(0);
- ip.ecn(0);
- ip.identification(0);
- ip.flags(0);
- ip.fragment_offset(0);
ip.time_to_live(IPV4_TIME_TO_LIVE);
ip.protocol(Ipv4_packet::Protocol::UDP);
ip.src(client_ip);
@@ -230,29 +224,18 @@ 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.construct_at_data(size);
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.construct_at_data(size);
dhcp.op(Dhcp_packet::REQUEST);
dhcp.htype(Dhcp_packet::Htype::ETH);
dhcp.hlen(sizeof(Mac_address));
- dhcp.hops(0);
- dhcp.xid(0x12345678);
- dhcp.secs(0);
- dhcp.flags(0);
dhcp.ciaddr(client_ip);
- dhcp.yiaddr(Ipv4_address());
- dhcp.siaddr(Ipv4_address());
- dhcp.giaddr(Ipv4_address());
dhcp.client_mac(client_mac);
- dhcp.zero_fill_sname();
- dhcp.zero_fill_file();
dhcp.default_magic_cookie();
/* append DHCP option fields to the request */
diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc
index 3bdb6470fe..c53a07a076 100644
--- a/repos/os/src/server/nic_router/interface.cc
+++ b/repos/os/src/server/nic_router/interface.cc
@@ -30,6 +30,7 @@ using Genode::uint32_t;
using Genode::log;
using Genode::error;
using Genode::warning;
+using Genode::construct_at;
using Genode::Signal_context_capability;
using Genode::Signal_transmitter;
@@ -169,9 +170,9 @@ static void *_prot_base(L3_protocol const prot,
Ipv4_packet &ip)
{
switch (prot) {
- case L3_protocol::TCP: return ip.data(prot_size);
- case L3_protocol::UDP: return ip.data(prot_size);
- case L3_protocol::ICMP: return ip.data(prot_size);
+ case L3_protocol::TCP: return &ip.data(prot_size);
+ case L3_protocol::UDP: return &ip.data(prot_size);
+ case L3_protocol::ICMP: return &ip.data(prot_size);
default: throw Interface::Bad_transport_protocol(); }
}
@@ -464,22 +465,16 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv,
/* create ETH header of the reply */
Size_guard size;
size.add(sizeof(Ethernet_frame));
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(client_mac);
eth.src(_router_mac);
eth.type(Ethernet_frame::Type::IPV4);
/* create IP header of the reply */
size_t const ip_off = size.curr();
- Ipv4_packet &ip = *eth.data(size.left());
- size.add(sizeof(Ipv4_packet));
+ Ipv4_packet &ip = eth.construct_at_data(size);
ip.header_length(sizeof(Ipv4_packet) / 4);
ip.version(4);
- ip.diff_service(0);
- ip.ecn(0);
- ip.identification(0);
- ip.flags(0);
- ip.fragment_offset(0);
ip.time_to_live(IPV4_TIME_TO_LIVE);
ip.protocol(Ipv4_packet::Protocol::UDP);
ip.src(local_intf.address);
@@ -487,28 +482,22 @@ 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.construct_at_data(size);
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.construct_at_data(size);
dhcp.op(Dhcp_packet::REPLY);
dhcp.htype(Dhcp_packet::Htype::ETH);
dhcp.hlen(sizeof(Mac_address));
- dhcp.hops(0);
dhcp.xid(xid);
- dhcp.secs(0);
- dhcp.flags(0);
- dhcp.ciaddr(msg_type == Dhcp_packet::Message_type::INFORM ? client_ip : Ipv4_address());
- dhcp.yiaddr(msg_type == Dhcp_packet::Message_type::INFORM ? Ipv4_address() : client_ip);
+ if (msg_type == Dhcp_packet::Message_type::INFORM) {
+ dhcp.ciaddr(client_ip); }
+ else {
+ dhcp.yiaddr(client_ip); }
dhcp.siaddr(local_intf.address);
- dhcp.giaddr(Ipv4_address());
dhcp.client_mac(client_mac);
- dhcp.zero_fill_sname();
- dhcp.zero_fill_file();
dhcp.default_magic_cookie();
/* append DHCP option fields to the reply */
@@ -716,37 +705,30 @@ void Interface::_send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf
/* create ETH header */
Size_guard size;
size.add(sizeof(Ethernet_frame));
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(req_eth.src());
eth.src(_router_mac);
eth.type(Ethernet_frame::Type::IPV4);
/* create IP header */
size_t const ip_off = size.curr();
- Ipv4_packet &ip = *eth.data(size.left());
- size.add(sizeof(Ipv4_packet));
+ Ipv4_packet &ip = eth.construct_at_data(size);
ip.header_length(sizeof(Ipv4_packet) / 4);
ip.version(4);
- ip.diff_service(0);
- ip.ecn(0);
- ip.identification(0);
- ip.flags(0);
- ip.fragment_offset(0);
ip.time_to_live(IPV4_TIME_TO_LIVE);
ip.protocol(Ipv4_packet::Protocol::ICMP);
ip.src(local_intf.address);
ip.dst(req_ip.src());
/* create ICMP header */
- Icmp_packet &icmp = *ip.data(size.left());
- size.add(sizeof(Icmp_packet));
+ Icmp_packet &icmp = ip.construct_at_data(size);
icmp.type(Icmp_packet::Type::DST_UNREACHABLE);
icmp.code(code);
- icmp.rest_of_header(0);
size_t icmp_data_size = req_ip.total_length();
if (icmp_data_size > ICMP_MAX_DATA_SIZE) {
icmp_data_size = ICMP_MAX_DATA_SIZE;
}
+ /* create ICMP data */
size.add(icmp_data_size);
Genode::memcpy(&icmp.data(~0), &req_ip, icmp_data_size);
@@ -890,7 +872,7 @@ void Interface::_handle_icmp(Ethernet_frame ð,
{
/* drop packet if ICMP checksum is invalid */
size_t const icmp_sz = ip.total_length() - sizeof(Ipv4_packet);
- Icmp_packet &icmp = *ip.data(icmp_sz);
+ Icmp_packet &icmp = ip.data(icmp_sz);
size_t const icmp_data_sz = icmp_sz - sizeof(Icmp_packet);
if (icmp.calc_checksum(icmp_data_sz) != icmp.checksum()) {
throw Drop_packet_inform("bad ICMP checksum");
@@ -910,7 +892,7 @@ void Interface::_handle_ip(Ethernet_frame ð,
Domain &local_domain)
{
/* read packet information */
- Ipv4_packet &ip = *eth.data(eth_size - sizeof(Ethernet_frame));
+ Ipv4_packet &ip = eth.data(eth_size - sizeof(Ethernet_frame));
Ipv4_address_prefix const &local_intf = local_domain.ip_config().interface;
/* try handling subnet-local IP packets */
@@ -933,13 +915,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(eth_size - 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(eth_size - 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 {
@@ -1063,16 +1045,19 @@ void Interface::_broadcast_arp_request(Ipv4_address const &src_ip,
ETH_CRC_SZ = sizeof(Genode::uint32_t),
PKT_SIZE = ETH_HDR_SZ + ETH_DAT_SZ + ETH_CRC_SZ,
};
+ using Size_guard = Genode::Size_guard_tpl;
send(PKT_SIZE, [&] (void *pkt_base) {
/* write Ethernet header */
- Ethernet_frame ð = *reinterpret_cast(pkt_base);
+ Size_guard size;
+ size.add(sizeof(Ethernet_frame));
+ Ethernet_frame ð = *construct_at(pkt_base);
eth.dst(Mac_address(0xff));
eth.src(_router_mac);
eth.type(Ethernet_frame::Type::ARP);
/* write ARP header */
- Arp_packet &arp = *eth.data(PKT_SIZE - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth.construct_at_data(size);
arp.hardware_address_type(Arp_packet::ETHERNET);
arp.protocol_address_type(Arp_packet::IPV4);
arp.hardware_address_size(sizeof(Mac_address));
@@ -1194,7 +1179,7 @@ void Interface::_handle_arp(Ethernet_frame ð,
Domain &local_domain)
{
/* ignore ARP regarding protocols other than IPv4 via ethernet */
- Arp_packet &arp = *eth.data(eth_size - sizeof(Ethernet_frame));
+ Arp_packet &arp = eth.data(eth_size - sizeof(Ethernet_frame));
if (!arp.ethernet_ipv4()) {
error("ARP for unknown protocol"); }
@@ -1306,8 +1291,7 @@ void Interface::_handle_eth(void *const eth_base,
}
catch (Pointer::Invalid) {
if (_config().verbose_packets()) {
- Ethernet_frame *const eth = reinterpret_cast(eth_base);
- log("[?] rcv ", *eth);
+ log("[?] rcv ", *reinterpret_cast(eth_base));
}
if (_config().verbose()) {
log("[?] drop packet: no domain"); }