diff --git a/include/packets.h b/include/packets.h new file mode 100644 index 0000000..ab100de --- /dev/null +++ b/include/packets.h @@ -0,0 +1,157 @@ +#pragma once +#include + + +struct Header { + /* + * ID (Packet Identifier) + * a random ID is assigned to query packets. + * Response packets must contain the same ID as the query. + */ + size_t packet_id : 16; + + /* + * QR (Query/Response) + * 0 if the packet is a query + * 1 if the packet is a response + */ + size_t is_response : 1; + + /* + * OPCODE (Operation Code) + * + * 0 - standard query (QUERY) + * 1 - inverse query (IQUERY) + * 2 - server status request (STATUS) + * 3-15 - reserved + * + * almost always will be 0 + */ + size_t opcode : 4; + + /* + * AA (Authoritative Answer) + * + * 1 if the responding server is authoritative for the queried domain + */ + 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) + * Set by the server to indicate success or failure of the query. + * Provides details about the cause of any failure. + * + * 0 - No error + * 1 - Format error - the nameserver was unable to interpret the query + * 2 - Server failure - the nameserver was unable to process the query due to an internal problem + * 3 - Name error - Meaningful only from authoritative nameserver -- the domain name specified in the query does not exist. + * 4 - Not implemented - the nameserver does not support the requested query type + * 5 - Refused - the nameserver refuses to perform the requested operation. for example, it may refuse a zone transfer. + * 6-15 - Reserved for future use + */ + size_t response_code : 4; + + /* + * QDCOUNT (Question Count) + * the number of entries in the question section + */ + size_t question_count : 16; + + /* + * ANCOUNT (Answer Count) + * the number of entries in the answer section + */ + size_t answer_count : 16; + + /* + * NSCOUNT (Nameserver Count) + * the number of entries in the authority records section + */ + size_t ns_count : 16; + + /* + * ARCOUNT (Additional Records Count) + * the number of entries in the additional records section + */ + size_t ar_count : 16; +}; + + +/* + * RecordPreamble + * shared fields that all DNS record types use + */ +struct RecordPreamble { + // TODO: add label sequence + + /* + * TYPE + * the record type + */ + size_t type : 16; + + /* + * CLASS + * specifies the class of the data in the RDATA field. + * in practice, always set to 1 + */ + size_t class : 16; + + /* + * TTL (Time-To-Live) + * how long a record can be cached before it should be requeried. + */ + size_t ttl : 32; + + /* + * RDLENGTH (Record Data Length) + * length of the record-type-specific data. + */ + size_t rd_data_length: 16; +}; + +/* + * A Record + * represents the mapping of a domain name to an IPv4 address + */ +struct ARecord { + struct RecordPreamble preamble; + size_t ip : 32; +};