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)
 
 FILE_SECBOOT (PERMITTED)
 
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 17 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 35 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 43 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 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.

◆ 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.

◆ DNS_FLAG_RD

#define DNS_FLAG_RD   0x0100

Recursion desired flag.

Definition at line 82 of file dns.h.

◆ DNS_CLASS_IN

#define DNS_CLASS_IN   1

DNS class "IN".

Definition at line 93 of file dns.h.

◆ DNS_TYPE_A

#define DNS_TYPE_A   1

Type of a DNS "A" record.

Definition at line 108 of file dns.h.

◆ DNS_TYPE_AAAA

#define DNS_TYPE_AAAA   28

Type of a DNS "AAAA" record.

Definition at line 119 of file dns.h.

◆ DNS_TYPE_CNAME

#define DNS_TYPE_CNAME   5

Type of a DNS "NAME" record.

Definition at line 130 of file dns.h.

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 
)

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 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
const char * name
Definition: ath9k_hw.c:1986
#define DNS_MAX_LABEL_LEN
Maximum length of a single DNS label.
Definition: dns.h:54
uint32_t start
Starting offset.
Definition: netvsc.h:12
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10
uint32_t end
Ending offset.
Definition: netvsc.h:18

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 
)

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 */
228  offset = dns_label ( name, offset );
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 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
const char * name
Definition: ath9k_hw.c:1986
A text label widget.
Definition: label.h:16
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
unsigned char uint8_t
Definition: stdint.h:10
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:163
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

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 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 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
uint32_t first
First block in range.
Definition: pccrr.h:15
#define ENOENT
No such file or directory.
Definition: errno.h:515
void * data
Start of data.
Definition: dns.h:22
ring len
Length.
Definition: dwmac.h:231
static int tolower(int character)
Convert character to lower case.
Definition: ctype.h:109
size_t offset
Offset of name within data.
Definition: dns.h:24
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:163

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 
)

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 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
A text label widget.
Definition: label.h:16
void * data
Start of data.
Definition: dns.h:22
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static const void * src
Definition: string.h:48
ring len
Length.
Definition: dwmac.h:231
size_t offset
Offset of name within data.
Definition: dns.h:24
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:163
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)

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 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
const char * name
Definition: ath9k_hw.c:1986
unsigned short uint16_t
Definition: stdint.h:11
A text label widget.
Definition: label.h:16
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:163
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

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

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