iPXE
dns.h File Reference

DNS protocol. More...

#include <stdint.h>
#include <ipxe/in.h>

Go to the source code of this file.

Data Structures

struct  dns_name
 An RFC1035-encoded DNS name. More...
struct  dns_header
 A DNS packet header. More...
struct  dns_question
 A DNS question. More...
struct  dns_rr_common
 A DNS resource record. More...
struct  dns_rr_a
 A DNS "A" record. More...
struct  dns_rr_aaaa
 A DNS "AAAA" record. More...
struct  dns_rr_cname
 A DNS "CNAME" record. More...
union  dns_rr
 A DNS resource record. More...

Macros

#define DNS_PORT   53
 DNS server port.
#define DNS_IS_COMPRESSED(byte)
 Test for a DNS compression pointer.
#define DNS_COMPRESSED_OFFSET(word)
 Extract DNS compression pointer.
#define DNS_LABEL_LEN(byte)
 Extract DNS label length.
#define DNS_MAX_LABEL_LEN   0x3f
 Maximum length of a single DNS label.
#define DNS_MAX_NAME_LEN   255
 Maximum length of a DNS name (mandated by RFC1035 section 2.3.4)
#define DNS_MAX_CNAME_RECURSION   32
 Maximum depth of CNAME recursion.
#define DNS_FLAG_RD   0x0100
 Recursion desired flag.
#define DNS_CLASS_IN   1
 DNS class "IN".
#define DNS_TYPE_A   1
 Type of a DNS "A" record.
#define DNS_TYPE_AAAA   28
 Type of a DNS "AAAA" record.
#define DNS_TYPE_CNAME   5
 Type of a DNS "NAME" record.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
int dns_encode (const char *string, struct dns_name *name)
 Encode a DNS name using RFC1035 encoding.
int dns_decode (struct dns_name *name, char *data, size_t len)
 Decode RFC1035-encoded DNS name.
int dns_compare (struct dns_name *first, struct dns_name *second)
 Compare DNS names for equality.
int dns_copy (struct dns_name *src, struct dns_name *dst)
 Copy a DNS name.
int dns_skip (struct dns_name *name)
 Skip RFC1035-encoded DNS name.

Detailed Description

DNS protocol.

Definition in file dns.h.

Macro Definition Documentation

◆ DNS_PORT

#define DNS_PORT   53

DNS server port.

Definition at line 17 of file dns.h.

Referenced by dns_send_packet().

◆ DNS_IS_COMPRESSED

#define DNS_IS_COMPRESSED ( byte)
Value:
( (byte) & 0xc0 )
unsigned char byte
Definition smc9000.h:38

Test for a DNS compression pointer.

Parameters
byteInitial byte
Return values
is_compressedIs a compression pointer

Definition at line 35 of file dns.h.

Referenced by dns_label().

◆ DNS_COMPRESSED_OFFSET

#define DNS_COMPRESSED_OFFSET ( word)
Value:
( (word) & ~0xc000 )
unsigned short word
Definition smc9000.h:39

Extract DNS compression pointer.

Parameters
wordInitial word
Return values
offsetOffset

Definition at line 43 of file dns.h.

Referenced by dns_label().

◆ DNS_LABEL_LEN

#define DNS_LABEL_LEN ( byte)
Value:
( (byte) & ~0xc0 )

Extract DNS label length.

Parameters
byteInitial byte
Return values
lenLabel length

Definition at line 51 of file dns.h.

◆ DNS_MAX_LABEL_LEN

#define DNS_MAX_LABEL_LEN   0x3f

Maximum length of a single DNS label.

Definition at line 54 of file dns.h.

Referenced by dns_encode().

◆ DNS_MAX_NAME_LEN

#define DNS_MAX_NAME_LEN   255

Maximum length of a DNS name (mandated by RFC1035 section 2.3.4)

Definition at line 57 of file dns.h.

◆ DNS_MAX_CNAME_RECURSION

#define DNS_MAX_CNAME_RECURSION   32

Maximum depth of CNAME recursion.

This is a policy decision.

Definition at line 63 of file dns.h.

Referenced by dns_xfer_deliver().

◆ DNS_FLAG_RD

#define DNS_FLAG_RD   0x0100

Recursion desired flag.

Definition at line 82 of file dns.h.

Referenced by dns_resolv().

◆ DNS_CLASS_IN

#define DNS_CLASS_IN   1

DNS class "IN".

Definition at line 93 of file dns.h.

Referenced by dns_question().

◆ DNS_TYPE_A

#define DNS_TYPE_A   1

Type of a DNS "A" record.

Definition at line 108 of file dns.h.

Referenced by dns_resolv(), dns_type(), and dns_xfer_deliver().

◆ DNS_TYPE_AAAA

#define DNS_TYPE_AAAA   28

Type of a DNS "AAAA" record.

Definition at line 119 of file dns.h.

Referenced by dns_resolv(), and dns_type().

◆ DNS_TYPE_CNAME

#define DNS_TYPE_CNAME   5

Type of a DNS "NAME" record.

Definition at line 130 of file dns.h.

Referenced by dns_type(), and dns_xfer_deliver().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ dns_encode()

int dns_encode ( const char * string,
struct dns_name * name )
extern

Encode a DNS name using RFC1035 encoding.

Parameters
stringDNS name as a string
nameDNS name to fill in
Return values
lenLength of DNS name, or negative error

Definition at line 101 of file dns.c.

101 {
102 uint8_t *start = ( name->data + name->offset );
103 uint8_t *end = ( name->data + name->len );
104 uint8_t *dst = start;
105 size_t len = 0;
106 char c;
107
108 /* Encode name */
109 while ( ( c = *(string++) ) ) {
110
111 /* Handle '.' separators */
112 if ( c == '.' ) {
113
114 /* Reject consecutive '.' */
115 if ( ( len == 0 ) && ( dst != start ) )
116 return -EINVAL;
117
118 /* Terminate if this is the trailing '.' */
119 if ( *string == '\0' )
120 break;
121
122 /* Reject initial non-terminating '.' */
123 if ( len == 0 )
124 return -EINVAL;
125
126 /* Reset length */
127 len = 0;
128
129 } else {
130
131 /* Increment length */
132 len++;
133
134 /* Check for overflow */
135 if ( len > DNS_MAX_LABEL_LEN )
136 return -EINVAL;
137 }
138
139 /* Copy byte, update length */
140 if ( ++dst < end ) {
141 *dst = c;
142 dst[-len] = len;
143 }
144 }
145
146 /* Add terminating root marker */
147 if ( len )
148 dst++;
149 if ( dst < end )
150 *dst = '\0';
151 dst++;
152
153 return ( dst - start );
154}
unsigned char uint8_t
Definition stdint.h:10
const char * name
Definition ath9k_hw.c:1986
#define DNS_MAX_LABEL_LEN
Maximum length of a single DNS label.
Definition dns.h:54
ring len
Length.
Definition dwmac.h:226
uint32_t start
Starting offset.
Definition netvsc.h:1
#define EINVAL
Invalid argument.
Definition errno.h:429
uint32_t end
Ending offset.
Definition netvsc.h:7

References DNS_MAX_LABEL_LEN, EINVAL, end, len, name, and start.

Referenced by apply_dns_search(), dns_encode_fail_okx(), dns_encode_okx(), and dns_resolv().

◆ dns_decode()

int dns_decode ( struct dns_name * name,
char * data,
size_t len )
extern

Decode RFC1035-encoded DNS name.

Parameters
nameDNS name
dataOutput buffer
lenLength of output buffer
Return values
lenLength of decoded DNS name, or negative error

Definition at line 217 of file dns.c.

217 {
218 unsigned int recursion_limit = name->len; /* Generous upper bound */
219 int offset = name->offset;
220 const uint8_t *label;
221 size_t decoded_len = 0;
222 size_t label_len;
223 size_t copy_len;
224
225 while ( recursion_limit-- ) {
226
227 /* Find valid DNS label */
229 if ( offset < 0 )
230 return offset;
231
232 /* Terminate if we have reached the root */
233 label = ( name->data + offset );
234 label_len = *(label++);
235 if ( label_len == 0 ) {
236 if ( decoded_len < len )
237 *data = '\0';
238 return decoded_len;
239 }
240
241 /* Prepend '.' if applicable */
242 if ( decoded_len && ( decoded_len++ < len ) )
243 *(data++) = '.';
244
245 /* Copy label to output buffer */
246 copy_len = ( ( decoded_len < len ) ? ( len - decoded_len ) : 0);
247 if ( copy_len > label_len )
248 copy_len = label_len;
249 memcpy ( data, label, copy_len );
250 data += copy_len;
251 decoded_len += label_len;
252
253 /* Move to next label */
254 offset += ( sizeof ( *label ) + label_len );
255 }
256
257 /* Recursion limit exceeded */
258 return -EINVAL;
259}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
static int dns_label(struct dns_name *name, size_t offset)
Find start of valid label within an RFC1035-encoded DNS name.
Definition dns.c:163
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A text label widget.
Definition label.h:16

References data, dns_label(), EINVAL, len, memcpy(), name, and offset.

Referenced by dns_decode_fail_okx(), dns_decode_okx(), dns_list_okx(), dns_name(), dns_progress(), and format_dnssl_setting().

◆ dns_compare()

int dns_compare ( struct dns_name * first,
struct dns_name * second )
extern

Compare DNS names for equality.

Parameters
firstFirst DNS name
secondSecond DNS name
Return values
rcReturn status code

Definition at line 268 of file dns.c.

268 {
269 unsigned int recursion_limit = first->len; /* Generous upper bound */
270 int first_offset = first->offset;
271 int second_offset = second->offset;
272 const uint8_t *first_label;
273 const uint8_t *second_label;
274 size_t label_len;
275 size_t len;
276
277 while ( recursion_limit-- ) {
278
279 /* Find valid DNS labels */
280 first_offset = dns_label ( first, first_offset );
281 if ( first_offset < 0 )
282 return first_offset;
283 second_offset = dns_label ( second, second_offset );
284 if ( second_offset < 0 )
285 return second_offset;
286
287 /* Compare label lengths */
288 first_label = ( first->data + first_offset );
289 second_label = ( second->data + second_offset );
290 label_len = *(first_label++);
291 if ( label_len != *(second_label++) )
292 return -ENOENT;
293 len = ( sizeof ( *first_label ) + label_len );
294
295 /* Terminate if we have reached the root */
296 if ( label_len == 0 )
297 return 0;
298
299 /* Compare label contents (case-insensitively) */
300 while ( label_len-- ) {
301 if ( tolower ( *(first_label++) ) !=
302 tolower ( *(second_label++) ) )
303 return -ENOENT;
304 }
305
306 /* Move to next labels */
307 first_offset += len;
308 second_offset += len;
309 }
310
311 /* Recursion limit exceeded */
312 return -EINVAL;
313}
static int tolower(int character)
Convert character to lower case.
Definition ctype.h:109
#define ENOENT
No such file or directory.
Definition errno.h:515
uint32_t first
First block in range.
Definition pccrr.h:1
size_t offset
Offset of name within data.
Definition dns.h:24
void * data
Start of data.
Definition dns.h:22

References dns_name::data, dns_label(), EINVAL, ENOENT, first, len, dns_name::offset, and tolower().

Referenced by dns_compare_fail_okx(), dns_compare_okx(), and dns_xfer_deliver().

◆ dns_copy()

int dns_copy ( struct dns_name * src,
struct dns_name * dst )
extern

Copy a DNS name.

Parameters
srcSource DNS name
dstDestination DNS name
Return values
lenLength of copied DNS name, or negative error

Definition at line 322 of file dns.c.

322 {
323 unsigned int recursion_limit = src->len; /* Generous upper bound */
324 int src_offset = src->offset;
325 size_t dst_offset = dst->offset;
326 const uint8_t *label;
327 size_t label_len;
328 size_t copy_len;
329 size_t len;
330
331 while ( recursion_limit-- ) {
332
333 /* Find valid DNS label */
334 src_offset = dns_label ( src, src_offset );
335 if ( src_offset < 0 )
336 return src_offset;
337
338 /* Copy as an uncompressed label */
339 label = ( src->data + src_offset );
340 label_len = *label;
341 len = ( sizeof ( *label ) + label_len );
342 copy_len = ( ( dst_offset < dst->len ) ?
343 ( dst->len - dst_offset ) : 0 );
344 if ( copy_len > len )
345 copy_len = len;
346 memcpy ( ( dst->data + dst_offset ), label, copy_len );
347 src_offset += len;
348 dst_offset += len;
349
350 /* Terminate if we have reached the root */
351 if ( label_len == 0 )
352 return ( dst_offset - dst->offset );
353 }
354
355 /* Recursion limit exceeded */
356 return -EINVAL;
357}
static const void * src
Definition string.h:48
size_t len
Total length of data.
Definition dns.h:26

References dns_name::data, dns_label(), EINVAL, dns_name::len, len, memcpy(), dns_name::offset, and src.

Referenced by dns_copy_fail_okx(), dns_copy_okx(), dns_question(), and dns_xfer_deliver().

◆ dns_skip()

int dns_skip ( struct dns_name * name)
extern

Skip RFC1035-encoded DNS name.

Parameters
nameDNS name
Return values
offsetOffset to next name, or negative error

Definition at line 365 of file dns.c.

365 {
366 unsigned int recursion_limit = name->len; /* Generous upper bound */
367 int offset = name->offset;
368 int prev_offset;
369 const uint8_t *label;
370 size_t label_len;
371
372 while ( recursion_limit-- ) {
373
374 /* Find valid DNS label */
375 prev_offset = offset;
376 offset = dns_label ( name, prev_offset );
377 if ( offset < 0 )
378 return offset;
379
380 /* Terminate if we have reached a compression pointer */
381 if ( offset != prev_offset )
382 return ( prev_offset + sizeof ( uint16_t ) );
383
384 /* Skip this label */
385 label = ( name->data + offset );
386 label_len = *label;
387 offset += ( sizeof ( *label ) + label_len );
388
389 /* Terminate if we have reached the root */
390 if ( label_len == 0 )
391 return offset;
392 }
393
394 /* Recursion limit exceeded */
395 return -EINVAL;
396}
unsigned short uint16_t
Definition stdint.h:11

References dns_label(), EINVAL, name, and offset.

Referenced by dns_list_okx(), dns_skip_search(), and dns_xfer_deliver().