dns_common.h
Go to the documentation of this file.
1 /**
2  * @file dns_common.h
3  * @brief Common DNS routines
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.6
29  **/
30 
31 #ifndef _DNS_COMMON_H
32 #define _DNS_COMMON_H
33 
34 //Dependencies
35 #include "core/net.h"
36 
37 //Maximum recursion limit when parsing domain names
38 #ifndef DNS_NAME_MAX_RECURSION
39  #define DNS_NAME_MAX_RECURSION 4
40 #elif (DNS_NAME_MAX_RECURSION < 1 || DNS_NAME_MAX_RECURSION > 8)
41  #error DNS_NAME_MAX_RECURSION parameter is not valid
42 #endif
43 
44 //Maximum size of DNS messages
45 #define DNS_MESSAGE_MAX_SIZE 512
46 //Maximum size of names
47 #define DNS_NAME_MAX_SIZE 255
48 //Maximum size of labels
49 #define DNS_LABEL_MAX_SIZE 63
50 
51 //Maximum length of reverse DNS names (IPv4)
52 #define DNS_MAX_IPV4_REVERSE_NAME_LEN 15
53 //Maximum length of reverse DNS names (IPv6)
54 #define DNS_MAX_IPV6_REVERSE_NAME_LEN 63
55 
56 //DNS port number
57 #define DNS_PORT 53
58 
59 //End marker
60 #define DNS_END_TAG 0x00
61 //Label compression tag
62 #define DNS_COMPRESSION_TAG 0xC0
63 
64 //Macro definition
65 #define DNS_GET_QUESTION(message, offset) (DnsQuestion *) ((uint8_t *) (message) + (offset))
66 #define DNS_GET_RESOURCE_RECORD(message, offset) (DnsResourceRecord *) ((uint8_t *) (message) + (offset))
67 
68 #define DNS_SET_NSEC_BITMAP(bitmap, type) bitmap[(type) / 8] |= 0x80 >> ((type) % 8)
69 #define DNS_CLR_NSEC_BITMAP(bitmap, type) bitmap[(type) / 8] &= ~(0x80 >> ((type) % 8))
70 
71 //C++ guard
72 #ifdef __cplusplus
73 extern "C" {
74 #endif
75 
76 
77 /**
78  * @brief DNS opcodes
79  **/
80 
81 typedef enum
82 {
83  DNS_OPCODE_QUERY = 0, ///<Query
84  DNS_OPCODE_IQUERY = 1, ///<Inverse query
85  DNS_OPCODE_STATUS = 2, ///<Status
86  DNS_OPCODE_NOTIFY = 4, ///<Notify
87  DNS_OPCODE_UPDATE = 5 ///<Update
89 
90 
91 /**
92  * @brief DNS response codes
93  **/
94 
95 typedef enum
96 {
97  DNS_RCODE_NOERROR = 0, ///<No error
98  DNS_RCODE_FORMERR = 1, ///<Format error
99  DNS_RCODE_SERVFAIL = 2, ///<Server failure
100  DNS_RCODE_NXDOMAIN = 3, ///<Non-existent domain
101  DNS_RCODE_NOTIMP = 4, ///<Not implemented
102  DNS_RCODE_REFUSED = 5, ///<Query refused
103  DNS_RCODE_YXDOMAIN = 6, ///<Name exists when it should not
104  DNS_RCODE_YXRRSET = 7, ///<RR set exists when it should not
105  DNS_RCODE_NXRRSET = 8, ///<RR set that should exist does not
106  DNS_RCODE_NOTAUTH = 9, ///<Server not authoritative for zone
107  DNS_RCODE_NOTZONE = 10, ///<Name not contained in zone
108  DNS_RCODE_BADVERS = 16, ///<Bad OPT version
109  DNS_RCODE_BADSIG = 16, ///<TSIG signature failure
110  DNS_RCODE_BADKEY = 17, ///<Key not recognized
111  DNS_RCODE_BADTIME = 18, ///<Signature out of time window
112  DNS_RCODE_BADMODE = 19, ///<Bad TKEY mode
113  DNS_RCODE_BADNAME = 20, ///<Duplicate key name
114  DNS_RCODE_BADALG = 21, ///<Algorithm not supported
115  DNS_RCODE_BADTRUC = 22, ///<Bad truncation
116  DNS_RCODE_BADCOOKIE = 23 ///<Bad server cookie
118 
119 
120 /**
121  * @brief DNS resource record classes
122  **/
123 
124 typedef enum
125 {
126  DNS_RR_CLASS_IN = 1, ///<Internet
127  DNS_RR_CLASS_CH = 3, ///<Chaos
128  DNS_RR_CLASS_HS = 4, ///<Hesiod
129  DNS_RR_CLASS_ANY = 255 ///<Any class
131 
132 
133 /**
134  * @brief DNS resource record types
135  **/
136 
137 typedef enum
138 {
139  DNS_RR_TYPE_A = 1, ///<Host address
140  DNS_RR_TYPE_NS = 2, ///<Authoritative name server
141  DNS_RR_TYPE_CNAME = 5, ///<Canonical name for an alias
142  DNS_RR_TYPE_SOA = 6, ///<Start of a zone of authority
143  DNS_RR_TYPE_WKS = 11, ///<Well known service description
144  DNS_RR_TYPE_PTR = 12, ///<Domain name pointer
145  DNS_RR_TYPE_HINFO = 13, ///<Host information
146  DNS_RR_TYPE_MINFO = 14, ///<Mailbox or mail list information
147  DNS_RR_TYPE_MX = 15, ///<Mail exchange
148  DNS_RR_TYPE_TXT = 16, ///<Text strings
149  DNS_RR_TYPE_AAAA = 28, ///<IPv6 address
150  DNS_RR_TYPE_NB = 32, ///<NetBIOS name
151  DNS_RR_TYPE_NBSTAT = 33, ///<NetBIOS node status
152  DNS_RR_TYPE_SRV = 33, ///<Server selection
153  DNS_RR_TYPE_NAPTR = 35, ///<Naming authority pointer
154  DNS_RR_TYPE_RRSIG = 46, ///<RRSIG record
155  DNS_RR_TYPE_NSEC = 47, ///<NSEC record
156  DNS_RR_TYPE_DNSKEY = 48, ///<DNSKEY record
157  DNS_RR_TYPE_EUI48 = 108, ///<EUI-48 address
158  DNS_RR_TYPE_EUI64 = 109, ///<EUI-64 address
159  DNS_RR_TYPE_AXFR = 252, ///<Transfer of an entire zone
160  DNS_RR_TYPE_ANY = 255, ///<A request for all records
161  DNS_RR_TYPE_URI = 256 ///<Uniform resource identifier
163 
164 
165 //CC-RX, CodeWarrior or Win32 compiler?
166 #if defined(__CCRX__)
167  #pragma pack
168 #elif defined(__CWCC__) || defined(_WIN32)
169  #pragma pack(push, 1)
170 #endif
171 
172 
173 /**
174  * @brief DNS message header
175  **/
176 
178 {
179  uint16_t id; //0-1
180 #if defined(_CPU_BIG_ENDIAN) && !defined(__ICCRX__)
181  uint8_t qr : 1; //2
182  uint8_t opcode : 4;
183  uint8_t aa : 1;
184  uint8_t tc : 1;
185  uint8_t rd : 1;
186  uint8_t ra : 1; //3
187  uint8_t z : 3;
188  uint8_t rcode : 4;
189 #else
190  uint8_t rd : 1; //2
191  uint8_t tc : 1;
192  uint8_t aa : 1;
193  uint8_t opcode : 4;
194  uint8_t qr : 1;
195  uint8_t rcode : 4; //3
196  uint8_t z : 3;
197  uint8_t ra : 1;
198 #endif
199  uint16_t qdcount; //4-5
200  uint16_t ancount; //6-7
201  uint16_t nscount; //8-9
202  uint16_t arcount; //10-11
203  uint8_t questions[]; //12
205 
206 
207 /**
208  * @brief Question format
209  **/
210 
211 typedef __packed_struct
212 {
213  uint16_t qtype;
214  uint16_t qclass;
216 
217 
218 /**
219  * @brief Resource record format
220  **/
221 
222 typedef __packed_struct
223 {
224  uint16_t rtype; //0-1
225  uint16_t rclass; //2-3
226  uint32_t ttl; //4-7
227  uint16_t rdlength; //8-9
228  uint8_t rdata[]; //10
230 
231 
232 /**
233  * @brief A resource record format
234  **/
235 
236 typedef __packed_struct
237 {
238  uint16_t rtype; //0-1
239  uint16_t rclass; //2-3
240  uint32_t ttl; //4-7
241  uint16_t rdlength; //8-9
242  uint8_t rdata[4]; //10-13
244 
245 
246 /**
247  * @brief AAAA resource record format
248  **/
249 
250 typedef __packed_struct
251 {
252  uint16_t rtype; //0-1
253  uint16_t rclass; //2-3
254  uint32_t ttl; //4-7
255  uint16_t rdlength; //8-9
256  uint8_t rdata[16]; //10-25
258 
259 
260 /**
261  * @brief SRV resource record format
262  **/
263 
264 typedef __packed_struct
265 {
266  uint16_t rtype; //0-1
267  uint16_t rclass; //2-3
268  uint32_t ttl; //4-7
269  uint16_t rdlength; //8-9
270  uint16_t priority; //10-11
271  uint16_t weight; //12-13
272  uint16_t port; //14-15
273  uint8_t target[]; //16
275 
276 
277 //CC-RX, CodeWarrior or Win32 compiler?
278 #if defined(__CCRX__)
279  #pragma unpack
280 #elif defined(__CWCC__) || defined(_WIN32)
281  #pragma pack(pop)
282 #endif
283 
284 //DNS related functions
285 size_t dnsEncodeName(const char_t *src, uint8_t *dest);
286 
287 size_t dnsParseName(const DnsHeader *message, size_t length, size_t pos,
288  uint_t level);
289 
290 int_t dnsCompareName(const DnsHeader *message, size_t length, size_t pos,
291  const char_t *name, uint_t level);
292 
293 int_t dnsCompareEncodedName(const DnsHeader *message1, size_t length1,
294  size_t pos1, const DnsHeader *message2, size_t length2, size_t pos2,
295  uint_t level);
296 
297 void dnsGenerateIpv4ReverseName(Ipv4Addr ipv4Addr, char_t *buffer);
298 void dnsGenerateIpv6ReverseName(const Ipv6Addr *ipv6Addr, char_t *buffer);
299 
300 //C++ guard
301 #ifdef __cplusplus
302 }
303 #endif
304 
305 #endif
@ DNS_RR_TYPE_WKS
Well known service description.
Definition: dns_common.h:143
uint8_t opcode
Definition: dns_common.h:193
@ DNS_OPCODE_IQUERY
Inverse query.
Definition: dns_common.h:84
@ DNS_RCODE_YXRRSET
RR set exists when it should not.
Definition: dns_common.h:104
@ DNS_RR_CLASS_ANY
Any class.
Definition: dns_common.h:129
uint8_t tc
Definition: dns_common.h:191
DnsSrvResourceRecord
Definition: dns_common.h:274
@ DNS_RCODE_BADCOOKIE
Bad server cookie.
Definition: dns_common.h:116
signed int int_t
Definition: compiler_port.h:56
uint16_t weight
Definition: dns_common.h:271
@ DNS_OPCODE_QUERY
Query.
Definition: dns_common.h:83
void dnsGenerateIpv6ReverseName(const Ipv6Addr *ipv6Addr, char_t *buffer)
Generate domain name for reverse DNS lookup (IPv6)
Definition: dns_common.c:482
@ DNS_RR_TYPE_SOA
Start of a zone of authority.
Definition: dns_common.h:142
uint8_t message[]
Definition: chap.h:154
@ DNS_RR_CLASS_CH
Chaos.
Definition: dns_common.h:127
DnsOpcode
DNS opcodes.
Definition: dns_common.h:82
@ DNS_RR_TYPE_MINFO
Mailbox or mail list information.
Definition: dns_common.h:146
Ipv6Addr
Definition: ipv6.h:282
@ DNS_RR_TYPE_NSEC
NSEC record.
Definition: dns_common.h:155
@ DNS_RR_TYPE_EUI64
EUI-64 address.
Definition: dns_common.h:158
@ DNS_RCODE_BADKEY
Key not recognized.
Definition: dns_common.h:110
uint8_t aa
Definition: dns_common.h:192
@ DNS_RCODE_NOTAUTH
Server not authoritative for zone.
Definition: dns_common.h:106
uint16_t rclass
Definition: dns_common.h:225
DnsResponseCode
DNS response codes.
Definition: dns_common.h:96
size_t dnsParseName(const DnsHeader *message, size_t length, size_t pos, uint_t level)
Decode a domain name that uses the DNS name encoding.
Definition: dns_common.c:131
@ DNS_RR_CLASS_IN
Internet.
Definition: dns_common.h:126
char_t name[]
DnsHeader
Definition: dns_common.h:204
@ DNS_OPCODE_STATUS
Status.
Definition: dns_common.h:85
uint8_t rcode
Definition: dns_common.h:195
DnsIpv4AddrResourceRecord
Definition: dns_common.h:243
uint16_t qdcount
Definition: dns_common.h:199
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:324
@ DNS_RCODE_BADVERS
Bad OPT version.
Definition: dns_common.h:108
@ DNS_RCODE_NXDOMAIN
Non-existent domain.
Definition: dns_common.h:100
uint16_t rdlength
Definition: dns_common.h:227
DnsIpv6AddrResourceRecord
Definition: dns_common.h:257
@ DNS_RCODE_NOERROR
No error.
Definition: dns_common.h:97
@ DNS_RR_TYPE_AXFR
Transfer of an entire zone.
Definition: dns_common.h:159
@ DNS_RR_TYPE_ANY
A request for all records.
Definition: dns_common.h:160
@ DNS_RCODE_YXDOMAIN
Name exists when it should not.
Definition: dns_common.h:103
@ DNS_RR_TYPE_NBSTAT
NetBIOS node status.
Definition: dns_common.h:151
@ DNS_RCODE_BADALG
Algorithm not supported.
Definition: dns_common.h:114
@ DNS_RR_TYPE_NB
NetBIOS name.
Definition: dns_common.h:150
int_t dnsCompareEncodedName(const DnsHeader *message1, size_t length1, size_t pos1, const DnsHeader *message2, size_t length2, size_t pos2, uint_t level)
Compare domain names encoded with DNS notation.
Definition: dns_common.c:319
@ DNS_RCODE_REFUSED
Query refused.
Definition: dns_common.h:102
uint16_t qclass
Definition: dns_common.h:214
uint8_t questions[]
Definition: dns_common.h:203
@ DNS_RR_TYPE_A
Host address.
Definition: dns_common.h:139
uint8_t qr
Definition: dns_common.h:194
@ DNS_RR_TYPE_PTR
Domain name pointer.
Definition: dns_common.h:144
@ DNS_OPCODE_NOTIFY
Notify.
Definition: dns_common.h:86
uint16_t ancount
Definition: dns_common.h:200
@ DNS_OPCODE_UPDATE
Update.
Definition: dns_common.h:87
uint8_t ra
Definition: dns_common.h:197
uint8_t length
Definition: tcp.h:375
@ DNS_RCODE_FORMERR
Format error.
Definition: dns_common.h:98
@ DNS_RR_TYPE_NS
Authoritative name server.
Definition: dns_common.h:140
int_t dnsCompareName(const DnsHeader *message, size_t length, size_t pos, const char_t *name, uint_t level)
Compare domain names.
Definition: dns_common.c:213
uint8_t z
Definition: dns_common.h:196
uint16_t port
Definition: dns_common.h:272
@ DNS_RCODE_BADTIME
Signature out of time window.
Definition: dns_common.h:111
char char_t
Definition: compiler_port.h:55
@ DNS_RCODE_BADTRUC
Bad truncation.
Definition: dns_common.h:115
@ DNS_RCODE_BADSIG
TSIG signature failure.
Definition: dns_common.h:109
uint16_t nscount
Definition: dns_common.h:201
@ DNS_RCODE_NOTZONE
Name not contained in zone.
Definition: dns_common.h:107
DnsResourceRecordClass
DNS resource record classes.
Definition: dns_common.h:125
@ DNS_RR_TYPE_TXT
Text strings.
Definition: dns_common.h:148
size_t dnsEncodeName(const char_t *src, uint8_t *dest)
Encode a domain name using the DNS name notation.
Definition: dns_common.c:58
@ DNS_RR_TYPE_DNSKEY
DNSKEY record.
Definition: dns_common.h:156
@ DNS_RCODE_SERVFAIL
Server failure.
Definition: dns_common.h:99
DnsQuestion
Definition: dns_common.h:215
uint8_t rdata[]
Definition: dns_common.h:228
@ DNS_RCODE_BADNAME
Duplicate key name.
Definition: dns_common.h:113
DnsResourceRecordType
DNS resource record types.
Definition: dns_common.h:138
uint16_t arcount
Definition: dns_common.h:202
uint8_t target[]
Definition: dns_common.h:273
@ DNS_RR_TYPE_MX
Mail exchange.
Definition: dns_common.h:147
@ DNS_RR_TYPE_CNAME
Canonical name for an alias.
Definition: dns_common.h:141
void dnsGenerateIpv4ReverseName(Ipv4Addr ipv4Addr, char_t *buffer)
Generate domain name for reverse DNS lookup (IPv4)
Definition: dns_common.c:463
@ DNS_RR_CLASS_HS
Hesiod.
Definition: dns_common.h:128
uint8_t rd
Definition: dns_common.h:190
@ DNS_RR_TYPE_EUI48
EUI-48 address.
Definition: dns_common.h:157
typedef __packed_struct
DNS message header.
Definition: dns_common.h:178
@ DNS_RR_TYPE_SRV
Server selection.
Definition: dns_common.h:152
@ DNS_RCODE_NXRRSET
RR set that should exist does not.
Definition: dns_common.h:105
uint32_t ttl
Definition: dns_common.h:226
@ DNS_RR_TYPE_RRSIG
RRSIG record.
Definition: dns_common.h:154
unsigned int uint_t
Definition: compiler_port.h:57
TCP/IP stack core.
DnsResourceRecord
Definition: dns_common.h:229
@ DNS_RCODE_NOTIMP
Not implemented.
Definition: dns_common.h:101
@ DNS_RR_TYPE_URI
Uniform resource identifier.
Definition: dns_common.h:161
@ DNS_RR_TYPE_AAAA
IPv6 address.
Definition: dns_common.h:149
uint16_t priority
Definition: dns_common.h:270
@ DNS_RR_TYPE_NAPTR
Naming authority pointer.
Definition: dns_common.h:153
@ DNS_RCODE_BADMODE
Bad TKEY mode.
Definition: dns_common.h:112
@ DNS_RR_TYPE_HINFO
Host information.
Definition: dns_common.h:145