iPXE
Data Structures | Macros | Functions
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. More...
 
#define DNS_IS_COMPRESSED(byte)   ( (byte) & 0xc0 )
 Test for a DNS compression pointer. More...
 
#define DNS_COMPRESSED_OFFSET(word)   ( (word) & ~0xc000 )
 Extract DNS compression pointer. More...
 
#define DNS_LABEL_LEN(byte)   ( (byte) & ~0xc0 )
 Extract DNS label length. More...
 
#define DNS_MAX_LABEL_LEN   0x3f
 Maximum length of a single DNS label. More...
 
#define DNS_MAX_NAME_LEN   255
 Maximum length of a DNS name (mandated by RFC1035 section 2.3.4) More...
 
#define DNS_MAX_CNAME_RECURSION   32
 Maximum depth of CNAME recursion. More...
 
#define DNS_FLAG_RD   0x0100
 Recursion desired flag. More...
 
#define DNS_CLASS_IN   1
 DNS class "IN". More...
 
#define DNS_TYPE_A   1
 Type of a DNS "A" record. More...
 
#define DNS_TYPE_AAAA   28
 Type of a DNS "AAAA" record. More...
 
#define DNS_TYPE_CNAME   5
 Type of a DNS "NAME" record. More...
 

Functions

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

Detailed Description

DNS protocol.

Definition in file dns.h.

Macro Definition Documentation

◆ DNS_PORT

#define DNS_PORT   53

DNS server port.

Definition at line 16 of file dns.h.

◆ DNS_IS_COMPRESSED

#define DNS_IS_COMPRESSED (   byte)    ( (byte) & 0xc0 )

Test for a DNS compression pointer.

Parameters
byteInitial byte
Return values
is_compressedIs a compression pointer

Definition at line 34 of file dns.h.

◆ DNS_COMPRESSED_OFFSET

#define DNS_COMPRESSED_OFFSET (   word)    ( (word) & ~0xc000 )

Extract DNS compression pointer.

Parameters
wordInitial word
Return values
offsetOffset

Definition at line 42 of file dns.h.

◆ DNS_LABEL_LEN

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

Extract DNS label length.

Parameters
byteInitial byte
Return values
lenLabel length

Definition at line 50 of file dns.h.

◆ DNS_MAX_LABEL_LEN

#define DNS_MAX_LABEL_LEN   0x3f

Maximum length of a single DNS label.

Definition at line 53 of file dns.h.

◆ 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 56 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 62 of file dns.h.

◆ DNS_FLAG_RD

#define DNS_FLAG_RD   0x0100

Recursion desired flag.

Definition at line 81 of file dns.h.

◆ DNS_CLASS_IN

#define DNS_CLASS_IN   1

DNS class "IN".

Definition at line 92 of file dns.h.

◆ DNS_TYPE_A

#define DNS_TYPE_A   1

Type of a DNS "A" record.

Definition at line 107 of file dns.h.

◆ DNS_TYPE_AAAA

#define DNS_TYPE_AAAA   28

Type of a DNS "AAAA" record.

Definition at line 118 of file dns.h.

◆ DNS_TYPE_CNAME

#define DNS_TYPE_CNAME   5

Type of a DNS "NAME" record.

Definition at line 129 of file dns.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ dns_encode()

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

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 100 of file dns.c.

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

References c, DNS_MAX_LABEL_LEN, dst, 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 
)

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 216 of file dns.c.

216  {
217  unsigned int recursion_limit = name->len; /* Generous upper bound */
218  int offset = name->offset;
219  const uint8_t *label;
220  size_t decoded_len = 0;
221  size_t label_len;
222  size_t copy_len;
223 
224  while ( recursion_limit-- ) {
225 
226  /* Find valid DNS label */
227  offset = dns_label ( name, offset );
228  if ( offset < 0 )
229  return offset;
230 
231  /* Terminate if we have reached the root */
232  label = ( name->data + offset );
233  label_len = *(label++);
234  if ( label_len == 0 ) {
235  if ( decoded_len < len )
236  *data = '\0';
237  return decoded_len;
238  }
239 
240  /* Prepend '.' if applicable */
241  if ( decoded_len && ( decoded_len++ < len ) )
242  *(data++) = '.';
243 
244  /* Copy label to output buffer */
245  copy_len = ( ( decoded_len < len ) ? ( len - decoded_len ) : 0);
246  if ( copy_len > label_len )
247  copy_len = label_len;
248  memcpy ( data, label, copy_len );
249  data += copy_len;
250  decoded_len += label_len;
251 
252  /* Move to next label */
253  offset += ( sizeof ( *label ) + label_len );
254  }
255 
256  /* Recursion limit exceeded */
257  return -EINVAL;
258 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
const char * name
Definition: ath9k_hw.c:1984
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
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:162

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 
)

Compare DNS names for equality.

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

Definition at line 267 of file dns.c.

267  {
268  unsigned int recursion_limit = first->len; /* Generous upper bound */
269  int first_offset = first->offset;
270  int second_offset = second->offset;
271  const uint8_t *first_label;
272  const uint8_t *second_label;
273  size_t label_len;
274  size_t len;
275 
276  while ( recursion_limit-- ) {
277 
278  /* Find valid DNS labels */
279  first_offset = dns_label ( first, first_offset );
280  if ( first_offset < 0 )
281  return first_offset;
282  second_offset = dns_label ( second, second_offset );
283  if ( second_offset < 0 )
284  return second_offset;
285 
286  /* Compare label lengths */
287  first_label = ( first->data + first_offset );
288  second_label = ( second->data + second_offset );
289  label_len = *(first_label++);
290  if ( label_len != *(second_label++) )
291  return -ENOENT;
292  len = ( sizeof ( *first_label ) + label_len );
293 
294  /* Terminate if we have reached the root */
295  if ( label_len == 0 )
296  return 0;
297 
298  /* Compare label contents (case-insensitively) */
299  while ( label_len-- ) {
300  if ( tolower ( *(first_label++) ) !=
301  tolower ( *(second_label++) ) )
302  return -ENOENT;
303  }
304 
305  /* Move to next labels */
306  first_offset += len;
307  second_offset += len;
308  }
309 
310  /* Recursion limit exceeded */
311  return -EINVAL;
312 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static __always_inline int off_t userptr_t second
Definition: efi_uaccess.h:80
#define ENOENT
No such file or directory.
Definition: errno.h:514
static int tolower(int character)
Convert character to lower case.
Definition: ctype.h:108
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
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:162
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23

References dns_label(), EINVAL, ENOENT, first, len, second, 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 
)

Copy a DNS name.

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

Definition at line 321 of file dns.c.

321  {
322  unsigned int recursion_limit = src->len; /* Generous upper bound */
323  int src_offset = src->offset;
324  size_t dst_offset = dst->offset;
325  const uint8_t *label;
326  size_t label_len;
327  size_t copy_len;
328  size_t len;
329 
330  while ( recursion_limit-- ) {
331 
332  /* Find valid DNS label */
333  src_offset = dns_label ( src, src_offset );
334  if ( src_offset < 0 )
335  return src_offset;
336 
337  /* Copy as an uncompressed label */
338  label = ( src->data + src_offset );
339  label_len = *label;
340  len = ( sizeof ( *label ) + label_len );
341  copy_len = ( ( dst_offset < dst->len ) ?
342  ( dst->len - dst_offset ) : 0 );
343  if ( copy_len > len )
344  copy_len = len;
345  memcpy ( ( dst->data + dst_offset ), label, copy_len );
346  src_offset += len;
347  dst_offset += len;
348 
349  /* Terminate if we have reached the root */
350  if ( label_len == 0 )
351  return ( dst_offset - dst->offset );
352  }
353 
354  /* Recursion limit exceeded */
355  return -EINVAL;
356 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static void const void void * dst
Definition: crypto.h:244
static void const void * src
Definition: crypto.h:244
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
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:162

References dns_label(), dst, EINVAL, len, memcpy(), 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)

Skip RFC1035-encoded DNS name.

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

Definition at line 364 of file dns.c.

364  {
365  unsigned int recursion_limit = name->len; /* Generous upper bound */
366  int offset = name->offset;
367  int prev_offset;
368  const uint8_t *label;
369  size_t label_len;
370 
371  while ( recursion_limit-- ) {
372 
373  /* Find valid DNS label */
374  prev_offset = offset;
375  offset = dns_label ( name, prev_offset );
376  if ( offset < 0 )
377  return offset;
378 
379  /* Terminate if we have reached a compression pointer */
380  if ( offset != prev_offset )
381  return ( prev_offset + sizeof ( uint16_t ) );
382 
383  /* Skip this label */
384  label = ( name->data + offset );
385  label_len = *label;
386  offset += ( sizeof ( *label ) + label_len );
387 
388  /* Terminate if we have reached the root */
389  if ( label_len == 0 )
390  return offset;
391  }
392 
393  /* Recursion limit exceeded */
394  return -EINVAL;
395 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
const char * name
Definition: ath9k_hw.c:1984
unsigned short uint16_t
Definition: stdint.h:11
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned char uint8_t
Definition: stdint.h:10
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:162

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

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