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-2024 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.4.0
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 //Label compression tag
60 #define DNS_COMPRESSION_TAG 0xC0
61 
62 //Macro definition
63 #define DNS_GET_QUESTION(message, offset) (DnsQuestion *) ((uint8_t *) (message) + (offset))
64 #define DNS_GET_RESOURCE_RECORD(message, offset) (DnsResourceRecord *) ((uint8_t *) (message) + (offset))
65 
66 #define DNS_SET_NSEC_BITMAP(bitmap, type) bitmap[(type) / 8] |= 0x80 >> ((type) % 8)
67 #define DNS_CLR_NSEC_BITMAP(bitmap, type) bitmap[(type) / 8] &= ~(0x80 >> ((type) % 8))
68 
69 //C++ guard
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 
74 
75 /**
76  * @brief DNS opcodes
77  **/
78 
79 typedef enum
80 {
81  DNS_OPCODE_QUERY = 0, ///<Query
82  DNS_OPCODE_IQUERY = 1, ///<Inverse query
83  DNS_OPCODE_STATUS = 2, ///<Status
84  DNS_OPCODE_NOTIFY = 4, ///<Notify
85  DNS_OPCODE_UPDATE = 5 ///<Update
87 
88 
89 /**
90  * @brief DNS response codes
91  **/
92 
93 typedef enum
94 {
95  DNS_RCODE_NOERROR = 0, ///<No error
96  DNS_RCODE_FORMERR = 1, ///<Format error
97  DNS_RCODE_SERVFAIL = 2, ///<Server failure
98  DNS_RCODE_NXDOMAIN = 3, ///<Non-existent domain
99  DNS_RCODE_NOTIMP = 4, ///<Not implemented
100  DNS_RCODE_REFUSED = 5, ///<Query refused
101  DNS_RCODE_YXDOMAIN = 6, ///<Name exists when it should not
102  DNS_RCODE_YXRRSET = 7, ///<RR set exists when it should not
103  DNS_RCODE_NXRRSET = 8, ///<RR set that should exist does not
104  DNS_RCODE_NOTAUTH = 9, ///<Server not authoritative for zone
105  DNS_RCODE_NOTZONE = 10, ///<Name not contained in zone
106  DNS_RCODE_BADVERS = 16, ///<Bad OPT version
107  DNS_RCODE_BADSIG = 16, ///<TSIG signature failure
108  DNS_RCODE_BADKEY = 17, ///<Key not recognized
109  DNS_RCODE_BADTIME = 18, ///<Signature out of time window
110  DNS_RCODE_BADMODE = 19, ///<Bad TKEY mode
111  DNS_RCODE_BADNAME = 20, ///<Duplicate key name
112  DNS_RCODE_BADALG = 21, ///<Algorithm not supported
113  DNS_RCODE_BADTRUC = 22, ///<Bad truncation
114  DNS_RCODE_BADCOOKIE = 23 ///<Bad server cookie
116 
117 
118 /**
119  * @brief DNS resource record classes
120  **/
121 
122 typedef enum
123 {
124  DNS_RR_CLASS_IN = 1, ///<Internet
125  DNS_RR_CLASS_CH = 3, ///<Chaos
126  DNS_RR_CLASS_HS = 4, ///<Hesiod
127  DNS_RR_CLASS_ANY = 255 ///<Any class
129 
130 
131 /**
132  * @brief DNS resource record types
133  **/
134 
135 typedef enum
136 {
137  DNS_RR_TYPE_A = 1, ///<Host address
138  DNS_RR_TYPE_NS = 2, ///<Authoritative name server
139  DNS_RR_TYPE_CNAME = 5, ///<Canonical name for an alias
140  DNS_RR_TYPE_SOA = 6, ///<Start of a zone of authority
141  DNS_RR_TYPE_WKS = 11, ///<Well known service description
142  DNS_RR_TYPE_PTR = 12, ///<Domain name pointer
143  DNS_RR_TYPE_HINFO = 13, ///<Host information
144  DNS_RR_TYPE_MINFO = 14, ///<Mailbox or mail list information
145  DNS_RR_TYPE_MX = 15, ///<Mail exchange
146  DNS_RR_TYPE_TXT = 16, ///<Text strings
147  DNS_RR_TYPE_AAAA = 28, ///<IPv6 address
148  DNS_RR_TYPE_NB = 32, ///<NetBIOS name service
149  DNS_RR_TYPE_SRV = 33, ///<Server selection
150  DNS_RR_TYPE_NAPTR = 35, ///<Naming authority pointer
151  DNS_RR_TYPE_NSEC = 47, ///<NSEC record
152  DNS_RR_TYPE_EUI48 = 108, ///<EUI-48 address
153  DNS_RR_TYPE_EUI64 = 109, ///<EUI-64 address
154  DNS_RR_TYPE_AXFR = 252, ///<Transfer of an entire zone
155  DNS_RR_TYPE_ANY = 255, ///<A request for all records
156  DNS_RR_TYPE_URI = 256 ///<Uniform resource identifier
158 
159 
160 //CC-RX, CodeWarrior or Win32 compiler?
161 #if defined(__CCRX__)
162  #pragma pack
163 #elif defined(__CWCC__) || defined(_WIN32)
164  #pragma pack(push, 1)
165 #endif
166 
167 
168 /**
169  * @brief DNS message header
170  **/
171 
173 {
174  uint16_t id; //0-1
175 #if defined(_CPU_BIG_ENDIAN) && !defined(__ICCRX__)
176  uint8_t qr : 1; //2
177  uint8_t opcode : 4;
178  uint8_t aa : 1;
179  uint8_t tc : 1;
180  uint8_t rd : 1;
181  uint8_t ra : 1; //3
182  uint8_t z : 3;
183  uint8_t rcode : 4;
184 #else
185  uint8_t rd : 1; //2
186  uint8_t tc : 1;
187  uint8_t aa : 1;
188  uint8_t opcode : 4;
189  uint8_t qr : 1;
190  uint8_t rcode : 4; //3
191  uint8_t z : 3;
192  uint8_t ra : 1;
193 #endif
194  uint16_t qdcount; //4-5
195  uint16_t ancount; //6-7
196  uint16_t nscount; //8-9
197  uint16_t arcount; //10-11
198  uint8_t questions[]; //12
200 
201 
202 /**
203  * @brief Question format
204  **/
205 
206 typedef __packed_struct
207 {
208  uint16_t qtype;
209  uint16_t qclass;
211 
212 
213 /**
214  * @brief Resource record format
215  **/
216 
217 typedef __packed_struct
218 {
219  uint16_t rtype; //0-1
220  uint16_t rclass; //2-3
221  uint32_t ttl; //4-7
222  uint16_t rdlength; //8-9
223  uint8_t rdata[]; //10
225 
226 
227 /**
228  * @brief A resource record format
229  **/
230 
231 typedef __packed_struct
232 {
233  uint16_t rtype; //0-1
234  uint16_t rclass; //2-3
235  uint32_t ttl; //4-7
236  uint16_t rdlength; //8-9
237  uint8_t rdata[4]; //10-13
239 
240 
241 /**
242  * @brief AAAA resource record format
243  **/
244 
245 typedef __packed_struct
246 {
247  uint16_t rtype; //0-1
248  uint16_t rclass; //2-3
249  uint32_t ttl; //4-7
250  uint16_t rdlength; //8-9
251  uint8_t rdata[16]; //10-25
253 
254 
255 /**
256  * @brief SRV resource record format
257  **/
258 
259 typedef __packed_struct
260 {
261  uint16_t rtype; //0-1
262  uint16_t rclass; //2-3
263  uint32_t ttl; //4-7
264  uint16_t rdlength; //8-9
265  uint16_t priority; //10-11
266  uint16_t weight; //12-13
267  uint16_t port; //14-15
268  uint8_t target[]; //16
270 
271 
272 //CC-RX, CodeWarrior or Win32 compiler?
273 #if defined(__CCRX__)
274  #pragma unpack
275 #elif defined(__CWCC__) || defined(_WIN32)
276  #pragma pack(pop)
277 #endif
278 
279 //DNS related functions
280 size_t dnsEncodeName(const char_t *src, uint8_t *dest);
281 
282 size_t dnsParseName(const DnsHeader *message, size_t length, size_t pos,
283  char_t *dest, uint_t level);
284 
285 int_t dnsCompareName(const DnsHeader *message, size_t length, size_t pos,
286  const char_t *name, uint_t level);
287 
288 int_t dnsCompareEncodedName(const DnsHeader *message1, size_t length1,
289  size_t pos1, const DnsHeader *message2, size_t length2, size_t pos2,
290  uint_t level);
291 
292 void dnsGenerateIpv4ReverseName(Ipv4Addr ipv4Addr, char_t *buffer);
293 void dnsGenerateIpv6ReverseName(const Ipv6Addr *ipv6Addr, char_t *buffer);
294 
295 //C++ guard
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif
uint8_t message[]
Definition: chap.h:154
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
uint16_t qdcount
Definition: dns_common.h:194
uint8_t rd
Definition: dns_common.h:185
DnsIpv6AddrResourceRecord
Definition: dns_common.h:252
uint16_t priority
Definition: dns_common.h:265
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:242
void dnsGenerateIpv4ReverseName(Ipv4Addr ipv4Addr, char_t *buffer)
Generate domain name for reverse DNS lookup (IPv4)
Definition: dns_common.c:479
uint8_t questions[]
Definition: dns_common.h:198
DnsSrvResourceRecord
Definition: dns_common.h:269
uint16_t ancount
Definition: dns_common.h:195
uint16_t weight
Definition: dns_common.h:266
DnsHeader
Definition: dns_common.h:199
uint8_t aa
Definition: dns_common.h:187
uint32_t ttl
Definition: dns_common.h:221
DnsResourceRecord
Definition: dns_common.h:224
uint8_t qr
Definition: dns_common.h:189
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:341
uint8_t opcode
Definition: dns_common.h:188
uint8_t tc
Definition: dns_common.h:186
size_t dnsParseName(const DnsHeader *message, size_t length, size_t pos, char_t *dest, uint_t level)
Decode a domain name that uses the DNS name encoding.
Definition: dns_common.c:132
uint16_t arcount
Definition: dns_common.h:197
DnsResponseCode
DNS response codes.
Definition: dns_common.h:94
@ DNS_RCODE_BADALG
Algorithm not supported.
Definition: dns_common.h:112
@ DNS_RCODE_SERVFAIL
Server failure.
Definition: dns_common.h:97
@ DNS_RCODE_BADKEY
Key not recognized.
Definition: dns_common.h:108
@ DNS_RCODE_REFUSED
Query refused.
Definition: dns_common.h:100
@ DNS_RCODE_NXRRSET
RR set that should exist does not.
Definition: dns_common.h:103
@ DNS_RCODE_NXDOMAIN
Non-existent domain.
Definition: dns_common.h:98
@ DNS_RCODE_BADVERS
Bad OPT version.
Definition: dns_common.h:106
@ DNS_RCODE_BADTIME
Signature out of time window.
Definition: dns_common.h:109
@ DNS_RCODE_BADNAME
Duplicate key name.
Definition: dns_common.h:111
@ DNS_RCODE_BADCOOKIE
Bad server cookie.
Definition: dns_common.h:114
@ DNS_RCODE_BADTRUC
Bad truncation.
Definition: dns_common.h:113
@ DNS_RCODE_NOERROR
No error.
Definition: dns_common.h:95
@ DNS_RCODE_NOTAUTH
Server not authoritative for zone.
Definition: dns_common.h:104
@ DNS_RCODE_YXDOMAIN
Name exists when it should not.
Definition: dns_common.h:101
@ DNS_RCODE_YXRRSET
RR set exists when it should not.
Definition: dns_common.h:102
@ DNS_RCODE_BADMODE
Bad TKEY mode.
Definition: dns_common.h:110
@ DNS_RCODE_NOTIMP
Not implemented.
Definition: dns_common.h:99
@ DNS_RCODE_NOTZONE
Name not contained in zone.
Definition: dns_common.h:105
@ DNS_RCODE_BADSIG
TSIG signature failure.
Definition: dns_common.h:107
@ DNS_RCODE_FORMERR
Format error.
Definition: dns_common.h:96
uint8_t ra
Definition: dns_common.h:192
DnsIpv4AddrResourceRecord
Definition: dns_common.h:238
uint16_t port
Definition: dns_common.h:267
uint8_t target[]
Definition: dns_common.h:268
DnsOpcode
DNS opcodes.
Definition: dns_common.h:80
@ DNS_OPCODE_NOTIFY
Notify.
Definition: dns_common.h:84
@ DNS_OPCODE_IQUERY
Inverse query.
Definition: dns_common.h:82
@ DNS_OPCODE_UPDATE
Update.
Definition: dns_common.h:85
@ DNS_OPCODE_STATUS
Status.
Definition: dns_common.h:83
@ DNS_OPCODE_QUERY
Query.
Definition: dns_common.h:81
DnsResourceRecordType
DNS resource record types.
Definition: dns_common.h:136
@ DNS_RR_TYPE_MX
Mail exchange.
Definition: dns_common.h:145
@ DNS_RR_TYPE_PTR
Domain name pointer.
Definition: dns_common.h:142
@ DNS_RR_TYPE_CNAME
Canonical name for an alias.
Definition: dns_common.h:139
@ DNS_RR_TYPE_NB
NetBIOS name service.
Definition: dns_common.h:148
@ DNS_RR_TYPE_SRV
Server selection.
Definition: dns_common.h:149
@ DNS_RR_TYPE_WKS
Well known service description.
Definition: dns_common.h:141
@ DNS_RR_TYPE_HINFO
Host information.
Definition: dns_common.h:143
@ DNS_RR_TYPE_A
Host address.
Definition: dns_common.h:137
@ DNS_RR_TYPE_AXFR
Transfer of an entire zone.
Definition: dns_common.h:154
@ DNS_RR_TYPE_AAAA
IPv6 address.
Definition: dns_common.h:147
@ DNS_RR_TYPE_EUI64
EUI-64 address.
Definition: dns_common.h:153
@ DNS_RR_TYPE_TXT
Text strings.
Definition: dns_common.h:146
@ DNS_RR_TYPE_ANY
A request for all records.
Definition: dns_common.h:155
@ DNS_RR_TYPE_NS
Authoritative name server.
Definition: dns_common.h:138
@ DNS_RR_TYPE_URI
Uniform resource identifier.
Definition: dns_common.h:156
@ DNS_RR_TYPE_MINFO
Mailbox or mail list information.
Definition: dns_common.h:144
@ DNS_RR_TYPE_NAPTR
Naming authority pointer.
Definition: dns_common.h:150
@ DNS_RR_TYPE_NSEC
NSEC record.
Definition: dns_common.h:151
@ DNS_RR_TYPE_SOA
Start of a zone of authority.
Definition: dns_common.h:140
@ DNS_RR_TYPE_EUI48
EUI-48 address.
Definition: dns_common.h:152
size_t dnsEncodeName(const char_t *src, uint8_t *dest)
Encode a domain name using the DNS name notation.
Definition: dns_common.c:58
DnsResourceRecordClass
DNS resource record classes.
Definition: dns_common.h:123
@ DNS_RR_CLASS_HS
Hesiod.
Definition: dns_common.h:126
@ DNS_RR_CLASS_ANY
Any class.
Definition: dns_common.h:127
@ DNS_RR_CLASS_CH
Chaos.
Definition: dns_common.h:125
@ DNS_RR_CLASS_IN
Internet.
Definition: dns_common.h:124
uint16_t nscount
Definition: dns_common.h:196
DnsQuestion
Definition: dns_common.h:210
uint8_t z
Definition: dns_common.h:191
uint16_t rclass
Definition: dns_common.h:220
uint8_t rdata[]
Definition: dns_common.h:223
typedef __packed_struct
DNS message header.
Definition: dns_common.h:173
uint16_t qclass
Definition: dns_common.h:209
uint8_t rcode
Definition: dns_common.h:190
uint16_t rdlength
Definition: dns_common.h:222
void dnsGenerateIpv6ReverseName(const Ipv6Addr *ipv6Addr, char_t *buffer)
Generate domain name for reverse DNS lookup (IPv6)
Definition: dns_common.c:498
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:267
Ipv6Addr
Definition: ipv6.h:251
TCP/IP stack core.
char_t name[]
uint8_t length
Definition: tcp.h:368