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

88  {
89  uint8_t *start = ( name->data + name->offset );
90  uint8_t *end = ( name->data + name->len );
91  uint8_t *dst = start;
92  size_t len = 0;
93  char c;
94 
95  /* Encode name */
96  while ( ( c = *(string++) ) ) {
97 
98  /* Handle '.' separators */
99  if ( c == '.' ) {
100 
101  /* Reject consecutive '.' */
102  if ( ( len == 0 ) && ( dst != start ) )
103  return -EINVAL;
104 
105  /* Terminate if this is the trailing '.' */
106  if ( *string == '\0' )
107  break;
108 
109  /* Reject initial non-terminating '.' */
110  if ( len == 0 )
111  return -EINVAL;
112 
113  /* Reset length */
114  len = 0;
115 
116  } else {
117 
118  /* Increment length */
119  len++;
120 
121  /* Check for overflow */
122  if ( len > DNS_MAX_LABEL_LEN )
123  return -EINVAL;
124  }
125 
126  /* Copy byte, update length */
127  if ( ++dst < end ) {
128  *dst = c;
129  dst[-len] = len;
130  }
131  }
132 
133  /* Add terminating root marker */
134  if ( len )
135  dst++;
136  if ( dst < end )
137  *dst = '\0';
138  dst++;
139 
140  return ( dst - start );
141 }
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
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, 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 204 of file dns.c.

204  {
205  unsigned int recursion_limit = name->len; /* Generous upper bound */
206  int offset = name->offset;
207  const uint8_t *label;
208  size_t decoded_len = 0;
209  size_t label_len;
210  size_t copy_len;
211 
212  while ( recursion_limit-- ) {
213 
214  /* Find valid DNS label */
215  offset = dns_label ( name, offset );
216  if ( offset < 0 )
217  return offset;
218 
219  /* Terminate if we have reached the root */
220  label = ( name->data + offset );
221  label_len = *(label++);
222  if ( label_len == 0 ) {
223  if ( decoded_len < len )
224  *data = '\0';
225  return decoded_len;
226  }
227 
228  /* Prepend '.' if applicable */
229  if ( decoded_len && ( decoded_len++ < len ) )
230  *(data++) = '.';
231 
232  /* Copy label to output buffer */
233  copy_len = ( ( decoded_len < len ) ? ( len - decoded_len ) : 0);
234  if ( copy_len > label_len )
235  copy_len = label_len;
236  memcpy ( data, label, copy_len );
237  data += copy_len;
238  decoded_len += label_len;
239 
240  /* Move to next label */
241  offset += ( sizeof ( *label ) + label_len );
242  }
243 
244  /* Recursion limit exceeded */
245  return -EINVAL;
246 }
#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
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:150
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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

255  {
256  unsigned int recursion_limit = first->len; /* Generous upper bound */
257  int first_offset = first->offset;
258  int second_offset = second->offset;
259  const uint8_t *first_label;
260  const uint8_t *second_label;
261  size_t label_len;
262  size_t len;
263 
264  while ( recursion_limit-- ) {
265 
266  /* Find valid DNS labels */
267  first_offset = dns_label ( first, first_offset );
268  if ( first_offset < 0 )
269  return first_offset;
270  second_offset = dns_label ( second, second_offset );
271  if ( second_offset < 0 )
272  return second_offset;
273 
274  /* Compare label lengths */
275  first_label = ( first->data + first_offset );
276  second_label = ( second->data + second_offset );
277  label_len = *(first_label++);
278  if ( label_len != *(second_label++) )
279  return -ENOENT;
280  len = ( sizeof ( *first_label ) + label_len );
281 
282  /* Terminate if we have reached the root */
283  if ( label_len == 0 )
284  return 0;
285 
286  /* Compare label contents (case-insensitively) */
287  while ( label_len-- ) {
288  if ( tolower ( *(first_label++) ) !=
289  tolower ( *(second_label++) ) )
290  return -ENOENT;
291  }
292 
293  /* Move to next labels */
294  first_offset += len;
295  second_offset += len;
296  }
297 
298  /* Recursion limit exceeded */
299  return -EINVAL;
300 }
#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:97
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:150
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 309 of file dns.c.

309  {
310  unsigned int recursion_limit = src->len; /* Generous upper bound */
311  int src_offset = src->offset;
312  size_t dst_offset = dst->offset;
313  const uint8_t *label;
314  size_t label_len;
315  size_t copy_len;
316  size_t len;
317 
318  while ( recursion_limit-- ) {
319 
320  /* Find valid DNS label */
321  src_offset = dns_label ( src, src_offset );
322  if ( src_offset < 0 )
323  return src_offset;
324 
325  /* Copy as an uncompressed label */
326  label = ( src->data + src_offset );
327  label_len = *label;
328  len = ( sizeof ( *label ) + label_len );
329  copy_len = ( ( dst_offset < dst->len ) ?
330  ( dst->len - dst_offset ) : 0 );
331  if ( copy_len > len )
332  copy_len = len;
333  memcpy ( ( dst->data + dst_offset ), label, copy_len );
334  src_offset += len;
335  dst_offset += len;
336 
337  /* Terminate if we have reached the root */
338  if ( label_len == 0 )
339  return ( dst_offset - dst->offset );
340  }
341 
342  /* Recursion limit exceeded */
343  return -EINVAL;
344 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
void * data
Start of data.
Definition: dns.h:21
void * memcpy(void *dest, const void *src, size_t len) __nonnull
size_t offset
Offset of name within data.
Definition: dns.h:23
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
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:150
size_t len
Total length of data.
Definition: dns.h:25

References dns_name::data, dns_label(), EINVAL, len, dns_name::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 352 of file dns.c.

352  {
353  unsigned int recursion_limit = name->len; /* Generous upper bound */
354  int offset = name->offset;
355  int prev_offset;
356  const uint8_t *label;
357  size_t label_len;
358 
359  while ( recursion_limit-- ) {
360 
361  /* Find valid DNS label */
362  prev_offset = offset;
363  offset = dns_label ( name, prev_offset );
364  if ( offset < 0 )
365  return offset;
366 
367  /* Terminate if we have reached a compression pointer */
368  if ( offset != prev_offset )
369  return ( prev_offset + sizeof ( uint16_t ) );
370 
371  /* Skip this label */
372  label = ( name->data + offset );
373  label_len = *label;
374  offset += ( sizeof ( *label ) + label_len );
375 
376  /* Terminate if we have reached the root */
377  if ( label_len == 0 )
378  return offset;
379  }
380 
381  /* Recursion limit exceeded */
382  return -EINVAL;
383 }
#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:150

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

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