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