diff --git a/kernel/include/net/udp_layer.hpp b/kernel/include/net/udp_layer.hpp index 44c2e419..83414577 100644 --- a/kernel/include/net/udp_layer.hpp +++ b/kernel/include/net/udp_layer.hpp @@ -11,6 +11,7 @@ #include #include "net/ethernet_layer.hpp" +#include "net/ip_layer.hpp" #include "net/network.hpp" namespace network { @@ -26,6 +27,10 @@ struct header { void decode(network::interface_descriptor& interface, network::ethernet::packet& packet); +std::expected prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t source, size_t target, size_t payload_size); +std::expected prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t source, size_t target, size_t payload_size); +void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p); + } // end of upd namespace } // end of network namespace diff --git a/kernel/src/net/udp_layer.cpp b/kernel/src/net/udp_layer.cpp index 0fdc0ad7..ac71f22a 100644 --- a/kernel/src/net/udp_layer.cpp +++ b/kernel/src/net/udp_layer.cpp @@ -9,7 +9,29 @@ #include "kernel_utils.hpp" -void network::udp::decode(network::interface_descriptor& interface, network::ethernet::packet& packet){ +namespace { + +void compute_checksum(network::udp::header* icmp_header){ + icmp_header->checksum = 0; + + //TODO +} + +void prepare_packet(network::ethernet::packet& packet, size_t source, size_t target, size_t payload_size){ + // Set the UDP header + + auto* udp_header = reinterpret_cast(packet.payload + packet.index); + + udp_header->source_port = switch_endian_16(source); + udp_header->target_port = switch_endian_16(target); + udp_header->length = switch_endian_16(sizeof(network::udp::header) + payload_size); + + packet.index += sizeof(network::udp::header); +} + +} //end of anonymous namespace + +void network::udp::decode(network::interface_descriptor& /*interface*/, network::ethernet::packet& packet){ packet.tag(2, packet.index); auto* udp_header = reinterpret_cast(packet.payload + packet.index); @@ -28,3 +50,37 @@ void network::udp::decode(network::interface_descriptor& interface, network::eth //TODO DNS decoding } } + +std::expected network::udp::prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t source, size_t target, size_t payload_size){ + // Ask the IP layer to craft a packet + auto packet = network::ip::prepare_packet(interface, sizeof(header) + payload_size, target_ip, 0x11); + + if(packet){ + ::prepare_packet(*packet, source, target, payload_size); + } + + return packet; +} + +std::expected network::udp::prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t source, size_t target, size_t payload_size){ + // Ask the IP layer to craft a packet + auto packet = network::ip::prepare_packet(buffer, interface, sizeof(header) + payload_size, target_ip, 0x11); + + if(packet){ + ::prepare_packet(*packet, source, target, payload_size); + } + + return packet; +} + +void network::udp::finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p){ + p.index -= sizeof(header); + + auto* udp_header = reinterpret_cast(p.payload + p.index); + + // Compute the checksum + compute_checksum(udp_header); + + // Give the packet to the IP layer for finalization + network::ip::finalize_packet(interface, p); +}