Complete DNS query

This commit is contained in:
Baptiste Wicht 2016-09-11 13:33:43 +02:00
parent c258de32ad
commit c30d95714c
4 changed files with 30 additions and 13 deletions

View File

@ -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<network::ethernet::packet> prepare_packet_query(network::interface_descriptor& interface, network::ip::address target_ip, uint16_t source_port, uint16_t identification, size_t payload_size);

View File

@ -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<char*>(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<uint16_t*>(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<uint16_t*>(packet->payload + packet->index + i);
*q_type = 0x0100; // A Record
auto* q_class = reinterpret_cast<uint16_t*>(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);
}
}

View File

@ -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::ethernet::packet> 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);
}

View File

@ -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<uint16_t*>(udp_header),
reinterpret_cast<uint16_t*>(udp_header) + udp_header->length * 2,
reinterpret_cast<uint16_t*>(udp_header) + udp_header->length / 2,
uint32_t(0));
// Accumulate the IP addresses