1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup
36 * @ingroup dnscore
37 * @brief
38 *
39 *
40 *
41 * @{
42 *
43 *----------------------------------------------------------------------------*/
44
45
46 #include "dnscore/dnscore-config.h"
47 #include <stdlib.h>
48 #include <arpa/inet.h>
49 #include <ctype.h>
50 #include <netdb.h>
51 #include <strings.h>
52
53 #include "dnscore/rfc.h"
54 #include "dnscore/ctrl-rfc.h"
55 #include "dnscore/string_set.h"
56 #include "dnscore/ptr_set.h"
57 #include "dnscore/u32_set.h"
58 #include "dnscore/format.h"
59 #include "dnscore/mutex.h"
60
61 #define DNSCORE_RFC_C
62
63 /*------------------------------------------------------------------------------
64 * GLOBAL VARIABLES */
65
66 static mutex_t rfc_init_mtx = MUTEX_INITIALIZER;
67 static string_node* class_set = NULL;
68 static string_node* type_set = NULL;
69 static string_node* dnssec_algo_set = NULL;
70 static string_set word_set = NULL;
71 static bool rfc_init_done = FALSE;
72
73 const class_table qclass[] = {
74 { CLASS_IN, CLASS_IN_NAME },
75 { CLASS_CS, CLASS_CS_NAME },
76 { CLASS_CH, CLASS_CH_NAME },
77 { CLASS_HS, CLASS_HS_NAME },
78 { CLASS_CTRL, CLASS_CTRL_NAME },
79
80 { CLASS_NONE, CLASS_NONE_NAME },
81 { CLASS_ANY, CLASS_ANY_NAME },
82 { 0, NULL }
83 };
84
85
86 const type_table qtype[] = {
87 { TYPE_A, TYPE_A_NAME }, // 1
88 { TYPE_NS, TYPE_NS_NAME }, // 2
89 { TYPE_MD, TYPE_MD_NAME }, // 3
90 { TYPE_MF, TYPE_MF_NAME }, // 4
91 { TYPE_CNAME, TYPE_CNAME_NAME }, // 5
92 { TYPE_SOA, TYPE_SOA_NAME }, // 6
93 { TYPE_MB, TYPE_MB_NAME }, // 7
94 { TYPE_MG, TYPE_MG_NAME }, // 8
95 { TYPE_MR, TYPE_MR_NAME }, // 9
96 { TYPE_NULL, TYPE_NULL_NAME }, // 10
97 { TYPE_WKS, TYPE_WKS_NAME }, // 11
98 { TYPE_PTR, TYPE_PTR_NAME }, // 12
99 { TYPE_HINFO, TYPE_HINFO_NAME }, // 13
100 { TYPE_MINFO, TYPE_MINFO_NAME }, // 14
101 { TYPE_MX, TYPE_MX_NAME }, // 15
102 { TYPE_TXT, TYPE_TXT_NAME }, // 16
103 { TYPE_RP, TYPE_RP_NAME }, // 17
104 { TYPE_AFSDB, TYPE_AFSDB_NAME }, // 18
105 { TYPE_X25, TYPE_X25_NAME }, // 19
106 { TYPE_ISDN, TYPE_ISDN_NAME }, // 20
107 { TYPE_RT, TYPE_RT_NAME }, // 21
108 { TYPE_NSAP, TYPE_NSAP_NAME }, // 22
109 { TYPE_NSAP_PTR, TYPE_NSAP_PTR_NAME }, // 23
110 { TYPE_SIG, TYPE_SIG_NAME }, // 24
111 { TYPE_KEY, TYPE_KEY_NAME }, // 25
112 { TYPE_PX, TYPE_PX_NAME }, // 26
113 { TYPE_GPOS, TYPE_GPOS_NAME }, // 27
114 { TYPE_AAAA, TYPE_AAAA_NAME }, // 28
115 { TYPE_LOC, TYPE_LOC_NAME }, // 29
116 { TYPE_NXT, TYPE_NXT_NAME }, // 30
117 { TYPE_EID, TYPE_EID_NAME }, // 31
118 { TYPE_NIMLOC, TYPE_NIMLOC_NAME }, // 32
119 { TYPE_SRV, TYPE_SRV_NAME }, // 33
120 { TYPE_ATMA, TYPE_ATMA_NAME }, // 34
121 { TYPE_NAPTR, TYPE_NAPTR_NAME }, // 35
122 { TYPE_KX, TYPE_KX_NAME }, // 36
123 { TYPE_CERT, TYPE_CERT_NAME }, // 37
124 { TYPE_A6, TYPE_A6_NAME }, // 38
125 { TYPE_DNAME, TYPE_DNAME_NAME }, // 39
126 { TYPE_SINK, TYPE_SINK_NAME }, // 40
127 { TYPE_OPT, TYPE_OPT_NAME }, // 41
128 { TYPE_APL, TYPE_APL_NAME }, // 42
129 { TYPE_DS, TYPE_DS_NAME }, // 43
130 { TYPE_SSHFP, TYPE_SSHFP_NAME }, // 44
131 { TYPE_IPSECKEY, TYPE_IPSECKEY_NAME }, // 45
132 { TYPE_RRSIG, TYPE_RRSIG_NAME }, // 46
133 { TYPE_NSEC, TYPE_NSEC_NAME }, // 47
134 { TYPE_DNSKEY, TYPE_DNSKEY_NAME }, // 48
135 { TYPE_DHCID, TYPE_DHCID_NAME }, // 49
136 { TYPE_NSEC3, TYPE_NSEC3_NAME }, // 50
137 { TYPE_NSEC3PARAM, TYPE_NSEC3PARAM_NAME }, // 51
138 { TYPE_TLSA, TYPE_TLSA_NAME }, // 52
139 { TYPE_HIP, TYPE_HIP_NAME }, // 55
140 { TYPE_NINFO, TYPE_NINFO_NAME }, // 56
141 { TYPE_RKEY, TYPE_RKEY_NAME }, // 57
142 { TYPE_TALINK, TYPE_TALINK_NAME }, // 58
143 { TYPE_CDS, TYPE_CDS_NAME }, // 59
144
145 { TYPE_CDNSKEY, TYPE_CDNSKEY_NAME }, // 60
146 { TYPE_OPENPGPKEY, TYPE_OPENPGPKEY_NAME }, // 61
147 { TYPE_CSYNC, TYPE_CSYNC_NAME }, // 62
148
149 { TYPE_SPF, TYPE_SPF_NAME }, // 99
150 { TYPE_UINFO, TYPE_UINFO_NAME }, // 100
151
152 { TYPE_UID, TYPE_UID_NAME }, // 101
153 { TYPE_GID, TYPE_GID_NAME }, // 102
154 { TYPE_UNSPEC, TYPE_UNSPEC_NAME }, // 103
155
156 { TYPE_NID, TYPE_NID_NAME }, // 104
157 { TYPE_L32, TYPE_L32_NAME }, // 105
158 { TYPE_L64, TYPE_L64_NAME }, // 106
159 { TYPE_LP, TYPE_LP_NAME }, // 107
160 { TYPE_EUI48, TYPE_EUI48_NAME }, // 108
161 { TYPE_EUI64, TYPE_EUI64_NAME }, // 109
162
163
164
165 { TYPE_TKEY, TYPE_TKEY_NAME }, // 249
166 { TYPE_TSIG, TYPE_TSIG_NAME }, // 250
167 { TYPE_IXFR, TYPE_IXFR_NAME }, // 251
168 { TYPE_AXFR, TYPE_AXFR_NAME }, // 252
169 { TYPE_MAILB, TYPE_MAILB_NAME }, // 253
170 { TYPE_MAILA, TYPE_MAILA_NAME }, // 254
171 { TYPE_ANY, TYPE_ANY_NAME }, // 255
172 { TYPE_URI, TYPE_URI_NAME }, // 256
173 { TYPE_CAA, TYPE_CAA_NAME }, // 257
174 { TYPE_AVC, TYPE_AVC_NAME }, // 258
175 { TYPE_TA, TYPE_TA_NAME }, // 32768
176 { TYPE_DLV, TYPE_DLV_NAME }, // 32769
177
178
179
180 #if 1//HAS_CTRL
181 { TYPE_CTRL_SRVCFGRELOAD, TYPE_CTRL_SRVCFGRELOAD_NAME },
182 { TYPE_CTRL_SRVQUERYLOG, TYPE_CTRL_SRVQUERYLOG_NAME },
183 { TYPE_CTRL_SRVLOGREOPEN, TYPE_CTRL_SRVLOGREOPEN_NAME },
184 { TYPE_CTRL_SRVLOGLEVEL, TYPE_CTRL_SRVLOGLEVEL_NAME },
185 { TYPE_CTRL_SRVSHUTDOWN, TYPE_CTRL_SHUTDOWN_NAME },
186 { TYPE_CTRL_ZONECFGRELOAD, TYPE_CTRL_ZONECFGRELOAD_NAME },
187 { TYPE_CTRL_ZONECFGRELOADALL, TYPE_CTRL_ZONECFGRELOADALL_NAME },
188 { TYPE_CTRL_ZONEFREEZE, TYPE_CTRL_ZONEFREEZE_NAME },
189 { TYPE_CTRL_ZONEFREEZEALL, TYPE_CTRL_ZONEFREEZEALL_NAME },
190 { TYPE_CTRL_ZONERELOAD, TYPE_CTRL_ZONERELOAD_NAME },
191 { TYPE_CTRL_ZONEUNFREEZE, TYPE_CTRL_ZONEUNFREEZE_NAME },
192 { TYPE_CTRL_ZONEUNFREEZEALL, TYPE_CTRL_ZONEUNFREEZEALL_NAME },
193 { TYPE_CTRL_ZONESYNC, TYPE_CTRL_ZONESYNC_NAME },
194 { TYPE_CTRL_ZONENOTIFY, TYPE_CTRL_ZONENOTIFY_NAME },
195
196 #endif
197 { 0, NULL }
198 };
199
200
201 const dnssec_algo_table dnssec_algo[] = {
202 /// @note 20160512 gve -- 3 algorithms are not used ( deprecated or not implemented )
203 // { DNSKEY_ALGORITHM_RSAMD5, DNSKEY_ALGORITHM_RSAMD5_NAME }, // 1
204 // { DNSKEY_ALGORITHM_DIFFIE_HELLMAN, DNSKEY_ALGORITHM_DIFFIE_HELLMAN_NAME }, // 2
205 { DNSKEY_ALGORITHM_DSASHA1, DNSKEY_ALGORITHM_DSASHA1_NAME }, // 3
206 { DNSKEY_ALGORITHM_RSASHA1, DNSKEY_ALGORITHM_RSASHA1_NAME }, // 5
207 { DNSKEY_ALGORITHM_DSASHA1_NSEC3, DNSKEY_ALGORITHM_DSASHA1_NSEC3_NAME }, // 6
208 { DNSKEY_ALGORITHM_RSASHA1_NSEC3, DNSKEY_ALGORITHM_RSASHA1_NSEC3_NAME }, // 7
209 { DNSKEY_ALGORITHM_RSASHA256_NSEC3, DNSKEY_ALGORITHM_RSASHA256_NSEC3_NAME }, // 8
210 { DNSKEY_ALGORITHM_RSASHA512_NSEC3, DNSKEY_ALGORITHM_RSASHA512_NSEC3_NAME }, // 10
211 // { DNSKEY_ALGORITHM_GOST, DNSKEY_ALGORITHM_GOST_NAME }, // 12
212 { DNSKEY_ALGORITHM_ECDSAP256SHA256, DNSKEY_ALGORITHM_ECDSAP256SHA256_NAME }, // 13
213 { DNSKEY_ALGORITHM_ECDSAP384SHA384, DNSKEY_ALGORITHM_ECDSAP384SHA384_NAME }, // 14
214 { DNSKEY_ALGORITHM_ED25519, DNSKEY_ALGORITHM_ED25519_NAME }, // 15
215 { DNSKEY_ALGORITHM_ED448, DNSKEY_ALGORITHM_ED448_NAME }, // 16
216 #ifdef DNSKEY_ALGORITHM_DUMMY
217 { DNSKEY_ALGORITHM_DUMMY, DNSKEY_ALGORITHM_DUMMY_NAME }, // 254
218 #endif
219 { 0, NULL }
220 };
221
222
223 static char *opcode[16] =
224 {
225 "QUERY", // 0
226 "IQUERY", // 1 obsolete
227 "STATUS",
228 "OPCODE3",
229 "NOTIFY",
230 "UPDATE",
231 "OPCODE6",
232 "OPCODE7",
233
234 "OPCODE8", // 8
235 "CTRL", /* special for yadifa client for view the result in verbose mode */
236 "OPCODE10",
237 "OPCODE11",
238 "OPCODE12",
239 "OPCODE13",
240 "OPCODE14",
241 "OPCODE15"
242 };
243
244 static char *rcode[32] =
245 {
246 "NOERROR", // 0 /* No error rfc 1035 */
247 "FORMERR", // 1 /* Format error rfc 1035 */
248 "SERVFAIL", // 2 /* Server failure rfc 1035 */
249 "NXDOMAIN", // 3 /* Name error rfc 1035 */
250 "NOTIMP", // 4 /* Not implemented rfc 1035 */
251 "REFUSED", // 5 /* Refused rfc 1035 */
252
253 "YXDOMAIN", // 6 /* Name exists when it should not rfc 2136 */
254 "YXRRSET", // 7 /* RR Set exists when it should not rfc 2136 */
255 "NXRRSET", // 8 /* RR set that should exist doesn't rfc 2136 */
256 "NOTAUTH", // 9 /* Server not Authortative for zone rfc 2136 */
257 // 9 /* Not Authorized rfc 2845 */
258 "NOTZONE", // 10 /* Name not contained in zone rfc 2136 */
259
260 "RCODE11",
261 "RCODE12",
262 "RCODE13",
263 "RCODE14",
264 "RCODE15",
265
266 "BADVERS", // or BADSIG // 16 /* Bad OPT Version rfc 2671 / rfc 6891 */
267
268 "BADKEY",
269 "BADTIME",
270 "BADMODE",
271
272 "BADNAME",
273 "BADALG",
274 "BADTRUNC",
275
276 "RCODE23",
277
278 "RCODE24",
279 "RCODE25",
280 "RCODE26",
281 "RCODE27",
282
283 "RCODE28",
284 "RCODE29",
285 "RCODE30",
286 "RCODE31"
287 };
288
289
290 static char*
rfc_word_get(const char * w)291 rfc_word_get(const char *w)
292 {
293 string_node *node = string_set_insert(&word_set, w); // assumes new value set to 0
294 if(node->value == 0)
295 {
296 node->key = strdup(w);
297 }
298
299 if(node->value < 0xffff)
300 {
301 ++node->value;
302 }
303
304 return (char*)node->key;
305 }
306
rfc_word_destroy_cb(string_node * node)307 static void rfc_word_destroy_cb(string_node *node)
308 {
309 free((char*)node->key);node->key = NULL;
310 }
311
rfc_word_destroy()312 static void rfc_word_destroy()
313 {
314 string_set_callback_and_destroy(&word_set, rfc_word_destroy_cb);
315 }
316
317 const char*
dns_message_opcode_get_name(u16 o)318 dns_message_opcode_get_name(u16 o)
319 {
320 return opcode[o & 0x0f];
321 }
322 const char*
dns_message_rcode_get_name(u16 r)323 dns_message_rcode_get_name(u16 r)
324 {
325 return rcode[r & 0x1f];
326 }
327 const char*
dns_class_get_name(u16 c)328 dns_class_get_name(u16 c)
329 {
330 switch(c)
331 {
332 case CLASS_IN:
333 return CLASS_IN_NAME;
334 case CLASS_CH:
335 return CLASS_CH_NAME;
336 case CLASS_HS:
337 return CLASS_HS_NAME;
338 case CLASS_CTRL:
339 return CLASS_CTRL_NAME;
340 case CLASS_NONE:
341 return CLASS_NONE_NAME;
342 case CLASS_ANY:
343 return CLASS_ANY_NAME;
344 default:
345 return NULL;
346 }
347 }
348
349 const char*
dns_type_get_name(u16 t)350 dns_type_get_name(u16 t)
351 {
352 switch(t)
353 {
354 case TYPE_A:
355 return TYPE_A_NAME;
356 case TYPE_NS:
357 return TYPE_NS_NAME;
358 case TYPE_MD:
359 return TYPE_MD_NAME;
360 case TYPE_MF:
361 return TYPE_MF_NAME;
362 case TYPE_CNAME:
363 return TYPE_CNAME_NAME;
364 case TYPE_SOA:
365 return TYPE_SOA_NAME;
366 case TYPE_MB:
367 return TYPE_MB_NAME;
368 case TYPE_MG:
369 return TYPE_MG_NAME;
370 case TYPE_MR:
371 return TYPE_MR_NAME;
372 case TYPE_NULL:
373 return TYPE_NULL_NAME;
374 case TYPE_WKS:
375 return TYPE_WKS_NAME;
376 case TYPE_PTR:
377 return TYPE_PTR_NAME;
378 case TYPE_HINFO:
379 return TYPE_HINFO_NAME;
380 case TYPE_MINFO:
381 return TYPE_MINFO_NAME;
382 case TYPE_MX:
383 return TYPE_MX_NAME;
384 case TYPE_TXT:
385 return TYPE_TXT_NAME;
386 case TYPE_RP:
387 return TYPE_RP_NAME;
388 case TYPE_AFSDB:
389 return TYPE_AFSDB_NAME;
390 case TYPE_X25:
391 return TYPE_X25_NAME;
392 case TYPE_ISDN:
393 return TYPE_ISDN_NAME;
394 case TYPE_RT:
395 return TYPE_RT_NAME;
396 case TYPE_NSAP:
397 return TYPE_NSAP_NAME;
398 case TYPE_NSAP_PTR:
399 return TYPE_NSAP_PTR_NAME;
400 case TYPE_SIG:
401 return TYPE_SIG_NAME;
402 case TYPE_KEY:
403 return TYPE_KEY_NAME;
404 case TYPE_PX:
405 return TYPE_PX_NAME;
406 case TYPE_GPOS:
407 return TYPE_GPOS_NAME;
408 case TYPE_AAAA:
409 return TYPE_AAAA_NAME;
410 case TYPE_LOC:
411 return TYPE_LOC_NAME;
412 case TYPE_NXT:
413 return TYPE_NXT_NAME;
414 case TYPE_EID:
415 return TYPE_EID_NAME;
416 case TYPE_NIMLOC:
417 return TYPE_NIMLOC_NAME;
418 case TYPE_SRV:
419 return TYPE_SRV_NAME;
420 case TYPE_ATMA:
421 return TYPE_ATMA_NAME;
422 case TYPE_NAPTR:
423 return TYPE_NAPTR_NAME;
424 case TYPE_KX:
425 return TYPE_KX_NAME;
426 case TYPE_CERT:
427 return TYPE_CERT_NAME;
428 case TYPE_A6:
429 return TYPE_A6_NAME;
430 case TYPE_DNAME:
431 return TYPE_DNAME_NAME;
432 case TYPE_SINK:
433 return TYPE_SINK_NAME;
434 case TYPE_OPT:
435 return TYPE_OPT_NAME;
436 case TYPE_APL:
437 return TYPE_APL_NAME;
438 case TYPE_DS:
439 return TYPE_DS_NAME;
440 case TYPE_SSHFP:
441 return TYPE_SSHFP_NAME;
442 case TYPE_IPSECKEY:
443 return TYPE_IPSECKEY_NAME;
444 case TYPE_RRSIG:
445 return TYPE_RRSIG_NAME;
446 case TYPE_NSEC:
447 return TYPE_NSEC_NAME;
448 case TYPE_DNSKEY:
449 return TYPE_DNSKEY_NAME;
450 case TYPE_DHCID:
451 return TYPE_DHCID_NAME;
452 case TYPE_NSEC3:
453 return TYPE_NSEC3_NAME;
454 case TYPE_NSEC3PARAM:
455 return TYPE_NSEC3PARAM_NAME;
456 case TYPE_TLSA:
457 return TYPE_TLSA_NAME;
458 case TYPE_HIP:
459 return TYPE_HIP_NAME;
460 case TYPE_NINFO:
461 return TYPE_NINFO_NAME;
462 case TYPE_RKEY:
463 return TYPE_RKEY_NAME;
464 case TYPE_TALINK:
465 return TYPE_TALINK_NAME;
466 case TYPE_CDS:
467 return TYPE_CDS_NAME;
468 case TYPE_CDNSKEY:
469 return TYPE_CDNSKEY_NAME;
470 case TYPE_OPENPGPKEY:
471 return TYPE_OPENPGPKEY_NAME;
472
473 case TYPE_SPF:
474 return TYPE_SPF_NAME;
475 case TYPE_UINFO:
476 return TYPE_UINFO_NAME;
477
478 case TYPE_NID:
479 return TYPE_NID_NAME;
480 case TYPE_L32:
481 return TYPE_L32_NAME;
482 case TYPE_L64:
483 return TYPE_L64_NAME;
484 case TYPE_LP:
485 return TYPE_LP_NAME;
486 case TYPE_EUI48:
487 return TYPE_EUI48_NAME;
488 case TYPE_EUI64:
489 return TYPE_EUI64_NAME;
490 case TYPE_TKEY:
491 return TYPE_TKEY_NAME;
492 case TYPE_TSIG:
493 return TYPE_TSIG_NAME;
494 case TYPE_IXFR:
495 return TYPE_IXFR_NAME;
496 case TYPE_AXFR:
497 return TYPE_AXFR_NAME;
498 case TYPE_MAILB:
499 return TYPE_MAILB_NAME;
500 case TYPE_MAILA:
501 return TYPE_MAILA_NAME;
502 case TYPE_ANY:
503 return TYPE_ANY_NAME;
504 case TYPE_URI:
505 return TYPE_URI_NAME;
506 case TYPE_CAA:
507 return TYPE_CAA_NAME;
508 case TYPE_TA:
509 return TYPE_TA_NAME;
510 case TYPE_DLV:
511 return TYPE_DLV_NAME;
512
513 #if HAS_CTRL
514 case TYPE_CTRL_SRVSHUTDOWN:
515 return TYPE_CTRL_SHUTDOWN_NAME;
516 case TYPE_CTRL_ZONEFREEZE:
517 return TYPE_CTRL_ZONEFREEZE_NAME;
518 case TYPE_CTRL_ZONEUNFREEZE:
519 return TYPE_CTRL_ZONEUNFREEZE_NAME;
520 case TYPE_CTRL_ZONERELOAD:
521 return TYPE_CTRL_ZONERELOAD_NAME;
522 case TYPE_CTRL_SRVLOGREOPEN:
523 return TYPE_CTRL_LOGREOPEN_NAME;
524 case TYPE_CTRL_SRVCFGRELOAD:
525 return TYPE_CTRL_SRVCFGRELOAD_NAME;
526 case TYPE_CTRL_ZONECFGRELOAD:
527 return TYPE_CTRL_ZONECFGRELOAD_NAME;
528 case TYPE_CTRL_ZONESYNC:
529 return TYPE_CTRL_ZONESYNC_NAME;
530 case TYPE_CTRL_SRVQUERYLOG:
531 return TYPE_CTRL_SRVQUERYLOG_NAME;
532 case TYPE_CTRL_SRVLOGLEVEL:
533 return TYPE_CTRL_SRVLOGLEVEL_NAME;
534 case TYPE_CTRL_ZONENOTIFY:
535 return TYPE_CTRL_ZONENOTIFY_NAME;
536 //case TYPE_CTRL_%:
537 // return TYPE_CTRL_SCFGMERGE_NAME;
538 //case TYPE_CTRL_CFGSAVE:
539 // return TYPE_CTRL_CFGSAVE_NAME;
540 //case TYPE_CTRL_CFGLOAD:
541 // return TYPE_CTRL_CFGLOAD_NAME;
542 #endif
543 default:
544 return NULL;
545 }
546 }
547
548 const char*
dns_encryption_algorithm_get_name(u16 d)549 dns_encryption_algorithm_get_name(u16 d)
550 {
551 switch(d)
552 {
553 case DNSKEY_ALGORITHM_RSAMD5:
554 return DNSKEY_ALGORITHM_RSAMD5_NAME;
555 case DNSKEY_ALGORITHM_DIFFIE_HELLMAN:
556 return DNSKEY_ALGORITHM_DIFFIE_HELLMAN_NAME;
557 case DNSKEY_ALGORITHM_DSASHA1:
558 return DNSKEY_ALGORITHM_DSASHA1_NAME;
559 case DNSKEY_ALGORITHM_RSASHA1:
560 return DNSKEY_ALGORITHM_RSASHA1_NAME;
561 case DNSKEY_ALGORITHM_DSASHA1_NSEC3:
562 return DNSKEY_ALGORITHM_DSASHA1_NSEC3_NAME;
563 case DNSKEY_ALGORITHM_RSASHA1_NSEC3:
564 return DNSKEY_ALGORITHM_RSASHA1_NSEC3_NAME;
565 case DNSKEY_ALGORITHM_RSASHA256_NSEC3:
566 return DNSKEY_ALGORITHM_RSASHA256_NSEC3_NAME;
567 case DNSKEY_ALGORITHM_RSASHA512_NSEC3:
568 return DNSKEY_ALGORITHM_RSASHA512_NSEC3_NAME;
569 case DNSKEY_ALGORITHM_GOST:
570 return DNSKEY_ALGORITHM_GOST_NAME;
571 case DNSKEY_ALGORITHM_ECDSAP256SHA256:
572 return DNSKEY_ALGORITHM_ECDSAP256SHA256_NAME;
573 case DNSKEY_ALGORITHM_ECDSAP384SHA384:
574 return DNSKEY_ALGORITHM_ECDSAP384SHA384_NAME;
575 case DNSKEY_ALGORITHM_ED25519:
576 return DNSKEY_ALGORITHM_ED25519_NAME;
577 case DNSKEY_ALGORITHM_ED448:
578 return DNSKEY_ALGORITHM_ED448_NAME;
579 #ifdef DNSKEY_ALGORITHM_DUMMY
580 case DNSKEY_ALGORITHM_DUMMY:
581 return DNSKEY_ALGORITHM_DUMMY_NAME;
582 #endif
583 default:
584 return NULL;
585 }
586 }
587
588
589 /** \brief Check in search table of class for the value
590 *
591 * @param[in] src data to be found in table
592 * @param[out] dst value found in table
593 *
594 * @retval OK
595 * @retval NOK
596 */
597 int
dns_class_from_name(const char * src,u16 * dst)598 dns_class_from_name(const char *src, u16 *dst)
599 {
600 const string_node *node = string_set_find(&class_set, (const char *)src);
601
602 if(node != NULL)
603 {
604 u16 c = node->value;
605 *dst = c;
606
607 return c;
608 }
609 else
610 {
611 /** @note supports CLASS# syntax (rfc 3597) */
612
613 if(strncasecmp(src, "CLASS", 5) == 0)
614 {
615 char *endptr;
616 long long int val;
617
618 src += 5;
619
620 val = strtoll(src, &endptr, 10);
621
622 int err = errno;
623
624 if(!((endptr == src) || (err == EINVAL) || (err == ERANGE) || ((val & 0xffffLL) != val)))
625 {
626 u16 c = htons((u16)val);
627 *dst = c;
628
629 return c;
630 }
631 }
632
633 return UNKNOWN_DNS_CLASS;
634 }
635 }
636
637 /** \brief Check in global table qtype for the value
638 *
639 * @param[in] src data to be found in table
640 * @param[oet] dst value found in table
641 *
642 * @retval OK
643 * @retval NOK
644 */
645 int
dns_type_from_name(const char * src,u16 * dst)646 dns_type_from_name(const char *src, u16 *dst)
647 {
648 string_node *node = string_set_find(&type_set, (const char *)src);
649
650 if(node != NULL)
651 {
652 u16 t = node->value;
653 *dst = t;
654 return 0;
655 }
656 else
657 {
658 /** @note supports TYPE# syntax (rfc 3597) */
659
660 if(strncasecmp(src, "TYPE", 4) == 0)
661 {
662 char *endptr;
663 long long int val;
664
665 src += 4;
666
667 errno = 0;
668
669 val = strtoll(src, &endptr, 10);
670
671 int err = errno;
672
673 if(!((endptr == src) || (err == EINVAL) || (err == ERANGE) || ((val & 0xffffLL) != val)))
674 {
675 u16 t = htons((u16)val);
676 *dst = t;
677 return 1;
678 }
679 }
680
681 return UNKNOWN_DNS_TYPE;
682 }
683 }
684
685
686 /** \brief Check in search table of class for the value
687 *
688 * @param[in] src data to be found in table
689 * @param[out] dst value found in table
690 *
691 * @retval OK
692 * @retval NOK
693 */
694 int
dns_encryption_algorithm_from_name(const char * src,u8 * dst)695 dns_encryption_algorithm_from_name(const char *src, u8 *dst)
696 {
697 const string_node *node = string_set_find(&dnssec_algo_set, (const char *)src);
698
699 if(node != NULL)
700 {
701 u8 c = node->value;
702 *dst = c;
703
704 return c;
705 }
706
707 return DNSSEC_ALGORITHM_UNKOWN;
708 }
709
710
711 int
dns_class_from_case_name(const char * src,u16 * dst)712 dns_class_from_case_name(const char *src, u16 *dst)
713 {
714 char txt[16];
715 size_t n = strlen(src);
716 if(n >= sizeof(txt))
717 {
718 return UNKNOWN_DNS_CLASS;
719 }
720
721 for(size_t i = 0; i < n; i++)
722 {
723 txt[i] = toupper(src[i]);
724 }
725
726 txt[n] = '\0';
727
728 return dns_class_from_name(txt, dst);
729 }
730
731
732 int
dns_type_from_case_name(const char * src,u16 * dst)733 dns_type_from_case_name(const char *src, u16 *dst)
734 {
735 char txt[16];
736 size_t n = strlen(src);
737 if(n >= sizeof(txt))
738 {
739 return UNKNOWN_DNS_TYPE;
740 }
741
742 for(size_t i = 0; i < n; i++)
743 {
744 txt[i] = toupper(src[i]);
745 }
746
747 txt[n] = '\0';
748
749 ya_result ret = dns_type_from_name(txt, dst);
750
751 return ret;
752 }
753
754
755 int
dns_encryption_algorithm_from_case_name(const char * src,u8 * dst)756 dns_encryption_algorithm_from_case_name(const char *src, u8 *dst)
757 {
758 char txt[32];
759 size_t n = strlen(src);
760 if(n >= sizeof(txt))
761 {
762 return DNSSEC_ALGORITHM_UNKOWN;
763 }
764
765 for(size_t i = 0; i < n; i++)
766 {
767 txt[i] = toupper(src[i]);
768 }
769
770 txt[n] = '\0';
771
772 return dns_encryption_algorithm_from_name(txt, dst);
773 }
774
775
776 int
dns_type_from_case_name_length(const char * src,int src_len,u16 * dst)777 dns_type_from_case_name_length(const char *src, int src_len, u16 *dst)
778 {
779 char txt[16];
780
781 if(src_len >= (int)sizeof(txt))
782 {
783 return UNKNOWN_DNS_TYPE;
784 }
785
786 for(int i = 0; i < src_len; i++)
787 {
788 txt[i] = toupper(src[i]);
789 }
790
791 txt[src_len] = '\0';
792
793 ya_result ret = dns_type_from_name(txt, dst);
794
795 return ret;
796 }
797
798 static ptr_set protocol_name_to_id_set = PTR_SET_ASCIIZCASE_EMPTY;
799 static u32_set protocol_id_to_name_set = U32_SET_EMPTY;
800 static ptr_set server_name_to_port_set = PTR_SET_ASCIIZCASE_EMPTY;
801 static u32_set server_port_to_name_set = U32_SET_EMPTY;
802
803 static void
protocol_name_to_id_init()804 protocol_name_to_id_init()
805 {
806 #ifndef WIN32
807 if(ptr_set_isempty(&protocol_name_to_id_set))
808 {
809 struct protoent *ent;
810
811 for(;;)
812 {
813 if((ent = getprotoent()) == NULL)
814 {
815 break;
816 }
817
818 ptr_node *node = ptr_set_insert(&protocol_name_to_id_set, ent->p_name);
819 node->key = rfc_word_get(ent->p_name);
820
821 if(node->value != NULL)
822 {
823 continue;
824 }
825
826 node->value = (void*)(intptr)ent->p_proto;
827
828 u32_node *id_node = u32_set_insert(&protocol_id_to_name_set, ent->p_proto);
829 id_node->value = node->key;
830
831 char **a = ent->p_aliases;
832 if(a != NULL)
833 {
834 while(*a != NULL)
835 {
836 node = ptr_set_insert(&protocol_name_to_id_set, *a);
837
838 if(node->value == NULL)
839 {
840 node->key = rfc_word_get(*a);
841 node->value = (void*)(intptr)ent->p_proto;
842 }
843 ++a;
844 }
845 }
846 }
847
848 endprotoent();
849 }
850 #endif
851 }
852
853 static void
protocol_name_to_id_finalize()854 protocol_name_to_id_finalize()
855 {
856 ptr_set_destroy(&protocol_name_to_id_set);
857 u32_set_destroy(&protocol_id_to_name_set);
858 }
859
860 ya_result
protocol_name_to_id(const char * name,int * out_proto)861 protocol_name_to_id(const char* name, int *out_proto)
862 {
863 ya_result ret = PARSEINT_ERROR;
864
865 if(sscanf(name, "%d", &ret) <= 0)
866 {
867 ptr_node *node = ptr_set_find(&protocol_name_to_id_set, name);
868
869 if(node != NULL)
870 {
871 ret = (int)(intptr)node->value;
872 }
873 }
874 else
875 {
876 if(ret > 255)
877 {
878 ret = INVALID_STATE_ERROR;
879 }
880 }
881
882 if(ISOK(ret) && (out_proto != NULL))
883 {
884 *out_proto = ret;
885 }
886
887 return ret;
888 }
889
890 ya_result
protocol_id_to_name(int proto,char * name,size_t name_len)891 protocol_id_to_name(int proto, char *name, size_t name_len)
892 {
893 u32_node *proto_node = u32_set_find(&protocol_id_to_name_set, proto);
894 if(proto_node != NULL)
895 {
896 return snformat(name, name_len, "%s", (const char*)proto_node->value);
897 }
898 else
899 {
900 return snformat(name, name_len, "%i", proto);
901 }
902 }
903
904 static void
server_name_to_port_init()905 server_name_to_port_init()
906 {
907 #ifndef WIN32
908 if(ptr_set_isempty(&server_name_to_port_set))
909 {
910 struct servent *ent;
911
912 for(;;)
913 {
914 if((ent = getservent()) == NULL)
915 {
916 break;
917 }
918
919 ptr_node *node = ptr_set_insert(&server_name_to_port_set, ent->s_name);
920
921 if(node->value != NULL)
922 {
923 continue;
924 }
925
926 node->key = rfc_word_get(ent->s_name);
927 u16 hport = ntohs(ent->s_port);
928 node->value = (void*)(intptr)hport;
929
930 u32_node *port_node = u32_set_insert(&server_port_to_name_set, hport);
931 port_node->value = node->key;
932
933 char **a = ent->s_aliases;
934 if(a != NULL)
935 {
936 while(*a != NULL)
937 {
938 node = ptr_set_insert(&server_name_to_port_set, *a);
939 if(node->value == NULL)
940 {
941 node->key = rfc_word_get(*a);
942 node->value = (void*)(intptr)ntohs(ent->s_port);
943 }
944
945 ++a;
946 }
947 }
948 }
949 endservent();
950 }
951 #endif
952 }
953
954 static void
server_name_to_port_finalize()955 server_name_to_port_finalize()
956 {
957 if(!ptr_set_isempty(&server_name_to_port_set))
958 {
959 ptr_set_destroy(&server_name_to_port_set);
960 u32_set_destroy(&server_port_to_name_set);
961 }
962 }
963
964 ya_result
server_name_to_port(const char * name,int * out_port)965 server_name_to_port(const char* name, int *out_port)
966 {
967 ya_result ret = PARSEINT_ERROR;
968
969 if(sscanf(name, "%d", &ret) <= 0)
970 {
971 ptr_node *node = ptr_set_find(&server_name_to_port_set, name);
972
973 if(node != NULL)
974 {
975 ret = (int)(intptr)node->value;
976 }
977 }
978 else
979 {
980 if(ret > 65535)
981 {
982 ret = INVALID_STATE_ERROR;
983 }
984 }
985
986 if(ISOK(ret) && (out_port != NULL))
987 {
988 *out_port = ret;
989 }
990
991 return ret;
992 }
993
994 ya_result
server_port_to_name(int port,char * name,size_t name_len)995 server_port_to_name(int port, char *name, size_t name_len)
996 {
997 u32_node *port_node = u32_set_find(&server_port_to_name_set, port);
998 if(port_node != NULL)
999 {
1000 return snformat(name, name_len, "%s", (const char*)port_node->value);
1001 }
1002 else
1003 {
1004 return snformat(name, name_len, "%i", port);
1005 }
1006 }
1007
1008 static void
rfc_dnssec_algo_init()1009 rfc_dnssec_algo_init()
1010 {
1011 int i;
1012
1013 string_set_init(&dnssec_algo_set);
1014
1015 for(i = 0; dnssec_algo[i].id != 0; i++)
1016 {
1017 string_node* node = string_set_insert(&dnssec_algo_set, dnssec_algo[i].data);
1018 node->value = dnssec_algo[i].id;
1019 }
1020
1021 // alias
1022 {
1023 string_node* node = string_set_insert(&dnssec_algo_set, DNSKEY_ALGORITHM_DSASHA1_NSEC3_NAME2);
1024 node->value = DNSKEY_ALGORITHM_DSASHA1_NSEC3;
1025 }
1026
1027 // alias
1028 {
1029 string_node* node = string_set_insert(&dnssec_algo_set, DNSKEY_ALGORITHM_RSASHA1_NSEC3_NAME2);
1030 node->value = DNSKEY_ALGORITHM_RSASHA1_NSEC3;
1031 }
1032 }
1033
1034 static void
rfc_dnssec_algo_finalize()1035 rfc_dnssec_algo_finalize()
1036 {
1037 string_set_destroy(&dnssec_algo_set);
1038 }
1039
1040 void
rfc_init()1041 rfc_init()
1042 {
1043 mutex_lock(&rfc_init_mtx);
1044
1045 if(rfc_init_done)
1046 {
1047 mutex_unlock(&rfc_init_mtx);
1048 return;
1049 }
1050
1051 rfc_init_done = TRUE;
1052
1053 int i;
1054
1055 string_set_init(&class_set);
1056
1057 for(i = 0; qclass[i].id != 0; i++)
1058 {
1059 string_node* node = string_set_insert(&class_set, qclass[i].data);
1060 node->value = qclass[i].id;
1061 }
1062
1063 string_set_init(&type_set);
1064
1065 for(i = 0; qtype[i].id != 0; i++)
1066 {
1067 string_node* node = string_set_insert(&type_set, qtype[i].data);
1068 node->value = qtype[i].id;
1069 }
1070
1071 protocol_name_to_id_init();
1072 server_name_to_port_init();
1073 rfc_dnssec_algo_init();
1074
1075 mutex_unlock(&rfc_init_mtx);
1076 }
1077
1078 void
rfc_finalize()1079 rfc_finalize()
1080 {
1081 mutex_lock(&rfc_init_mtx);
1082 if(!rfc_init_done)
1083 {
1084 mutex_unlock(&rfc_init_mtx);
1085 return;
1086 }
1087
1088 rfc_init_done = FALSE;
1089
1090 rfc_dnssec_algo_finalize();
1091 server_name_to_port_finalize();
1092 protocol_name_to_id_finalize();
1093 string_set_destroy(&type_set);
1094 string_set_destroy(&class_set);
1095 rfc_word_destroy();
1096
1097 mutex_unlock(&rfc_init_mtx);
1098 }
1099
1100 ya_result
value_name_table_get_value_from_casename(const value_name_table * table,const char * name,u32 * out_value)1101 value_name_table_get_value_from_casename(const value_name_table *table, const char *name, u32 *out_value)
1102 {
1103 while(table->data != NULL)
1104 {
1105 if(strcasecmp(table->data, name) == 0)
1106 {
1107 *out_value = table->id;
1108
1109 return SUCCESS;
1110 }
1111
1112 table++;
1113 }
1114
1115 return UNKNOWN_NAME;
1116 }
1117
1118 ya_result
value_name_table_get_name_from_value(const value_name_table * table,u32 value,const char ** out_name)1119 value_name_table_get_name_from_value(const value_name_table *table, u32 value, const char** out_name)
1120 {
1121 while(table->data != NULL)
1122 {
1123 if(table->id == value)
1124 {
1125 *out_name = table->data;
1126 return SUCCESS;
1127 }
1128
1129 table++;
1130 }
1131
1132 return INVALID_ARGUMENT_ERROR;
1133 }
1134
1135 /*
1136 * SOA
1137 */
1138
1139 ya_result
rr_soa_get_serial(const u8 * rdata,u16 rdata_size,u32 * out_serial)1140 rr_soa_get_serial(const u8* rdata, u16 rdata_size, u32* out_serial)
1141 {
1142 s32 soa_size = rdata_size;
1143
1144 const u8* soa_start = rdata;
1145
1146 u32 len = dnsname_len(soa_start);
1147
1148 soa_size -= len;
1149
1150 if(soa_size <= 0)
1151 {
1152 return INCORRECT_RDATA;
1153 }
1154
1155 soa_start += len;
1156
1157 len = dnsname_len(soa_start);
1158 soa_size -= len;
1159
1160 if(soa_size != 5 * 4) /* Only the 5 32 bits (should) remain */
1161 {
1162 return INCORRECT_RDATA;
1163 }
1164
1165 soa_start += len;
1166
1167 if(out_serial != NULL)
1168 {
1169 *out_serial = ntohl(GET_U32_AT(*soa_start));
1170 }
1171
1172 return SUCCESS;
1173 }
1174
1175 ya_result
rr_soa_increase_serial(u8 * rdata,u16 rdata_size,u32 increment)1176 rr_soa_increase_serial(u8* rdata, u16 rdata_size, u32 increment)
1177 {
1178 s32 soa_size = rdata_size;
1179
1180 u8* soa_start = rdata;
1181
1182 u32 len = dnsname_len(soa_start);
1183
1184 soa_size -= len;
1185
1186 if(soa_size <= 0)
1187 {
1188 return INCORRECT_RDATA;
1189 }
1190
1191 soa_start += len;
1192
1193 len = dnsname_len(soa_start);
1194 soa_size -= len;
1195
1196 if(soa_size != 5 * 4) /* Only the 5 32 bits (should) remain */
1197 {
1198 return INCORRECT_RDATA;
1199 }
1200
1201 soa_start += len;
1202
1203 SET_U32_AT(*soa_start, htonl(ntohl(GET_U32_AT(*soa_start)) + increment));
1204
1205 return SUCCESS;
1206 }
1207
1208 ya_result
rr_soa_set_serial(u8 * rdata,u16 rdata_size,u32 serial)1209 rr_soa_set_serial(u8* rdata, u16 rdata_size, u32 serial)
1210 {
1211 s32 soa_size = rdata_size;
1212
1213 u8* soa_start = rdata;
1214
1215 u32 len = dnsname_len(soa_start);
1216
1217 soa_size -= len;
1218
1219 if(soa_size <= 0)
1220 {
1221 return INCORRECT_RDATA;
1222 }
1223
1224 soa_start += len;
1225
1226 len = dnsname_len(soa_start);
1227 soa_size -= len;
1228
1229 if(soa_size != 5 * 4) /* Only the 5 32 bits (should) remain */
1230 {
1231 return INCORRECT_RDATA;
1232 }
1233
1234 soa_start += len;
1235
1236 SET_U32_AT(*soa_start, htonl(serial));
1237
1238 return SUCCESS;
1239 }
1240
1241 ya_result
rr_soa_get_minimumttl(const u8 * rdata,u16 rdata_size,s32 * out_minimum_ttl)1242 rr_soa_get_minimumttl(const u8* rdata, u16 rdata_size, s32 *out_minimum_ttl)
1243 {
1244 s32 soa_size = rdata_size;
1245
1246 const u8* soa_start = rdata;
1247
1248 u32 len = dnsname_len(soa_start);
1249
1250 soa_size -= len;
1251
1252 if(soa_size <= 0)
1253 {
1254 return INCORRECT_RDATA;
1255 }
1256
1257 soa_start += len;
1258
1259 len = dnsname_len(soa_start);
1260 soa_size -= len;
1261
1262 if(soa_size != 5 * 4) /* Only the 5 32 bits (should) remain */
1263 {
1264 return INCORRECT_RDATA;
1265 }
1266
1267 soa_start += len + 16;
1268
1269 *out_minimum_ttl = ntohl(GET_U32_AT(*soa_start));
1270
1271 return SUCCESS;
1272 }
1273
1274 /** @} */
1275