diff --git a/CMakeLists.txt b/CMakeLists.txt index 23a4478..4e5144e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 4.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_BUILD_TYPE Debug) project(pupdns VERSION 0.1) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/include/dns_packet_buffer.h b/include/dns_packet_buffer.h index 9457e54..f23287d 100644 --- a/include/dns_packet_buffer.h +++ b/include/dns_packet_buffer.h @@ -1,14 +1,13 @@ #pragma once #include -#define PB_SIZE 512 -#define PB_OUT_OF_BOUNDS 9999; +#define PACKET_BUFFER_SIZE 512 struct DNSPacketBuffer { - unsigned char buf[PB_SIZE]; + char buf[PACKET_BUFFER_SIZE]; size_t pos; }; struct DNSPacketBuffer *new_dns_packet_buffer(); -unsigned char pb_read_byte(struct DNSPacketBuffer *); +struct DNSPacketHeader *dns_header(struct DNSPacketBuffer); diff --git a/include/dns_packets.h b/include/dns_packets.h index b80b66c..f4a1ac8 100644 --- a/include/dns_packets.h +++ b/include/dns_packets.h @@ -1,7 +1,6 @@ #pragma once #include -#define DNS_HEADER_BYTES 12 struct DNSPacketHeader { /* @@ -9,34 +8,14 @@ struct DNSPacketHeader { * a random ID is assigned to query packets. * Response packets must contain the same ID as the query. */ - unsigned int packet_id : 16; - - /* - * RD (Recursion Desired) - * if set by the client, the server should - * attempt to resolve the query recursively - * - * the server may not allow recursive resolution. - * (see RA / Recursion Available) - */ - unsigned int recursion_desired : 1; + size_t packet_id : 16; /* - * TC (Truncated) - * if true, this message was truncated. - * usually happens when the response payload - * is larger than the max UDP packet size - * - * if set, the query may be re-issued over TCP for the full payload. + * QR (Query/Response) + * 0 if the packet is a query + * 1 if the packet is a response */ - unsigned int is_truncated : 1; - - /* - * AA (Authoritative Answer) - * - * 1 if the responding server is authoritative for the queried domain - */ - unsigned int is_authoritative : 1; + size_t is_response : 1; /* * OPCODE (Operation Code) @@ -48,14 +27,51 @@ struct DNSPacketHeader { * * almost always will be 0 */ - unsigned int opcode : 4; + size_t opcode : 4; /* - * QR (Query/Response) - * 0 if the packet is a query - * 1 if the packet is a response + * AA (Authoritative Answer) + * + * 1 if the responding server is authoritative for the queried domain */ - unsigned int is_response : 1; + size_t is_authoritative : 1; + + /* + * TC (Truncated) + * if true, this message was truncated. + * usually happens when the response payload + * is larger than the max UDP packet size + * + * if set, the query may be re-issued over TCP for the full payload. + */ + size_t is_truncated : 1; + + /* + * RD (Recursion Desired) + * if set by the client, the server should + * attempt to resolve the query recursively + * + * the server may not allow recursive resolution. + * (see RA / Recursion Available) + */ + size_t recursion_desired : 1; + + + /* + * RA (Recursion Available) + * if set by the server, incicates that the server allows + * recursive queries. + */ + size_t recursion_available : 1; + + /* + * Z (Reserved) + * in the original spec, this is reserved for future use. + * + * in later RFCs, it is used for DNSSEC queries. + * (to be implemented) + */ + size_t z : 3; /* * RCODE (Response Code) @@ -70,47 +86,31 @@ struct DNSPacketHeader { * 5 - Refused - the nameserver refuses to perform the requested operation. for example, it may refuse a zone transfer. * 6-15 - Reserved for future use */ - unsigned int response_code : 4; - - /* - * Z (Reserved) - * in the original spec, this is reserved for future use. - * - * in later RFCs, it is used for DNSSEC queries. - * (to be implemented) - */ - unsigned int z : 3; - - /* - * RA (Recursion Available) - * if set by the server, incicates that the server allows - * recursive queries. - */ - unsigned int recursion_available : 1; + size_t response_code : 4; /* * QDCOUNT (Question Count) * the number of entries in the question section */ - unsigned int question_count : 16; + size_t question_count : 16; /* * ANCOUNT (Answer Count) * the number of entries in the answer section */ - unsigned int answer_count : 16; + size_t answer_count : 16; /* * NSCOUNT (Nameserver Count) * the number of entries in the authority records section */ - unsigned int ns_count : 16; + size_t ns_count : 16; /* * ARCOUNT (Additional Records Count) * the number of entries in the additional records section */ - unsigned int ar_count : 16; + size_t ar_count : 16; }; @@ -125,26 +125,26 @@ struct RecordPreamble { * TYPE * the record type */ - unsigned int type : 16; + size_t type : 16; /* * CLASS * specifies the class of the data in the RDATA field. * in practice, always set to 1 */ - unsigned int class : 16; + size_t class : 16; /* * TTL (Time-To-Live) * how long a record can be cached before it should be requeried. */ - unsigned int ttl : 32; + size_t ttl : 32; /* * RDLENGTH (Record Data Length) * length of the record-type-specific data. */ - unsigned int rd_data_length: 16; + size_t rd_data_length: 16; }; /* @@ -153,5 +153,5 @@ struct RecordPreamble { */ struct ARecord { struct RecordPreamble preamble; - unsigned int ip : 32; + size_t ip : 32; }; diff --git a/include/dns_request.h b/include/dns_request.h index 393c01b..aeecf54 100644 --- a/include/dns_request.h +++ b/include/dns_request.h @@ -1,10 +1,7 @@ #pragma once #include "dns_packets.h" -#include "dns_packet_buffer.h" struct DNSRequest { - struct DNSPacketHeader *header; + struct DNSPacketHeader header; }; - -struct DNSRequest *parse_dns_query(struct DNSPacketBuffer *pb); diff --git a/include/udp_server.h b/include/udp_server.h index 40276be..cd63cfc 100644 --- a/include/udp_server.h +++ b/include/udp_server.h @@ -1,5 +1,5 @@ #pragma once -#define UDP_PORT 1053 +#define UDP_PORT 53 int start_server(); diff --git a/src/dns_packet_buffer.c b/src/dns_packet_buffer.c index d47f1e5..55fe986 100644 --- a/src/dns_packet_buffer.c +++ b/src/dns_packet_buffer.c @@ -1,5 +1,4 @@ #include "dns_packet_buffer.h" -#include #include struct DNSPacketBuffer *new_dns_packet_buffer() @@ -8,3 +7,8 @@ struct DNSPacketBuffer *new_dns_packet_buffer() buf = malloc(sizeof(struct DNSPacketBuffer)); return buf; } + +struct DNSPacketHeader *dns_header(struct DNSPacketBuffer) +{ + +} diff --git a/src/dns_request.c b/src/dns_request.c index 6e0cd57..243502c 100644 --- a/src/dns_request.c +++ b/src/dns_request.c @@ -1,36 +1,3 @@ -#include -#include - #include "dns_request.h" -struct DNSRequest *parse_dns_query(struct DNSPacketBuffer *pb) -{ - struct DNSRequest *req; - req = malloc(sizeof(struct DNSRequest)); - req->header = (struct DNSPacketHeader *) pb->buf; - /* - * casting the buffer directly into the packet header struct like this - * works okay, but because of the nature of the DNS protocol, it needs - * a lot of manual tweaking. - * - * the struct fields are defined in a weird order (compared to the spec) - * because C wants to read each byte from right to left, - * but DNS fields go left to right. - * - * so for each set of fields adding up to 8 bits of data, i reversed the - * order of the fields in the struct definition so that the fields end up - * with the correct bits off the wire. - * - * DNS also has multi-bit (but less than a byte) fields such as - * opcode and response code. fortunately we can skip these for now, - * since opcode is practically always zero for our purposes, - * and response_code only makes sense in the server response. - * - * but we do need to take care of all the network-order 16-bit fields. - */ - req->header->packet_id = ntohs(req->header->packet_id); - req->header->question_count = ntohs(req->header->question_count); - - return req; -} diff --git a/src/udp_server.c b/src/udp_server.c index 0027214..04de262 100644 --- a/src/udp_server.c +++ b/src/udp_server.c @@ -2,10 +2,10 @@ #include "dns_packet_buffer.h" #include "dns_request.h" -#include #include #include #include +#include #include #include #include @@ -37,37 +37,20 @@ int start_server() return -1; } - while (true) { - socklen_t len = 0; + socklen_t len = 0; - int n = recvfrom(sockfd, (char *)pb->buf, sizeof(pb->buf), MSG_WAITALL, 0, &len); + int n = recvfrom(sockfd, (char *)pb->buf, sizeof(pb->buf), MSG_WAITALL, 0, &len); - printf("===== NEW REQUEST =====\n"); - printf("received %d bytes\n", n); + printf("received %d bytes\n", n); - struct DNSRequest *req = parse_dns_query(pb); + struct DNSRequest *req = new_dns_request(pb); - printf("packet_id: %x\n", req->header->packet_id); - printf("is_response: %d\n", req->header->is_response); - printf("opcode: %d\n", req->header->opcode); - printf("is_authoritative: %d\n", req->header->is_authoritative); - printf("is_truncated: %d\n", req->header->is_truncated); - printf("recursion_desired: %d\n", req->header->recursion_desired); - printf("recursion_available: %d\n", req->header->recursion_available); - printf("reserved: %d\n", req->header->z); - printf("response_code: %d\n", req->header->response_code); - printf("question_count: %d\n", req->header->question_count); - printf("answer_count: %d\n", req->header->answer_count); - printf("ns_count: %d\n", req->header->ns_count); - printf("ar_count: %d\n", req->header->ar_count); - - // for (int i=0; ibuf[i]); - // } - - free(pb); - free(req); - } + printf("packet_id: %x\n", req->header->packet_id); + printf("is_response: %d\n", req->header->is_response); + printf("opcode: %d\n", req->header->opcode); + printf("is_authoritative: %d\n", req->header->is_authoritative); + printf("is_truncated: %d\n", req->header->is_truncated); + printf("recursion_desired: %d\n", req->header->recursion_desired); close(sockfd); return 0;