diff --git a/kernel/include/net/dns_layer.hpp b/kernel/include/net/dns_layer.hpp index ed24a305..fb528348 100644 --- a/kernel/include/net/dns_layer.hpp +++ b/kernel/include/net/dns_layer.hpp @@ -40,6 +40,8 @@ struct header { uint16_t additional_rrs; } __attribute__((packed)); +static_assert(sizeof(header) == 12, "DNS flags must be 96 bits"); + 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); diff --git a/kernel/src/net/alpha.cpp b/kernel/src/net/alpha.cpp index 52c27e76..afe5b5d4 100644 --- a/kernel/src/net/alpha.cpp +++ b/kernel/src/net/alpha.cpp @@ -7,7 +7,6 @@ #include "net/alpha.hpp" #include "net/ethernet_layer.hpp" -#include "net/icmp_layer.hpp" #include "net/ip_layer.hpp" #include "net/dns_layer.hpp" @@ -24,27 +23,37 @@ void network::alpha(){ std::string domain("www.google.ch"); - size_t payload_size = 1 + domain.size() + 2 * 2; + auto parts = std::split(domain, '.'); + + size_t characters = domain.size() - (parts.size() - 1); // The dots are not included + size_t labels = parts.size(); + + size_t payload_size = labels + characters + 1 + 2 * 2; // Ask the DNS layer to craft a packet - auto packet = network::dns::prepare_packet_query(interface, target_ip, 3456, 666, payload_size); + auto packet = network::dns::prepare_packet_query(interface, target_ip, 3456, 0x666, payload_size); if(packet){ auto* payload = reinterpret_cast(packet->payload + packet->index); - payload[0] = domain.size(); + size_t i = 0; + for(auto& part : parts){ + payload[i++] = part.size(); - for(size_t i = 0; i < domain.size(); ++i){ - payload[i + 1] = domain[i]; + for(size_t j = 0; j < part.size(); ++j){ + payload[i++] = part[j]; + } } - auto* q_type = reinterpret_cast(packet->payload + packet->index + 1 + domain.size()); - *q_type = 1; // A Record + payload[i++] = 0; - auto* q_class = q_type + 1; - *q_class = 1; // IN (internet) + auto* q_type = reinterpret_cast(packet->payload + packet->index + i); + *q_type = 0x0100; // A Record + + auto* q_class = reinterpret_cast(packet->payload + packet->index + i + 2); + *q_class = 0x0100; // IN (internet) // Send the packet back to ICMP - network::icmp::finalize_packet(interface, *packet); + network::dns::finalize_packet(interface, *packet); } } diff --git a/kernel/src/net/dns_layer.cpp b/kernel/src/net/dns_layer.cpp index b0c027be..fe4588e6 100644 --- a/kernel/src/net/dns_layer.cpp +++ b/kernel/src/net/dns_layer.cpp @@ -51,10 +51,14 @@ void network::dns::decode(network::interface_descriptor& /*interface*/, network: auto identification = switch_endian_16(dns_header->identification); auto questions = switch_endian_16(dns_header->questions); auto answers = switch_endian_16(dns_header->answers); + auto authority_rrs = switch_endian_16(dns_header->authority_rrs); + auto additional_rrs = switch_endian_16(dns_header->additional_rrs); logging::logf(logging::log_level::TRACE, "dns: Identification %h \n", size_t(identification)); - logging::logf(logging::log_level::TRACE, "dns: Questions %h \n", size_t(questions)); logging::logf(logging::log_level::TRACE, "dns: Answers %h \n", size_t(answers)); + logging::logf(logging::log_level::TRACE, "dns: Questions %h \n", size_t(questions)); + logging::logf(logging::log_level::TRACE, "dns: Authorithy RRs %h \n", size_t(authority_rrs)); + logging::logf(logging::log_level::TRACE, "dns: Additional RRs %h \n", size_t(additional_rrs)); auto flags = dns_header->flags; @@ -90,6 +94,8 @@ std::expected network::dns::prepare_packet_query(char } void network::dns::finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p){ + p.index -= sizeof(header); + // Give the packet to the UDP layer for finalization network::udp::finalize_packet(interface, p); } diff --git a/kernel/src/net/udp_layer.cpp b/kernel/src/net/udp_layer.cpp index 8106c065..3593b12d 100644 --- a/kernel/src/net/udp_layer.cpp +++ b/kernel/src/net/udp_layer.cpp @@ -22,7 +22,7 @@ void compute_checksum(network::ethernet::packet& packet, network::udp::header* u // Accumulate the ICMP header auto sum = std::accumulate( reinterpret_cast(udp_header), - reinterpret_cast(udp_header) + udp_header->length * 2, + reinterpret_cast(udp_header) + udp_header->length / 2, uint32_t(0)); // Accumulate the IP addresses