From bd501404db5285c1588a52af3c4e97f8a3718d93 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 18 May 2022 13:09:35 +0200 Subject: [PATCH] net: add methods required for WireGuard port * Adds methods for copying raw data to the data field of Ethernet frames and UDP packets. This is used in the port to wrap the higher-layer packet data prepared by the contrib code with the additionally required headers before sending it at a network session. * Adds a method to cast raw data to an IPv4 packet. This is required in the port in order to check values in stand-alone IP packets produced by the contrib code before sending them at a network session. * Adds methods for setting UDP ports given big endian port values without having to convert to little endian in the app and then back to big endian in the net lib. Ref #4397 --- repos/os/include/net/ethernet.h | 9 +++++++++ repos/os/include/net/ipv4.h | 10 ++++++++++ repos/os/include/net/udp.h | 17 ++++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/repos/os/include/net/ethernet.h b/repos/os/include/net/ethernet.h index f78afe7bb5..97ca624ecc 100644 --- a/repos/os/include/net/ethernet.h +++ b/repos/os/include/net/ethernet.h @@ -102,6 +102,15 @@ class Net::Ethernet_frame return *Genode::construct_at(_data); } + template + void memcpy_to_data(void const *src_base, + Genode::size_t src_size, + SIZE_GUARD &size_guard) + { + size_guard.consume_head(src_size); + Genode::memcpy(_data, src_base, src_size); + } + static Ethernet_frame &construct_at(void *base, Size_guard &size_guard) { diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h index f2f12dd752..7609bd9b9d 100644 --- a/repos/os/include/net/ipv4.h +++ b/repos/os/include/net/ipv4.h @@ -143,6 +143,13 @@ class Net::Ipv4_packet UDP = 17, }; + static Ipv4_packet const &cast_from(void const *base, + Size_guard &size_guard) + { + size_guard.consume_head(sizeof(Ipv4_packet)); + return *(Ipv4_packet const *)base; + } + template T const &data(Size_guard &size_guard) const { @@ -191,6 +198,7 @@ class Net::Ipv4_packet void version(Genode::uint8_t v) { Offset_0_u8::Version::set(_offset_0_u8, v); } void diff_service(Genode::uint8_t v) { Offset_1_u8::Dscp::set(_offset_1_u8, v); } void ecn(Genode::uint8_t v) { Offset_1_u8::Ecn::set(_offset_1_u8, v); } + void diff_service_ecn(Genode::uint8_t v) { _offset_1_u8 = v; } void total_length(Genode::size_t v) { _total_length = host_to_big_endian((Genode::uint16_t)v); } void identification(Genode::uint16_t v) { _identification = host_to_big_endian(v); } void time_to_live(Genode::uint8_t v) { _time_to_live = v; } @@ -198,6 +206,8 @@ class Net::Ipv4_packet void checksum(Genode::uint16_t checksum) { _checksum = host_to_big_endian(checksum); } void src(Ipv4_address v) { v.copy(&_src); } void dst(Ipv4_address v) { v.copy(&_dst); } + void src_big_endian(Genode::uint32_t v) { *(Genode::uint32_t *)&_src = v; } + void dst_big_endian(Genode::uint32_t v) { *(Genode::uint32_t *)&_dst = v; } void flags(Genode::uint8_t v) { diff --git a/repos/os/include/net/udp.h b/repos/os/include/net/udp.h index 82702c6d71..fc1e50310f 100644 --- a/repos/os/include/net/udp.h +++ b/repos/os/include/net/udp.h @@ -72,6 +72,15 @@ class Net::Udp_packet return *Genode::construct_at(_data); } + template + void memcpy_to_data(void const *src_base, + Genode::size_t src_size, + SIZE_GUARD &size_guard) + { + size_guard.consume_head(src_size); + Genode::memcpy(_data, src_base, src_size); + } + void update_checksum(Ipv4_address ip_src, Ipv4_address ip_dst); @@ -88,9 +97,11 @@ class Net::Udp_packet 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); } - void dst_port(Port p) { _dst_port = host_to_big_endian(p.value); } + 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 dst_port(Port p) { _dst_port = host_to_big_endian(p.value); } + void src_port_big_endian(Genode::uint16_t v) { _src_port = v; } + void dst_port_big_endian(Genode::uint16_t v) { _dst_port = v; } /*********