1 #ifndef _IPXE_DNS_H
2 #define _IPXE_DNS_H
3 
4 /** @file
5  *
6  * DNS protocol
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/in.h>
14 
15 /** DNS server port */
16 #define DNS_PORT 53
17 
18 /** An RFC1035-encoded DNS name */
19 struct dns_name {
20 	/** Start of data */
21 	void *data;
22 	/** Offset of name within data */
23 	size_t offset;
24 	/** Total length of data */
25 	size_t len;
26 };
27 
28 /**
29  * Test for a DNS compression pointer
30  *
31  * @v byte		Initial byte
32  * @ret is_compressed	Is a compression pointer
33  */
34 #define DNS_IS_COMPRESSED( byte ) ( (byte) & 0xc0 )
35 
36 /**
37  * Extract DNS compression pointer
38  *
39  * @v word		Initial word
40  * @ret offset		Offset
41  */
42 #define DNS_COMPRESSED_OFFSET( word ) ( (word) & ~0xc000 )
43 
44 /**
45  * Extract DNS label length
46  *
47  * @v byte		Initial byte
48  * @ret len		Label length
49  */
50 #define DNS_LABEL_LEN( byte ) ( (byte) & ~0xc0 )
51 
52 /** Maximum length of a single DNS label */
53 #define DNS_MAX_LABEL_LEN 0x3f
54 
55 /** Maximum length of a DNS name (mandated by RFC1035 section 2.3.4) */
56 #define DNS_MAX_NAME_LEN 255
57 
58 /** Maximum depth of CNAME recursion
59  *
60  * This is a policy decision.
61  */
62 #define DNS_MAX_CNAME_RECURSION 32
63 
64 /** A DNS packet header */
65 struct dns_header {
66 	/** Query identifier */
67 	uint16_t id;
68 	/** Flags */
69 	uint16_t flags;
70 	/** Number of question records */
71 	uint16_t qdcount;
72 	/** Number of answer records */
73 	uint16_t ancount;
74 	/** Number of name server records */
75 	uint16_t nscount;
76 	/** Number of additional records */
77 	uint16_t arcount;
78 } __attribute__ (( packed ));
79 
80 /** Recursion desired flag */
81 #define DNS_FLAG_RD 0x0100
82 
83 /** A DNS question */
84 struct dns_question {
85 	/** Query type */
86 	uint16_t qtype;
87 	/** Query class */
88 	uint16_t qclass;
89 } __attribute__ (( packed ));
90 
91 /** DNS class "IN" */
92 #define DNS_CLASS_IN 1
93 
94 /** A DNS resource record */
95 struct dns_rr_common {
96 	/** Type */
97 	uint16_t type;
98 	/** Class */
99 	uint16_t class;
100 	/** Time to live */
101 	uint32_t ttl;
102 	/** Resource data length */
103 	uint16_t rdlength;
104 } __attribute__ (( packed ));
105 
106 /** Type of a DNS "A" record */
107 #define DNS_TYPE_A 1
108 
109 /** A DNS "A" record */
110 struct dns_rr_a {
111 	/** Common fields */
112 	struct dns_rr_common common;
113 	/** IPv4 address */
114 	struct in_addr in_addr;
115 } __attribute__ (( packed ));
116 
117 /** Type of a DNS "AAAA" record */
118 #define DNS_TYPE_AAAA 28
119 
120 /** A DNS "AAAA" record */
121 struct dns_rr_aaaa {
122 	/** Common fields */
123 	struct dns_rr_common common;
124 	/** IPv6 address */
125 	struct in6_addr in6_addr;
126 } __attribute__ (( packed ));
127 
128 /** Type of a DNS "NAME" record */
129 #define DNS_TYPE_CNAME 5
130 
131 /** A DNS "CNAME" record */
132 struct dns_rr_cname {
133 	/** Common fields */
134 	struct dns_rr_common common;
135 } __attribute__ (( packed ));
136 
137 /** A DNS resource record */
138 union dns_rr {
139 	/** Common fields */
140 	struct dns_rr_common common;
141 	/** "A" record */
142 	struct dns_rr_a a;
143 	/** "AAAA" record */
144 	struct dns_rr_aaaa aaaa;
145 	/** "CNAME" record */
146 	struct dns_rr_cname cname;
147 };
148 
149 extern int dns_encode ( const char *string, struct dns_name *name );
150 extern int dns_decode ( struct dns_name *name, char *data, size_t len );
151 extern int dns_compare ( struct dns_name *first, struct dns_name *second );
152 extern int dns_copy ( struct dns_name *src, struct dns_name *dst );
153 extern int dns_skip ( struct dns_name *name );
154 
155 #endif /* _IPXE_DNS_H */
156