diff --git a/kernel/include/net/dns_layer.hpp b/kernel/include/net/dns_layer.hpp index 0b2f2f3a..ed24a305 100644 --- a/kernel/include/net/dns_layer.hpp +++ b/kernel/include/net/dns_layer.hpp @@ -42,6 +42,10 @@ struct header { void decode(network::interface_descriptor& interface, network::ethernet::packet& packet); +std::expected prepare_packet_query(network::interface_descriptor& interface, network::ip::address target_ip, uint16_t source_port, uint16_t identification, size_t payload_size); +std::expected prepare_packet_query(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, uint16_t source_port, uint16_t identification, size_t payload_size); +void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p); + } // end of dns namespace } // end of network namespace diff --git a/kernel/src/net/dns_layer.cpp b/kernel/src/net/dns_layer.cpp index 7044a582..b0c027be 100644 --- a/kernel/src/net/dns_layer.cpp +++ b/kernel/src/net/dns_layer.cpp @@ -6,11 +6,38 @@ //======================================================================= #include "net/dns_layer.hpp" +#include "net/udp_layer.hpp" #include "kernel_utils.hpp" namespace { +void prepare_packet_query(network::ethernet::packet& packet, uint16_t identification){ + // Set the DNS header + + auto* dns_header = reinterpret_cast(packet.payload + packet.index); + + // Set the identification + dns_header->identification = switch_endian_16(identification); + + // There is one question, nothing else + dns_header->questions = switch_endian_16(1); + dns_header->answers = switch_endian_16(0); + dns_header->authority_rrs = switch_endian_16(0); + dns_header->additional_rrs = switch_endian_16(0); + + // Set all the flags + dns_header->flags.qr = 0; // This is a query + dns_header->flags.opcode = 0; // This is a standard query + dns_header->flags.aa = 0; // This is a query (field not used) + dns_header->flags.tc = 0; // The question is not truncated + dns_header->flags.rd = 0; // No need for recursion + dns_header->flags.ra = 0; // This is a query (field not used) + dns_header->flags.zeroes = 0; // Always zero + dns_header->flags.rcode = 0; // This is a query (field not used) + + packet.index += sizeof(network::dns::header); +} } //end of anonymous namespace @@ -39,3 +66,30 @@ void network::dns::decode(network::interface_descriptor& /*interface*/, network: //TODO } + +std::expected network::dns::prepare_packet_query(network::interface_descriptor& interface, network::ip::address target_ip, uint16_t source_port, uint16_t identification, size_t payload_size){ + // Ask the UDP layer to craft a packet + auto packet = network::udp::prepare_packet(interface, target_ip, source_port, 53, sizeof(header) + payload_size); + + if(packet){ + ::prepare_packet_query(*packet, identification); + } + + return packet; +} + +std::expected network::dns::prepare_packet_query(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, uint16_t source_port, uint16_t identification, size_t payload_size){ + // Ask the UDP layer to craft a packet + auto packet = network::udp::prepare_packet(buffer, interface, target_ip, source_port, 53, sizeof(header) + payload_size); + + if(packet){ + ::prepare_packet_query(*packet, identification); + } + + return packet; +} + +void network::dns::finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p){ + // Give the packet to the UDP layer for finalization + network::udp::finalize_packet(interface, p); +}