diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d40b532..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/alog"] - path = lib/alog - url = https://gitlab.com/whom/alog 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 5884dad..4539e02 100644 --- a/include/dns_packet_buffer.h +++ b/include/dns_packet_buffer.h @@ -5,7 +5,7 @@ #define PB_OUT_OF_BOUNDS 9999; struct DNSPacketBuffer { - unsigned char buf[PB_SIZE]; + char buf[PB_SIZE]; size_t pos; }; @@ -13,4 +13,4 @@ struct DNSPacketBuffer *new_dns_packet_buffer(); struct DNSPacketHeader *dns_header(struct DNSPacketBuffer); -unsigned char pb_read_byte(struct DNSPacketBuffer *); +char pb_read_byte(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..e5705ff 100644 --- a/include/dns_request.h +++ b/include/dns_request.h @@ -7,4 +7,4 @@ struct DNSRequest { struct DNSPacketHeader *header; }; -struct DNSRequest *parse_dns_query(struct DNSPacketBuffer *pb); +struct DNSRequest *new_dns_request(struct DNSPacketBuffer *pb); diff --git a/lib/alog b/lib/alog deleted file mode 160000 index 56f8741..0000000 --- a/lib/alog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 56f87419f164e4fb0f1b79e53f308084432fdb7e diff --git a/src/dns_packet_buffer.c b/src/dns_packet_buffer.c index eb84f12..7d7cd69 100644 --- a/src/dns_packet_buffer.c +++ b/src/dns_packet_buffer.c @@ -16,9 +16,9 @@ struct DNSPacketHeader *dns_header(struct DNSPacketBuffer) // read a single byte and move the cursor one byte forward -unsigned char pb_read_byte(struct DNSPacketBuffer *pb) +char pb_read_byte(struct DNSPacketBuffer *pb) { - unsigned char b = pb->buf[pb->pos]; + char b = pb->buf[pb->pos]; pb->pos++; if (pb->pos >= PB_SIZE) { @@ -32,7 +32,7 @@ unsigned char pb_read_byte(struct DNSPacketBuffer *pb) return b; } -unsigned char pb_get_byte(struct DNSPacketBuffer *pb) +char pb_get_byte(struct DNSPacketBuffer *pb) { if (pb->pos >= PB_SIZE) { printf( diff --git a/src/dns_request.c b/src/dns_request.c index 034359e..b960d9d 100644 --- a/src/dns_request.c +++ b/src/dns_request.c @@ -1,66 +1,14 @@ #include -#include #include "dns_request.h" -/* - * get k'th bit from byte c - * because of how the DNS spec works, this starts counting from the LEFTMOST bit. - */ -// unsigned int get_bit(unsigned char c, unsigned int k) -// { -// unsigned int flag = 1U; // flag = 0000.....00001 -// -// flag = flag << (8U-k); // flag = 0000...010...000 (shifted k positions) -// -// return c & flag; -// } -/* - * get n bits from byte c starting at position k - * because of how the DNS spec works, this starts counting from the LEFTMOST bit. - */ -// unsigned int get_bits(unsigned char c, unsigned int n, unsigned int k) -// { -// unsigned int ret = 0; -// unsigned int flag = 1U; // flag = 0000.....00001 -// -// for (int j = 0; j < n; j++) { -// unsigned int bit_pos = 8U - k + j; -// ret = ret | get_bit(c, k+j) << bit_pos; -// } -// -// return ret; -// } -struct DNSRequest *parse_dns_query(struct DNSPacketBuffer *pb) +struct DNSRequest *new_dns_request(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;