22 * @file dns.h
33 * @author Craig Edwards (craigedwards@brainbox.cc)
44 * @copyright Copyright (c) 2012-2026
5+ *
6+ * @brief Non-blocking DNS resolver support
57 */
68#pragma once
79
810#include "kernel.h"
911
10- /* highest 6 bits in a DN label header */
11- #define DN_COMP_BITMASK 0xC000
12+ /**
13+ * @brief DNS compression pointer marker bits
14+ *
15+ * DNS names may use a two-byte compression pointer. The top two bits are set
16+ * to indicate that the remaining fourteen bits are an offset into the DNS
17+ * message.
18+ */
19+ #define DN_COMP_BITMASK 0xC000
1220
13- /* Result is an error */
21+ /**
22+ * @brief Resolver result flag indicating failure
23+ */
1424#define ERROR_MASK 0x10000
1525
16- #define FLAGS_MASK_RD 0x01 /* Recursive */
26+ /**
27+ * @brief DNS recursion desired flag
28+ */
29+ #define FLAGS_MASK_RD 0x01
30+
31+ /**
32+ * @brief DNS truncated response flag
33+ */
1734#define FLAGS_MASK_TC 0x02
18- #define FLAGS_MASK_AA 0x04 /* Authoritative */
35+
36+ /**
37+ * @brief DNS authoritative answer flag
38+ */
39+ #define FLAGS_MASK_AA 0x04
40+
41+ /**
42+ * @brief DNS opcode mask
43+ */
1944#define FLAGS_MASK_OPCODE 0x78
45+
46+ /**
47+ * @brief DNS query/response flag
48+ */
2049#define FLAGS_MASK_QR 0x80
21- #define FLAGS_MASK_RCODE 0x0F /* Request */
50+
51+ /**
52+ * @brief DNS response code mask
53+ */
54+ #define FLAGS_MASK_RCODE 0x0F
55+
56+ /**
57+ * @brief DNS reserved flag mask
58+ */
2259#define FLAGS_MASK_Z 0x70
60+
61+ /**
62+ * @brief DNS recursion available flag
63+ */
2364#define FLAGS_MASK_RA 0x80
2465
2566/**
26- * Returned by dns_lookup_host_async() if the result is immediately
27- * available in the ip parameter, and the ip parameter was non-NULL.
67+ * @brief Returned by dns_lookup_host_async() when the result is cached
68+ *
69+ * This value is returned if the result is immediately available in the ip
70+ * parameter, and the ip parameter was non-NULL.
2871 */
2972#define DNS_RESULT_CACHED 0xFFFFFFFF
3073
74+ /**
75+ * @brief DNS query and resource record types
76+ */
3177enum query_type_t {
32- /** Uninitialized Query */
33- DNS_QUERY_NONE = 0 ,
34- /** 'A' record: an ipv4 address */
35- DNS_QUERY_A = 1 ,
36- /** 'CNAME' record: An alias */
37- DNS_QUERY_CNAME = 5 ,
38- /** 'PTR' record: a hostname */
39- DNS_QUERY_PTR = 12 ,
40- /** 'AAAA' record: an ipv6 address */
41- DNS_QUERY_AAAA = 28 ,
42-
43- /** Force 'PTR' to use IPV4 scemantics */
44- DNS_QUERY_PTR4 = 0xFFFD ,
45- /** Force 'PTR' to use IPV6 scemantics */
46- DNS_QUERY_PTR6 = 0xFFFE
78+ /** Uninitialised query */
79+ DNS_QUERY_NONE = 0 ,
80+
81+ /** A record: an IPv4 address */
82+ DNS_QUERY_A = 1 ,
83+
84+ /** CNAME record: an alias to another hostname */
85+ DNS_QUERY_CNAME = 5 ,
86+
87+ /** PTR record: a reverse lookup hostname */
88+ DNS_QUERY_PTR = 12 ,
89+
90+ /** AAAA record: an IPv6 address */
91+ DNS_QUERY_AAAA = 28 ,
92+
93+ /** Force PTR to use IPv4 semantics */
94+ DNS_QUERY_PTR4 = 0xFFFD ,
95+
96+ /** Force PTR to use IPv6 semantics */
97+ DNS_QUERY_PTR6 = 0xFFFE
4798};
4899
100+ /**
101+ * @brief Size of the fixed DNS packet header
102+ */
49103#define DNS_HEADER_SIZE 12
50104
105+ /**
106+ * @brief Size of the fixed part of a DNS resource record after the name
107+ *
108+ * This covers TYPE, CLASS, TTL, and RDLENGTH. It does not include the owner
109+ * name or RDATA.
110+ */
51111#define DNS_RR_FIXED_SIZE 10
52112
113+ /**
114+ * @brief Maximum decoded DNS result size used by the resolver
115+ */
53116#define DNS_RESULT_MAX 1023
54117
55- /** Represents a dns request/reply header, and its payload as opaque data.
118+ /**
119+ * @brief Maximum number of CNAME redirects followed for one request
120+ */
121+ #define DNS_MAX_CNAME_DEPTH 8
122+
123+ /**
124+ * @brief Standard DNS server UDP port
125+ */
126+ #define DNS_DST_PORT 53
127+
128+ /**
129+ * @brief DNS request/reply header with opaque packet payload
56130 */
57131typedef struct dns_header {
58- uint16_t id ; /* Request id */
59- uint8_t flags1 ; /* Flags */
60- uint8_t flags2 ; /* Flags */
132+ /** Request or reply identifier */
133+ uint16_t id ;
134+
135+ /** First DNS flags byte */
136+ uint8_t flags1 ;
137+
138+ /** Second DNS flags byte */
139+ uint8_t flags2 ;
140+
141+ /** Question count */
61142 uint16_t qdcount ;
62- uint16_t ancount ; /* Answer count */
63- uint16_t nscount ; /* Nameserver count */
143+
144+ /** Answer count */
145+ uint16_t ancount ;
146+
147+ /** Authority resource record count */
148+ uint16_t nscount ;
149+
150+ /** Additional resource record count */
64151 uint16_t arcount ;
65- uint8_t payload [512 ]; /* Packet payload */
152+
153+ /** Packet payload following the fixed DNS header */
154+ uint8_t payload [512 ];
66155} __attribute__((packed )) dns_header_t ;
67156
157+ /**
158+ * @brief Callback for completed IPv4 A lookups
159+ *
160+ * @param result IPv4 address result, or 0 on failure
161+ * @param hostname Original hostname supplied to the lookup
162+ * @param reply_id DNS request identifier
163+ */
68164typedef void (* dns_reply_callback_a )(uint32_t result , const char * hostname , uint16_t reply_id );
165+
166+ /**
167+ * @brief Callback for completed IPv6 AAAA lookups
168+ *
169+ * @param result IPv6 address result
170+ * @param hostname Original hostname supplied to the lookup
171+ * @param reply_id DNS request identifier
172+ */
69173typedef void (* dns_reply_callback_aaaa )(uint8_t * result , const char * hostname , uint16_t reply_id );
174+
175+ /**
176+ * @brief Callback for completed PTR lookups
177+ *
178+ * @param result Hostname result
179+ * @param ip Original IP address supplied to the lookup
180+ * @param reply_id DNS request identifier
181+ */
70182typedef void (* dns_reply_callback_ptr )(const char * const result , const uint32_t ip , uint16_t reply_id );
71183
184+ /**
185+ * @brief Pending DNS request state
186+ */
72187typedef struct dns_request {
73- uint16_t id ; /* Request id */
74- uint32_t rr_class ; /* Request class */
188+ /** Request identifier */
189+ uint16_t id ;
190+
191+ /** Requested resource record class */
192+ uint32_t rr_class ;
193+
194+ /** Time to live from the accepted resource record */
75195 uint32_t ttl ;
76- uint16_t type ; /* Request type */
77- unsigned char * orig ; /* Original requested name/ip */
196+
197+ /** Requested resource record type */
198+ uint16_t type ;
199+
200+ /** Original requested hostname or IP string */
201+ unsigned char * orig ;
202+
203+ /** Result buffer for resolved binary or textual data */
78204 char result [256 ];
205+
206+ /** Number of valid bytes in result */
79207 uint8_t result_length ;
80- dns_reply_callback_a callback_a ; /* For later */
81- dns_reply_callback_aaaa callback_aaaa ; /* For later */
82- dns_reply_callback_ptr callback_ptr ; /* For later */
83- uint32_t resolver_ip ; /* Resolver IP address */
208+
209+ /** Completion callback for A lookups */
210+ dns_reply_callback_a callback_a ;
211+
212+ /** Completion callback for AAAA lookups */
213+ dns_reply_callback_aaaa callback_aaaa ;
214+
215+ /** Completion callback for PTR lookups */
216+ dns_reply_callback_ptr callback_ptr ;
217+
218+ /** Resolver IPv4 address */
219+ uint32_t resolver_ip ;
220+
221+ /** Number of CNAME redirects followed by this request */
222+ uint8_t cname_depth ;
84223} dns_request_t ;
85224
225+ /**
226+ * @brief Cached DNS lookup entry
227+ */
86228typedef struct dns_cache_entry_t {
229+ /** Cached hostname */
87230 const char * host ;
231+
232+ /** Cached result string */
88233 const char * result ;
89234} dns_cache_entry_t ;
90235
236+ /**
237+ * @brief DNS resource record metadata
238+ */
91239typedef struct resource_record {
92- uint16_t type ; /* Record type */
93- uint16_t rr_class ; /* Record class */
94- uint32_t ttl ; /* Time to live */
95- uint16_t rdlength ; /* Record length */
240+ /** Resource record type */
241+ uint16_t type ;
242+
243+ /** Resource record class */
244+ uint16_t rr_class ;
245+
246+ /** Time to live */
247+ uint32_t ttl ;
248+
249+ /** Resource data length */
250+ uint16_t rdlength ;
96251} __attribute__((packed )) resource_record_t ;
97252
253+ /**
254+ * @brief DNS resolver result metadata
255+ */
98256struct dns_result_t {
257+ /** Error string, or NULL if no error occurred */
99258 char * error ;
100259};
101260
102- #define DNS_DST_PORT 53
103-
104261/**
105- * @brief Look up an IPV4 hostname to IP address, with timeout
106- * @note This function is synchronous! It will block until a suitable DNS request
107- * has been obtained from the DNS server you specify, or a timeout is reached.
108- *
109- * @param resolver_ip The IP of the resolver to use, in network byte order
110- * @param hostname Host address to resolve
111- * @param timeout_ms Timeout in millisseconds
112- * @return uint32_t Resolved IP address. On error or timeout, the return value is 0,
113- * which translates to 0.0.0.0.
262+ * @brief Look up an IPv4 hostname to IP address, with timeout
263+ *
264+ * @note This function is synchronous. It blocks until a suitable DNS response
265+ * has been obtained from the specified DNS server, or a timeout is reached.
266+ *
267+ * @param resolver_ip IP address of the resolver to use, in network byte order
268+ * @param hostname Hostname to resolve
269+ * @param timeout_ms Timeout in milliseconds
270+ * @return Resolved IP address. On error or timeout, the return value is 0,
271+ * which represents 0.0.0.0.
114272 */
115273uint32_t dns_lookup_host (uint32_t resolver_ip , const char * hostname , uint32_t timeout_ms );
116274
117275/**
118- * @brief Look up an IPV4 hostname to IP address, with timeout
119- * @note This function is asynchronous. It will return the ID of the request,
120- * and will call the callback once the request has completed.
121- *
122- * @param resolver_ip The IP of the resolver to use, in network byte order
123- * @param hostname Host address to resolve
124- * @param ip Pointer to uint32_t IP address to immediately return if the result is cached
125- * @param dns_reply_callback_a Callback to receive the resolved IP address.
126- * If an error occured during resolution, the received IP address will be 0,
127- * which is a representation of 0.0.0.0.
128- * @return uint16_t Request ID that was submitted, or 0 on error.
129- * a special value DNS_RESULT_CACHED (0xffffffff) is returned if the result was immediately
130- * filled from the DNS cache.
276+ * @brief Look up an IPv4 hostname to IP address asynchronously
277+ *
278+ * @note This function returns the ID of the submitted request. The callback is
279+ * called once the request has completed. If the result is already cached and ip
280+ * is non-NULL, DNS_RESULT_CACHED is returned and ip is filled immediately.
281+ *
282+ * @param resolver_ip IP address of the resolver to use, in network byte order
283+ * @param hostname Hostname to resolve
284+ * @param ip Optional pointer to receive an immediate cached result
285+ * @param callback Callback to receive the resolved IP address
286+ * @return Request ID that was submitted, 0 on error, or DNS_RESULT_CACHED if
287+ * the result was returned from cache.
131288 */
132289uint32_t dns_lookup_host_async (uint32_t resolver_ip , const char * hostname , uint32_t * ip , dns_reply_callback_a callback );
133290
134291/**
135- * @brief Initialise DNS protocol.
136- * This binds a UDP port for use with replies.
292+ * @brief Initialise DNS protocol support
293+ *
294+ * This binds a UDP port for use with DNS replies.
137295 */
138296void init_dns ();
0 commit comments