• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 2023 Brad House
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 #include "ares_setup.h"
27 #include "ares.h"
28 #include "ares_private.h"
29 
ares_dns_opcode_isvalid(ares_dns_opcode_t opcode)30 ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode)
31 {
32   switch (opcode) {
33     case ARES_OPCODE_QUERY:
34     case ARES_OPCODE_IQUERY:
35     case ARES_OPCODE_STATUS:
36     case ARES_OPCODE_NOTIFY:
37     case ARES_OPCODE_UPDATE:
38       return ARES_TRUE;
39   }
40   return ARES_FALSE;
41 }
42 
ares_dns_rcode_isvalid(ares_dns_rcode_t rcode)43 ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode)
44 {
45   switch (rcode) {
46     case ARES_RCODE_NOERROR:
47     case ARES_RCODE_FORMERR:
48     case ARES_RCODE_SERVFAIL:
49     case ARES_RCODE_NXDOMAIN:
50     case ARES_RCODE_NOTIMP:
51     case ARES_RCODE_REFUSED:
52     case ARES_RCODE_YXDOMAIN:
53     case ARES_RCODE_YXRRSET:
54     case ARES_RCODE_NXRRSET:
55     case ARES_RCODE_NOTAUTH:
56     case ARES_RCODE_NOTZONE:
57     case ARES_RCODE_DSOTYPEI:
58     case ARES_RCODE_BADSIG:
59     case ARES_RCODE_BADKEY:
60     case ARES_RCODE_BADTIME:
61     case ARES_RCODE_BADMODE:
62     case ARES_RCODE_BADNAME:
63     case ARES_RCODE_BADALG:
64     case ARES_RCODE_BADTRUNC:
65     case ARES_RCODE_BADCOOKIE:
66       return ARES_TRUE;
67   }
68   return ARES_FALSE;
69 }
70 
ares_dns_flags_arevalid(unsigned short flags)71 ares_bool_t ares_dns_flags_arevalid(unsigned short flags)
72 {
73   unsigned short allflags = ARES_FLAG_QR | ARES_FLAG_AA | ARES_FLAG_TC |
74                             ARES_FLAG_RD | ARES_FLAG_RA | ARES_FLAG_AD |
75                             ARES_FLAG_CD;
76 
77   if (flags & ~allflags) {
78     return ARES_FALSE;
79   }
80 
81   return ARES_TRUE;
82 }
83 
ares_dns_rec_type_isvalid(ares_dns_rec_type_t type,ares_bool_t is_query)84 ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type,
85                                       ares_bool_t         is_query)
86 {
87   switch (type) {
88     case ARES_REC_TYPE_A:
89     case ARES_REC_TYPE_NS:
90     case ARES_REC_TYPE_CNAME:
91     case ARES_REC_TYPE_SOA:
92     case ARES_REC_TYPE_PTR:
93     case ARES_REC_TYPE_HINFO:
94     case ARES_REC_TYPE_MX:
95     case ARES_REC_TYPE_TXT:
96     case ARES_REC_TYPE_AAAA:
97     case ARES_REC_TYPE_SRV:
98     case ARES_REC_TYPE_NAPTR:
99     case ARES_REC_TYPE_OPT:
100     case ARES_REC_TYPE_TLSA:
101     case ARES_REC_TYPE_SVCB:
102     case ARES_REC_TYPE_HTTPS:
103     case ARES_REC_TYPE_ANY:
104     case ARES_REC_TYPE_URI:
105     case ARES_REC_TYPE_CAA:
106       return ARES_TRUE;
107     case ARES_REC_TYPE_RAW_RR:
108       return is_query ? ARES_FALSE : ARES_TRUE;
109     default:
110       break;
111   }
112   return is_query ? ARES_TRUE : ARES_FALSE;
113 }
114 
ares_dns_rec_type_allow_name_compression(ares_dns_rec_type_t type)115 ares_bool_t ares_dns_rec_type_allow_name_compression(ares_dns_rec_type_t type)
116 {
117   /* Only record types defined in RFC1035 allow name compression within the
118    * RDATA.  Otherwise nameservers that don't understand an RR may not be
119    * able to pass along the RR in a proper manner */
120   switch (type) {
121     case ARES_REC_TYPE_A:
122     case ARES_REC_TYPE_NS:
123     case ARES_REC_TYPE_CNAME:
124     case ARES_REC_TYPE_SOA:
125     case ARES_REC_TYPE_PTR:
126     case ARES_REC_TYPE_HINFO:
127     case ARES_REC_TYPE_MX:
128     case ARES_REC_TYPE_TXT:
129       return ARES_TRUE;
130     default:
131       break;
132   }
133   return ARES_FALSE;
134 }
135 
ares_dns_class_isvalid(ares_dns_class_t qclass,ares_bool_t is_query)136 ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass,
137                                    ares_bool_t      is_query)
138 {
139   switch (qclass) {
140     case ARES_CLASS_IN:
141     case ARES_CLASS_CHAOS:
142     case ARES_CLASS_HESOID:
143     case ARES_CLASS_NONE:
144       return ARES_TRUE;
145     case ARES_CLASS_ANY:
146       return is_query ? ARES_TRUE : ARES_FALSE;
147   }
148   return ARES_FALSE;
149 }
150 
ares_dns_section_isvalid(ares_dns_section_t sect)151 ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect)
152 {
153   switch (sect) {
154     case ARES_SECTION_ANSWER:
155     case ARES_SECTION_AUTHORITY:
156     case ARES_SECTION_ADDITIONAL:
157       return ARES_TRUE;
158   }
159   return ARES_FALSE;
160 }
161 
ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key)162 ares_dns_rec_type_t ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key)
163 {
164   /* NOTE: due to the way we've numerated the keys, we can simply divide by
165    *       100 to get the type rather than having to do a huge switch
166    *       statement.  That said, we do then validate the type returned is
167    *       valid in case something completely bogus is passed in */
168   ares_dns_rec_type_t type = key / 100;
169   if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) {
170     return 0;
171   }
172   return type;
173 }
174 
ares_dns_rec_type_tostr(ares_dns_rec_type_t type)175 const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type)
176 {
177   switch (type) {
178     case ARES_REC_TYPE_A:
179       return "A";
180     case ARES_REC_TYPE_NS:
181       return "NS";
182     case ARES_REC_TYPE_CNAME:
183       return "CNAME";
184     case ARES_REC_TYPE_SOA:
185       return "SOA";
186     case ARES_REC_TYPE_PTR:
187       return "PTR";
188     case ARES_REC_TYPE_HINFO:
189       return "HINFO";
190     case ARES_REC_TYPE_MX:
191       return "MX";
192     case ARES_REC_TYPE_TXT:
193       return "TXT";
194     case ARES_REC_TYPE_AAAA:
195       return "AAAA";
196     case ARES_REC_TYPE_SRV:
197       return "SRV";
198     case ARES_REC_TYPE_NAPTR:
199       return "NAPTR";
200     case ARES_REC_TYPE_OPT:
201       return "OPT";
202     case ARES_REC_TYPE_TLSA:
203       return "TLSA";
204     case ARES_REC_TYPE_SVCB:
205       return "SVCB";
206     case ARES_REC_TYPE_HTTPS:
207       return "HTTPS";
208     case ARES_REC_TYPE_ANY:
209       return "ANY";
210     case ARES_REC_TYPE_URI:
211       return "URI";
212     case ARES_REC_TYPE_CAA:
213       return "CAA";
214     case ARES_REC_TYPE_RAW_RR:
215       return "RAWRR";
216   }
217   return "UNKNOWN";
218 }
219 
ares_dns_class_tostr(ares_dns_class_t qclass)220 const char *ares_dns_class_tostr(ares_dns_class_t qclass)
221 {
222   switch (qclass) {
223     case ARES_CLASS_IN:
224       return "IN";
225     case ARES_CLASS_CHAOS:
226       return "CH";
227     case ARES_CLASS_HESOID:
228       return "HS";
229     case ARES_CLASS_ANY:
230       return "ANY";
231     case ARES_CLASS_NONE:
232       return "NONE";
233   }
234   return "UNKNOWN";
235 }
236 
ares_dns_opcode_tostr(ares_dns_opcode_t opcode)237 const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode)
238 {
239   switch (opcode) {
240     case ARES_OPCODE_QUERY:
241       return "QUERY";
242     case ARES_OPCODE_IQUERY:
243       return "IQUERY";
244     case ARES_OPCODE_STATUS:
245       return "STATUS";
246     case ARES_OPCODE_NOTIFY:
247       return "NOTIFY";
248     case ARES_OPCODE_UPDATE:
249       return "UPDATE";
250   }
251   return "UNKNOWN";
252 }
253 
ares_dns_rr_key_tostr(ares_dns_rr_key_t key)254 const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key)
255 {
256   switch (key) {
257     case ARES_RR_A_ADDR:
258       return "ADDR";
259 
260     case ARES_RR_NS_NSDNAME:
261       return "NSDNAME";
262 
263     case ARES_RR_CNAME_CNAME:
264       return "CNAME";
265 
266     case ARES_RR_SOA_MNAME:
267       return "MNAME";
268 
269     case ARES_RR_SOA_RNAME:
270       return "RNAME";
271 
272     case ARES_RR_SOA_SERIAL:
273       return "SERIAL";
274 
275     case ARES_RR_SOA_REFRESH:
276       return "REFRESH";
277 
278     case ARES_RR_SOA_RETRY:
279       return "RETRY";
280 
281     case ARES_RR_SOA_EXPIRE:
282       return "EXPIRE";
283 
284     case ARES_RR_SOA_MINIMUM:
285       return "MINIMUM";
286 
287     case ARES_RR_PTR_DNAME:
288       return "DNAME";
289 
290     case ARES_RR_AAAA_ADDR:
291       return "ADDR";
292 
293     case ARES_RR_HINFO_CPU:
294       return "CPU";
295 
296     case ARES_RR_HINFO_OS:
297       return "OS";
298 
299     case ARES_RR_MX_PREFERENCE:
300       return "PREFERENCE";
301 
302     case ARES_RR_MX_EXCHANGE:
303       return "EXCHANGE";
304 
305     case ARES_RR_TXT_DATA:
306       return "DATA";
307 
308     case ARES_RR_SRV_PRIORITY:
309       return "PRIORITY";
310 
311     case ARES_RR_SRV_WEIGHT:
312       return "WEIGHT";
313 
314     case ARES_RR_SRV_PORT:
315       return "PORT";
316 
317     case ARES_RR_SRV_TARGET:
318       return "TARGET";
319 
320     case ARES_RR_NAPTR_ORDER:
321       return "ORDER";
322 
323     case ARES_RR_NAPTR_PREFERENCE:
324       return "PREFERENCE";
325 
326     case ARES_RR_NAPTR_FLAGS:
327       return "FLAGS";
328 
329     case ARES_RR_NAPTR_SERVICES:
330       return "SERVICES";
331 
332     case ARES_RR_NAPTR_REGEXP:
333       return "REGEXP";
334 
335     case ARES_RR_NAPTR_REPLACEMENT:
336       return "REPLACEMENT";
337 
338     case ARES_RR_OPT_UDP_SIZE:
339       return "UDP_SIZE";
340 
341     case ARES_RR_OPT_VERSION:
342       return "VERSION";
343 
344     case ARES_RR_OPT_FLAGS:
345       return "FLAGS";
346 
347     case ARES_RR_OPT_OPTIONS:
348       return "OPTIONS";
349 
350     case ARES_RR_TLSA_CERT_USAGE:
351       return "CERT_USAGE";
352 
353     case ARES_RR_TLSA_SELECTOR:
354       return "SELECTOR";
355 
356     case ARES_RR_TLSA_MATCH:
357       return "MATCH";
358 
359     case ARES_RR_TLSA_DATA:
360       return "DATA";
361 
362     case ARES_RR_SVCB_PRIORITY:
363       return "PRIORITY";
364 
365     case ARES_RR_SVCB_TARGET:
366       return "TARGET";
367 
368     case ARES_RR_SVCB_PARAMS:
369       return "PARAMS";
370 
371     case ARES_RR_HTTPS_PRIORITY:
372       return "PRIORITY";
373 
374     case ARES_RR_HTTPS_TARGET:
375       return "TARGET";
376 
377     case ARES_RR_HTTPS_PARAMS:
378       return "PARAMS";
379 
380     case ARES_RR_URI_PRIORITY:
381       return "PRIORITY";
382 
383     case ARES_RR_URI_WEIGHT:
384       return "WEIGHT";
385 
386     case ARES_RR_URI_TARGET:
387       return "TARGET";
388 
389     case ARES_RR_CAA_CRITICAL:
390       return "CRITICAL";
391 
392     case ARES_RR_CAA_TAG:
393       return "TAG";
394 
395     case ARES_RR_CAA_VALUE:
396       return "VALUE";
397 
398     case ARES_RR_RAW_RR_TYPE:
399       return "TYPE";
400 
401     case ARES_RR_RAW_RR_DATA:
402       return "DATA";
403   }
404 
405   return "UNKNOWN";
406 }
407 
ares_dns_rr_key_datatype(ares_dns_rr_key_t key)408 ares_dns_datatype_t ares_dns_rr_key_datatype(ares_dns_rr_key_t key)
409 {
410   switch (key) {
411     case ARES_RR_A_ADDR:
412       return ARES_DATATYPE_INADDR;
413 
414     case ARES_RR_AAAA_ADDR:
415       return ARES_DATATYPE_INADDR6;
416 
417     case ARES_RR_NS_NSDNAME:
418     case ARES_RR_CNAME_CNAME:
419     case ARES_RR_SOA_MNAME:
420     case ARES_RR_SOA_RNAME:
421     case ARES_RR_PTR_DNAME:
422     case ARES_RR_MX_EXCHANGE:
423     case ARES_RR_SRV_TARGET:
424     case ARES_RR_SVCB_TARGET:
425     case ARES_RR_HTTPS_TARGET:
426     case ARES_RR_NAPTR_REPLACEMENT:
427     case ARES_RR_URI_TARGET:
428       return ARES_DATATYPE_NAME;
429 
430     case ARES_RR_HINFO_CPU:
431     case ARES_RR_HINFO_OS:
432     case ARES_RR_NAPTR_FLAGS:
433     case ARES_RR_NAPTR_SERVICES:
434     case ARES_RR_NAPTR_REGEXP:
435     case ARES_RR_CAA_TAG:
436       return ARES_DATATYPE_STR;
437 
438     case ARES_RR_SOA_SERIAL:
439     case ARES_RR_SOA_REFRESH:
440     case ARES_RR_SOA_RETRY:
441     case ARES_RR_SOA_EXPIRE:
442     case ARES_RR_SOA_MINIMUM:
443       return ARES_DATATYPE_U32;
444 
445     case ARES_RR_MX_PREFERENCE:
446     case ARES_RR_SRV_PRIORITY:
447     case ARES_RR_SRV_WEIGHT:
448     case ARES_RR_SRV_PORT:
449     case ARES_RR_NAPTR_ORDER:
450     case ARES_RR_NAPTR_PREFERENCE:
451     case ARES_RR_OPT_UDP_SIZE:
452     case ARES_RR_OPT_FLAGS:
453     case ARES_RR_SVCB_PRIORITY:
454     case ARES_RR_HTTPS_PRIORITY:
455     case ARES_RR_URI_PRIORITY:
456     case ARES_RR_URI_WEIGHT:
457     case ARES_RR_RAW_RR_TYPE:
458       return ARES_DATATYPE_U16;
459 
460     case ARES_RR_OPT_VERSION:
461     case ARES_RR_TLSA_CERT_USAGE:
462     case ARES_RR_TLSA_SELECTOR:
463     case ARES_RR_TLSA_MATCH:
464     case ARES_RR_CAA_CRITICAL:
465       return ARES_DATATYPE_U8;
466 
467     case ARES_RR_CAA_VALUE:
468     case ARES_RR_TXT_DATA:
469       return ARES_DATATYPE_BINP;
470 
471     case ARES_RR_TLSA_DATA:
472     case ARES_RR_RAW_RR_DATA:
473       return ARES_DATATYPE_BIN;
474 
475     case ARES_RR_OPT_OPTIONS:
476     case ARES_RR_SVCB_PARAMS:
477     case ARES_RR_HTTPS_PARAMS:
478       return ARES_DATATYPE_OPT;
479   }
480 
481   return 0;
482 }
483 
484 static const ares_dns_rr_key_t rr_a_keys[]     = { ARES_RR_A_ADDR };
485 static const ares_dns_rr_key_t rr_ns_keys[]    = { ARES_RR_NS_NSDNAME };
486 static const ares_dns_rr_key_t rr_cname_keys[] = { ARES_RR_CNAME_CNAME };
487 static const ares_dns_rr_key_t rr_soa_keys[]   = {
488   ARES_RR_SOA_MNAME,   ARES_RR_SOA_RNAME, ARES_RR_SOA_SERIAL,
489   ARES_RR_SOA_REFRESH, ARES_RR_SOA_RETRY, ARES_RR_SOA_EXPIRE,
490   ARES_RR_SOA_MINIMUM
491 };
492 static const ares_dns_rr_key_t rr_ptr_keys[]   = { ARES_RR_PTR_DNAME };
493 static const ares_dns_rr_key_t rr_hinfo_keys[] = { ARES_RR_HINFO_CPU,
494                                                    ARES_RR_HINFO_OS };
495 static const ares_dns_rr_key_t rr_mx_keys[]    = { ARES_RR_MX_PREFERENCE,
496                                                    ARES_RR_MX_EXCHANGE };
497 static const ares_dns_rr_key_t rr_txt_keys[]   = { ARES_RR_TXT_DATA };
498 static const ares_dns_rr_key_t rr_aaaa_keys[]  = { ARES_RR_AAAA_ADDR };
499 static const ares_dns_rr_key_t rr_srv_keys[]   = {
500   ARES_RR_SRV_PRIORITY, ARES_RR_SRV_WEIGHT, ARES_RR_SRV_PORT, ARES_RR_SRV_TARGET
501 };
502 static const ares_dns_rr_key_t rr_naptr_keys[] = {
503   ARES_RR_NAPTR_ORDER,    ARES_RR_NAPTR_PREFERENCE, ARES_RR_NAPTR_FLAGS,
504   ARES_RR_NAPTR_SERVICES, ARES_RR_NAPTR_REGEXP,     ARES_RR_NAPTR_REPLACEMENT
505 };
506 static const ares_dns_rr_key_t rr_opt_keys[]    = { ARES_RR_OPT_UDP_SIZE,
507                                                     ARES_RR_OPT_VERSION,
508                                                     ARES_RR_OPT_FLAGS,
509                                                     ARES_RR_OPT_OPTIONS };
510 static const ares_dns_rr_key_t rr_tlsa_keys[]   = { ARES_RR_TLSA_CERT_USAGE,
511                                                     ARES_RR_TLSA_SELECTOR,
512                                                     ARES_RR_TLSA_MATCH,
513                                                     ARES_RR_TLSA_DATA };
514 static const ares_dns_rr_key_t rr_svcb_keys[]   = { ARES_RR_SVCB_PRIORITY,
515                                                     ARES_RR_SVCB_TARGET,
516                                                     ARES_RR_SVCB_PARAMS };
517 static const ares_dns_rr_key_t rr_https_keys[]  = { ARES_RR_HTTPS_PRIORITY,
518                                                     ARES_RR_HTTPS_TARGET,
519                                                     ARES_RR_HTTPS_PARAMS };
520 static const ares_dns_rr_key_t rr_uri_keys[]    = { ARES_RR_URI_PRIORITY,
521                                                     ARES_RR_URI_WEIGHT,
522                                                     ARES_RR_URI_TARGET };
523 static const ares_dns_rr_key_t rr_caa_keys[]    = { ARES_RR_CAA_CRITICAL,
524                                                     ARES_RR_CAA_TAG,
525                                                     ARES_RR_CAA_VALUE };
526 static const ares_dns_rr_key_t rr_raw_rr_keys[] = { ARES_RR_RAW_RR_TYPE,
527                                                     ARES_RR_RAW_RR_DATA };
528 
ares_dns_rr_get_keys(ares_dns_rec_type_t type,size_t * cnt)529 const ares_dns_rr_key_t       *ares_dns_rr_get_keys(ares_dns_rec_type_t type,
530                                                     size_t             *cnt)
531 {
532   if (cnt == NULL) {
533     return NULL;
534   }
535 
536   *cnt = 0;
537 
538   switch (type) {
539     case ARES_REC_TYPE_A:
540       *cnt = sizeof(rr_a_keys) / sizeof(*rr_a_keys);
541       return rr_a_keys;
542     case ARES_REC_TYPE_NS:
543       *cnt = sizeof(rr_ns_keys) / sizeof(*rr_ns_keys);
544       return rr_ns_keys;
545     case ARES_REC_TYPE_CNAME:
546       *cnt = sizeof(rr_cname_keys) / sizeof(*rr_cname_keys);
547       return rr_cname_keys;
548     case ARES_REC_TYPE_SOA:
549       *cnt = sizeof(rr_soa_keys) / sizeof(*rr_soa_keys);
550       return rr_soa_keys;
551     case ARES_REC_TYPE_PTR:
552       *cnt = sizeof(rr_ptr_keys) / sizeof(*rr_ptr_keys);
553       return rr_ptr_keys;
554     case ARES_REC_TYPE_HINFO:
555       *cnt = sizeof(rr_hinfo_keys) / sizeof(*rr_hinfo_keys);
556       return rr_hinfo_keys;
557     case ARES_REC_TYPE_MX:
558       *cnt = sizeof(rr_mx_keys) / sizeof(*rr_mx_keys);
559       return rr_mx_keys;
560     case ARES_REC_TYPE_TXT:
561       *cnt = sizeof(rr_txt_keys) / sizeof(*rr_txt_keys);
562       return rr_txt_keys;
563     case ARES_REC_TYPE_AAAA:
564       *cnt = sizeof(rr_aaaa_keys) / sizeof(*rr_aaaa_keys);
565       return rr_aaaa_keys;
566     case ARES_REC_TYPE_SRV:
567       *cnt = sizeof(rr_srv_keys) / sizeof(*rr_srv_keys);
568       return rr_srv_keys;
569     case ARES_REC_TYPE_NAPTR:
570       *cnt = sizeof(rr_naptr_keys) / sizeof(*rr_naptr_keys);
571       return rr_naptr_keys;
572     case ARES_REC_TYPE_OPT:
573       *cnt = sizeof(rr_opt_keys) / sizeof(*rr_opt_keys);
574       return rr_opt_keys;
575     case ARES_REC_TYPE_TLSA:
576       *cnt = sizeof(rr_tlsa_keys) / sizeof(*rr_tlsa_keys);
577       return rr_tlsa_keys;
578     case ARES_REC_TYPE_SVCB:
579       *cnt = sizeof(rr_svcb_keys) / sizeof(*rr_svcb_keys);
580       return rr_svcb_keys;
581     case ARES_REC_TYPE_HTTPS:
582       *cnt = sizeof(rr_https_keys) / sizeof(*rr_https_keys);
583       return rr_https_keys;
584     case ARES_REC_TYPE_ANY:
585       /* Not real */
586       break;
587     case ARES_REC_TYPE_URI:
588       *cnt = sizeof(rr_uri_keys) / sizeof(*rr_uri_keys);
589       return rr_uri_keys;
590     case ARES_REC_TYPE_CAA:
591       *cnt = sizeof(rr_caa_keys) / sizeof(*rr_caa_keys);
592       return rr_caa_keys;
593     case ARES_REC_TYPE_RAW_RR:
594       *cnt = sizeof(rr_raw_rr_keys) / sizeof(*rr_raw_rr_keys);
595       return rr_raw_rr_keys;
596   }
597 
598   return NULL;
599 }
600 
ares_dns_class_fromstr(ares_dns_class_t * qclass,const char * str)601 ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, const char *str)
602 {
603   size_t i;
604 
605   static const struct {
606     const char      *name;
607     ares_dns_class_t qclass;
608   } list[] = {
609     {"IN",    ARES_CLASS_IN    },
610     { "CH",   ARES_CLASS_CHAOS },
611     { "HS",   ARES_CLASS_HESOID},
612     { "NONE", ARES_CLASS_NONE  },
613     { "ANY",  ARES_CLASS_ANY   },
614     { NULL,   0                }
615   };
616 
617   if (qclass == NULL || str == NULL) {
618     return ARES_FALSE;
619   }
620 
621   for (i = 0; list[i].name != NULL; i++) {
622     if (strcasecmp(list[i].name, str) == 0) {
623       *qclass = list[i].qclass;
624       return ARES_TRUE;
625     }
626   }
627   return ARES_FALSE;
628 }
629 
ares_dns_rec_type_fromstr(ares_dns_rec_type_t * qtype,const char * str)630 ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype,
631                                       const char          *str)
632 {
633   size_t i;
634 
635   static const struct {
636     const char         *name;
637     ares_dns_rec_type_t type;
638   } list[] = {
639     {"A",       ARES_REC_TYPE_A     },
640     { "NS",     ARES_REC_TYPE_NS    },
641     { "CNAME",  ARES_REC_TYPE_CNAME },
642     { "SOA",    ARES_REC_TYPE_SOA   },
643     { "PTR",    ARES_REC_TYPE_PTR   },
644     { "HINFO",  ARES_REC_TYPE_HINFO },
645     { "MX",     ARES_REC_TYPE_MX    },
646     { "TXT",    ARES_REC_TYPE_TXT   },
647     { "AAAA",   ARES_REC_TYPE_AAAA  },
648     { "SRV",    ARES_REC_TYPE_SRV   },
649     { "NAPTR",  ARES_REC_TYPE_NAPTR },
650     { "OPT",    ARES_REC_TYPE_OPT   },
651     { "TLSA",   ARES_REC_TYPE_TLSA  },
652     { "SVCB",   ARES_REC_TYPE_SVCB  },
653     { "HTTPS",  ARES_REC_TYPE_HTTPS },
654     { "ANY",    ARES_REC_TYPE_ANY   },
655     { "URI",    ARES_REC_TYPE_URI   },
656     { "CAA",    ARES_REC_TYPE_CAA   },
657     { "RAW_RR", ARES_REC_TYPE_RAW_RR},
658     { NULL,     0                   }
659   };
660 
661   if (qtype == NULL || str == NULL) {
662     return ARES_FALSE;
663   }
664 
665   for (i = 0; list[i].name != NULL; i++) {
666     if (strcasecmp(list[i].name, str) == 0) {
667       *qtype = list[i].type;
668       return ARES_TRUE;
669     }
670   }
671   return ARES_FALSE;
672 }
673 
ares_dns_section_tostr(ares_dns_section_t section)674 const char *ares_dns_section_tostr(ares_dns_section_t section)
675 {
676   switch (section) {
677     case ARES_SECTION_ANSWER:
678       return "ANSWER";
679     case ARES_SECTION_AUTHORITY:
680       return "AUTHORITY";
681     case ARES_SECTION_ADDITIONAL:
682       return "ADDITIONAL";
683   }
684   return "UNKNOWN";
685 }
686 
ares_dns_opt_get_type_opt(unsigned short opt)687 static ares_dns_opt_datatype_t ares_dns_opt_get_type_opt(unsigned short opt)
688 {
689   ares_opt_param_t param = (ares_opt_param_t)opt;
690   switch (param) {
691     case ARES_OPT_PARAM_LLQ:
692       /* Really it is u16 version, u16 opcode, u16 error, u64 id, u32 lease */
693       return ARES_OPT_DATATYPE_BIN;
694     case ARES_OPT_PARAM_UL:
695       return ARES_OPT_DATATYPE_U32;
696     case ARES_OPT_PARAM_NSID:
697       return ARES_OPT_DATATYPE_BIN;
698     case ARES_OPT_PARAM_DAU:
699       return ARES_OPT_DATATYPE_U8_LIST;
700     case ARES_OPT_PARAM_DHU:
701       return ARES_OPT_DATATYPE_U8_LIST;
702     case ARES_OPT_PARAM_N3U:
703       return ARES_OPT_DATATYPE_U8_LIST;
704     case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
705       /* Really it is a u16 address family, u8 source prefix length,
706        * u8 scope prefix length, address */
707       return ARES_OPT_DATATYPE_BIN;
708     case ARES_OPT_PARAM_EDNS_EXPIRE:
709       return ARES_OPT_DATATYPE_U32;
710     case ARES_OPT_PARAM_COOKIE:
711       /* 8 bytes for client, 16-40 bytes for server */
712       return ARES_OPT_DATATYPE_BIN;
713     case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
714       /* Timeout in 100ms intervals */
715       return ARES_OPT_DATATYPE_U16;
716     case ARES_OPT_PARAM_PADDING:
717       /* Arbitrary padding */
718       return ARES_OPT_DATATYPE_BIN;
719     case ARES_OPT_PARAM_CHAIN:
720       return ARES_OPT_DATATYPE_NAME;
721     case ARES_OPT_PARAM_EDNS_KEY_TAG:
722       return ARES_OPT_DATATYPE_U16_LIST;
723     case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
724       /* Really 16bit code followed by textual message */
725       return ARES_OPT_DATATYPE_BIN;
726   }
727   return ARES_OPT_DATATYPE_BIN;
728 }
729 
ares_dns_opt_get_type_svcb(unsigned short opt)730 static ares_dns_opt_datatype_t ares_dns_opt_get_type_svcb(unsigned short opt)
731 {
732   ares_svcb_param_t param = (ares_svcb_param_t)opt;
733   switch (param) {
734     case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
735       return ARES_OPT_DATATYPE_NONE;
736     case ARES_SVCB_PARAM_ECH:
737       return ARES_OPT_DATATYPE_BIN;
738     case ARES_SVCB_PARAM_MANDATORY:
739       return ARES_OPT_DATATYPE_U16_LIST;
740     case ARES_SVCB_PARAM_ALPN:
741       return ARES_OPT_DATATYPE_STR_LIST;
742     case ARES_SVCB_PARAM_PORT:
743       return ARES_OPT_DATATYPE_U16;
744     case ARES_SVCB_PARAM_IPV4HINT:
745       return ARES_OPT_DATATYPE_INADDR4_LIST;
746     case ARES_SVCB_PARAM_IPV6HINT:
747       return ARES_OPT_DATATYPE_INADDR6_LIST;
748   }
749   return ARES_OPT_DATATYPE_BIN;
750 }
751 
ares_dns_opt_get_datatype(ares_dns_rr_key_t key,unsigned short opt)752 ares_dns_opt_datatype_t ares_dns_opt_get_datatype(ares_dns_rr_key_t key,
753                                                   unsigned short    opt)
754 {
755   switch (key) {
756     case ARES_RR_OPT_OPTIONS:
757       return ares_dns_opt_get_type_opt(opt);
758     case ARES_RR_SVCB_PARAMS:
759     case ARES_RR_HTTPS_PARAMS:
760       return ares_dns_opt_get_type_svcb(opt);
761     default:
762       break;
763   }
764   return ARES_OPT_DATATYPE_BIN;
765 }
766 
ares_dns_opt_get_name_opt(unsigned short opt)767 static const char *ares_dns_opt_get_name_opt(unsigned short opt)
768 {
769   ares_opt_param_t param = (ares_opt_param_t)opt;
770   switch (param) {
771     case ARES_OPT_PARAM_LLQ:
772       return "LLQ";
773     case ARES_OPT_PARAM_UL:
774       return "UL";
775     case ARES_OPT_PARAM_NSID:
776       return "NSID";
777     case ARES_OPT_PARAM_DAU:
778       return "DAU";
779     case ARES_OPT_PARAM_DHU:
780       return "DHU";
781     case ARES_OPT_PARAM_N3U:
782       return "N3U";
783     case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
784       return "edns-client-subnet";
785     case ARES_OPT_PARAM_EDNS_EXPIRE:
786       return "edns-expire";
787     case ARES_OPT_PARAM_COOKIE:
788       return "COOKIE";
789     case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
790       return "edns-tcp-keepalive";
791     case ARES_OPT_PARAM_PADDING:
792       return "Padding";
793     case ARES_OPT_PARAM_CHAIN:
794       return "CHAIN";
795     case ARES_OPT_PARAM_EDNS_KEY_TAG:
796       return "edns-key-tag";
797     case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
798       return "extended-dns-error";
799   }
800   return NULL;
801 }
802 
ares_dns_opt_get_name_svcb(unsigned short opt)803 static const char *ares_dns_opt_get_name_svcb(unsigned short opt)
804 {
805   ares_svcb_param_t param = (ares_svcb_param_t)opt;
806   switch (param) {
807     case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
808       return "no-default-alpn";
809     case ARES_SVCB_PARAM_ECH:
810       return "ech";
811     case ARES_SVCB_PARAM_MANDATORY:
812       return "mandatory";
813     case ARES_SVCB_PARAM_ALPN:
814       return "alpn";
815     case ARES_SVCB_PARAM_PORT:
816       return "port";
817     case ARES_SVCB_PARAM_IPV4HINT:
818       return "ipv4hint";
819     case ARES_SVCB_PARAM_IPV6HINT:
820       return "ipv6hint";
821   }
822   return NULL;
823 }
824 
ares_dns_opt_get_name(ares_dns_rr_key_t key,unsigned short opt)825 const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, unsigned short opt)
826 {
827   switch (key) {
828     case ARES_RR_OPT_OPTIONS:
829       return ares_dns_opt_get_name_opt(opt);
830     case ARES_RR_SVCB_PARAMS:
831     case ARES_RR_HTTPS_PARAMS:
832       return ares_dns_opt_get_name_svcb(opt);
833     default:
834       break;
835   }
836   return NULL;
837 }
838 
ares_dns_rcode_tostr(ares_dns_rcode_t rcode)839 const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode)
840 {
841   switch (rcode) {
842     case ARES_RCODE_NOERROR:
843       return "NOERROR";
844     case ARES_RCODE_FORMERR:
845       return "FORMERR";
846     case ARES_RCODE_SERVFAIL:
847       return "SERVFAIL";
848     case ARES_RCODE_NXDOMAIN:
849       return "NXDOMAIN";
850     case ARES_RCODE_NOTIMP:
851       return "NOTIMP";
852     case ARES_RCODE_REFUSED:
853       return "REFUSED";
854     case ARES_RCODE_YXDOMAIN:
855       return "YXDOMAIN";
856     case ARES_RCODE_YXRRSET:
857       return "YXRRSET";
858     case ARES_RCODE_NXRRSET:
859       return "NXRRSET";
860     case ARES_RCODE_NOTAUTH:
861       return "NOTAUTH";
862     case ARES_RCODE_NOTZONE:
863       return "NOTZONE";
864     case ARES_RCODE_DSOTYPEI:
865       return "DSOTYPEI";
866     case ARES_RCODE_BADSIG:
867       return "BADSIG";
868     case ARES_RCODE_BADKEY:
869       return "BADKEY";
870     case ARES_RCODE_BADTIME:
871       return "BADTIME";
872     case ARES_RCODE_BADMODE:
873       return "BADMODE";
874     case ARES_RCODE_BADNAME:
875       return "BADNAME";
876     case ARES_RCODE_BADALG:
877       return "BADALG";
878     case ARES_RCODE_BADTRUNC:
879       return "BADTRUNC";
880     case ARES_RCODE_BADCOOKIE:
881       return "BADCOOKIE";
882   }
883 
884   return "UNKNOWN";
885 }
886