/* * \brief User datagram protocol. * \author Stefan Kalkowski * \date 2010-08-19 */ /* * Copyright (C) 2010-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ #ifndef _UDP_H_ #define _UDP_H_ /* Genode */ #include #include #include #include #include #include namespace Net { class Udp_packet; } /** * Data layout of this class conforms to an UDP packet (RFC 768) * * UDP-header-format: * * ----------------------------------------------------------------------- * | source-port | destination-port | length | checksum | * | 2 bytes | 2 bytes | 2 bytes | 2 bytes | * ----------------------------------------------------------------------- */ class Net::Udp_packet { private: /*********************** ** UDP header fields ** ***********************/ Genode::uint16_t _src_port; Genode::uint16_t _dst_port; Genode::uint16_t _length; Genode::uint16_t _checksum; unsigned _data[0]; public: template T const &data(Size_guard &size_guard) const { size_guard.consume_head(sizeof(T)); return *(T const *)(_data); } template T &data(Size_guard &size_guard) { size_guard.consume_head(sizeof(T)); return *(T *)(_data); } template T &construct_at_data(SIZE_GUARD &size_guard) { size_guard.consume_head(sizeof(T)); 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); void update_checksum(Internet_checksum_diff const &icd); bool checksum_error(Ipv4_address ip_src, Ipv4_address ip_dst) const; /*************** ** 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); } 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; } void src_port(Port p, Internet_checksum_diff &icd); void dst_port(Port p, Internet_checksum_diff &icd); /********* ** log ** *********/ void print(Genode::Output &output) const; } __attribute__((packed)); #endif /* _UDP_H_ */