xref: /dragonfly/contrib/ldns/host2str.c (revision 7733acb50455a11cc2ee36edd926ff0fa3361e9a)
1 /*
2  * host2str.c
3  *
4  * conversion routines from the host format
5  * to the presentation format (strings)
6  *
7  * a Net::DNS like library for C
8  *
9  * (c) NLnet Labs, 2004-2006
10  *
11  * See the file LICENSE for the license
12  */
13 #include <ldns/config.h>
14 
15 #include <ldns/ldns.h>
16 
17 #include <limits.h>
18 
19 #ifdef HAVE_SYS_SOCKET_H
20 #include <sys/socket.h>
21 #endif
22 #ifdef HAVE_ARPA_INET_H
23 #include <arpa/inet.h>
24 #endif
25 #ifdef HAVE_NETDB_H
26 #include <netdb.h>
27 #endif
28 #include <time.h>
29 #include <sys/time.h>
30 
31 #ifdef HAVE_SSL
32 #include <openssl/bn.h>
33 #include <openssl/rsa.h>
34 #ifdef USE_DSA
35 #include <openssl/dsa.h>
36 #endif
37 #endif
38 
39 #ifndef INET_ADDRSTRLEN
40 #define INET_ADDRSTRLEN 16
41 #endif
42 #ifndef INET6_ADDRSTRLEN
43 #define INET6_ADDRSTRLEN 46
44 #endif
45 
46 /* Internal helper function */
47 ldns_edns_option_list*
48 pkt_edns_data2edns_option_list(const ldns_rdf *edns_data);
49 
50 /* lookup tables for standard DNS stuff  */
51 
52 /* Taken from RFC 2535, section 7.  */
53 ldns_lookup_table ldns_algorithms[] = {
54         { LDNS_RSAMD5, "RSAMD5" },
55         { LDNS_DH, "DH" },
56         { LDNS_DSA, "DSA" },
57         { LDNS_ECC, "ECC" },
58         { LDNS_RSASHA1, "RSASHA1" },
59         { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
60         { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
61           { LDNS_RSASHA256, "RSASHA256"},
62           { LDNS_RSASHA512, "RSASHA512"},
63           { LDNS_ECC_GOST, "ECC-GOST"},
64         { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
65         { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
66           { LDNS_ED25519, "ED25519"},
67           { LDNS_ED448, "ED448"},
68         { LDNS_INDIRECT, "INDIRECT" },
69         { LDNS_PRIVATEDNS, "PRIVATEDNS" },
70         { LDNS_PRIVATEOID, "PRIVATEOID" },
71         { 0, NULL }
72 };
73 
74 /* Hashing algorithms used in the DS record */
75 ldns_lookup_table ldns_hashes[] = {
76         {LDNS_SHA1     , "SHA1" },      /* RFC 4034 */
77         {LDNS_SHA256   , "SHA256" },    /* RFC 4509 */
78         {LDNS_HASH_GOST, "HASH-GOST" }, /* RFC 5933 */
79         {LDNS_SHA384   , "SHA384" },    /* RFC 6605 */
80         { 0, NULL }
81 };
82 
83 /* Taken from RFC 4398  */
84 ldns_lookup_table ldns_cert_algorithms[] = {
85         { LDNS_CERT_PKIX, "PKIX" },
86         { LDNS_CERT_SPKI, "SPKI" },
87         { LDNS_CERT_PGP, "PGP" },
88         { LDNS_CERT_IPKIX, "IPKIX" },
89         { LDNS_CERT_ISPKI, "ISPKI" },
90         { LDNS_CERT_IPGP, "IPGP" },
91         { LDNS_CERT_ACPKIX, "ACPKIX" },
92         { LDNS_CERT_IACPKIX, "IACPKIX" },
93         { LDNS_CERT_URI, "URI" },
94         { LDNS_CERT_OID, "OID" },
95         { 0, NULL }
96 };
97 
98 /* classes  */
99 ldns_lookup_table ldns_rr_classes[] = {
100         { LDNS_RR_CLASS_IN, "IN" },
101         { LDNS_RR_CLASS_CH, "CH" },
102         { LDNS_RR_CLASS_HS, "HS" },
103         { LDNS_RR_CLASS_NONE, "NONE" },
104         { LDNS_RR_CLASS_ANY, "ANY" },
105         { 0, NULL }
106 };
107 
108 /* if these are used elsewhere */
109 ldns_lookup_table ldns_rcodes[] = {
110         { LDNS_RCODE_NOERROR, "NOERROR" },
111         { LDNS_RCODE_FORMERR, "FORMERR" },
112         { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
113         { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
114         { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
115         { LDNS_RCODE_REFUSED, "REFUSED" },
116         { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
117         { LDNS_RCODE_YXRRSET, "YXRRSET" },
118         { LDNS_RCODE_NXRRSET, "NXRRSET" },
119         { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
120         { LDNS_RCODE_NOTZONE, "NOTZONE" },
121         { 0, NULL }
122 };
123 
124 ldns_lookup_table ldns_opcodes[] = {
125         { LDNS_PACKET_QUERY, "QUERY" },
126         { LDNS_PACKET_IQUERY, "IQUERY" },
127         { LDNS_PACKET_STATUS, "STATUS" },
128           { LDNS_PACKET_NOTIFY, "NOTIFY" },
129           { LDNS_PACKET_UPDATE, "UPDATE" },
130         { 0, NULL }
131 };
132 
133 const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
134 const ldns_output_format  *ldns_output_format_nocomments
135                               = &ldns_output_format_nocomments_record;
136 const ldns_output_format   ldns_output_format_onlykeyids_record = {
137           LDNS_COMMENT_KEY, NULL
138 };
139 const ldns_output_format  *ldns_output_format_onlykeyids
140                               = &ldns_output_format_onlykeyids_record;
141 const ldns_output_format  *ldns_output_format_default
142                               = &ldns_output_format_onlykeyids_record;
143 
144 const ldns_output_format   ldns_output_format_bubblebabble_record = {
145           LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
146 };
147 const ldns_output_format  *ldns_output_format_bubblebabble
148                               = &ldns_output_format_bubblebabble_record;
149 
150 static bool
ldns_output_format_covers_type(const ldns_output_format * fmt,ldns_rr_type t)151 ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
152 {
153           return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
154                     ((ldns_output_format_storage*)fmt)->bitmap &&
155                     ldns_nsec_bitmap_covers_type(
156                                         ((ldns_output_format_storage*)fmt)->bitmap, t);
157 }
158 
159 ldns_status
ldns_output_format_set_type(ldns_output_format * fmt,ldns_rr_type t)160 ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
161 {
162           ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
163           ldns_status s;
164 
165           assert(fmt != NULL);
166 
167           if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
168                     ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
169           }
170           if (! fmt_st->bitmap) {
171                     s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
172                     if (s != LDNS_STATUS_OK) {
173                               return s;
174                     }
175           }
176           return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
177 }
178 
179 ldns_status
ldns_output_format_clear_type(ldns_output_format * fmt,ldns_rr_type t)180 ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
181 {
182           ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
183           ldns_status s;
184 
185           assert(fmt != NULL);
186 
187           if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
188                     ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
189           }
190           if (! fmt_st->bitmap) {
191                     s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
192                     if (s != LDNS_STATUS_OK) {
193                               return s;
194                     }
195           }
196           return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
197 }
198 
199 ldns_status
ldns_pkt_opcode2buffer_str(ldns_buffer * output,ldns_pkt_opcode opcode)200 ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
201 {
202           ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
203           if (lt && lt->name) {
204                     ldns_buffer_printf(output, "%s", lt->name);
205           } else {
206                     ldns_buffer_printf(output, "OPCODE%u", opcode);
207           }
208           return ldns_buffer_status(output);
209 }
210 
211 ldns_status
ldns_pkt_rcode2buffer_str(ldns_buffer * output,ldns_pkt_rcode rcode)212 ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
213 {
214           ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
215           if (lt && lt->name) {
216                     ldns_buffer_printf(output, "%s", lt->name);
217           } else {
218                     ldns_buffer_printf(output, "RCODE%u", rcode);
219           }
220           return ldns_buffer_status(output);
221 }
222 
223 ldns_status
ldns_algorithm2buffer_str(ldns_buffer * output,ldns_algorithm algorithm)224 ldns_algorithm2buffer_str(ldns_buffer *output,
225                           ldns_algorithm algorithm)
226 {
227           ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
228                                                     algorithm);
229           if (lt && lt->name) {
230                     ldns_buffer_printf(output, "%s", lt->name);
231           } else {
232                     ldns_buffer_printf(output, "ALG%u", algorithm);
233           }
234           return ldns_buffer_status(output);
235 }
236 
237 ldns_status
ldns_cert_algorithm2buffer_str(ldns_buffer * output,ldns_cert_algorithm cert_algorithm)238 ldns_cert_algorithm2buffer_str(ldns_buffer *output,
239                                ldns_cert_algorithm cert_algorithm)
240 {
241           ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
242                                                     cert_algorithm);
243           if (lt && lt->name) {
244                     ldns_buffer_printf(output, "%s", lt->name);
245           } else {
246                     ldns_buffer_printf(output, "CERT_ALG%u",
247                                        cert_algorithm);
248           }
249           return ldns_buffer_status(output);
250 }
251 
252 char *
ldns_pkt_opcode2str(ldns_pkt_opcode opcode)253 ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
254 {
255           char *str;
256           ldns_buffer *buf;
257 
258           buf = ldns_buffer_new(12);
259           if (!buf) {
260                     return NULL;
261           }
262 
263           str = NULL;
264           if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
265                     str = ldns_buffer_export2str(buf);
266           }
267 
268           ldns_buffer_free(buf);
269           return str;
270 }
271 
272 char *
ldns_pkt_rcode2str(ldns_pkt_rcode rcode)273 ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
274 {
275           char *str;
276           ldns_buffer *buf;
277 
278           buf = ldns_buffer_new(10);
279           if (!buf) {
280                     return NULL;
281           }
282 
283           str = NULL;
284           if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
285                     str = ldns_buffer_export2str(buf);
286           }
287 
288           ldns_buffer_free(buf);
289           return str;
290 }
291 
292 char *
ldns_pkt_algorithm2str(ldns_algorithm algorithm)293 ldns_pkt_algorithm2str(ldns_algorithm algorithm)
294 {
295           char *str;
296           ldns_buffer *buf;
297 
298           buf = ldns_buffer_new(10);
299           if (!buf) {
300                     return NULL;
301           }
302 
303           str = NULL;
304           if (ldns_algorithm2buffer_str(buf, algorithm)
305               == LDNS_STATUS_OK) {
306                     str = ldns_buffer_export2str(buf);
307           }
308 
309           ldns_buffer_free(buf);
310           return str;
311 }
312 
313 char *
ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)314 ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
315 {
316           char *str;
317           ldns_buffer *buf;
318 
319           buf = ldns_buffer_new(10);
320           if (!buf) {
321                     return NULL;
322           }
323 
324           str = NULL;
325           if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
326               == LDNS_STATUS_OK) {
327                     str = ldns_buffer_export2str(buf);
328           }
329 
330           ldns_buffer_free(buf);
331           return str;
332 }
333 
334 
335 /* do NOT pass compressed data here :p */
336 ldns_status
ldns_rdf2buffer_str_dname(ldns_buffer * output,const ldns_rdf * dname)337 ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
338 {
339           /* can we do with 1 pos var? or without at all? */
340           uint8_t src_pos = 0;
341           uint8_t len;
342           uint8_t *data;
343           uint8_t i;
344           unsigned char c;
345 
346           data = (uint8_t*)ldns_rdf_data(dname);
347           len = data[src_pos];
348 
349           if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
350                     /* too large, return */
351                     return LDNS_STATUS_DOMAINNAME_OVERFLOW;
352           }
353 
354           /* special case: root label */
355           if (1 == ldns_rdf_size(dname)) {
356                     ldns_buffer_printf(output, ".");
357           } else {
358                     while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
359                               src_pos++;
360                               for(i = 0; i < len; i++) {
361                                         /* paranoia check for various 'strange'
362                                            characters in dnames
363                                         */
364                                         c = (unsigned char) data[src_pos];
365                                         if(c == '.' || c == ';' ||
366                                            c == '(' || c == ')' ||
367                                            c == '\\') {
368                                                   ldns_buffer_printf(output, "\\%c",
369                                                                       data[src_pos]);
370                                         } else if (!(isascii(c) && isgraph(c))) {
371                                                   ldns_buffer_printf(output, "\\%03u",
372                                                                     data[src_pos]);
373                                         } else {
374                                                   ldns_buffer_printf(output, "%c", data[src_pos]);
375                                         }
376                                         src_pos++;
377                               }
378 
379                               if (src_pos < ldns_rdf_size(dname)) {
380                                         ldns_buffer_printf(output, ".");
381                               }
382                               len = data[src_pos];
383                     }
384           }
385           return ldns_buffer_status(output);
386 }
387 
388 ldns_status
ldns_rdf2buffer_str_int8(ldns_buffer * output,const ldns_rdf * rdf)389 ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
390 {
391           uint8_t data = ldns_rdf_data(rdf)[0];
392           ldns_buffer_printf(output, "%lu", (unsigned long) data);
393           return ldns_buffer_status(output);
394 }
395 
396 ldns_status
ldns_rdf2buffer_str_int16(ldns_buffer * output,const ldns_rdf * rdf)397 ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
398 {
399           uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
400           ldns_buffer_printf(output, "%lu", (unsigned long) data);
401           return ldns_buffer_status(output);
402 }
403 
404 ldns_status
ldns_rdf2buffer_str_int32(ldns_buffer * output,const ldns_rdf * rdf)405 ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
406 {
407           uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
408           ldns_buffer_printf(output, "%lu", (unsigned long) data);
409           return ldns_buffer_status(output);
410 }
411 
412 ldns_status
ldns_rdf2buffer_str_time(ldns_buffer * output,const ldns_rdf * rdf)413 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
414 {
415           /* create a YYYYMMDDHHMMSS string if possible */
416           struct tm tm;
417           char date_buf[16];
418 
419           memset(&tm, 0, sizeof(tm));
420           if (ldns_serial_arithmetics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
421               && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
422                     ldns_buffer_printf(output, "%s", date_buf);
423           }
424           return ldns_buffer_status(output);
425 }
426 
427 ldns_status
ldns_rdf2buffer_str_a(ldns_buffer * output,const ldns_rdf * rdf)428 ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
429 {
430           char str[INET_ADDRSTRLEN];
431 
432           if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
433                     ldns_buffer_printf(output, "%s", str);
434           }
435           return ldns_buffer_status(output);
436 }
437 
438 ldns_status
ldns_rdf2buffer_str_aaaa(ldns_buffer * output,const ldns_rdf * rdf)439 ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
440 {
441           char str[INET6_ADDRSTRLEN];
442 
443           if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
444                     ldns_buffer_printf(output, "%s", str);
445           }
446 
447           return ldns_buffer_status(output);
448 }
449 
450 static void
ldns_characters2buffer_str(ldns_buffer * output,size_t amount,const uint8_t * characters)451 ldns_characters2buffer_str(ldns_buffer* output,
452                     size_t amount, const uint8_t* characters)
453 {
454           uint8_t ch;
455           while (amount > 0) {
456                     ch = *characters++;
457                     if (isprint((int)ch) || ch == '\t') {
458                               if (ch == '\"' || ch == '\\')
459                                         ldns_buffer_printf(output, "\\%c", ch);
460                               else
461                                         ldns_buffer_printf(output, "%c", ch);
462                     } else {
463                               ldns_buffer_printf(output, "\\%03u",
464                                 (unsigned)(uint8_t) ch);
465                     }
466                     amount--;
467           }
468 }
469 
470 ldns_status
ldns_rdf2buffer_str_str(ldns_buffer * output,const ldns_rdf * rdf)471 ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
472 {
473         if(ldns_rdf_size(rdf) < 1) {
474                 return LDNS_STATUS_WIRE_RDATA_ERR;
475         }
476         if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
477                 return LDNS_STATUS_WIRE_RDATA_ERR;
478         }
479           ldns_buffer_printf(output, "\"");
480           ldns_characters2buffer_str(output,
481                               ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
482           ldns_buffer_printf(output, "\"");
483           return ldns_buffer_status(output);
484 }
485 
486 ldns_status
ldns_rdf2buffer_str_b64(ldns_buffer * output,const ldns_rdf * rdf)487 ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
488 {
489           size_t size;
490           char *b64;
491 
492           if (ldns_rdf_size(rdf) == 0) {
493                     ldns_buffer_printf(output, "0");
494                     return ldns_buffer_status(output);
495           } else
496                     size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
497 
498           if (!(b64 = LDNS_XMALLOC(char, size)))
499                     return LDNS_STATUS_MEM_ERR;
500 
501           if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
502                     ldns_buffer_printf(output, "%s", b64);
503           }
504           LDNS_FREE(b64);
505           return ldns_buffer_status(output);
506 }
507 
508 ldns_status
ldns_rdf2buffer_str_b32_ext(ldns_buffer * output,const ldns_rdf * rdf)509 ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
510 {
511           size_t size;
512           char *b32;
513           if(ldns_rdf_size(rdf) == 0)
514                     return LDNS_STATUS_OK;
515         /* remove -1 for the b32-hash-len octet */
516           size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
517         /* add one for the end nul for the string */
518           b32 = LDNS_XMALLOC(char, size + 1);
519           if(!b32) return LDNS_STATUS_MEM_ERR;
520           size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
521                     ldns_rdf_size(rdf) - 1, b32, size+1);
522           if (size > 0) {
523                     ldns_buffer_printf(output, "%s", b32);
524           }
525           LDNS_FREE(b32);
526           return ldns_buffer_status(output);
527 }
528 
529 ldns_status
ldns_rdf2buffer_str_hex(ldns_buffer * output,const ldns_rdf * rdf)530 ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
531 {
532           size_t i;
533           for (i = 0; i < ldns_rdf_size(rdf); i++) {
534                     ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
535           }
536 
537           return ldns_buffer_status(output);
538 }
539 
540 static ldns_status
ldns_rdf2buffer_str_type_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)541 ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
542                     const ldns_output_format* fmt, const ldns_rdf *rdf)
543 {
544         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
545 
546           if (! ldns_output_format_covers_type(fmt, data) &&
547                               ldns_rr_descript(data) &&
548                               ldns_rr_descript(data)->_name) {
549 
550                     ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
551           } else {
552                     ldns_buffer_printf(output, "TYPE%u", data);
553           }
554           return  ldns_buffer_status(output);
555 }
556 
557 ldns_status
ldns_rdf2buffer_str_type(ldns_buffer * output,const ldns_rdf * rdf)558 ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
559 {
560           return ldns_rdf2buffer_str_type_fmt(output,
561                               ldns_output_format_default, rdf);
562 }
563 
564 ldns_status
ldns_rdf2buffer_str_class(ldns_buffer * output,const ldns_rdf * rdf)565 ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
566 {
567           uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
568           ldns_lookup_table *lt;
569 
570           lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
571           if (lt) {
572                     ldns_buffer_printf(output, "\t%s", lt->name);
573           } else {
574                     ldns_buffer_printf(output, "\tCLASS%d", data);
575           }
576           return ldns_buffer_status(output);
577 }
578 
579 ldns_status
ldns_rdf2buffer_str_cert_alg(ldns_buffer * output,const ldns_rdf * rdf)580 ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
581 {
582         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
583           ldns_lookup_table *lt;
584           lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
585           if (lt) {
586                     ldns_buffer_printf(output, "%s", lt->name);
587           } else {
588                     ldns_buffer_printf(output, "%d", data);
589           }
590           return ldns_buffer_status(output);
591 }
592 
593 ldns_status
ldns_rdf2buffer_str_alg(ldns_buffer * output,const ldns_rdf * rdf)594 ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
595 {
596           return ldns_rdf2buffer_str_int8(output, rdf);
597 }
598 
599 static void
loc_cm_print(ldns_buffer * output,uint8_t mantissa,uint8_t exponent)600 loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
601 {
602           uint8_t i;
603           /* is it 0.<two digits> ? */
604           if(exponent < 2) {
605                     if(exponent == 1)
606                               mantissa *= 10;
607                     ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
608                     return;
609           }
610           /* always <digit><string of zeros> */
611           ldns_buffer_printf(output, "%d", (int)mantissa);
612           for(i=0; i<exponent-2; i++)
613                     ldns_buffer_printf(output, "0");
614 }
615 
616 ldns_status
ldns_rr_type2buffer_str(ldns_buffer * output,const ldns_rr_type type)617 ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
618 {
619           const ldns_rr_descriptor *descriptor;
620 
621           descriptor = ldns_rr_descript(type);
622 
623           switch (type) {
624                     case LDNS_RR_TYPE_IXFR:
625                               ldns_buffer_printf(output, "IXFR");
626                               break;
627                     case LDNS_RR_TYPE_AXFR:
628                               ldns_buffer_printf(output, "AXFR");
629                               break;
630                     case LDNS_RR_TYPE_MAILA:
631                               ldns_buffer_printf(output, "MAILA");
632                               break;
633                     case LDNS_RR_TYPE_MAILB:
634                               ldns_buffer_printf(output, "MAILB");
635                               break;
636                     case LDNS_RR_TYPE_ANY:
637                               ldns_buffer_printf(output, "ANY");
638                               break;
639                     default:
640                               if (descriptor && descriptor->_name) {
641                                         ldns_buffer_printf(output, "%s", descriptor->_name);
642                               } else {
643                                         ldns_buffer_printf(output, "TYPE%u", type);
644                               }
645           }
646           return ldns_buffer_status(output);
647 }
648 
649 char *
ldns_rr_type2str(const ldns_rr_type type)650 ldns_rr_type2str(const ldns_rr_type type)
651 {
652           char *str;
653           ldns_buffer *buf;
654 
655           buf = ldns_buffer_new(10);
656           if (!buf) {
657                     return NULL;
658           }
659 
660           str = NULL;
661           if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
662                     str = ldns_buffer_export2str(buf);
663           }
664 
665           ldns_buffer_free(buf);
666           return str;
667 }
668 
669 
670 ldns_status
ldns_rr_class2buffer_str(ldns_buffer * output,const ldns_rr_class klass)671 ldns_rr_class2buffer_str(ldns_buffer *output,
672                          const ldns_rr_class klass)
673 {
674           ldns_lookup_table *lt;
675 
676           lt = ldns_lookup_by_id(ldns_rr_classes, klass);
677           if (lt) {
678                     ldns_buffer_printf(output, "%s", lt->name);
679           } else {
680                     ldns_buffer_printf(output, "CLASS%d", klass);
681           }
682           return ldns_buffer_status(output);
683 }
684 
685 char *
ldns_rr_class2str(const ldns_rr_class klass)686 ldns_rr_class2str(const ldns_rr_class klass)
687 {
688           ldns_buffer *buf;
689           char *str;
690 
691           buf = ldns_buffer_new(10);
692           if (!buf) {
693                     return NULL;
694           }
695 
696           str = NULL;
697           if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
698                     str = ldns_buffer_export2str(buf);
699           }
700           ldns_buffer_free(buf);
701           return str;
702 }
703 
704 ldns_status
ldns_rdf2buffer_str_loc(ldns_buffer * output,const ldns_rdf * rdf)705 ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
706 {
707           /* we could do checking (ie degrees < 90 etc)? */
708           uint8_t version;
709           uint8_t size;
710           uint8_t horizontal_precision;
711           uint8_t vertical_precision;
712           uint32_t longitude;
713           uint32_t latitude;
714           uint32_t altitude;
715           char latitude_hemisphere;
716           char longitude_hemisphere;
717           uint32_t h;
718           uint32_t m;
719           double s;
720 
721           uint32_t equator = (uint32_t) ldns_power(2, 31);
722 
723         if(ldns_rdf_size(rdf) < 1) {
724                 return LDNS_STATUS_WIRE_RDATA_ERR;
725         }
726           version = ldns_rdf_data(rdf)[0];
727           if (version == 0) {
728                     if(ldns_rdf_size(rdf) < 16) {
729                               return LDNS_STATUS_WIRE_RDATA_ERR;
730                     }
731                     size = ldns_rdf_data(rdf)[1];
732                     horizontal_precision = ldns_rdf_data(rdf)[2];
733                     vertical_precision = ldns_rdf_data(rdf)[3];
734 
735                     latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
736                     longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
737                     altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
738 
739                     if (latitude > equator) {
740                               latitude_hemisphere = 'N';
741                               latitude = latitude - equator;
742                     } else {
743                               latitude_hemisphere = 'S';
744                               latitude = equator - latitude;
745                     }
746                     h = latitude / (1000 * 60 * 60);
747                     latitude = latitude % (1000 * 60 * 60);
748                     m = latitude / (1000 * 60);
749                     latitude = latitude % (1000 * 60);
750                     s = (double) latitude / 1000.0;
751                     ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
752                               h, m, s, latitude_hemisphere);
753 
754                     if (longitude > equator) {
755                               longitude_hemisphere = 'E';
756                               longitude = longitude - equator;
757                     } else {
758                               longitude_hemisphere = 'W';
759                               longitude = equator - longitude;
760                     }
761                     h = longitude / (1000 * 60 * 60);
762                     longitude = longitude % (1000 * 60 * 60);
763                     m = longitude / (1000 * 60);
764                     longitude = longitude % (1000 * 60);
765                     s = (double) longitude / (1000.0);
766                     ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
767                               h, m, s, longitude_hemisphere);
768 
769                     s = ((double) altitude) / 100;
770                     s -= 100000;
771 
772                     if(altitude%100 != 0)
773                               ldns_buffer_printf(output, "%.2f", s);
774                     else
775                               ldns_buffer_printf(output, "%.0f", s);
776 
777                     ldns_buffer_printf(output, "m ");
778 
779                     loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
780                     ldns_buffer_printf(output, "m ");
781 
782                     loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
783                               horizontal_precision & 0x0f);
784                     ldns_buffer_printf(output, "m ");
785 
786                     loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
787                               vertical_precision & 0x0f);
788                     ldns_buffer_printf(output, "m");
789 
790                     return ldns_buffer_status(output);
791           } else {
792                     return ldns_rdf2buffer_str_hex(output, rdf);
793           }
794 }
795 
796 ldns_status
ldns_rdf2buffer_str_unknown(ldns_buffer * output,const ldns_rdf * rdf)797 ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
798 {
799           ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
800           return ldns_rdf2buffer_str_hex(output, rdf);
801 }
802 
803 ldns_status
ldns_rdf2buffer_str_nsap(ldns_buffer * output,const ldns_rdf * rdf)804 ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
805 {
806           ldns_buffer_printf(output, "0x");
807           return ldns_rdf2buffer_str_hex(output, rdf);
808 }
809 
810 ldns_status
ldns_rdf2buffer_str_atma(ldns_buffer * output,const ldns_rdf * rdf)811 ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
812 {
813           return ldns_rdf2buffer_str_hex(output, rdf);
814 }
815 
816 ldns_status
ldns_rdf2buffer_str_wks(ldns_buffer * output,const ldns_rdf * rdf)817 ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
818 {
819           /* protocol, followed by bitmap of services */
820           struct protoent *protocol;
821           char *proto_name = NULL;
822           uint8_t protocol_nr;
823           struct servent *service;
824           uint16_t current_service;
825 
826         if(ldns_rdf_size(rdf) < 1) {
827                 return LDNS_STATUS_WIRE_RDATA_ERR;
828         }
829           protocol_nr = ldns_rdf_data(rdf)[0];
830           protocol = getprotobynumber((int) protocol_nr);
831           if (protocol && (protocol->p_name != NULL)) {
832                     proto_name = protocol->p_name;
833                     ldns_buffer_printf(output, "%s ", protocol->p_name);
834           } else {
835                     ldns_buffer_printf(output, "%u ", protocol_nr);
836           }
837 
838 #ifdef HAVE_ENDPROTOENT
839           endprotoent();
840 #endif
841 
842           for (current_service = 0;
843                current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
844                     if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
845                               service = getservbyport((int) htons(current_service),
846                                                       proto_name);
847                               if (service && service->s_name) {
848                                         ldns_buffer_printf(output, "%s ", service->s_name);
849                               } else {
850                                         ldns_buffer_printf(output, "%u ", current_service);
851                               }
852 #ifdef HAVE_ENDSERVENT
853                               endservent();
854 #endif
855                     }
856                     /* exit from loop before integer overflow */
857                     if(current_service == 65535) { break; }
858           }
859           return ldns_buffer_status(output);
860 }
861 
862 static ldns_status
ldns_rdf2buffer_str_nsec_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)863 ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
864                     const ldns_output_format* fmt, const ldns_rdf *rdf)
865 {
866           /* Note: this code is duplicated in higher.c in
867            * ldns_nsec_type_check() function
868            */
869           uint8_t window_block_nr;
870           uint8_t bitmap_length;
871           uint16_t type;
872           uint16_t pos = 0;
873           uint16_t bit_pos;
874           uint8_t *data = ldns_rdf_data(rdf);
875 
876           while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
877                     window_block_nr = data[pos];
878                     bitmap_length = data[pos + 1];
879                     pos += 2;
880                     if (ldns_rdf_size(rdf) < pos + bitmap_length) {
881                               return LDNS_STATUS_WIRE_RDATA_ERR;
882                     }
883                     for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
884                               if (! ldns_get_bit(&data[pos], bit_pos)) {
885                                         continue;
886                               }
887                               type = 256 * (uint16_t) window_block_nr + bit_pos;
888 
889                               if (! ldns_output_format_covers_type(fmt, type) &&
890                                                   ldns_rr_descript(type) &&
891                                                   ldns_rr_descript(type)->_name){
892 
893                                         ldns_buffer_printf(output, "%s ",
894                                                             ldns_rr_descript(type)->_name);
895                               } else {
896                                         ldns_buffer_printf(output, "TYPE%u ", type);
897                               }
898                     }
899                     pos += (uint16_t) bitmap_length;
900           }
901           return ldns_buffer_status(output);
902 }
903 
904 ldns_status
ldns_rdf2buffer_str_nsec(ldns_buffer * output,const ldns_rdf * rdf)905 ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
906 {
907           return ldns_rdf2buffer_str_nsec_fmt(output,
908                               ldns_output_format_default, rdf);
909 }
910 
911 ldns_status
ldns_rdf2buffer_str_nsec3_salt(ldns_buffer * output,const ldns_rdf * rdf)912 ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
913 {
914           uint8_t salt_length;
915           uint8_t salt_pos;
916 
917           uint8_t *data = ldns_rdf_data(rdf);
918 
919         if(ldns_rdf_size(rdf) < 1) {
920                 return LDNS_STATUS_WIRE_RDATA_ERR;
921         }
922           salt_length = data[0];
923           /* from now there are variable length entries so remember pos */
924           if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
925                     ldns_buffer_printf(output, "- ");
926           } else {
927                     for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
928                               ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
929                     }
930                     ldns_buffer_printf(output, " ");
931           }
932 
933           return ldns_buffer_status(output);
934 }
935 
936 ldns_status
ldns_rdf2buffer_str_period(ldns_buffer * output,const ldns_rdf * rdf)937 ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
938 {
939           /* period is the number of seconds */
940           if (ldns_rdf_size(rdf) != 4) {
941                     return LDNS_STATUS_WIRE_RDATA_ERR;
942           }
943           ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
944           return ldns_buffer_status(output);
945 }
946 
947 ldns_status
ldns_rdf2buffer_str_tsigtime(ldns_buffer * output,const ldns_rdf * rdf)948 ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
949 {
950           /* tsigtime is 48 bits network order unsigned integer */
951           uint64_t tsigtime = 0;
952           uint8_t *data = ldns_rdf_data(rdf);
953           uint64_t d0, d1, d2, d3, d4, d5;
954 
955           if (ldns_rdf_size(rdf) < 6) {
956                     return LDNS_STATUS_WIRE_RDATA_ERR;
957           }
958           d0 = data[0]; /* cast to uint64 for shift operations */
959           d1 = data[1];
960           d2 = data[2];
961           d3 = data[3];
962           d4 = data[4];
963           d5 = data[5];
964           tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
965 
966           ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
967 
968           return ldns_buffer_status(output);
969 }
970 
971 ldns_status
ldns_rdf2buffer_str_apl(ldns_buffer * output,const ldns_rdf * rdf)972 ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
973 {
974           uint8_t *data = ldns_rdf_data(rdf);
975           uint16_t address_family;
976           uint8_t prefix;
977           bool negation;
978           uint8_t adf_length;
979           size_t i;
980           size_t pos = 0;
981 
982           while (pos < (unsigned int) ldns_rdf_size(rdf)) {
983                 if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
984                         return LDNS_STATUS_WIRE_RDATA_ERR;
985                     address_family = ldns_read_uint16(&data[pos]);
986                     prefix = data[pos + 2];
987                     negation = data[pos + 3] & LDNS_APL_NEGATION;
988                     adf_length = data[pos + 3] & LDNS_APL_MASK;
989                     if (address_family == LDNS_APL_IP4) {
990                               /* check if prefix < 32? */
991                               if (negation) {
992                                         ldns_buffer_printf(output, "!");
993                               }
994                               ldns_buffer_printf(output, "%u:", address_family);
995                               /* address is variable length 0 - 4 */
996                               for (i = 0; i < 4; i++) {
997                                         if (i > 0) {
998                                                   ldns_buffer_printf(output, ".");
999                                         }
1000                                         if (i < (unsigned short) adf_length) {
1001                                         if(pos+i+4 >= ldns_rdf_size(rdf))
1002                                                       return LDNS_STATUS_WIRE_RDATA_ERR;
1003                                                   ldns_buffer_printf(output, "%d",
1004                                                                      data[pos + i + 4]);
1005                                         } else {
1006                                                   ldns_buffer_printf(output, "0");
1007                                         }
1008                               }
1009                               ldns_buffer_printf(output, "/%u ", prefix);
1010                     } else if (address_family == LDNS_APL_IP6) {
1011                               /* check if prefix < 128? */
1012                               if (negation) {
1013                                         ldns_buffer_printf(output, "!");
1014                               }
1015                               ldns_buffer_printf(output, "%u:", address_family);
1016                               /* address is variable length 0 - 16 */
1017                               for (i = 0; i < 16; i++) {
1018                                         if (i % 2 == 0 && i > 0) {
1019                                                   ldns_buffer_printf(output, ":");
1020                                         }
1021                                         if (i < (unsigned short) adf_length) {
1022                                         if(pos+i+4 >= ldns_rdf_size(rdf))
1023                                                       return LDNS_STATUS_WIRE_RDATA_ERR;
1024                                                   ldns_buffer_printf(output, "%02x",
1025                                                                      data[pos + i + 4]);
1026                                         } else {
1027                                                   ldns_buffer_printf(output, "00");
1028                                         }
1029                               }
1030                               ldns_buffer_printf(output, "/%u ", prefix);
1031 
1032                     } else {
1033                               /* unknown address family */
1034                               ldns_buffer_printf(output,
1035                                                   "Unknown address family: %u data: ",
1036                                                   address_family);
1037                               for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
1038                                 if(pos+i >= ldns_rdf_size(rdf))
1039                                         return LDNS_STATUS_WIRE_RDATA_ERR;
1040                                         ldns_buffer_printf(output, "%02x", data[i]);
1041                               }
1042                     }
1043                     pos += 4 + adf_length;
1044           }
1045           return ldns_buffer_status(output);
1046 }
1047 
1048 ldns_status
ldns_rdf2buffer_str_int16_data(ldns_buffer * output,const ldns_rdf * rdf)1049 ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
1050 {
1051           size_t size;
1052           char *b64;
1053           if (ldns_rdf_size(rdf) < 2) {
1054                     return LDNS_STATUS_WIRE_RDATA_ERR;
1055           }
1056           /* Subtract the size (2) of the number that specifies the length */
1057           size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
1058           ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
1059           if (ldns_rdf_size(rdf) > 2) {
1060                     b64 = LDNS_XMALLOC(char, size);
1061                     if(!b64)
1062                               return LDNS_STATUS_MEM_ERR;
1063 
1064                     if (ldns_rdf_size(rdf) > 2 &&
1065                     ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
1066                                                   ldns_rdf_size(rdf) - 2,
1067                                                   b64, size)) {
1068                               ldns_buffer_printf(output, "%s", b64);
1069                     }
1070                     LDNS_FREE(b64);
1071           }
1072           return ldns_buffer_status(output);
1073 }
1074 
1075 ldns_status
ldns_rdf2buffer_str_ipseckey(ldns_buffer * output,const ldns_rdf * rdf)1076 ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
1077 {
1078           /* wire format from
1079              http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
1080           */
1081           uint8_t *data = ldns_rdf_data(rdf);
1082           uint8_t precedence;
1083           uint8_t gateway_type;
1084           uint8_t algorithm;
1085 
1086           ldns_rdf *gateway = NULL;
1087           uint8_t *gateway_data;
1088 
1089           size_t public_key_size;
1090           uint8_t *public_key_data;
1091           ldns_rdf *public_key;
1092 
1093           size_t offset = 0;
1094           ldns_status status;
1095 
1096           if (ldns_rdf_size(rdf) < 3) {
1097                     return LDNS_STATUS_WIRE_RDATA_ERR;
1098           }
1099           precedence = data[0];
1100           gateway_type = data[1];
1101           algorithm = data[2];
1102           offset = 3;
1103 
1104           switch (gateway_type) {
1105                     case 0:
1106                               /* no gateway */
1107                               break;
1108                     case 1:
1109                               if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1110                                         return LDNS_STATUS_ERR;
1111                               }
1112                               gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1113                         if(!gateway_data)
1114                                 return LDNS_STATUS_MEM_ERR;
1115                               memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
1116                               gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
1117                                                   LDNS_IP4ADDRLEN , gateway_data);
1118                               offset += LDNS_IP4ADDRLEN;
1119                         if(!gateway) {
1120                                 LDNS_FREE(gateway_data);
1121                                 return LDNS_STATUS_MEM_ERR;
1122                         }
1123                               break;
1124                     case 2:
1125                               if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1126                                         return LDNS_STATUS_ERR;
1127                               }
1128                               gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1129                         if(!gateway_data)
1130                                 return LDNS_STATUS_MEM_ERR;
1131                               memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
1132                               offset += LDNS_IP6ADDRLEN;
1133                               gateway =
1134                                         ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1135                                                             LDNS_IP6ADDRLEN, gateway_data);
1136                         if(!gateway) {
1137                                 LDNS_FREE(gateway_data);
1138                                 return LDNS_STATUS_MEM_ERR;
1139                         }
1140                               break;
1141                     case 3:
1142                               status = ldns_wire2dname(&gateway, data,
1143                                                   ldns_rdf_size(rdf), &offset);
1144                         if(status != LDNS_STATUS_OK)
1145                                 return status;
1146                               break;
1147                     default:
1148                               /* error? */
1149                               break;
1150           }
1151 
1152           if (ldns_rdf_size(rdf) <= offset) {
1153                 ldns_rdf_deep_free(gateway);
1154                     return LDNS_STATUS_ERR;
1155           }
1156           public_key_size = ldns_rdf_size(rdf) - offset;
1157           public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1158         if(!public_key_data) {
1159                 ldns_rdf_deep_free(gateway);
1160                 return LDNS_STATUS_MEM_ERR;
1161         }
1162           memcpy(public_key_data, &data[offset], public_key_size);
1163           public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
1164                               public_key_size, public_key_data);
1165         if(!public_key) {
1166                 LDNS_FREE(public_key_data);
1167                 ldns_rdf_deep_free(gateway);
1168                 return LDNS_STATUS_MEM_ERR;
1169         }
1170 
1171           ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1172           if (gateway)
1173                     (void) ldns_rdf2buffer_str(output, gateway);
1174           else
1175                     ldns_buffer_printf(output, ".");
1176           ldns_buffer_printf(output, " ");
1177           (void) ldns_rdf2buffer_str(output, public_key);
1178 
1179           ldns_rdf_deep_free(gateway);
1180           ldns_rdf_deep_free(public_key);
1181 
1182           return ldns_buffer_status(output);
1183 }
1184 
1185 ldns_status
ldns_rdf2buffer_str_ilnp64(ldns_buffer * output,const ldns_rdf * rdf)1186 ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
1187 {
1188           if (ldns_rdf_size(rdf) != 8) {
1189                     return LDNS_STATUS_WIRE_RDATA_ERR;
1190           }
1191           ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
1192                                         ldns_read_uint16(ldns_rdf_data(rdf)),
1193                                         ldns_read_uint16(ldns_rdf_data(rdf)+2),
1194                                         ldns_read_uint16(ldns_rdf_data(rdf)+4),
1195                                         ldns_read_uint16(ldns_rdf_data(rdf)+6));
1196           return ldns_buffer_status(output);
1197 }
1198 
1199 ldns_status
ldns_rdf2buffer_str_eui48(ldns_buffer * output,const ldns_rdf * rdf)1200 ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
1201 {
1202           if (ldns_rdf_size(rdf) != 6) {
1203                     return LDNS_STATUS_WIRE_RDATA_ERR;
1204           }
1205           ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1206                                         ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1207                                         ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1208                                         ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
1209           return ldns_buffer_status(output);
1210 }
1211 
1212 ldns_status
ldns_rdf2buffer_str_eui64(ldns_buffer * output,const ldns_rdf * rdf)1213 ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
1214 {
1215           if (ldns_rdf_size(rdf) != 8) {
1216                     return LDNS_STATUS_WIRE_RDATA_ERR;
1217           }
1218           ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1219                                         ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1220                                         ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1221                                         ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
1222                                         ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
1223           return ldns_buffer_status(output);
1224 }
1225 
1226 ldns_status
ldns_rdf2buffer_str_tag(ldns_buffer * output,const ldns_rdf * rdf)1227 ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
1228 {
1229           size_t nchars;
1230           const uint8_t* chars;
1231           char ch;
1232           if (ldns_rdf_size(rdf) < 2) {
1233                     return LDNS_STATUS_WIRE_RDATA_ERR;
1234           }
1235           nchars = ldns_rdf_data(rdf)[0];
1236           if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
1237                               nchars < 1) {
1238                     return LDNS_STATUS_WIRE_RDATA_ERR;
1239           }
1240           chars = ldns_rdf_data(rdf) + 1;
1241           while (nchars > 0) {
1242                     ch = (char)*chars++;
1243                     if (! isalnum((unsigned char)ch)) {
1244                               return LDNS_STATUS_WIRE_RDATA_ERR;
1245                     }
1246                     ldns_buffer_printf(output, "%c", ch);
1247                     nchars--;
1248           }
1249           return ldns_buffer_status(output);
1250 }
1251 
1252 ldns_status
ldns_rdf2buffer_str_long_str(ldns_buffer * output,const ldns_rdf * rdf)1253 ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
1254 {
1255 
1256           ldns_buffer_printf(output, "\"");
1257           ldns_characters2buffer_str(output,
1258                               ldns_rdf_size(rdf), ldns_rdf_data(rdf));
1259           ldns_buffer_printf(output, "\"");
1260           return ldns_buffer_status(output);
1261 }
1262 
1263 ldns_status
ldns_rdf2buffer_str_hip(ldns_buffer * output,const ldns_rdf * rdf)1264 ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
1265 {
1266           uint8_t *data = ldns_rdf_data(rdf);
1267           size_t rdf_size = ldns_rdf_size(rdf);
1268           uint8_t hit_size;
1269           uint16_t pk_size;
1270           int written;
1271 
1272           if (rdf_size < 6) {
1273                     return LDNS_STATUS_WIRE_RDATA_ERR;
1274           }
1275           if ((hit_size = data[0]) == 0 ||
1276                               (pk_size = ldns_read_uint16(data + 2)) == 0 ||
1277                               rdf_size < (size_t) hit_size + pk_size + 4) {
1278 
1279                     return LDNS_STATUS_WIRE_RDATA_ERR;
1280           }
1281 
1282           ldns_buffer_printf(output, "%d ", (int) data[1]);
1283 
1284           for (data += 4; hit_size > 0; hit_size--, data++) {
1285 
1286                     ldns_buffer_printf(output, "%02x", (int) *data);
1287           }
1288           ldns_buffer_write_char(output, (uint8_t) ' ');
1289 
1290           if (ldns_buffer_reserve(output,
1291                                         ldns_b64_ntop_calculate_size(pk_size))) {
1292 
1293                     written = ldns_b64_ntop(data, pk_size,
1294                                         (char *) ldns_buffer_current(output),
1295                                         ldns_buffer_remaining(output));
1296 
1297                     if (written > 0 &&
1298                                         written < (int) ldns_buffer_remaining(output)) {
1299 
1300                               output->_position += written;
1301                     }
1302           }
1303           return ldns_buffer_status(output);
1304 }
1305 
1306 /* implementation mimicked from ldns_rdf2buffer_str_ipseckey */
1307 ldns_status
ldns_rdf2buffer_str_amtrelay(ldns_buffer * output,const ldns_rdf * rdf)1308 ldns_rdf2buffer_str_amtrelay(ldns_buffer *output, const ldns_rdf *rdf)
1309 {
1310           /* wire format from
1311            * draft-ietf-mboned-driad-amt-discovery Section 4.2
1312            */
1313           uint8_t *data = ldns_rdf_data(rdf);
1314           uint8_t precedence;
1315           uint8_t discovery_optional;
1316           uint8_t relay_type;
1317 
1318           ldns_rdf *relay = NULL;
1319           uint8_t *relay_data;
1320 
1321           size_t offset = 0;
1322           ldns_status status;
1323 
1324           if (ldns_rdf_size(rdf) < 2) {
1325                     return LDNS_STATUS_WIRE_RDATA_ERR;
1326           }
1327           precedence = data[0];
1328           discovery_optional = ((data[1] & 0x80) >> 7);
1329           relay_type = data[1] & 0x7F;
1330           offset = 2;
1331 
1332           switch (relay_type) {
1333                     case 0:
1334                               /* no relay */
1335                               break;
1336                     case 1:
1337                               if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1338                                         return LDNS_STATUS_ERR;
1339                               }
1340                               relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1341                         if(!relay_data)
1342                                 return LDNS_STATUS_MEM_ERR;
1343                               memcpy(relay_data, &data[offset], LDNS_IP4ADDRLEN);
1344                               relay = ldns_rdf_new(LDNS_RDF_TYPE_A,
1345                                                   LDNS_IP4ADDRLEN , relay_data);
1346                               offset += LDNS_IP4ADDRLEN;
1347                         if(!relay) {
1348                                 LDNS_FREE(relay_data);
1349                                 return LDNS_STATUS_MEM_ERR;
1350                         }
1351                               break;
1352                     case 2:
1353                               if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1354                                         return LDNS_STATUS_ERR;
1355                               }
1356                               relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1357                         if(!relay_data)
1358                                 return LDNS_STATUS_MEM_ERR;
1359                               memcpy(relay_data, &data[offset], LDNS_IP6ADDRLEN);
1360                               offset += LDNS_IP6ADDRLEN;
1361                               relay =
1362                                         ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1363                                                             LDNS_IP6ADDRLEN, relay_data);
1364                         if(!relay) {
1365                                 LDNS_FREE(relay_data);
1366                                 return LDNS_STATUS_MEM_ERR;
1367                         }
1368                               break;
1369                     case 3:
1370                               status = ldns_wire2dname(&relay, data,
1371                                                   ldns_rdf_size(rdf), &offset);
1372                         if(status != LDNS_STATUS_OK)
1373                                 return status;
1374                               break;
1375                     default:
1376                               /* error? */
1377                               break;
1378           }
1379 
1380           if (ldns_rdf_size(rdf) != offset) {
1381                 ldns_rdf_deep_free(relay);
1382                     return LDNS_STATUS_ERR;
1383           }
1384           ldns_buffer_printf(output, "%u %u %u ",
1385                               precedence, discovery_optional, relay_type);
1386           if (relay)
1387                     (void) ldns_rdf2buffer_str(output, relay);
1388 
1389           ldns_rdf_deep_free(relay);
1390           return ldns_buffer_status(output);
1391 }
1392 
1393 #ifdef RRTYPE_SVCB_HTTPS
1394 ldns_status svcparam_key2buffer_str(ldns_buffer *output, uint16_t key);
1395 
1396 static ldns_status
svcparam_mandatory2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1397 svcparam_mandatory2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1398 {
1399           if (sz % 2)
1400                     return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1401 
1402           svcparam_key2buffer_str(output, ldns_read_uint16(data));
1403           for (data += 2, sz -= 2; sz; data += 2, sz -= 2) {
1404                     ldns_buffer_write_char(output, ',');
1405                     svcparam_key2buffer_str(output, ldns_read_uint16(data));
1406           }
1407           return ldns_buffer_status(output);
1408 }
1409 
1410 static ldns_status
svcparam_alpn2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1411 svcparam_alpn2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1412 {
1413           uint8_t *eod = data + sz, *dp;
1414           bool quote = false;
1415           size_t i;
1416 
1417           for (dp = data; dp < eod && !quote; dp += 1 + *dp) {
1418                     if (dp + 1 + *dp > eod)
1419                               return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1420 
1421                     for (i = 0; i < *dp; i++)
1422                               if (isspace(dp[i + 1]))
1423                                         break;
1424                     quote = i < *dp;
1425           }
1426           if (quote)
1427                     ldns_buffer_write_char(output, '"');
1428           while (data < eod) {
1429                     uint8_t *eot = data + 1 + *data;
1430 
1431                     if (eot > eod)
1432                               return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1433 
1434                     if (eod - data < (int)sz)
1435                               ldns_buffer_write_char(output, ',');
1436 
1437                     for (data += 1; data < eot; data += 1) {
1438                               uint8_t ch = *data;
1439 
1440                               if (isprint(ch) || ch == '\t') {
1441                                         if (ch == '"' ||  ch == ',' || ch == '\\')
1442                                                   ldns_buffer_write_char(output, '\\');
1443                                         ldns_buffer_write_char(output, ch);
1444                               } else
1445                                         ldns_buffer_printf(output, "\\%03u"
1446                                                                  , (unsigned)ch);
1447                     }
1448           }
1449           if (quote)
1450                     ldns_buffer_write_char(output, '"');
1451           return ldns_buffer_status(output);
1452 }
1453 
1454 static ldns_status
svcparam_port2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1455 svcparam_port2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1456 {
1457           if (sz != 2)
1458                     return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1459           ldns_buffer_printf(output, "%d", (int)ldns_read_uint16(data));
1460           return ldns_buffer_status(output);
1461 }
1462 
1463 static ldns_status
svcparam_ipv4hint2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1464 svcparam_ipv4hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1465 {
1466           char str[INET_ADDRSTRLEN];
1467 
1468           if (sz % 4 || !inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
1469                     return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1470 
1471           ldns_buffer_write_chars(output, str);
1472 
1473           for (data += 4, sz -= 4; sz ; data += 4, sz -= 4 ) {
1474                     ldns_buffer_write_char(output, ',');
1475                     if (!inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
1476                               return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1477 
1478                     ldns_buffer_write_chars(output, str);
1479           }
1480           return ldns_buffer_status(output);
1481 }
1482 
1483 static ldns_status
svcparam_ech2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1484 svcparam_ech2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1485 {
1486           size_t str_sz = ldns_b64_ntop_calculate_size(sz);
1487           int written;
1488 
1489           if (!ldns_buffer_reserve(output, str_sz))
1490                     return LDNS_STATUS_MEM_ERR;
1491 
1492           written = ldns_b64_ntop( data, sz
1493                                  , (char *)ldns_buffer_current(output), str_sz);
1494           if (written > 0)
1495                     ldns_buffer_skip(output, written);
1496           else
1497                     return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1498 
1499           return ldns_buffer_status(output);
1500 }
1501 
1502 static ldns_status
svcparam_ipv6hint2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1503 svcparam_ipv6hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1504 {
1505           char str[INET6_ADDRSTRLEN];
1506 
1507           if (sz % 16 || !inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
1508                     return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1509 
1510           ldns_buffer_write_chars(output, str);
1511 
1512           for (data += 16, sz -= 16; sz ; data += 16, sz -= 16) {
1513                     ldns_buffer_write_char(output, ',');
1514                     if (!inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
1515                               return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1516 
1517                     ldns_buffer_write_chars(output, str);
1518           }
1519           return ldns_buffer_status(output);
1520 }
1521 
1522 static ldns_status
svcparam_value2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1523 svcparam_value2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1524 {
1525           uint8_t *eod = data + sz, *dp;
1526           bool quote = false;
1527 
1528           for (dp = data; dp < eod && !isspace(*dp); dp++)
1529                     ; /* pass */
1530 
1531           if ((quote = dp < eod))
1532                     ldns_buffer_write_char(output, '"');
1533 
1534           for (dp = data; dp < eod; dp++) {
1535                     uint8_t ch = *dp;
1536 
1537                     if (isprint(ch) || ch == '\t') {
1538                               if (ch == '"' ||  ch == '\\')
1539                                         ldns_buffer_write_char(output, '\\');
1540                               ldns_buffer_write_char(output, ch);
1541                     } else
1542                               ldns_buffer_printf(output, "\\%03u", (unsigned)ch);
1543           }
1544           if (quote)
1545                     ldns_buffer_write_char(output, '"');
1546           return ldns_buffer_status(output);
1547 }
1548 
1549 ldns_status
ldns_rdf2buffer_str_svcparams(ldns_buffer * output,const ldns_rdf * rdf)1550 ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
1551 {
1552           uint8_t    *data, *dp, *next_dp = NULL;
1553           size_t      sz;
1554           ldns_status st;
1555 
1556           if (!output)
1557                     return LDNS_STATUS_NULL;
1558 
1559           if (!rdf || !(data = ldns_rdf_data(rdf)) || !(sz = ldns_rdf_size(rdf)))
1560                     /* No svcparams is just fine. Just nothing to print. */
1561                     return LDNS_STATUS_OK;
1562 
1563           for (dp = data; dp + 4 <= data + sz; dp = next_dp) {
1564                     ldns_svcparam_key key    = ldns_read_uint16(dp);
1565                     uint16_t          val_sz = ldns_read_uint16(dp + 2);
1566 
1567                     if ((next_dp = dp + 4 + val_sz) > data + sz)
1568                               return LDNS_STATUS_RDATA_OVERFLOW;
1569 
1570                     if (dp > data)
1571                               ldns_buffer_write_char(output, ' ');
1572 
1573                     if ((st = svcparam_key2buffer_str(output, key)))
1574                               return st;
1575 
1576                     if (val_sz == 0)
1577                               continue;
1578                     dp += 4;
1579                     ldns_buffer_write_char(output, '=');
1580                     switch (key) {
1581                     case LDNS_SVCPARAM_KEY_MANDATORY:
1582                               st = svcparam_mandatory2buffer_str(output, val_sz, dp);
1583                               break;
1584                     case LDNS_SVCPARAM_KEY_ALPN:
1585                               st = svcparam_alpn2buffer_str(output, val_sz, dp);
1586                               break;
1587                     case LDNS_SVCPARAM_KEY_NO_DEFAULT_ALPN:
1588                               return LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED;
1589                     case LDNS_SVCPARAM_KEY_PORT:
1590                               st = svcparam_port2buffer_str(output, val_sz, dp);
1591                               break;
1592                     case LDNS_SVCPARAM_KEY_IPV4HINT:
1593                               st = svcparam_ipv4hint2buffer_str(output, val_sz, dp);
1594                               break;
1595                     case LDNS_SVCPARAM_KEY_ECH:
1596                               st = svcparam_ech2buffer_str(output, val_sz, dp);
1597                               break;
1598                     case LDNS_SVCPARAM_KEY_IPV6HINT:
1599                               st = svcparam_ipv6hint2buffer_str(output, val_sz, dp);
1600                               break;
1601                     default:
1602                               st = svcparam_value2buffer_str(output, val_sz, dp);
1603                               break;
1604                     }
1605                     if (st)
1606                               return st;
1607           }
1608           return ldns_buffer_status(output);
1609 }
1610 #else     /* #ifdef RRTYPE_SVCB_HTTPS */
1611 ldns_status
ldns_rdf2buffer_str_svcparams(ldns_buffer * output,const ldns_rdf * rdf)1612 ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
1613 {
1614           (void)output; (void)rdf;
1615           return LDNS_STATUS_NOT_IMPL;
1616 }
1617 #endif    /* #ifdef RRTYPE_SVCB_HTTPS */
1618 
1619 static ldns_status
ldns_rdf2buffer_str_fmt(ldns_buffer * buffer,const ldns_output_format * fmt,const ldns_rdf * rdf)1620 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
1621                     const ldns_output_format* fmt, const ldns_rdf *rdf)
1622 {
1623           ldns_status res = LDNS_STATUS_OK;
1624 
1625           /*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1626           if (rdf) {
1627                     switch(ldns_rdf_get_type(rdf)) {
1628                     case LDNS_RDF_TYPE_NONE:
1629                               break;
1630                     case LDNS_RDF_TYPE_DNAME:
1631                               res = ldns_rdf2buffer_str_dname(buffer, rdf);
1632                               break;
1633                     case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
1634                     case LDNS_RDF_TYPE_ALG:
1635                     case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
1636                     case LDNS_RDF_TYPE_SELECTOR:
1637                     case LDNS_RDF_TYPE_MATCHING_TYPE:
1638                               res = ldns_rdf2buffer_str_int8(buffer, rdf);
1639                               break;
1640                     case LDNS_RDF_TYPE_INT16:
1641                               res = ldns_rdf2buffer_str_int16(buffer, rdf);
1642                               break;
1643                     case LDNS_RDF_TYPE_INT32:
1644                               res = ldns_rdf2buffer_str_int32(buffer, rdf);
1645                               break;
1646                     case LDNS_RDF_TYPE_PERIOD:
1647                               res = ldns_rdf2buffer_str_period(buffer, rdf);
1648                               break;
1649                     case LDNS_RDF_TYPE_TSIGTIME:
1650                               res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1651                               break;
1652                     case LDNS_RDF_TYPE_A:
1653                               res = ldns_rdf2buffer_str_a(buffer, rdf);
1654                               break;
1655                     case LDNS_RDF_TYPE_AAAA:
1656                               res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1657                               break;
1658                     case LDNS_RDF_TYPE_STR:
1659                               res = ldns_rdf2buffer_str_str(buffer, rdf);
1660                               break;
1661                     case LDNS_RDF_TYPE_APL:
1662                               res = ldns_rdf2buffer_str_apl(buffer, rdf);
1663                               break;
1664                     case LDNS_RDF_TYPE_B32_EXT:
1665                               res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1666                               break;
1667                     case LDNS_RDF_TYPE_B64:
1668                               res = ldns_rdf2buffer_str_b64(buffer, rdf);
1669                               break;
1670                     case LDNS_RDF_TYPE_HEX:
1671                               res = ldns_rdf2buffer_str_hex(buffer, rdf);
1672                               break;
1673                     case LDNS_RDF_TYPE_NSEC:
1674                               res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
1675                               break;
1676                     case LDNS_RDF_TYPE_NSEC3_SALT:
1677                               res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1678                               break;
1679                     case LDNS_RDF_TYPE_TYPE:
1680                               res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
1681                               break;
1682                     case LDNS_RDF_TYPE_CLASS:
1683                               res = ldns_rdf2buffer_str_class(buffer, rdf);
1684                               break;
1685                     case LDNS_RDF_TYPE_CERT_ALG:
1686                               res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1687                               break;
1688                     case LDNS_RDF_TYPE_UNKNOWN:
1689                               res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1690                               break;
1691                     case LDNS_RDF_TYPE_TIME:
1692                               res = ldns_rdf2buffer_str_time(buffer, rdf);
1693                               break;
1694                     case LDNS_RDF_TYPE_HIP:
1695                               res = ldns_rdf2buffer_str_hip(buffer, rdf);
1696                               break;
1697                     case LDNS_RDF_TYPE_LOC:
1698                               res = ldns_rdf2buffer_str_loc(buffer, rdf);
1699                               break;
1700                     case LDNS_RDF_TYPE_WKS:
1701                     case LDNS_RDF_TYPE_SERVICE:
1702                               res = ldns_rdf2buffer_str_wks(buffer, rdf);
1703                               break;
1704                     case LDNS_RDF_TYPE_NSAP:
1705                               res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1706                               break;
1707                     case LDNS_RDF_TYPE_ATMA:
1708                               res = ldns_rdf2buffer_str_atma(buffer, rdf);
1709                               break;
1710                     case LDNS_RDF_TYPE_IPSECKEY:
1711                               res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1712                               break;
1713                     case LDNS_RDF_TYPE_INT16_DATA:
1714                               res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1715                               break;
1716                     case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1717                               res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1718                               break;
1719                     case LDNS_RDF_TYPE_ILNP64:
1720                               res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
1721                               break;
1722                     case LDNS_RDF_TYPE_EUI48:
1723                               res = ldns_rdf2buffer_str_eui48(buffer, rdf);
1724                               break;
1725                     case LDNS_RDF_TYPE_EUI64:
1726                               res = ldns_rdf2buffer_str_eui64(buffer, rdf);
1727                               break;
1728                     case LDNS_RDF_TYPE_TAG:
1729                               res = ldns_rdf2buffer_str_tag(buffer, rdf);
1730                               break;
1731                     case LDNS_RDF_TYPE_LONG_STR:
1732                               res = ldns_rdf2buffer_str_long_str(buffer, rdf);
1733                               break;
1734                     case LDNS_RDF_TYPE_AMTRELAY:
1735                               res = ldns_rdf2buffer_str_amtrelay(buffer, rdf);
1736                               break;
1737                     case LDNS_RDF_TYPE_SVCPARAMS:
1738                               res = ldns_rdf2buffer_str_svcparams(buffer, rdf);
1739                               break;
1740                     }
1741           } else {
1742                     /** This will write mangled RRs */
1743                     ldns_buffer_printf(buffer, "(null) ");
1744                     res = LDNS_STATUS_ERR;
1745           }
1746           return res;
1747 }
1748 
1749 ldns_status
ldns_rdf2buffer_str(ldns_buffer * buffer,const ldns_rdf * rdf)1750 ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1751 {
1752           return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
1753 }
1754 
1755 static ldns_rdf *
ldns_b32_ext2dname(const ldns_rdf * rdf)1756 ldns_b32_ext2dname(const ldns_rdf *rdf)
1757 {
1758           size_t size;
1759           char *b32;
1760           ldns_rdf *out;
1761           if(ldns_rdf_size(rdf) == 0)
1762                     return NULL;
1763         /* remove -1 for the b32-hash-len octet */
1764           size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1765         /* add one for the end nul for the string */
1766           b32 = LDNS_XMALLOC(char, size + 2);
1767           if (b32) {
1768                     if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
1769                                         ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1770                               b32[size] = '.';
1771                               b32[size+1] = '\0';
1772                               if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1773                                         LDNS_FREE(b32);
1774                                         return out;
1775                               }
1776                     }
1777                     LDNS_FREE(b32);
1778           }
1779           return NULL;
1780 }
1781 
1782 static ldns_status
ldns_rr2buffer_str_rfc3597(ldns_buffer * output,const ldns_rr * rr)1783 ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
1784 {
1785           size_t total_rdfsize = 0;
1786           size_t i, j;
1787 
1788           ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
1789           for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1790                     total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
1791           }
1792           if (total_rdfsize == 0) {
1793                     ldns_buffer_printf(output, "\\# 0\n");
1794                     return ldns_buffer_status(output);
1795           }
1796           ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
1797           for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1798                     for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
1799                               ldns_buffer_printf(output, "%.2x",
1800                                                   ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
1801                     }
1802           }
1803           ldns_buffer_printf(output, "\n");
1804           return ldns_buffer_status(output);
1805 }
1806 
1807 ldns_status
ldns_rr2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr * rr)1808 ldns_rr2buffer_str_fmt(ldns_buffer *output,
1809                     const ldns_output_format *fmt, const ldns_rr *rr)
1810 {
1811           uint16_t i, flags;
1812           ldns_status status = LDNS_STATUS_OK;
1813           ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
1814 
1815           if (fmt_st == NULL) {
1816                     fmt_st = (ldns_output_format_storage*)
1817                                 ldns_output_format_default;
1818           }
1819           if (!(fmt_st->flags & LDNS_FMT_SHORT)) {
1820                     if (!rr) {
1821                               if (LDNS_COMMENT_NULLS & fmt_st->flags) {
1822                                         ldns_buffer_printf(output, "; (null)\n");
1823                               }
1824                               return ldns_buffer_status(output);
1825                     }
1826                     if (ldns_rr_owner(rr)) {
1827                               status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1828                     }
1829                     if (status != LDNS_STATUS_OK) {
1830                               return status;
1831                     }
1832 
1833                     /* TTL should NOT be printed if it is a question */
1834                     if (!ldns_rr_is_question(rr)) {
1835                               ldns_buffer_printf(output, "\t%u", (unsigned)ldns_rr_ttl(rr));
1836                     }
1837 
1838                     ldns_buffer_printf(output, "\t");
1839                     status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1840                     if (status != LDNS_STATUS_OK) {
1841                               return status;
1842                     }
1843                     ldns_buffer_printf(output, "\t");
1844 
1845                     if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
1846                               return ldns_rr2buffer_str_rfc3597(output, rr);
1847                     }
1848                     status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1849                     if (status != LDNS_STATUS_OK) {
1850                               return status;
1851                     }
1852 
1853                     if (ldns_rr_rd_count(rr) > 0) {
1854                               ldns_buffer_printf(output, "\t");
1855                     } else if (!ldns_rr_is_question(rr)) {
1856                               ldns_buffer_printf(output, "\t\\# 0");
1857                     }
1858           } else if (ldns_rr_rd_count(rr) == 0) {
1859                     /* assert(fmt_st->flags & LDNS_FMT_SHORT); */
1860 
1861                     ldns_buffer_printf(output, "# 0");
1862           }
1863           for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1864                     /* ldns_rdf2buffer_str handles NULL input fine! */
1865                     if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1866                                         (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1867                                         ((/* inception  */ i == 4 &&
1868                                           ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
1869                                                                       LDNS_RDF_TYPE_TIME) ||
1870                                           (/* expiration */ i == 5 &&
1871                                            ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1872                                                                       LDNS_RDF_TYPE_TIME) ||
1873                                           (/* signature  */ i == 8 &&
1874                                            ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1875                                                                       LDNS_RDF_TYPE_B64))) {
1876 
1877                               ldns_buffer_printf(output, "(null)");
1878                               status = ldns_buffer_status(output);
1879                     } else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1880                                         (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1881                                         /* serial */ i == 2 &&
1882                                         ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1883                                                                       LDNS_RDF_TYPE_INT32) {
1884                               ldns_buffer_printf(output, "%10lu",
1885                                         (unsigned long) ldns_read_uint32(
1886                                                   ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1887                               status = ldns_buffer_status(output);
1888                     } else {
1889                               status = ldns_rdf2buffer_str_fmt(output,
1890                                                   fmt, ldns_rr_rdf(rr, i));
1891                     }
1892                     if(status != LDNS_STATUS_OK)
1893                               return status;
1894                     if (i < ldns_rr_rd_count(rr) - 1) {
1895                               ldns_buffer_printf(output, " ");
1896                     }
1897           }
1898           /* per RR special comments - handy for DNSSEC types */
1899           /* check to prevent question sec. rr from
1900            * getting here */
1901           if (ldns_rr_rd_count(rr) > 0) {
1902                     switch (ldns_rr_get_type(rr)) {
1903                     case LDNS_RR_TYPE_DNSKEY:
1904                               /* if ldns_rr_rd_count(rr) > 0
1905                                         then ldns_rr_rdf(rr, 0) exists! */
1906                               if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
1907                                         break;
1908                               }
1909                               flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
1910                               ldns_buffer_printf(output, " ;{");
1911                               if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
1912                                         ldns_buffer_printf(output, "id = %u",
1913                                                   (unsigned int) ldns_calc_keytag(rr));
1914                               }
1915                               if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
1916                                                   (flags & LDNS_KEY_ZONE_KEY)){
1917 
1918                                         if (flags & LDNS_KEY_SEP_KEY) {
1919                                                   ldns_buffer_printf(output, " (ksk)");
1920                                         } else {
1921                                                   ldns_buffer_printf(output, " (zsk)");
1922                                         }
1923                                         if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
1924                                                   ldns_buffer_printf(output, ", ");
1925                                         }
1926                               } else if (fmt_st->flags
1927                                                   & (LDNS_COMMENT_KEY_ID
1928                                                             |LDNS_COMMENT_KEY_SIZE)) {
1929                                         ldns_buffer_printf( output, ", ");
1930                               }
1931                               if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
1932                                         ldns_buffer_printf(output, "size = %db",
1933                                                   ldns_rr_dnskey_key_size(rr));
1934                               }
1935                               ldns_buffer_printf(output, "}");
1936                               break;
1937                     case LDNS_RR_TYPE_RRSIG:
1938                               if ((fmt_st->flags & LDNS_COMMENT_KEY)
1939                                                   && (fmt_st->flags& LDNS_COMMENT_RRSIGS)
1940                                                   && ldns_rr_rdf(rr, 6) != NULL) {
1941                                         ldns_buffer_printf(output, " ;{id = %d}",
1942                                                             ldns_rdf2native_int16(
1943                                                                       ldns_rr_rdf(rr, 6)));
1944                               }
1945                               break;
1946                     case LDNS_RR_TYPE_DS:
1947                               if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
1948                                                   ldns_rr_rdf(rr, 3) != NULL) {
1949 
1950                                         uint8_t *data = ldns_rdf_data(
1951                                                             ldns_rr_rdf(rr, 3));
1952                                         size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
1953                                         char *babble = ldns_bubblebabble(data, len);
1954                                         if(babble) {
1955                                                   ldns_buffer_printf(output,
1956                                                                       " ;{%s}", babble);
1957                                         }
1958                                         LDNS_FREE(babble);
1959                               }
1960                               break;
1961                     case LDNS_RR_TYPE_NSEC3:
1962                               if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
1963                                         ! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
1964                                         break;
1965                               }
1966                               ldns_buffer_printf(output, " ;{");
1967                               if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
1968                                         if (ldns_nsec3_optout(rr)) {
1969                                                   ldns_buffer_printf(output,
1970                                                             " flags: optout");
1971                                         } else {
1972                                                   ldns_buffer_printf(output," flags: -");
1973                                         }
1974                                         if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1975                                                             fmt_st->hashmap != NULL) {
1976                                                   ldns_buffer_printf(output, ", ");
1977                                         }
1978                               }
1979                               if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1980                                                   fmt_st->hashmap != NULL) {
1981                                         ldns_rbnode_t *node;
1982                                         ldns_rdf *key = ldns_dname_label(
1983                                                             ldns_rr_owner(rr), 0);
1984                                         if (key) {
1985                                                   node = ldns_rbtree_search(
1986                                                             fmt_st->hashmap,
1987                                                             (void *) key);
1988                                                   if (node->data) {
1989                                                             ldns_buffer_printf(output,
1990                                                                       "from: ");
1991                                                             (void) ldns_rdf2buffer_str(
1992                                                                       output,
1993                                                                       ldns_dnssec_name_name(
1994                                                                          (ldns_dnssec_name*)
1995                                                                          node->data
1996                                                                       ));
1997                                                   }
1998                                                   ldns_rdf_deep_free(key);
1999                                         }
2000                                         key = ldns_b32_ext2dname(
2001                                                             ldns_nsec3_next_owner(rr));
2002                                         if (key) {
2003                                                   node = ldns_rbtree_search(
2004                                                             fmt_st->hashmap,
2005                                                             (void *) key);
2006                                                   if (node->data) {
2007                                                             ldns_buffer_printf(output,
2008                                                                       " to: ");
2009                                                             (void) ldns_rdf2buffer_str(
2010                                                                       output,
2011                                                                       ldns_dnssec_name_name(
2012                                                                          (ldns_dnssec_name*)
2013                                                                          node->data
2014                                                                       ));
2015                                                   }
2016                                                   ldns_rdf_deep_free(key);
2017                                         }
2018                               }
2019                               ldns_buffer_printf(output, "}");
2020                               break;
2021                     default:
2022                               break;
2023 
2024                     }
2025           }
2026           /* last */
2027           ldns_buffer_printf(output, "\n");
2028           return ldns_buffer_status(output);
2029 }
2030 
2031 ldns_status
ldns_rr2buffer_str(ldns_buffer * output,const ldns_rr * rr)2032 ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
2033 {
2034           return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
2035 }
2036 
2037 ldns_status
ldns_rr_list2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr_list * list)2038 ldns_rr_list2buffer_str_fmt(ldns_buffer *output,
2039                     const ldns_output_format *fmt, const ldns_rr_list *list)
2040 {
2041           uint16_t i;
2042 
2043           for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
2044                     (void) ldns_rr2buffer_str_fmt(output, fmt,
2045                                         ldns_rr_list_rr(list, i));
2046           }
2047           return ldns_buffer_status(output);
2048 }
2049 
2050 ldns_status
ldns_rr_list2buffer_str(ldns_buffer * output,const ldns_rr_list * list)2051 ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
2052 {
2053           return ldns_rr_list2buffer_str_fmt(
2054                               output, ldns_output_format_default, list);
2055 }
2056 
2057 ldns_status
ldns_pktheader2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)2058 ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
2059 {
2060           ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
2061                                                   (int) ldns_pkt_get_opcode(pkt));
2062           ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
2063                                                   (int) ldns_pkt_get_rcode(pkt));
2064 
2065           ldns_buffer_printf(output, ";; ->>HEADER<<- ");
2066           if (opcode) {
2067                     ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
2068           } else {
2069                     ldns_buffer_printf(output, "opcode: ?? (%u), ",
2070                                         ldns_pkt_get_opcode(pkt));
2071           }
2072           if (rcode) {
2073                     ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
2074           } else {
2075                     ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
2076           }
2077           ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
2078           ldns_buffer_printf(output, ";; flags: ");
2079 
2080           if (ldns_pkt_qr(pkt)) {
2081                     ldns_buffer_printf(output, "qr ");
2082           }
2083           if (ldns_pkt_aa(pkt)) {
2084                     ldns_buffer_printf(output, "aa ");
2085           }
2086           if (ldns_pkt_tc(pkt)) {
2087                     ldns_buffer_printf(output, "tc ");
2088           }
2089           if (ldns_pkt_rd(pkt)) {
2090                     ldns_buffer_printf(output, "rd ");
2091           }
2092           if (ldns_pkt_cd(pkt)) {
2093                     ldns_buffer_printf(output, "cd ");
2094           }
2095           if (ldns_pkt_ra(pkt)) {
2096                     ldns_buffer_printf(output, "ra ");
2097           }
2098           if (ldns_pkt_ad(pkt)) {
2099                     ldns_buffer_printf(output, "ad ");
2100           }
2101           ldns_buffer_printf(output, "; ");
2102           ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
2103           ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
2104           ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
2105           ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
2106           return ldns_buffer_status(output);
2107 }
2108 
2109 
2110 /* print EDNS option data in the Dig format: 76 61 6c 69 ... */
2111 static void
ldns_edns_hex_data2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2112 ldns_edns_hex_data2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2113 {
2114           size_t j;
2115           for (j = 0; j < len; j++) {
2116                     ldns_buffer_printf(output, " %02x", data[j]);
2117           }
2118 }
2119 
2120 static ldns_status
ldns_edns_llq2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2121 ldns_edns_llq2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2122 {
2123           /* LLQ constants */
2124           const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC",
2125                     "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"};
2126           const unsigned int llq_errors_num = 7;
2127           const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"};
2128           const unsigned int llq_opcodes_num = 3;
2129 
2130           uint16_t version, llq_opcode, error_code;
2131           uint64_t llq_id;
2132           uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */
2133 
2134           ldns_buffer_printf(output, "; Long-Lived Query:");
2135 
2136           /* read the record */
2137           if(len != 18) {
2138                     ldns_buffer_printf(output, " malformed LLQ ");
2139                     ldns_edns_hex_data2buffer_str(output, data, len);
2140 
2141                     return ldns_buffer_status(output);
2142           }
2143           version = ldns_read_uint16(data);
2144           llq_opcode = ldns_read_uint16(data+2);
2145           error_code = ldns_read_uint16(data+4);
2146           memmove(&llq_id, data+6, sizeof(uint64_t));
2147           lease_life = ldns_read_uint32(data+14);
2148 
2149           /* print option field entires */
2150           ldns_buffer_printf(output, "v%d ", (int)version);
2151 
2152           if(llq_opcode < llq_opcodes_num) {
2153                     ldns_buffer_printf(output, "%s", llq_opcodes[llq_opcode]);
2154           } else {
2155                     ldns_buffer_printf(output, "opcode %d", (int)llq_opcode);
2156           }
2157 
2158           if(error_code < llq_errors_num)
2159                     ldns_buffer_printf(output, " %s", llq_errors[error_code]);
2160           else {
2161                     ldns_buffer_printf(output, " error %d", (int)error_code);
2162           }
2163 
2164 #ifndef USE_WINSOCK
2165           ldns_buffer_printf(output, " id %llx lease-life %lu",
2166                     (unsigned long long)llq_id, (unsigned long)lease_life);
2167 #else
2168           ldns_buffer_printf(output, " id %I64x lease-life %lu",
2169                     (unsigned long long)llq_id, (unsigned long)lease_life);
2170 #endif
2171           return ldns_buffer_status(output);
2172 }
2173 
2174 
2175 static ldns_status
ldns_edns_ul2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2176 ldns_edns_ul2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2177 {
2178           uint32_t lease;
2179 
2180           ldns_buffer_printf(output, "; Update Lease:");
2181 
2182           if(len != 4) {
2183                     ldns_buffer_printf(output, " malformed UL ");
2184                     ldns_edns_hex_data2buffer_str(output, data, len);
2185                     return ldns_buffer_status(output);
2186           }
2187           lease = ldns_read_uint32(data);
2188           ldns_buffer_printf(output, "lease %lu", (unsigned long)lease);
2189 
2190           return ldns_buffer_status(output);
2191 }
2192 
2193 static ldns_status
ldns_edns_nsid2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2194 ldns_edns_nsid2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2195 {
2196           size_t i, printed=0;
2197 
2198           ldns_buffer_printf(output, "; NSID:");
2199           ldns_edns_hex_data2buffer_str(output, data, len);
2200 
2201           /* print the human-readable text string */
2202           for(i = 0; i < len; i++) {
2203                     if(isprint((unsigned char)data[i]) || data[i] == '\t') {
2204                               if(!printed) {
2205                                         ldns_buffer_printf(output, " (");
2206                                         printed = 1;
2207                               }
2208                               ldns_buffer_printf(output, "%c", (char)data[i]);
2209                     }
2210           }
2211           if(printed)
2212                     ldns_buffer_printf(output, ")");
2213           return ldns_buffer_status(output);
2214 }
2215 
2216 
2217 static ldns_status
ldns_edns_dau2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2218 ldns_edns_dau2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2219 {
2220           size_t i;
2221           ldns_lookup_table *lt;
2222 
2223           ldns_buffer_printf(output, "; DNSSEC Algorithm Understood (DAU):");
2224 
2225           for(i = 0; i <len; i++) {
2226                     lt = ldns_lookup_by_id(ldns_algorithms, data[i]);
2227                     if (lt && lt->name) {
2228                               ldns_buffer_printf(output, " %s", lt->name);
2229                     } else {
2230                               ldns_buffer_printf(output, " ALG%u", data[i]);
2231                     }
2232           }
2233           return ldns_buffer_status(output);
2234 }
2235 
2236 static ldns_status
ldns_edns_dhu2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2237 ldns_edns_dhu2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2238 {
2239           size_t i;
2240           ldns_lookup_table *lt;
2241 
2242           ldns_buffer_printf(output, "; DS Hash Understood (DHU):");
2243 
2244           for(i = 0; i < len; i++) {
2245                     lt = ldns_lookup_by_id(ldns_hashes, data[i]);
2246                     if (lt && lt->name) {
2247                               ldns_buffer_printf(output, " %s", lt->name);
2248                     } else {
2249                               ldns_buffer_printf(output, " ALG%u", data[i]);
2250                     }
2251           }
2252           return ldns_buffer_status(output);
2253 }
2254 
2255 static ldns_status
ldns_edns_d3u2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2256 ldns_edns_d3u2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2257 {
2258           size_t i;
2259 
2260           ldns_buffer_printf(output, "; NSEC3 Hash Understood (N3U):");
2261 
2262           for(i=0; i<len; i++) {
2263                     if(data[i] == 1) {
2264                               ldns_buffer_printf(output, " SHA1");
2265                     } else {
2266                               ldns_buffer_printf(output, " %d", (int)data[i]);
2267                     }
2268           }
2269           return ldns_buffer_status(output);
2270 }
2271 
2272 static ldns_status
ldns_edns_subnet2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2273 ldns_edns_subnet2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2274 {
2275           uint16_t family;
2276           uint8_t source, scope;
2277           if(len < 4) {
2278                     ldns_buffer_printf(output, "malformed subnet ");
2279                     ldns_edns_hex_data2buffer_str(output, data, len);
2280                     return ldns_buffer_status(output);
2281           }
2282           family = ldns_read_uint16(data);
2283           source = data[2];
2284           scope = data[3];
2285           if(family == 1) {
2286                     /* IPv4 */
2287                     char buf[64];
2288                     uint8_t ip4[4];
2289                     memset(ip4, 0, sizeof(ip4));
2290                     if(len-4 > 4) {
2291                               ldns_buffer_printf(output, "trailingdata:");
2292                               ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2293                               ldns_buffer_printf(output, " ");
2294                               len = 4+4;
2295                     }
2296                     memmove(ip4, data+4, len-4);
2297                     if(!inet_ntop(AF_INET, ip4, buf, (socklen_t) sizeof(buf))) {
2298                               ldns_buffer_printf(output, "ip4ntoperror ");
2299                               ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2300                     } else {
2301                               ldns_buffer_printf(output, "%s", buf);
2302                     }
2303           } else if(family == 2) {
2304                     /* IPv6 */
2305                     char buf[64];
2306                     uint8_t ip6[16];
2307                     memset(ip6, 0, sizeof(ip6));
2308                     if(len-4 > 16) {
2309                               ldns_buffer_printf(output, "trailingdata:");
2310                               ldns_edns_hex_data2buffer_str(output, data+4+16, len-4-16);
2311                               ldns_buffer_printf(output, " ");
2312                               len = 4+16;
2313                     }
2314                     memmove(ip6, data+4, len-4);
2315 #ifdef AF_INET6
2316                     if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t) sizeof(buf))) {
2317                               ldns_buffer_printf(output, "ip6ntoperror ");
2318                               ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2319                     } else {
2320                               ldns_buffer_printf(output, "%s", buf);
2321                     }
2322 #else
2323                     ldns_edns_hex_data2buffer_str(output,  data+4+4, len-4-4);
2324 #endif
2325           } else {
2326                     /* unknown */
2327                     ldns_buffer_printf(output, "family %d ", (int)family);
2328                     ldns_edns_hex_data2buffer_str(output, data, len);
2329           }
2330           ldns_buffer_printf(output, "/%d scope /%d", (int)source, (int)scope);
2331 
2332           return ldns_buffer_status(output);
2333 }
2334 
2335 static ldns_status
ldns_edns_expire2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2336 ldns_edns_expire2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2337 {
2338 
2339           ldns_buffer_printf(output, "; EXPIRE:");
2340 
2341           if (!(len == 0) || len == 4) {
2342                     ldns_buffer_printf(output, "malformed expire ");
2343                     ldns_edns_hex_data2buffer_str(output, data, len);
2344 
2345                     return ldns_buffer_status(output);
2346           }
2347 
2348           // TODO can this output be more accurate?
2349           ldns_edns_hex_data2buffer_str(output, data, len);
2350 
2351           return ldns_buffer_status(output);
2352 }
2353 
2354 
2355 static ldns_status
ldns_edns_cookie2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2356 ldns_edns_cookie2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2357 {
2358           ldns_buffer_printf(output, "; COOKIE:");
2359 
2360           /* the size of an EDNS cookie is restricted by RFC 7873 */
2361           if (!(len == 8 || (len >= 16 && len < 40))) {
2362                     ldns_buffer_printf(output, "malformed cookie ");
2363                     ldns_edns_hex_data2buffer_str(output, data, len);
2364           }
2365           ldns_edns_hex_data2buffer_str(output, data, len);
2366 
2367           return ldns_buffer_status(output);
2368 }
2369 
2370 static ldns_status
ldns_edns_keepalive2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2371 ldns_edns_keepalive2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2372 {
2373           uint16_t timeout;
2374 
2375           ldns_buffer_printf(output, "; KEEPALIVE:");
2376 
2377           if(!(len == 0 || len == 2)) {
2378                     ldns_buffer_printf(output, "malformed keepalive ");
2379                     ldns_edns_hex_data2buffer_str(output, data, len);
2380 
2381                     return ldns_buffer_status(output);
2382           }
2383 
2384           if(len == 0) {
2385                     ldns_buffer_printf(output, "no timeout value (only valid for client option)");
2386           } else {
2387                     timeout = ldns_read_uint16(data);
2388                     ldns_buffer_printf(output, "timeout value in units of 100ms %u", (int)timeout);
2389           }
2390           return ldns_buffer_status(output);
2391 }
2392 
2393 static ldns_status
ldns_edns_padding2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2394 ldns_edns_padding2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2395 {
2396           ldns_buffer_printf(output, "; PADDING: ");
2397           ldns_edns_hex_data2buffer_str(output, data, len);
2398 
2399           return ldns_buffer_status(output);
2400 }
2401 
2402 static ldns_status
ldns_edns_chain2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2403 ldns_edns_chain2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2404 {
2405           ldns_rdf** temp = NULL;
2406 
2407           ldns_buffer_printf(output, "; CHAIN: ");
2408 
2409           if (ldns_str2rdf_dname(temp, (char*) data) != LDNS_STATUS_OK) {
2410                     ldns_buffer_printf(output, "malformed chain ");
2411                     ldns_edns_hex_data2buffer_str(output, data, len);
2412 
2413                     return ldns_buffer_status(output);
2414           }
2415 
2416           ldns_characters2buffer_str(output, len, data);
2417 
2418           return ldns_buffer_status(output);
2419 }
2420 
2421 static ldns_status
ldns_edns_key_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2422 ldns_edns_key_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2423 {
2424           size_t i;
2425 
2426           ldns_buffer_printf(output, "; KEY TAG: ");
2427 
2428           if(len < 2 || len % 2 != 0) {
2429                     ldns_buffer_printf(output, "malformed key tag ");
2430                     ldns_edns_hex_data2buffer_str(output, data, len);
2431 
2432                     return ldns_buffer_status(output);
2433           }
2434 
2435           for (i = 0; i < len; i += 2) {
2436                     uint16_t tag = ldns_read_uint16(data);
2437 
2438                     ldns_buffer_printf(output, " %hu", tag);
2439           }
2440 
2441           return ldns_buffer_status(output);
2442 }
2443 
2444 static ldns_status
ldns_edns_ede2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2445 ldns_edns_ede2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2446 {
2447           size_t i;
2448           uint16_t ede;
2449           ldns_buffer_printf(output, "; EDE:");
2450 
2451           if(len < 2) {
2452                     ldns_buffer_printf(output, "malformed ede ");
2453                     ldns_edns_hex_data2buffer_str(output, data, len);
2454 
2455                     return ldns_buffer_status(output);
2456           }
2457 
2458           ede = ldns_read_uint16(data);
2459 
2460           switch (ede) {
2461           case LDNS_EDE_OTHER:
2462                     ldns_buffer_printf(output, " 0 (Other): ");
2463                     break;
2464           case LDNS_EDE_UNSUPPORTED_DNSKEY_ALG:
2465                     ldns_buffer_printf(output, " 1 (Unsupported DNSKEY Algorithm)");
2466                     break;
2467           case LDNS_EDE_UNSUPPORTED_DS_DIGEST:
2468                     ldns_buffer_printf(output, " 2 (Unsupported DS Digest type)");
2469                     break;
2470           case LDNS_EDE_STALE_ANSWER:
2471                     ldns_buffer_printf(output, " 3 (Stale Answer)");
2472                     break;
2473           case LDNS_EDE_FORGED_ANSWER:
2474                     ldns_buffer_printf(output, " 4 (Forged Answer)");
2475                     break;
2476           case LDNS_EDE_DNSSEC_INDETERMINATE:
2477                     ldns_buffer_printf(output, " 5 (DNSSEC Indeterminate)");
2478                     break;
2479           case LDNS_EDE_DNSSEC_BOGUS:
2480                     ldns_buffer_printf(output, " 6 (DNSSEC Bogus)");
2481                     break;
2482           case LDNS_EDE_SIGNATURE_EXPIRED:
2483                     ldns_buffer_printf(output, " 7 (Signature Expired)");
2484                     break;
2485           case LDNS_EDE_SIGNATURE_NOT_YET_VALID:
2486                     ldns_buffer_printf(output, " 8 (Signature Not Yet Valid)");
2487                     break;
2488           case LDNS_EDE_DNSKEY_MISSING:
2489                     ldns_buffer_printf(output, " 9 (DNSKEY Missing)");
2490                     break;
2491           case LDNS_EDE_RRSIGS_MISSING:
2492                     ldns_buffer_printf(output, " 10 (RRSIGs Missing)");
2493                     break;
2494           case LDNS_EDE_NO_ZONE_KEY_BIT_SET:
2495                     ldns_buffer_printf(output, " 11 (No Zone Key Bit Set)");
2496                     break;
2497           case LDNS_EDE_NSEC_MISSING:
2498                     ldns_buffer_printf(output, " 12 (NSEC Missing)");
2499                     break;
2500           case LDNS_EDE_CACHED_ERROR:
2501                     ldns_buffer_printf(output, " 13 (Cached Error)");
2502                     break;
2503           case LDNS_EDE_NOT_READY:
2504                     ldns_buffer_printf(output, " 14 (Not Ready)");
2505                     break;
2506           case LDNS_EDE_BLOCKED:
2507                     ldns_buffer_printf(output, " 15 (Blocked)");
2508                     break;
2509           case LDNS_EDE_CENSORED:
2510                     ldns_buffer_printf(output, " 16 (Censored)");
2511                     break;
2512           case LDNS_EDE_FILTERED:
2513                     ldns_buffer_printf(output, " 17 (Filtered)");
2514                     break;
2515           case LDNS_EDE_PROHIBITED:
2516                     ldns_buffer_printf(output, " 18 (Prohibited)");
2517                     break;
2518           case LDNS_EDE_STALE_NXDOMAIN_ANSWER:
2519                     ldns_buffer_printf(output, " 19 (NXDOMAIN Answer)");
2520                     break;
2521           case LDNS_EDE_NOT_AUTHORITATIVE:
2522                     ldns_buffer_printf(output, " 20 (Not Authoritative)");
2523                     break;
2524           case LDNS_EDE_NOT_SUPPORTED:
2525                     ldns_buffer_printf(output, " 21 (Not Supported)");
2526                     break;
2527           case LDNS_EDE_NO_REACHABLE_AUTHORITY:
2528                     ldns_buffer_printf(output, " 22 (No Reachable Authority)");
2529                     break;
2530           case LDNS_EDE_NETWORK_ERROR:
2531                     ldns_buffer_printf(output, " 23 (Network Error)");
2532                     break;
2533           case LDNS_EDE_INVALID_DATA:
2534                     ldns_buffer_printf(output, " 24 (Invalid Data)");
2535                     break;
2536           case LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID:
2537                     ldns_buffer_printf(output, " 25 (Signature Expired Before Valid)");
2538                     break;
2539           case LDNS_EDE_TOO_EARLY:
2540                     ldns_buffer_printf(output, " 26 (Too Early)");
2541                     break;
2542           default:
2543                     ldns_buffer_printf(output, " %02x", data[0]);
2544                     ldns_buffer_printf(output, " %02x", data[1]);
2545                     break;
2546           }
2547 
2548           /* skip the EDE code in the output */
2549           data += 2;
2550           len -= 2;
2551 
2552           if (len > 2) {
2553                     /* format the hex bytes */
2554                     ldns_buffer_printf(output, ":");
2555                     for (i = 0; i < len; i++) {
2556                               ldns_buffer_printf(output, " %02x", data[i]);
2557                     }
2558 
2559                     /* format the human-readable string */
2560                     ldns_buffer_printf(output, " (");
2561                     ldns_characters2buffer_str(output, len, data);
2562                     ldns_buffer_printf(output, ")");
2563           }
2564 
2565           return ldns_buffer_status(output);
2566 }
2567 
2568 static ldns_status
ldns_edns_client_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2569 ldns_edns_client_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2570 {
2571           ldns_buffer_printf(output, "; CLIENT-TAG:");
2572 
2573           if (len > 2) {
2574                     ldns_buffer_printf(output, "malformed client-tag ");
2575                     ldns_edns_hex_data2buffer_str(output, data, len);
2576 
2577                     return ldns_buffer_status(output);
2578           }
2579 
2580           ldns_edns_hex_data2buffer_str(output, data, len);
2581 
2582           return ldns_buffer_status(output);
2583 }
2584 
2585 static ldns_status
ldns_edns_server_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2586 ldns_edns_server_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2587 {
2588           ldns_buffer_printf(output, "; SERVER-TAG:");
2589 
2590           if (len > 2) {
2591                     ldns_buffer_printf(output, "malformed server-tag ");
2592                     ldns_edns_hex_data2buffer_str(output, data, len);
2593 
2594                     return ldns_buffer_status(output);
2595           }
2596 
2597           ldns_edns_hex_data2buffer_str(output, data, len);
2598 
2599           return ldns_buffer_status(output);
2600 }
2601 
2602 ldns_status
ldns_edns_option_list2buffer_str(ldns_buffer * output,ldns_edns_option_list * edns_list)2603 ldns_edns_option_list2buffer_str(ldns_buffer *output, ldns_edns_option_list* edns_list)
2604 {
2605           size_t count = ldns_edns_option_list_get_count(edns_list);
2606           size_t i, size;
2607           uint8_t* data;
2608 
2609           for (i = 0; i < count; i++) {
2610                     ldns_edns_option_code code;
2611                     ldns_edns_option* edns = ldns_edns_option_list_get_option(edns_list, i);
2612 
2613                     if (!edns) {
2614                               break;
2615                     }
2616 
2617                     code = ldns_edns_get_code(edns);
2618                     size = ldns_edns_get_size(edns);
2619                     data = ldns_edns_get_data(edns);
2620 
2621                     switch(code) {
2622                     case LDNS_EDNS_LLQ:
2623                               ldns_edns_llq2buffer_str(output, data, size);
2624                               break;
2625                     case LDNS_EDNS_UL:
2626                               ldns_edns_ul2buffer_str(output, data, size);
2627                               break;
2628                     case LDNS_EDNS_NSID:
2629                               ldns_edns_nsid2buffer_str(output, data, size);
2630                               break;
2631                     case LDNS_EDNS_DAU:
2632                               ldns_edns_dau2buffer_str(output, data, size);
2633                               break;
2634                     case LDNS_EDNS_DHU:
2635                               ldns_edns_dhu2buffer_str(output, data, size);
2636                               break;
2637                     case LDNS_EDNS_N3U:
2638                               ldns_edns_d3u2buffer_str(output, data, size);
2639                               break;
2640                     case LDNS_EDNS_CLIENT_SUBNET:
2641                               ldns_edns_subnet2buffer_str(output, data, size);
2642                               break;
2643                     case LDNS_EDNS_EXPIRE:
2644                               ldns_edns_expire2buffer_str(output, data, size);
2645                               break;
2646                     case LDNS_EDNS_COOKIE:
2647                               ldns_edns_cookie2buffer_str(output, data, size);
2648                               break;
2649                     case LDNS_EDNS_KEEPALIVE:
2650                               ldns_edns_keepalive2buffer_str(output, data, size);
2651                               break;
2652                     case LDNS_EDNS_PADDING:
2653                               ldns_edns_padding2buffer_str(output, data, size);
2654                               break;
2655                     case LDNS_EDNS_CHAIN:
2656                               ldns_edns_chain2buffer_str(output, data, size);
2657                               break;
2658                     case LDNS_EDNS_KEY_TAG:
2659                               ldns_edns_key_tag2buffer_str(output, data, size);
2660                               break;
2661                     case LDNS_EDNS_EDE:
2662                               ldns_edns_ede2buffer_str(output, data, size);
2663                               break;
2664                     case LDNS_EDNS_CLIENT_TAG:
2665                               ldns_edns_client_tag2buffer_str(output, data, size);
2666                               break;
2667                     case LDNS_EDNS_SERVER_TAG:
2668                               ldns_edns_server_tag2buffer_str(output, data, size);
2669                               break;
2670                     default:
2671                               ldns_buffer_printf(output, "; OPT=%d:", code);
2672                               ldns_edns_hex_data2buffer_str(output, data, size);
2673                               break;
2674                     }
2675                     ldns_buffer_printf(output, "\n");
2676           }
2677 
2678           return ldns_buffer_status(output);
2679 }
2680 
2681 
2682 ldns_status
ldns_pkt2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_pkt * pkt)2683 ldns_pkt2buffer_str_fmt(ldns_buffer *output,
2684                     const ldns_output_format *fmt, const ldns_pkt *pkt)
2685 {
2686           uint16_t i;
2687           ldns_status status = LDNS_STATUS_OK;
2688           char *tmp;
2689           struct timeval time;
2690           time_t time_tt;
2691           int short_fmt = fmt && (fmt->flags & LDNS_FMT_SHORT);
2692 
2693           if (!pkt) {
2694                     ldns_buffer_printf(output, "null");
2695                     return LDNS_STATUS_OK;
2696           }
2697 
2698           if (!ldns_buffer_status_ok(output)) {
2699                     return ldns_buffer_status(output);
2700           }
2701 
2702           if (!short_fmt) {
2703                     status = ldns_pktheader2buffer_str(output, pkt);
2704                     if (status != LDNS_STATUS_OK) {
2705                               return status;
2706                     }
2707 
2708                     ldns_buffer_printf(output, "\n");
2709 
2710                     ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
2711 
2712 
2713                     for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
2714                               status = ldns_rr2buffer_str_fmt(output, fmt,
2715                                                ldns_rr_list_rr(
2716                                                          ldns_pkt_question(pkt), i));
2717                               if (status != LDNS_STATUS_OK) {
2718                                         return status;
2719                               }
2720                     }
2721                     ldns_buffer_printf(output, "\n");
2722 
2723                     ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
2724           }
2725           for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
2726                     status = ldns_rr2buffer_str_fmt(output, fmt,
2727                                      ldns_rr_list_rr(
2728                                                ldns_pkt_answer(pkt), i));
2729                     if (status != LDNS_STATUS_OK) {
2730                               return status;
2731                     }
2732           }
2733           if (!short_fmt) {
2734                     ldns_buffer_printf(output, "\n");
2735 
2736                     ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
2737 
2738                     for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
2739                               status = ldns_rr2buffer_str_fmt(output, fmt,
2740                                                ldns_rr_list_rr(
2741                                                          ldns_pkt_authority(pkt), i));
2742                               if (status != LDNS_STATUS_OK) {
2743                                         return status;
2744                               }
2745                     }
2746                     ldns_buffer_printf(output, "\n");
2747 
2748                     ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
2749                     for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
2750                               status = ldns_rr2buffer_str_fmt(output, fmt,
2751                                                ldns_rr_list_rr(
2752                                                          ldns_pkt_additional(pkt), i));
2753                               if (status != LDNS_STATUS_OK) {
2754                                         return status;
2755                               }
2756 
2757                     }
2758                     ldns_buffer_printf(output, "\n");
2759                     /* add some further fields */
2760                     ldns_buffer_printf(output, ";; Query time: %d msec\n",
2761                                         ldns_pkt_querytime(pkt));
2762                     if (ldns_pkt_edns(pkt)) {
2763                               ldns_buffer_printf(output,
2764                                            ";; EDNS: version %u; flags:",
2765                                            ldns_pkt_edns_version(pkt));
2766                               if (ldns_pkt_edns_do(pkt)) {
2767                                         ldns_buffer_printf(output, " do");
2768                               }
2769                               /* the extended rcode is the value set, shifted four bits,
2770                                * and or'd with the original rcode */
2771                               if (ldns_pkt_edns_extended_rcode(pkt)) {
2772                                         ldns_buffer_printf(output, " ; ext-rcode: %d",
2773                                                   (ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
2774                               }
2775                               ldns_buffer_printf(output, " ; udp: %u\n",
2776                                                      ldns_pkt_edns_udp_size(pkt));
2777 
2778                               if (pkt->_edns_list)
2779                                         ldns_edns_option_list2buffer_str(output, pkt->_edns_list);
2780 
2781                               else if (ldns_pkt_edns_data(pkt)) {
2782                                         ldns_edns_option_list* edns_list;
2783                                         /* parse the EDNS data into separate EDNS options
2784                                          * and add them to the list */
2785                                         if ((edns_list = pkt_edns_data2edns_option_list(ldns_pkt_edns_data(pkt)))) {
2786                                                   ldns_edns_option_list2buffer_str(output, edns_list);
2787                                                   ldns_edns_option_list_deep_free(edns_list);
2788                                         } else {
2789                                                   ldns_buffer_printf(output, ";; Data: ");
2790                                                   (void)ldns_rdf2buffer_str(output, ldns_pkt_edns_data(pkt));
2791                                         }
2792                               }
2793                     }
2794                     if (ldns_pkt_tsig(pkt)) {
2795                               ldns_buffer_printf(output, ";; TSIG:\n;; ");
2796                               (void) ldns_rr2buffer_str_fmt(
2797                                                   output, fmt, ldns_pkt_tsig(pkt));
2798                               ldns_buffer_printf(output, "\n");
2799                     }
2800                     if (ldns_pkt_answerfrom(pkt)) {
2801                               tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
2802                               ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
2803                               LDNS_FREE(tmp);
2804                     }
2805                     time = ldns_pkt_timestamp(pkt);
2806                     time_tt = (time_t)time.tv_sec;
2807                     ldns_buffer_printf(output, ";; WHEN: %s",
2808                                         (char*)ctime(&time_tt));
2809 
2810                     ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
2811                                         (int)ldns_pkt_size(pkt));
2812           }
2813           return status;
2814 }
2815 
2816 ldns_status
ldns_pkt2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)2817 ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
2818 {
2819           return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
2820 }
2821 
2822 
2823 #ifdef HAVE_SSL
2824 static ldns_status
ldns_hmac_key2buffer_str(ldns_buffer * output,const ldns_key * k)2825 ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
2826 {
2827           ldns_status status;
2828           size_t i;
2829           ldns_rdf *b64_bignum;
2830 
2831           ldns_buffer_printf(output, "Key: ");
2832 
2833           i = ldns_key_hmac_size(k);
2834           b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
2835           status = ldns_rdf2buffer_str(output, b64_bignum);
2836           ldns_rdf_deep_free(b64_bignum);
2837           ldns_buffer_printf(output, "\n");
2838           return status;
2839 }
2840 #endif
2841 
2842 #if defined(HAVE_SSL) && defined(USE_GOST)
2843 static ldns_status
ldns_gost_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2844 ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2845 {
2846           unsigned char* pp = NULL;
2847           int ret;
2848           ldns_rdf *b64_bignum;
2849           ldns_status status;
2850 
2851           ldns_buffer_printf(output, "GostAsn1: ");
2852 
2853           ret = i2d_PrivateKey(p, &pp);
2854           b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
2855           status = ldns_rdf2buffer_str(output, b64_bignum);
2856 
2857           ldns_rdf_deep_free(b64_bignum);
2858           OPENSSL_free(pp);
2859           ldns_buffer_printf(output, "\n");
2860           return status;
2861 }
2862 #endif
2863 
2864 #if defined(HAVE_SSL) && defined(USE_ED25519)
2865 static ldns_status
ldns_ed25519_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2866 ldns_ed25519_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2867 {
2868           unsigned char* pp = NULL;
2869           int ret;
2870           ldns_rdf *b64_bignum;
2871           ldns_status status;
2872 
2873           ldns_buffer_printf(output, "PrivateKey: ");
2874 
2875           ret = i2d_PrivateKey(p, &pp);
2876           /* 16 byte asn (302e020100300506032b657004220420) + 32byte key */
2877           if(ret != 16 + 32) {
2878                     OPENSSL_free(pp);
2879                     return LDNS_STATUS_ERR;
2880           }
2881           b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2882                     (size_t)ret-16, pp+16);
2883           status = ldns_rdf2buffer_str(output, b64_bignum);
2884 
2885           ldns_rdf_deep_free(b64_bignum);
2886           OPENSSL_free(pp);
2887           ldns_buffer_printf(output, "\n");
2888           return status;
2889 }
2890 #endif
2891 
2892 #if defined(HAVE_SSL) && defined(USE_ED448)
2893 static ldns_status
ldns_ed448_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2894 ldns_ed448_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2895 {
2896           unsigned char* pp = NULL;
2897           int ret;
2898           ldns_rdf *b64_bignum;
2899           ldns_status status;
2900 
2901           ldns_buffer_printf(output, "PrivateKey: ");
2902 
2903           ret = i2d_PrivateKey(p, &pp);
2904           /* some-ASN + 57byte key */
2905           if(ret != 16 + 57) {
2906                     OPENSSL_free(pp);
2907                     return LDNS_STATUS_ERR;
2908           }
2909           b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2910                     (size_t)ret-16, pp+16);
2911           status = ldns_rdf2buffer_str(output, b64_bignum);
2912 
2913           ldns_rdf_deep_free(b64_bignum);
2914           OPENSSL_free(pp);
2915           ldns_buffer_printf(output, "\n");
2916           return status;
2917 }
2918 #endif
2919 
2920 #if defined(HAVE_SSL)
2921 /** print one b64 encoded bignum to a line in the keybuffer */
2922 static int
ldns_print_bignum_b64_line(ldns_buffer * output,const char * label,const BIGNUM * num)2923 ldns_print_bignum_b64_line(ldns_buffer* output, const char* label, const BIGNUM* num)
2924 {
2925           unsigned char  *bignumbuf = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
2926           if(!bignumbuf) return 0;
2927 
2928           ldns_buffer_printf(output, "%s: ", label);
2929           if(num) {
2930                     ldns_rdf *b64_bignum = NULL;
2931                     int i = BN_bn2bin(num, bignumbuf);
2932                     if (i > LDNS_MAX_KEYLEN) {
2933                               LDNS_FREE(bignumbuf);
2934                               return 0;
2935                     }
2936                     b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)i, bignumbuf);
2937                     if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2938                               ldns_rdf_deep_free(b64_bignum);
2939                               LDNS_FREE(bignumbuf);
2940                               return 0;
2941                     }
2942                     ldns_rdf_deep_free(b64_bignum);
2943                     ldns_buffer_printf(output, "\n");
2944           } else {
2945                     ldns_buffer_printf(output, "(Not available)\n");
2946           }
2947           LDNS_FREE(bignumbuf);
2948           return 1;
2949 }
2950 #endif
2951 
2952 ldns_status
ldns_key2buffer_str(ldns_buffer * output,const ldns_key * k)2953 ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
2954 {
2955           ldns_status status = LDNS_STATUS_OK;
2956           unsigned char  *bignum;
2957 #ifdef HAVE_SSL
2958           RSA *rsa;
2959 #ifdef USE_DSA
2960           DSA *dsa;
2961 #endif /* USE_DSA */
2962 #endif /* HAVE_SSL */
2963 
2964           if (!k) {
2965                     return LDNS_STATUS_ERR;
2966           }
2967 
2968           bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
2969           if (!bignum) {
2970                     return LDNS_STATUS_ERR;
2971           }
2972 
2973           if (ldns_buffer_status_ok(output)) {
2974 #ifdef HAVE_SSL
2975                     switch(ldns_key_algorithm(k)) {
2976                               case LDNS_SIGN_RSASHA1:
2977                               case LDNS_SIGN_RSASHA1_NSEC3:
2978                               case LDNS_SIGN_RSASHA256:
2979                               case LDNS_SIGN_RSASHA512:
2980                               case LDNS_SIGN_RSAMD5:
2981                                         /* copied by looking at dnssec-keygen output */
2982                                         /* header */
2983                                         rsa = ldns_key_rsa_key(k);
2984 
2985                                         ldns_buffer_printf(output,"Private-key-format: v1.2\n");
2986                                         switch(ldns_key_algorithm(k)) {
2987                                         case LDNS_SIGN_RSAMD5:
2988                                                   ldns_buffer_printf(output,
2989                                                                                     "Algorithm: %u (RSA)\n",
2990                                                                                     LDNS_RSAMD5);
2991                                                   break;
2992                                         case LDNS_SIGN_RSASHA1:
2993                                                   ldns_buffer_printf(output,
2994                                                                                     "Algorithm: %u (RSASHA1)\n",
2995                                                                                     LDNS_RSASHA1);
2996                                                   break;
2997                                         case LDNS_SIGN_RSASHA1_NSEC3:
2998                                                   ldns_buffer_printf(output,
2999                                                                                     "Algorithm: %u (RSASHA1_NSEC3)\n",
3000                                                                                     LDNS_RSASHA1_NSEC3);
3001                                                   break;
3002 #ifdef USE_SHA2
3003                                         case LDNS_SIGN_RSASHA256:
3004                                                   ldns_buffer_printf(output,
3005                                                                                     "Algorithm: %u (RSASHA256)\n",
3006                                                                                     LDNS_RSASHA256);
3007                                                   break;
3008                                         case LDNS_SIGN_RSASHA512:
3009                                                   ldns_buffer_printf(output,
3010                                                                                     "Algorithm: %u (RSASHA512)\n",
3011                                                                                     LDNS_RSASHA512);
3012                                                   break;
3013 #endif
3014                                         default:
3015 #ifdef STDERR_MSGS
3016                                                   fprintf(stderr, "Warning: unknown signature ");
3017                                                   fprintf(stderr,
3018                                                                "algorithm type %u\n",
3019                                                                ldns_key_algorithm(k));
3020 #endif
3021                                                   ldns_buffer_printf(output,
3022                                                                                     "Algorithm: %u (Unknown)\n",
3023                                                                                     ldns_key_algorithm(k));
3024                                                   break;
3025                                         }
3026 
3027                                         /* print to buf, convert to bin, convert to b64,
3028                                          * print to buf */
3029 
3030 #ifndef S_SPLINT_S
3031                                         if(1) {
3032                                                   const BIGNUM *n=NULL, *e=NULL, *d=NULL,
3033                                                             *p=NULL, *q=NULL, *dmp1=NULL,
3034                                                             *dmq1=NULL, *iqmp=NULL;
3035 #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
3036                                                   n = rsa->n;
3037                                                   e = rsa->e;
3038                                                   d = rsa->d;
3039                                                   p = rsa->p;
3040                                                   q = rsa->q;
3041                                                   dmp1 = rsa->dmp1;
3042                                                   dmq1 = rsa->dmq1;
3043                                                   iqmp = rsa->iqmp;
3044 #else
3045                                                   RSA_get0_key(rsa, &n, &e, &d);
3046                                                   RSA_get0_factors(rsa, &p, &q);
3047                                                   RSA_get0_crt_params(rsa, &dmp1,
3048                                                             &dmq1, &iqmp);
3049 #endif
3050                                                   if(!ldns_print_bignum_b64_line(output, "Modulus", n))
3051                                                             goto error;
3052                                                   if(!ldns_print_bignum_b64_line(output, "PublicExponent", e))
3053                                                             goto error;
3054                                                   if(!ldns_print_bignum_b64_line(output, "PrivateExponent", d))
3055                                                             goto error;
3056                                                   if(!ldns_print_bignum_b64_line(output, "Prime1", p))
3057                                                             goto error;
3058                                                   if(!ldns_print_bignum_b64_line(output, "Prime2", q))
3059                                                             goto error;
3060                                                   if(!ldns_print_bignum_b64_line(output, "Exponent1", dmp1))
3061                                                             goto error;
3062                                                   if(!ldns_print_bignum_b64_line(output, "Exponent2", dmq1))
3063                                                             goto error;
3064                                                   if(!ldns_print_bignum_b64_line(output, "Coefficient", iqmp))
3065                                                             goto error;
3066                                         }
3067 #endif /* splint */
3068 
3069                                         RSA_free(rsa);
3070                                         break;
3071 #ifdef USE_DSA
3072                               case LDNS_SIGN_DSA:
3073                               case LDNS_SIGN_DSA_NSEC3:
3074                                         dsa = ldns_key_dsa_key(k);
3075 
3076                                         ldns_buffer_printf(output,"Private-key-format: v1.2\n");
3077                                         if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
3078                                                   ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
3079                                         } else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
3080                                                   ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
3081                                         }
3082 
3083                                         /* print to buf, convert to bin, convert to b64,
3084                                          * print to buf */
3085                                         if(1) {
3086                                                   const BIGNUM *p=NULL, *q=NULL, *g=NULL,
3087                                                             *priv_key=NULL, *pub_key=NULL;
3088 #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
3089 #ifndef S_SPLINT_S
3090                                                   p = dsa->p;
3091                                                   q = dsa->q;
3092                                                   g = dsa->g;
3093                                                   priv_key = dsa->priv_key;
3094                                                   pub_key = dsa->pub_key;
3095 #endif /* splint */
3096 #else
3097                                                   DSA_get0_pqg(dsa, &p, &q, &g);
3098                                                   DSA_get0_key(dsa, &pub_key, &priv_key);
3099 #endif
3100                                                   if(!ldns_print_bignum_b64_line(output, "Prime(p)", p))
3101                                                             goto error;
3102                                                   if(!ldns_print_bignum_b64_line(output, "Subprime(q)", q))
3103                                                             goto error;
3104                                                   if(!ldns_print_bignum_b64_line(output, "Base(g)", g))
3105                                                             goto error;
3106                                                   if(!ldns_print_bignum_b64_line(output, "Private_value(x)", priv_key))
3107                                                             goto error;
3108                                                   if(!ldns_print_bignum_b64_line(output, "Public_value(y)", pub_key))
3109                                                             goto error;
3110                                         }
3111                                         break;
3112 #endif /* USE_DSA */
3113                               case LDNS_SIGN_ECC_GOST:
3114                                         /* no format defined, use blob */
3115 #if defined(HAVE_SSL) && defined(USE_GOST)
3116                                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3117                                         ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
3118                                         status = ldns_gost_key2buffer_str(output,
3119 #ifndef S_SPLINT_S
3120                                                   k->_key.key
3121 #else
3122                                                   NULL
3123 #endif
3124                                         );
3125 #else
3126                                         goto error;
3127 #endif /* GOST */
3128                                         break;
3129                               case LDNS_SIGN_ECDSAP256SHA256:
3130                               case LDNS_SIGN_ECDSAP384SHA384:
3131 #ifdef USE_ECDSA
3132                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3133                                         ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3134                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3135 #ifndef S_SPLINT_S
3136                                         ldns_buffer_printf(output, ")\n");
3137                                 if(k->_key.key) {
3138                                         EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
3139                                         const BIGNUM* b = EC_KEY_get0_private_key(ec);
3140                                                   if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
3141                                                             goto error;
3142                                         /* down reference count in EC_KEY
3143                                          * its still assigned to the PKEY */
3144                                         EC_KEY_free(ec);
3145                                 }
3146 #endif /* splint */
3147 #else
3148                                         goto error;
3149 #endif /* ECDSA */
3150                                 break;
3151 #ifdef USE_ED25519
3152                               case LDNS_SIGN_ED25519:
3153                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3154                                         ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3155                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3156                                         ldns_buffer_printf(output, ")\n");
3157                                         if (status) break;
3158                                         status = ldns_ed25519_key2buffer_str(output,
3159                                                   k->_key.key);
3160                                         break;
3161 #endif /* USE_ED25519 */
3162 #ifdef USE_ED448
3163                               case LDNS_SIGN_ED448:
3164                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3165                                         ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3166                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3167                                         ldns_buffer_printf(output, ")\n");
3168                                         if (status) break;
3169                                         status = ldns_ed448_key2buffer_str(output,
3170                                                   k->_key.key);
3171                                         break;
3172 #endif /* USE_ED448 */
3173                               case LDNS_SIGN_HMACMD5:
3174                                         /* there's not much of a format defined for TSIG */
3175                                         /* It's just a binary blob, Same for all algorithms */
3176                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3177                 ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
3178                                         status = ldns_hmac_key2buffer_str(output, k);
3179                                         break;
3180                               case LDNS_SIGN_HMACSHA1:
3181                             ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3182                             ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
3183                                         status = ldns_hmac_key2buffer_str(output, k);
3184                                         break;
3185                               case LDNS_SIGN_HMACSHA224:
3186                             ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3187                             ldns_buffer_printf(output, "Algorithm: 162 (HMAC_SHA224)\n");
3188                                         status = ldns_hmac_key2buffer_str(output, k);
3189                                         break;
3190                               case LDNS_SIGN_HMACSHA256:
3191                             ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3192                             ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
3193                                         status = ldns_hmac_key2buffer_str(output, k);
3194                                         break;
3195                               case LDNS_SIGN_HMACSHA384:
3196                             ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3197                             ldns_buffer_printf(output, "Algorithm: 164 (HMAC_SHA384)\n");
3198                                         status = ldns_hmac_key2buffer_str(output, k);
3199                                         break;
3200                               case LDNS_SIGN_HMACSHA512:
3201                             ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3202                             ldns_buffer_printf(output, "Algorithm: 165 (HMAC_SHA512)\n");
3203                                         status = ldns_hmac_key2buffer_str(output, k);
3204                                         break;
3205                     }
3206 #endif /* HAVE_SSL */
3207           } else {
3208                     LDNS_FREE(bignum);
3209                     return ldns_buffer_status(output);
3210           }
3211           LDNS_FREE(bignum);
3212           return status;
3213 
3214 #ifdef HAVE_SSL
3215           /* compiles warn the label isn't used */
3216 error:
3217           LDNS_FREE(bignum);
3218           return LDNS_STATUS_ERR;
3219 #endif /* HAVE_SSL */
3220 
3221 }
3222 
3223 /*
3224  * Zero terminate the buffer and copy data.
3225  */
3226 char *
ldns_buffer2str(ldns_buffer * buffer)3227 ldns_buffer2str(ldns_buffer *buffer)
3228 {
3229           char *str;
3230 
3231           /* check if buffer ends with \0, if not, and
3232              if there is space, add it */
3233           if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
3234                     if (!ldns_buffer_reserve(buffer, 1)) {
3235                               return NULL;
3236                     }
3237                     ldns_buffer_write_char(buffer, (uint8_t) '\0');
3238                     if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
3239                               return NULL;
3240                     }
3241           }
3242 
3243           str = strdup((const char *)ldns_buffer_begin(buffer));
3244         if(!str) {
3245                 return NULL;
3246         }
3247           return str;
3248 }
3249 
3250 /*
3251  * Zero terminate the buffer and export data.
3252  */
3253 char *
ldns_buffer_export2str(ldns_buffer * buffer)3254 ldns_buffer_export2str(ldns_buffer *buffer)
3255 {
3256           /* Append '\0' as string terminator */
3257           if (! ldns_buffer_reserve(buffer, 1)) {
3258                     return NULL;
3259           }
3260           ldns_buffer_write_char(buffer, 0);
3261 
3262           /* reallocate memory to the size of the string and export */
3263           ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
3264           return ldns_buffer_export(buffer);
3265 }
3266 
3267 char *
ldns_rdf2str(const ldns_rdf * rdf)3268 ldns_rdf2str(const ldns_rdf *rdf)
3269 {
3270           char *result = NULL;
3271           ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3272 
3273           if (!tmp_buffer) {
3274                     return NULL;
3275           }
3276           if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
3277                     /* export and return string, destroy rest */
3278                     result = ldns_buffer_export2str(tmp_buffer);
3279           }
3280           ldns_buffer_free(tmp_buffer);
3281           return result;
3282 }
3283 
3284 char *
ldns_rr2str_fmt(const ldns_output_format * fmt,const ldns_rr * rr)3285 ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
3286 {
3287           char *result = NULL;
3288           ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3289 
3290           if (!tmp_buffer) {
3291                     return NULL;
3292           }
3293           if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
3294                               == LDNS_STATUS_OK) {
3295                     /* export and return string, destroy rest */
3296                     result = ldns_buffer_export2str(tmp_buffer);
3297           }
3298           ldns_buffer_free(tmp_buffer);
3299           return result;
3300 }
3301 
3302 char *
ldns_rr2str(const ldns_rr * rr)3303 ldns_rr2str(const ldns_rr *rr)
3304 {
3305           return ldns_rr2str_fmt(ldns_output_format_default, rr);
3306 }
3307 
3308 char *
ldns_pkt2str_fmt(const ldns_output_format * fmt,const ldns_pkt * pkt)3309 ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
3310 {
3311           char *result = NULL;
3312           ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3313 
3314           if (!tmp_buffer) {
3315                     return NULL;
3316           }
3317           if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
3318                               == LDNS_STATUS_OK) {
3319                     /* export and return string, destroy rest */
3320                     result = ldns_buffer_export2str(tmp_buffer);
3321           }
3322 
3323           ldns_buffer_free(tmp_buffer);
3324           return result;
3325 }
3326 
3327 char *
ldns_pkt2str(const ldns_pkt * pkt)3328 ldns_pkt2str(const ldns_pkt *pkt)
3329 {
3330           return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
3331 }
3332 
3333 char *
ldns_key2str(const ldns_key * k)3334 ldns_key2str(const ldns_key *k)
3335 {
3336           char *result = NULL;
3337           ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3338 
3339           if (!tmp_buffer) {
3340                     return NULL;
3341           }
3342           if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
3343                     /* export and return string, destroy rest */
3344                     result = ldns_buffer_export2str(tmp_buffer);
3345           }
3346           ldns_buffer_free(tmp_buffer);
3347           return result;
3348 }
3349 
3350 char *
ldns_rr_list2str_fmt(const ldns_output_format * fmt,const ldns_rr_list * list)3351 ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
3352 {
3353           char *result = NULL;
3354           ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3355 
3356           if (!tmp_buffer) {
3357                     return NULL;
3358           }
3359           if (list) {
3360                     if (ldns_rr_list2buffer_str_fmt(
3361                                            tmp_buffer, fmt, list)
3362                                         == LDNS_STATUS_OK) {
3363                     }
3364           } else {
3365                     if (fmt == NULL) {
3366                               fmt = ldns_output_format_default;
3367                     }
3368                     if (fmt->flags & LDNS_COMMENT_NULLS) {
3369                               ldns_buffer_printf(tmp_buffer, "; (null)\n");
3370                     }
3371           }
3372 
3373           /* export and return string, destroy rest */
3374           result = ldns_buffer_export2str(tmp_buffer);
3375           ldns_buffer_free(tmp_buffer);
3376           return result;
3377 }
3378 
3379 char *
ldns_rr_list2str(const ldns_rr_list * list)3380 ldns_rr_list2str(const ldns_rr_list *list)
3381 {
3382           return ldns_rr_list2str_fmt(ldns_output_format_default, list);
3383 }
3384 
3385 void
ldns_rdf_print(FILE * output,const ldns_rdf * rdf)3386 ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
3387 {
3388           char *str = ldns_rdf2str(rdf);
3389           if (str) {
3390                     fprintf(output, "%s", str);
3391           } else {
3392                     fprintf(output, ";Unable to convert rdf to string\n");
3393           }
3394           LDNS_FREE(str);
3395 }
3396 
3397 void
ldns_rr_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr * rr)3398 ldns_rr_print_fmt(FILE *output,
3399                     const ldns_output_format *fmt, const ldns_rr *rr)
3400 {
3401           char *str = ldns_rr2str_fmt(fmt, rr);
3402           if (str) {
3403                     fprintf(output, "%s", str);
3404           } else {
3405                     fprintf(output, ";Unable to convert rr to string\n");
3406           }
3407           LDNS_FREE(str);
3408 }
3409 
3410 void
ldns_rr_print(FILE * output,const ldns_rr * rr)3411 ldns_rr_print(FILE *output, const ldns_rr *rr)
3412 {
3413           ldns_rr_print_fmt(output, ldns_output_format_default, rr);
3414 }
3415 
3416 void
ldns_pkt_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_pkt * pkt)3417 ldns_pkt_print_fmt(FILE *output,
3418                     const ldns_output_format *fmt, const ldns_pkt *pkt)
3419 {
3420           char *str = ldns_pkt2str_fmt(fmt, pkt);
3421           if (str) {
3422                     fprintf(output, "%s", str);
3423           } else {
3424                     fprintf(output, ";Unable to convert packet to string\n");
3425           }
3426           LDNS_FREE(str);
3427 }
3428 
3429 void
ldns_pkt_print(FILE * output,const ldns_pkt * pkt)3430 ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
3431 {
3432           ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
3433 }
3434 
3435 void
ldns_rr_list_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr_list * lst)3436 ldns_rr_list_print_fmt(FILE *output,
3437                     const ldns_output_format *fmt, const ldns_rr_list *lst)
3438 {
3439           size_t i;
3440           for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
3441                     ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
3442           }
3443 }
3444 
3445 void
ldns_rr_list_print(FILE * output,const ldns_rr_list * lst)3446 ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
3447 {
3448           ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
3449 }
3450 
3451 void
ldns_resolver_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_resolver * r)3452 ldns_resolver_print_fmt(FILE *output,
3453                     const ldns_output_format *fmt, const ldns_resolver *r)
3454 {
3455           uint16_t i;
3456           ldns_rdf **n;
3457           ldns_rdf **s;
3458           size_t *rtt;
3459           if (!r) {
3460                     return;
3461           }
3462           n = ldns_resolver_nameservers(r);
3463           s = ldns_resolver_searchlist(r);
3464           rtt = ldns_resolver_rtt(r);
3465 
3466           fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
3467           fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
3468           fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
3469 
3470           fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
3471           fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
3472           fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
3473           fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
3474           fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
3475           fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
3476           fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
3477           fprintf(output, "random: %d\n", ldns_resolver_random(r));
3478           fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
3479           fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
3480           fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
3481           fprintf(output, "trust anchors (%d listed):\n",
3482                     (int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
3483           ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
3484           fprintf(output, "tsig: %s %s\n",
3485                 ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
3486                 ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
3487           fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
3488 
3489           fprintf(output, "default domain: ");
3490           ldns_rdf_print(output, ldns_resolver_domain(r));
3491           fprintf(output, "\n");
3492           fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
3493 
3494           fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
3495           for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
3496                     fprintf(output, "\t");
3497                     ldns_rdf_print(output, s[i]);
3498                     fprintf(output, "\n");
3499           }
3500           fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
3501 
3502           fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
3503           for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
3504                     fprintf(output, "\t");
3505                     ldns_rdf_print(output, n[i]);
3506 
3507                     switch ((int)rtt[i]) {
3508                               case LDNS_RESOLV_RTT_MIN:
3509                               fprintf(output, " - reachable\n");
3510                               break;
3511                               case LDNS_RESOLV_RTT_INF:
3512                               fprintf(output, " - unreachable\n");
3513                               break;
3514                     }
3515           }
3516 }
3517 
3518 void
ldns_resolver_print(FILE * output,const ldns_resolver * r)3519 ldns_resolver_print(FILE *output, const ldns_resolver *r)
3520 {
3521           ldns_resolver_print_fmt(output, ldns_output_format_default, r);
3522 }
3523 
3524 void
ldns_zone_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_zone * z)3525 ldns_zone_print_fmt(FILE *output,
3526                     const ldns_output_format *fmt, const ldns_zone *z)
3527 {
3528           if(ldns_zone_soa(z))
3529                     ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
3530           ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
3531 }
3532 void
ldns_zone_print(FILE * output,const ldns_zone * z)3533 ldns_zone_print(FILE *output, const ldns_zone *z)
3534 {
3535           ldns_zone_print_fmt(output, ldns_output_format_default, z);
3536 }
3537