1 /*
2  * Author Jerry Lundström <jerry@dns-oarc.net>
3  * Copyright (c) 2017, OARC, Inc.
4  * All rights reserved.
5  *
6  * This file is part of omg-dns.
7  *
8  * omg-dns is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * omg-dns is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with omg-dns.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef __omg_dns_h
23 #define __omg_dns_h
24 
25 #include <netinet/in.h>
26 #if OMG_DNS_ENABLE_ASSERT
27 #include <assert.h>
28 #define omg_dns_assert(x) assert(x)
29 #else
30 #define omg_dns_assert(x)
31 #endif
32 
33 #define OMG_DNS_VERSION_STR     "1.0.0"
34 #define OMG_DNS_VERSION_MAJOR   1
35 #define OMG_DNS_VERSION_MINOR   0
36 #define OMG_DNS_VERSION_PATCH   0
37 
38 #define OMG_DNS_OK              0
39 #define OMG_DNS_EINVAL          1
40 #define OMG_DNS_EINCOMP         2
41 #define OMG_DNS_ENOMEM          3
42 #define OMG_DNS_EOVERRUN        4
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 const char* omg_dns_version_str(void);
49 int omg_dns_version_major(void);
50 int omg_dns_version_minor(void);
51 int omg_dns_version_patch(void);
52 
53 #define OMG_DNS_LABEL_T_INIT { \
54     0, \
55     0, \
56     0,0,0,0, 0, \
57     0, 0, 0, 0 \
58 }
59 
60 typedef struct omg_dns_label omg_dns_label_t;
61 struct omg_dns_label {
62     size_t          _offset;
63 
64     unsigned short  is_end : 1;
65 
66     unsigned short  have_length : 1;
67     unsigned short  have_offset : 1;
68     unsigned short  have_extension_bits : 1;
69     unsigned short  have_dn : 1;
70 
71     unsigned short  is_complete : 1;
72 
73     uint8_t         length;
74     uint16_t        offset;
75     unsigned short  extension_bits : 2;
76     size_t          dn_offset;
77 };
78 
79 int omg_dns_label_is_end(const omg_dns_label_t* label);
80 int omg_dns_label_have_length(const omg_dns_label_t* label);
81 int omg_dns_label_have_offset(const omg_dns_label_t* label);
82 int omg_dns_label_have_extension_bits(const omg_dns_label_t* label);
83 int omg_dns_label_have_dn(const omg_dns_label_t* label);
84 int omg_dns_label_is_complete(const omg_dns_label_t* label);
85 uint8_t omg_dns_label_length(const omg_dns_label_t* label);
86 uint16_t omg_dns_label_offset(const omg_dns_label_t* label);
87 unsigned short omg_dns_label_extension_bits(const omg_dns_label_t* label);
88 size_t omg_dns_label_dn_offset(const omg_dns_label_t* label);
89 
90 typedef int (*omg_dns_label_callback_t)(const omg_dns_label_t* label, void* context);
91 
92 #define OMG_DNS_RR_T_INIT { \
93     0, \
94     0,0, \
95     0, \
96     0, \
97     0,0,0,0,0,0,0, \
98     0,0, \
99     0, \
100     0,0,0,0,0,0,0,0, \
101 }
102 
103 typedef struct omg_dns_rr omg_dns_rr_t;
104 struct omg_dns_rr {
105     size_t          _offset;
106 
107     omg_dns_label_callback_t    label_callback;
108     void*                       label_callback_context;
109 
110     unsigned short  is_question : 1;
111 
112     unsigned short  have_labels : 1;
113 
114     unsigned short  have_type : 1;
115     unsigned short  have_class : 1;
116     unsigned short  have_ttl : 1;
117     unsigned short  have_rdlength : 1;
118     unsigned short  have_rdata : 1;
119     unsigned short  have_rdata_labels : 1;
120     unsigned short  have_padding : 1;
121 
122     unsigned short  is_complete : 1;
123     size_t          bytes_parsed;
124 
125     size_t          labels;
126 
127     uint16_t        type;
128     uint16_t        class;
129     uint32_t        ttl;
130     uint16_t        rdlength;
131     size_t          rdata_offset;
132     size_t          rdata_labels;
133     size_t          padding_offset;
134     size_t          padding_length;
135 };
136 
137 omg_dns_label_callback_t omg_dns_rr_label_callback(const omg_dns_rr_t* rr);
138 void* omg_dns_rr_label_callback_context(const omg_dns_rr_t* rr);
139 void omg_dns_rr_set_label_callback(omg_dns_rr_t* rr, omg_dns_label_callback_t label_callback, void* label_callback_context);
140 
141 int omg_dns_rr_is_question(const omg_dns_rr_t* rr);
142 int omg_dns_rr_have_labels(const omg_dns_rr_t* rr);
143 int omg_dns_rr_have_type(const omg_dns_rr_t* rr);
144 int omg_dns_rr_have_class(const omg_dns_rr_t* rr);
145 int omg_dns_rr_have_ttl(const omg_dns_rr_t* rr);
146 int omg_dns_rr_have_rdlength(const omg_dns_rr_t* rr);
147 int omg_dns_rr_have_rdata(const omg_dns_rr_t* rr);
148 int omg_dns_rr_have_rdata_labels(const omg_dns_rr_t* rr);
149 int omg_dns_rr_have_padding(const omg_dns_rr_t* rr);
150 int omg_dns_rr_is_complete(const omg_dns_rr_t* rr);
151 size_t omg_dns_rr_bytes_parsed(const omg_dns_rr_t* rr);
152 size_t omg_dns_rr_labels(const omg_dns_rr_t* rr);
153 uint16_t omg_dns_rr_type(const omg_dns_rr_t* rr);
154 uint16_t omg_dns_rr_class(const omg_dns_rr_t* rr);
155 uint32_t omg_dns_rr_ttl(const omg_dns_rr_t* rr);
156 uint16_t omg_dns_rr_rdlength(const omg_dns_rr_t* rr);
157 size_t omg_dns_rr_rdata_offset(const omg_dns_rr_t* rr);
158 size_t omg_dns_rr_rdata_labels(const omg_dns_rr_t* rr);
159 size_t omg_dns_rr_padding_offset(const omg_dns_rr_t* rr);
160 size_t omg_dns_rr_padding_length(const omg_dns_rr_t* rr);
161 size_t omg_dns_rr_num_rdata_labels(const omg_dns_rr_t* rr);
162 
163 typedef int (*omg_dns_rr_callback_t)(int ret, const omg_dns_rr_t* rr, void* context);
164 
165 #define OMG_DNS_T_INIT { \
166     0,0, 0,0, \
167     0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0, 0,0,0,0, 0, \
168     0,0, \
169     0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0 \
170 }
171 
172 typedef struct omg_dns omg_dns_t;
173 struct omg_dns {
174     omg_dns_label_callback_t    label_callback;
175     void*                       label_callback_context;
176 
177     omg_dns_rr_callback_t   rr_callback;
178     void*                   rr_callback_context;
179 
180     unsigned short  have_id : 1;
181 
182     unsigned short  have_qr : 1;
183     unsigned short  have_opcode : 1;
184     unsigned short  have_aa : 1;
185     unsigned short  have_tc : 1;
186     unsigned short  have_rd : 1;
187 
188     unsigned short  have_ra : 1;
189     unsigned short  have_z : 1;
190     unsigned short  have_ad : 1;
191     unsigned short  have_cd : 1;
192     unsigned short  have_rcode : 1;
193 
194     unsigned short  have_qdcount : 1;
195     unsigned short  have_ancount : 1;
196     unsigned short  have_nscount : 1;
197     unsigned short  have_arcount : 1;
198 
199     unsigned short  have_questions : 1;
200     unsigned short  have_answers : 1;
201     unsigned short  have_authorities : 1;
202     unsigned short  have_additionals : 1;
203 
204     unsigned short  have_padding : 1;
205 
206     unsigned short  is_complete : 1;
207     size_t          bytes_parsed;
208 
209     uint16_t        id;
210 
211     unsigned short  qr : 1;
212     unsigned short  opcode : 4;
213     unsigned short  aa : 1;
214     unsigned short  tc : 1;
215     unsigned short  rd : 1;
216 
217     unsigned short  ra : 1;
218     unsigned short  z : 1;
219     unsigned short  ad : 1;
220     unsigned short  cd : 1;
221     unsigned short  rcode : 4;
222 
223     uint16_t        qdcount;
224     uint16_t        ancount;
225     uint16_t        nscount;
226     uint16_t        arcount;
227 
228     size_t          questions;
229     size_t          answers;
230     size_t          authorities;
231     size_t          additionals;
232 
233     size_t          padding_offset;
234     size_t          padding_length;
235 };
236 
237 omg_dns_label_callback_t omg_dns_label_callback(const omg_dns_t* dns);
238 void* omg_dns_label_callback_context(const omg_dns_t* dns);
239 void omg_dns_set_label_callback(omg_dns_t* dns, omg_dns_label_callback_t label_callback, void* label_callback_context);
240 
241 omg_dns_rr_callback_t omg_dns_rr_callback(const omg_dns_t* dns);
242 void* omg_dns_rr_callback_context(const omg_dns_t* dns);
243 void omg_dns_set_rr_callback(omg_dns_t* dns, omg_dns_rr_callback_t rr_callback, void* rr_callback_context);
244 
245 int omg_dns_have_id(const omg_dns_t* dns);
246 int omg_dns_have_qr(const omg_dns_t* dns);
247 int omg_dns_have_opcode(const omg_dns_t* dns);
248 int omg_dns_have_aa(const omg_dns_t* dns);
249 int omg_dns_have_tc(const omg_dns_t* dns);
250 int omg_dns_have_rd(const omg_dns_t* dns);
251 int omg_dns_have_ra(const omg_dns_t* dns);
252 int omg_dns_have_z(const omg_dns_t* dns);
253 int omg_dns_have_ad(const omg_dns_t* dns);
254 int omg_dns_have_cd(const omg_dns_t* dns);
255 int omg_dns_have_rcode(const omg_dns_t* dns);
256 int omg_dns_have_qdcount(const omg_dns_t* dns);
257 int omg_dns_have_ancount(const omg_dns_t* dns);
258 int omg_dns_have_nscount(const omg_dns_t* dns);
259 int omg_dns_have_arcount(const omg_dns_t* dns);
260 int omg_dns_have_questions(const omg_dns_t* dns);
261 int omg_dns_have_answers(const omg_dns_t* dns);
262 int omg_dns_have_authorities(const omg_dns_t* dns);
263 int omg_dns_have_additionals(const omg_dns_t* dns);
264 int omg_dns_have_padding(const omg_dns_t* dns);
265 int omg_dns_is_complete(const omg_dns_t* dns);
266 size_t omg_dns_bytes_parsed(const omg_dns_t* dns);
267 uint16_t omg_dns_id(const omg_dns_t* dns);
268 int omg_dns_qr(const omg_dns_t* dns);
269 int omg_dns_opcode(const omg_dns_t* dns);
270 int omg_dns_aa(const omg_dns_t* dns);
271 int omg_dns_tc(const omg_dns_t* dns);
272 int omg_dns_rd(const omg_dns_t* dns);
273 int omg_dns_ra(const omg_dns_t* dns);
274 int omg_dns_z(const omg_dns_t* dns);
275 int omg_dns_ad(const omg_dns_t* dns);
276 int omg_dns_cd(const omg_dns_t* dns);
277 int omg_dns_rcode(const omg_dns_t* dns);
278 uint16_t omg_dns_qdcount(const omg_dns_t* dns);
279 uint16_t omg_dns_ancount(const omg_dns_t* dns);
280 uint16_t omg_dns_nscount(const omg_dns_t* dns);
281 uint16_t omg_dns_arcount(const omg_dns_t* dns);
282 size_t omg_dns_questions(const omg_dns_t* dns);
283 size_t omg_dns_answers(const omg_dns_t* dns);
284 size_t omg_dns_authorities(const omg_dns_t* dns);
285 size_t omg_dns_additionals(const omg_dns_t* dns);
286 size_t omg_dns_padding_offset(const omg_dns_t* dns);
287 size_t omg_dns_padding_length(const omg_dns_t* dns);
288 
289 int omg_dns_parse_header(omg_dns_t* dns, const uint8_t* buffer, size_t length);
290 int omg_dns_parse(omg_dns_t* dns, const uint8_t* buffer, size_t length);
291 int omg_dns_parse_rr(omg_dns_rr_t* rr, const uint8_t* buffer, size_t length);
292 
293 #ifdef __cplusplus
294 }
295 #endif
296 
297 /*
298  * 2016-12-09 https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
299  */
300 
301 #define OMG_DNS_CLASS_IN        1
302 #define OMG_DNS_CLASS_CH        3
303 #define OMG_DNS_CLASS_HS        4
304 #define OMG_DNS_CLASS_NONE      254
305 #define OMG_DNS_CLASS_ANY       255
306 
307 #define OMG_DNS_TYPE_A          1
308 #define OMG_DNS_TYPE_NS         2
309 #define OMG_DNS_TYPE_MD         3
310 #define OMG_DNS_TYPE_MF         4
311 #define OMG_DNS_TYPE_CNAME      5
312 #define OMG_DNS_TYPE_SOA        6
313 #define OMG_DNS_TYPE_MB         7
314 #define OMG_DNS_TYPE_MG         8
315 #define OMG_DNS_TYPE_MR         9
316 #define OMG_DNS_TYPE_NULL       10
317 #define OMG_DNS_TYPE_WKS        11
318 #define OMG_DNS_TYPE_PTR        12
319 #define OMG_DNS_TYPE_HINFO      13
320 #define OMG_DNS_TYPE_MINFO      14
321 #define OMG_DNS_TYPE_MX         15
322 #define OMG_DNS_TYPE_TXT        16
323 #define OMG_DNS_TYPE_RP         17
324 #define OMG_DNS_TYPE_AFSDB      18
325 #define OMG_DNS_TYPE_X25        19
326 #define OMG_DNS_TYPE_ISDN       20
327 #define OMG_DNS_TYPE_RT         21
328 #define OMG_DNS_TYPE_NSAP       22
329 #define OMG_DNS_TYPE_NSAP_PTR   23
330 #define OMG_DNS_TYPE_SIG        24
331 #define OMG_DNS_TYPE_KEY        25
332 #define OMG_DNS_TYPE_PX         26
333 #define OMG_DNS_TYPE_GPOS       27
334 #define OMG_DNS_TYPE_AAAA       28
335 #define OMG_DNS_TYPE_LOC        29
336 #define OMG_DNS_TYPE_NXT        30
337 #define OMG_DNS_TYPE_EID        31
338 #define OMG_DNS_TYPE_NIMLOC     32
339 #define OMG_DNS_TYPE_SRV        33
340 #define OMG_DNS_TYPE_ATMA       34
341 #define OMG_DNS_TYPE_NAPTR      35
342 #define OMG_DNS_TYPE_KX         36
343 #define OMG_DNS_TYPE_CERT       37
344 #define OMG_DNS_TYPE_A6         38
345 #define OMG_DNS_TYPE_DNAME      39
346 #define OMG_DNS_TYPE_SINK       40
347 #define OMG_DNS_TYPE_OPT        41
348 #define OMG_DNS_TYPE_APL        42
349 #define OMG_DNS_TYPE_DS         43
350 #define OMG_DNS_TYPE_SSHFP      44
351 #define OMG_DNS_TYPE_IPSECKEY   45
352 #define OMG_DNS_TYPE_RRSIG      46
353 #define OMG_DNS_TYPE_NSEC       47
354 #define OMG_DNS_TYPE_DNSKEY     48
355 #define OMG_DNS_TYPE_DHCID      49
356 #define OMG_DNS_TYPE_NSEC3      50
357 #define OMG_DNS_TYPE_NSEC3PARAM 51
358 #define OMG_DNS_TYPE_TLSA       52
359 #define OMG_DNS_TYPE_SMIMEA     53
360 #define OMG_DNS_TYPE_HIP        55
361 #define OMG_DNS_TYPE_NINFO      56
362 #define OMG_DNS_TYPE_RKEY       57
363 #define OMG_DNS_TYPE_TALINK     58
364 #define OMG_DNS_TYPE_CDS        59
365 #define OMG_DNS_TYPE_CDNSKEY    60
366 #define OMG_DNS_TYPE_OPENPGPKEY 61
367 #define OMG_DNS_TYPE_CSYNC      62
368 #define OMG_DNS_TYPE_SPF        99
369 #define OMG_DNS_TYPE_UINFO      100
370 #define OMG_DNS_TYPE_UID        101
371 #define OMG_DNS_TYPE_GID        102
372 #define OMG_DNS_TYPE_UNSPEC     103
373 #define OMG_DNS_TYPE_NID        104
374 #define OMG_DNS_TYPE_L32        105
375 #define OMG_DNS_TYPE_L64        106
376 #define OMG_DNS_TYPE_LP         107
377 #define OMG_DNS_TYPE_EUI48      108
378 #define OMG_DNS_TYPE_EUI64      109
379 #define OMG_DNS_TYPE_TKEY       249
380 #define OMG_DNS_TYPE_TSIG       250
381 #define OMG_DNS_TYPE_IXFR       251
382 #define OMG_DNS_TYPE_AXFR       252
383 #define OMG_DNS_TYPE_MAILB      253
384 #define OMG_DNS_TYPE_MAILA      254
385 #define OMG_DNS_TYPE_ANY        255
386 #define OMG_DNS_TYPE_URI        256
387 #define OMG_DNS_TYPE_CAA        257
388 #define OMG_DNS_TYPE_AVC        258
389 #define OMG_DNS_TYPE_TA         32768
390 #define OMG_DNS_TYPE_DLV        32769
391 
392 #define OMG_DNS_OPCODE_QUERY    0
393 #define OMG_DNS_OPCODE_IQUERY   1
394 #define OMG_DNS_OPCODE_STATUS   2
395 #define OMG_DNS_OPCODE_NOTIFY   4
396 #define OMG_DNS_OPCODE_UPDATE   5
397 
398 #define OMG_DNS_RCODE_NOERROR   0
399 #define OMG_DNS_RCODE_FORMERR   1
400 #define OMG_DNS_RCODE_SERVFAIL  2
401 #define OMG_DNS_RCODE_NXDOMAIN  3
402 #define OMG_DNS_RCODE_NOTIMP    4
403 #define OMG_DNS_RCODE_REFUSED   5
404 #define OMG_DNS_RCODE_YXDOMAIN  6
405 #define OMG_DNS_RCODE_YXRRSET   7
406 #define OMG_DNS_RCODE_NXRRSET   8
407 #define OMG_DNS_RCODE_NOTAUTH   9
408 #define OMG_DNS_RCODE_NOTZONE   10
409 #define OMG_DNS_RCODE_BADVERS   16
410 #define OMG_DNS_RCODE_BADSIG    16
411 #define OMG_DNS_RCODE_BADKEY    17
412 #define OMG_DNS_RCODE_BADTIME   18
413 #define OMG_DNS_RCODE_BADMODE   19
414 #define OMG_DNS_RCODE_BADNAME   20
415 #define OMG_DNS_RCODE_BADALG    21
416 #define OMG_DNS_RCODE_BADTRUNC  22
417 #define OMG_DNS_RCODE_BADCOOKIE 23
418 
419 #define OMG_DNS_AFSDB_SUBTYPE_AFS3LOCSRV    1
420 #define OMG_DNS_AFSDB_SUBTYPE_DCENCA_ROOT   2
421 
422 #define OMG_DNS_DHCID_TYPE_1OCTET       0
423 #define OMG_DNS_DHCID_TYPE_DATAOCTET    1
424 #define OMG_DNS_DHCID_TYPE_CLIENT_DUID  2
425 
426 #define OMG_DNS_EDNS0_OPT_LLQ           1
427 #define OMG_DNS_EDNS0_OPT_UL            2
428 #define OMG_DNS_EDNS0_OPT_NSID          3
429 #define OMG_DNS_EDNS0_OPT_DAU           5
430 #define OMG_DNS_EDNS0_OPT_DHU           6
431 #define OMG_DNS_EDNS0_OPT_N3U           7
432 #define OMG_DNS_EDNS0_OPT_CLIENT_SUBNET 8
433 #define OMG_DNS_EDNS0_OPT_EXPIRE        9
434 #define OMG_DNS_EDNS0_OPT_COOKIE        10
435 #define OMG_DNS_EDNS0_OPT_TCP_KEEPALIVE 11
436 #define OMG_DNS_EDNS0_OPT_PADDING       12
437 #define OMG_DNS_EDNS0_OPT_CHAIN         13
438 #define OMG_DNS_EDNS0_OPT_DEVICEID      26946
439 
440 #endif /* __omg_dns_h */
441