]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ldns/host2str.c
stand/powerpc: Only build loader.kboot for powerpc64
[FreeBSD/FreeBSD.git] / contrib / ldns / host2str.c
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 #ifndef INET_ADDRSTRLEN
32 #define INET_ADDRSTRLEN 16
33 #endif
34 #ifndef INET6_ADDRSTRLEN
35 #define INET6_ADDRSTRLEN 46
36 #endif
37
38 /* lookup tables for standard DNS stuff  */
39
40 /* Taken from RFC 2535, section 7.  */
41 ldns_lookup_table ldns_algorithms[] = {
42         { LDNS_RSAMD5, "RSAMD5" },
43         { LDNS_DH, "DH" },
44         { LDNS_DSA, "DSA" },
45         { LDNS_ECC, "ECC" },
46         { LDNS_RSASHA1, "RSASHA1" },
47         { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
48         { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
49 #ifdef USE_SHA2
50         { LDNS_RSASHA256, "RSASHA256"},
51         { LDNS_RSASHA512, "RSASHA512"},
52 #endif
53 #ifdef USE_GOST
54         { LDNS_ECC_GOST, "ECC-GOST"},
55 #endif
56 #ifdef USE_ECDSA
57         { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
58         { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
59 #endif
60 #ifdef USE_ED25519
61         { LDNS_ED25519, "ED25519"},
62 #endif
63 #ifdef USE_ED448
64         { LDNS_ED448, "ED448"},
65 #endif
66         { LDNS_INDIRECT, "INDIRECT" },
67         { LDNS_PRIVATEDNS, "PRIVATEDNS" },
68         { LDNS_PRIVATEOID, "PRIVATEOID" },
69         { 0, NULL }
70 };
71
72 /* Taken from RFC 4398  */
73 ldns_lookup_table ldns_cert_algorithms[] = {
74         { LDNS_CERT_PKIX, "PKIX" },
75         { LDNS_CERT_SPKI, "SPKI" },
76         { LDNS_CERT_PGP, "PGP" },
77         { LDNS_CERT_IPKIX, "IPKIX" },
78         { LDNS_CERT_ISPKI, "ISPKI" },
79         { LDNS_CERT_IPGP, "IPGP" },
80         { LDNS_CERT_ACPKIX, "ACPKIX" },
81         { LDNS_CERT_IACPKIX, "IACPKIX" },
82         { LDNS_CERT_URI, "URI" },
83         { LDNS_CERT_OID, "OID" },
84         { 0, NULL }
85 };
86
87 /* classes  */
88 ldns_lookup_table ldns_rr_classes[] = {
89         { LDNS_RR_CLASS_IN, "IN" },
90         { LDNS_RR_CLASS_CH, "CH" },
91         { LDNS_RR_CLASS_HS, "HS" },
92         { LDNS_RR_CLASS_NONE, "NONE" },
93         { LDNS_RR_CLASS_ANY, "ANY" },
94         { 0, NULL }
95 };
96
97 /* if these are used elsewhere */
98 ldns_lookup_table ldns_rcodes[] = {
99         { LDNS_RCODE_NOERROR, "NOERROR" },
100         { LDNS_RCODE_FORMERR, "FORMERR" },
101         { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
102         { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
103         { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
104         { LDNS_RCODE_REFUSED, "REFUSED" },
105         { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
106         { LDNS_RCODE_YXRRSET, "YXRRSET" },
107         { LDNS_RCODE_NXRRSET, "NXRRSET" },
108         { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
109         { LDNS_RCODE_NOTZONE, "NOTZONE" },
110         { 0, NULL }
111 };
112
113 ldns_lookup_table ldns_opcodes[] = {
114         { LDNS_PACKET_QUERY, "QUERY" },
115         { LDNS_PACKET_IQUERY, "IQUERY" },
116         { LDNS_PACKET_STATUS, "STATUS" },
117         { LDNS_PACKET_NOTIFY, "NOTIFY" },
118         { LDNS_PACKET_UPDATE, "UPDATE" },
119         { 0, NULL }
120 };
121
122 const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
123 const ldns_output_format  *ldns_output_format_nocomments 
124                         = &ldns_output_format_nocomments_record;
125 const ldns_output_format   ldns_output_format_onlykeyids_record = {
126         LDNS_COMMENT_KEY, NULL
127 };
128 const ldns_output_format  *ldns_output_format_onlykeyids
129                         = &ldns_output_format_onlykeyids_record;
130 const ldns_output_format  *ldns_output_format_default
131                         = &ldns_output_format_onlykeyids_record;
132
133 const ldns_output_format   ldns_output_format_bubblebabble_record = { 
134         LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
135 };
136 const ldns_output_format  *ldns_output_format_bubblebabble 
137                         = &ldns_output_format_bubblebabble_record;
138
139 static bool
140 ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
141 {
142         return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
143                 ((ldns_output_format_storage*)fmt)->bitmap &&
144                 ldns_nsec_bitmap_covers_type(
145                                 ((ldns_output_format_storage*)fmt)->bitmap, t);
146 }
147
148 ldns_status
149 ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
150 {
151         ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
152         ldns_status s;
153         
154         assert(fmt != NULL);
155         
156         if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
157                 ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
158         }
159         if (! fmt_st->bitmap) {
160                 s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
161                 if (s != LDNS_STATUS_OK) {
162                         return s;
163                 }
164         }
165         return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
166 }
167
168 ldns_status
169 ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
170 {
171         ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
172         ldns_status s;
173         
174         assert(fmt != NULL);
175
176         if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
177                 ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
178         }
179         if (! fmt_st->bitmap) {
180                 s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
181                 if (s != LDNS_STATUS_OK) {
182                         return s;
183                 }
184         }
185         return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
186 }
187
188 ldns_status
189 ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
190 {
191         ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
192         if (lt && lt->name) {
193                 ldns_buffer_printf(output, "%s", lt->name);
194         } else {
195                 ldns_buffer_printf(output, "OPCODE%u", opcode);
196         }
197         return ldns_buffer_status(output);
198 }
199
200 ldns_status
201 ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
202 {
203         ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
204         if (lt && lt->name) {
205                 ldns_buffer_printf(output, "%s", lt->name);
206         } else {
207                 ldns_buffer_printf(output, "RCODE%u", rcode);
208         }
209         return ldns_buffer_status(output);
210 }
211
212 ldns_status
213 ldns_algorithm2buffer_str(ldns_buffer *output,
214                           ldns_algorithm algorithm)
215 {
216         ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
217                                                   algorithm);
218         if (lt && lt->name) {
219                 ldns_buffer_printf(output, "%s", lt->name);
220         } else {
221                 ldns_buffer_printf(output, "ALG%u", algorithm);
222         }
223         return ldns_buffer_status(output);
224 }
225
226 ldns_status
227 ldns_cert_algorithm2buffer_str(ldns_buffer *output,
228                                ldns_cert_algorithm cert_algorithm)
229 {
230         ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
231                                                   cert_algorithm);
232         if (lt && lt->name) {
233                 ldns_buffer_printf(output, "%s", lt->name);
234         } else {
235                 ldns_buffer_printf(output, "CERT_ALG%u",
236                                    cert_algorithm);
237         }
238         return ldns_buffer_status(output);
239 }
240
241 char *
242 ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
243 {
244         char *str;
245         ldns_buffer *buf;
246
247         buf = ldns_buffer_new(12);
248         if (!buf) {
249                 return NULL;
250         }
251
252         str = NULL;
253         if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
254                 str = ldns_buffer_export2str(buf);
255         }
256
257         ldns_buffer_free(buf);
258         return str;
259 }
260
261 char *
262 ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
263 {
264         char *str;
265         ldns_buffer *buf;
266
267         buf = ldns_buffer_new(10);
268         if (!buf) {
269                 return NULL;
270         }
271
272         str = NULL;
273         if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
274                 str = ldns_buffer_export2str(buf);
275         }
276
277         ldns_buffer_free(buf);
278         return str;
279 }
280
281 char *
282 ldns_pkt_algorithm2str(ldns_algorithm algorithm)
283 {
284         char *str;
285         ldns_buffer *buf;
286
287         buf = ldns_buffer_new(10);
288         if (!buf) {
289                 return NULL;
290         }
291
292         str = NULL;
293         if (ldns_algorithm2buffer_str(buf, algorithm)
294             == LDNS_STATUS_OK) {
295                 str = ldns_buffer_export2str(buf);
296         }
297
298         ldns_buffer_free(buf);
299         return str;
300 }
301
302 char *
303 ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
304 {
305         char *str;
306         ldns_buffer *buf;
307
308         buf = ldns_buffer_new(10);
309         if (!buf) {
310                 return NULL;
311         }
312
313         str = NULL;
314         if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
315             == LDNS_STATUS_OK) {
316                 str = ldns_buffer_export2str(buf);
317         }
318
319         ldns_buffer_free(buf);
320         return str;
321 }
322
323
324 /* do NOT pass compressed data here :p */
325 ldns_status
326 ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
327 {
328         /* can we do with 1 pos var? or without at all? */
329         uint8_t src_pos = 0;
330         uint8_t len;
331         uint8_t *data;
332         uint8_t i;
333         unsigned char c;
334
335         data = (uint8_t*)ldns_rdf_data(dname);
336         len = data[src_pos];
337
338         if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
339                 /* too large, return */
340                 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
341         }
342
343         /* special case: root label */
344         if (1 == ldns_rdf_size(dname)) {
345                 ldns_buffer_printf(output, ".");
346         } else {
347                 while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
348                         src_pos++;
349                         for(i = 0; i < len; i++) {
350                                 /* paranoia check for various 'strange'
351                                    characters in dnames
352                                 */
353                                 c = (unsigned char) data[src_pos];
354                                 if(c == '.' || c == ';' ||
355                                    c == '(' || c == ')' ||
356                                    c == '\\') {
357                                         ldns_buffer_printf(output, "\\%c",
358                                                         data[src_pos]);
359                                 } else if (!(isascii(c) && isgraph(c))) {
360                                         ldns_buffer_printf(output, "\\%03u",
361                                                         data[src_pos]);
362                                 } else {
363                                         ldns_buffer_printf(output, "%c", data[src_pos]);
364                                 }
365                                 src_pos++;
366                         }
367
368                         if (src_pos < ldns_rdf_size(dname)) {
369                                 ldns_buffer_printf(output, ".");
370                         }
371                         len = data[src_pos];
372                 }
373         }
374         return ldns_buffer_status(output);
375 }
376
377 ldns_status
378 ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
379 {
380         uint8_t data = ldns_rdf_data(rdf)[0];
381         ldns_buffer_printf(output, "%lu", (unsigned long) data);
382         return ldns_buffer_status(output);
383 }
384
385 ldns_status
386 ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
387 {
388         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
389         ldns_buffer_printf(output, "%lu", (unsigned long) data);
390         return ldns_buffer_status(output);
391 }
392
393 ldns_status
394 ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
395 {
396         uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
397         ldns_buffer_printf(output, "%lu", (unsigned long) data);
398         return ldns_buffer_status(output);
399 }
400
401 ldns_status
402 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
403 {
404         /* create a YYYYMMDDHHMMSS string if possible */
405         struct tm tm;
406         char date_buf[16];
407
408         memset(&tm, 0, sizeof(tm));
409         if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
410             && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
411                 ldns_buffer_printf(output, "%s", date_buf);
412         }
413         return ldns_buffer_status(output);
414 }
415
416 ldns_status
417 ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
418 {
419         char str[INET_ADDRSTRLEN];
420
421         if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
422                 ldns_buffer_printf(output, "%s", str);
423         }
424         return ldns_buffer_status(output);
425 }
426
427 ldns_status
428 ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
429 {
430         char str[INET6_ADDRSTRLEN];
431
432         if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
433                 ldns_buffer_printf(output, "%s", str);
434         }
435
436         return ldns_buffer_status(output);
437 }
438
439 static void 
440 ldns_characters2buffer_str(ldns_buffer* output,
441                 size_t amount, const uint8_t* characters)
442 {
443         uint8_t ch;
444         while (amount > 0) {
445                 ch = *characters++;
446                 if (isprint((int)ch) || ch == '\t') {
447                         if (ch == '\"' || ch == '\\')
448                                 ldns_buffer_printf(output, "\\%c", ch);
449                         else
450                                 ldns_buffer_printf(output, "%c", ch);
451                 } else {
452                         ldns_buffer_printf(output, "\\%03u",
453                                 (unsigned)(uint8_t) ch);
454                 }
455                 amount--;
456         }
457 }
458
459 ldns_status
460 ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
461 {
462         if(ldns_rdf_size(rdf) < 1) {
463                 return LDNS_STATUS_WIRE_RDATA_ERR;
464         }
465         if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
466                 return LDNS_STATUS_WIRE_RDATA_ERR;
467         }
468         ldns_buffer_printf(output, "\"");
469         ldns_characters2buffer_str(output, 
470                         ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
471         ldns_buffer_printf(output, "\"");
472         return ldns_buffer_status(output);
473 }
474
475 ldns_status
476 ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
477 {
478         size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
479         char *b64 = LDNS_XMALLOC(char, size);
480         if(!b64) return LDNS_STATUS_MEM_ERR;
481         if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
482                 ldns_buffer_printf(output, "%s", b64);
483         }
484         LDNS_FREE(b64);
485         return ldns_buffer_status(output);
486 }
487
488 ldns_status
489 ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
490 {
491         size_t size;
492         char *b32;
493         if(ldns_rdf_size(rdf) == 0)
494                 return LDNS_STATUS_OK;
495         /* remove -1 for the b32-hash-len octet */
496         size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
497         /* add one for the end nul for the string */
498         b32 = LDNS_XMALLOC(char, size + 1);
499         if(!b32) return LDNS_STATUS_MEM_ERR;
500         size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
501                 ldns_rdf_size(rdf) - 1, b32, size+1);
502         if (size > 0) {
503                 ldns_buffer_printf(output, "%s", b32);
504         }
505         LDNS_FREE(b32);
506         return ldns_buffer_status(output);
507 }
508
509 ldns_status
510 ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
511 {
512         size_t i;
513         for (i = 0; i < ldns_rdf_size(rdf); i++) {
514                 ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
515         }
516
517         return ldns_buffer_status(output);
518 }
519
520 static ldns_status
521 ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
522                 const ldns_output_format* fmt, const ldns_rdf *rdf)
523 {
524         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
525
526         if (! ldns_output_format_covers_type(fmt, data) &&
527                         ldns_rr_descript(data) &&
528                         ldns_rr_descript(data)->_name) {
529
530                 ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
531         } else {
532                 ldns_buffer_printf(output, "TYPE%u", data);
533         }
534         return  ldns_buffer_status(output);
535 }
536
537 ldns_status
538 ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
539 {
540         return ldns_rdf2buffer_str_type_fmt(output,
541                         ldns_output_format_default, rdf);
542 }
543
544 ldns_status
545 ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
546 {
547         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
548         ldns_lookup_table *lt;
549
550         lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
551         if (lt) {
552                 ldns_buffer_printf(output, "\t%s", lt->name);
553         } else {
554                 ldns_buffer_printf(output, "\tCLASS%d", data);
555         }
556         return ldns_buffer_status(output);
557 }
558
559 ldns_status
560 ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
561 {
562         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
563         ldns_lookup_table *lt;
564         lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
565         if (lt) {
566                 ldns_buffer_printf(output, "%s", lt->name);
567         } else {
568                 ldns_buffer_printf(output, "%d", data);
569         }
570         return ldns_buffer_status(output);
571 }
572
573 ldns_status
574 ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
575 {
576         return ldns_rdf2buffer_str_int8(output, rdf);
577 }
578
579 static void
580 loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
581 {
582         uint8_t i;
583         /* is it 0.<two digits> ? */
584         if(exponent < 2) {
585                 if(exponent == 1)
586                         mantissa *= 10;
587                 ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
588                 return;
589         }
590         /* always <digit><string of zeros> */
591         ldns_buffer_printf(output, "%d", (int)mantissa);
592         for(i=0; i<exponent-2; i++)
593                 ldns_buffer_printf(output, "0");
594 }
595
596 ldns_status
597 ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
598 {
599         const ldns_rr_descriptor *descriptor;
600
601         descriptor = ldns_rr_descript(type);
602
603         switch (type) {
604                 case LDNS_RR_TYPE_IXFR:
605                         ldns_buffer_printf(output, "IXFR");
606                         break;
607                 case LDNS_RR_TYPE_AXFR:
608                         ldns_buffer_printf(output, "AXFR");
609                         break;
610                 case LDNS_RR_TYPE_MAILA:
611                         ldns_buffer_printf(output, "MAILA");
612                         break;
613                 case LDNS_RR_TYPE_MAILB:
614                         ldns_buffer_printf(output, "MAILB");
615                         break;
616                 case LDNS_RR_TYPE_ANY:
617                         ldns_buffer_printf(output, "ANY");
618                         break;
619                 default:
620                         if (descriptor && descriptor->_name) {
621                                 ldns_buffer_printf(output, "%s", descriptor->_name);
622                         } else {
623                                 ldns_buffer_printf(output, "TYPE%u", type);
624                         }
625         }
626         return ldns_buffer_status(output);
627 }
628
629 char *
630 ldns_rr_type2str(const ldns_rr_type type)
631 {
632         char *str;
633         ldns_buffer *buf;
634
635         buf = ldns_buffer_new(10);
636         if (!buf) {
637                 return NULL;
638         }
639
640         str = NULL;
641         if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
642                 str = ldns_buffer_export2str(buf);
643         }
644
645         ldns_buffer_free(buf);
646         return str;
647 }
648
649
650 ldns_status
651 ldns_rr_class2buffer_str(ldns_buffer *output,
652                          const ldns_rr_class klass)
653 {
654         ldns_lookup_table *lt;
655
656         lt = ldns_lookup_by_id(ldns_rr_classes, klass);
657         if (lt) {
658                 ldns_buffer_printf(output, "%s", lt->name);
659         } else {
660                 ldns_buffer_printf(output, "CLASS%d", klass);
661         }
662         return ldns_buffer_status(output);
663 }
664
665 char *
666 ldns_rr_class2str(const ldns_rr_class klass)
667 {
668         ldns_buffer *buf;
669         char *str;
670
671         buf = ldns_buffer_new(10);
672         if (!buf) {
673                 return NULL;
674         }
675
676         str = NULL;
677         if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
678                 str = ldns_buffer_export2str(buf);
679         }
680         ldns_buffer_free(buf);
681         return str;
682 }
683
684 ldns_status
685 ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
686 {
687         /* we could do checking (ie degrees < 90 etc)? */
688         uint8_t version;
689         uint8_t size;
690         uint8_t horizontal_precision;
691         uint8_t vertical_precision;
692         uint32_t longitude;
693         uint32_t latitude;
694         uint32_t altitude;
695         char northerness;
696         char easterness;
697         uint32_t h;
698         uint32_t m;
699         double s;
700
701         uint32_t equator = (uint32_t) ldns_power(2, 31);
702
703         if(ldns_rdf_size(rdf) < 1) {
704                 return LDNS_STATUS_WIRE_RDATA_ERR;
705         }
706         version = ldns_rdf_data(rdf)[0];
707         if (version == 0) {
708                 if(ldns_rdf_size(rdf) < 16) {
709                         return LDNS_STATUS_WIRE_RDATA_ERR;
710                 }
711                 size = ldns_rdf_data(rdf)[1];
712                 horizontal_precision = ldns_rdf_data(rdf)[2];
713                 vertical_precision = ldns_rdf_data(rdf)[3];
714
715                 latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
716                 longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
717                 altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
718
719                 if (latitude > equator) {
720                         northerness = 'N';
721                         latitude = latitude - equator;
722                 } else {
723                         northerness = 'S';
724                         latitude = equator - latitude;
725                 }
726                 h = latitude / (1000 * 60 * 60);
727                 latitude = latitude % (1000 * 60 * 60);
728                 m = latitude / (1000 * 60);
729                 latitude = latitude % (1000 * 60);
730                 s = (double) latitude / 1000.0;
731                 ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
732                         h, m, s, northerness);
733
734                 if (longitude > equator) {
735                         easterness = 'E';
736                         longitude = longitude - equator;
737                 } else {
738                         easterness = 'W';
739                         longitude = equator - longitude;
740                 }
741                 h = longitude / (1000 * 60 * 60);
742                 longitude = longitude % (1000 * 60 * 60);
743                 m = longitude / (1000 * 60);
744                 longitude = longitude % (1000 * 60);
745                 s = (double) longitude / (1000.0);
746                 ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
747                         h, m, s, easterness);
748
749
750                 s = ((double) altitude) / 100;
751                 s -= 100000;
752
753                 if(altitude%100 != 0)
754                         ldns_buffer_printf(output, "%.2f", s);
755                 else
756                         ldns_buffer_printf(output, "%.0f", s);
757
758                 ldns_buffer_printf(output, "m ");
759
760                 loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
761                 ldns_buffer_printf(output, "m ");
762
763                 loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
764                         horizontal_precision & 0x0f);
765                 ldns_buffer_printf(output, "m ");
766
767                 loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
768                         vertical_precision & 0x0f);
769                 ldns_buffer_printf(output, "m");
770
771                 return ldns_buffer_status(output);
772         } else {
773                 return ldns_rdf2buffer_str_hex(output, rdf);
774         }
775 }
776
777 ldns_status
778 ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
779 {
780         ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
781         return ldns_rdf2buffer_str_hex(output, rdf);
782 }
783
784 ldns_status
785 ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
786 {
787         ldns_buffer_printf(output, "0x");
788         return ldns_rdf2buffer_str_hex(output, rdf);
789 }
790
791 ldns_status
792 ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
793 {
794         return ldns_rdf2buffer_str_hex(output, rdf);
795 }
796
797 ldns_status
798 ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
799 {
800         /* protocol, followed by bitmap of services */
801         struct protoent *protocol;
802         char *proto_name = NULL;
803         uint8_t protocol_nr;
804         struct servent *service;
805         uint16_t current_service;
806
807         if(ldns_rdf_size(rdf) < 1) {
808                 return LDNS_STATUS_WIRE_RDATA_ERR;
809         }
810         protocol_nr = ldns_rdf_data(rdf)[0];
811         protocol = getprotobynumber((int) protocol_nr);
812         if (protocol && (protocol->p_name != NULL)) {
813                 proto_name = protocol->p_name;
814                 ldns_buffer_printf(output, "%s ", protocol->p_name);
815         } else {
816                 ldns_buffer_printf(output, "%u ", protocol_nr);
817         }
818
819 #ifdef HAVE_ENDPROTOENT
820         endprotoent();
821 #endif
822
823         for (current_service = 0;
824              current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
825                 if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
826                         service = getservbyport((int) htons(current_service),
827                                                 proto_name);
828                         if (service && service->s_name) {
829                                 ldns_buffer_printf(output, "%s ", service->s_name);
830                         } else {
831                                 ldns_buffer_printf(output, "%u ", current_service);
832                         }
833 #ifdef HAVE_ENDSERVENT
834                         endservent();
835 #endif
836                 }
837         }
838         return ldns_buffer_status(output);
839 }
840
841 static ldns_status
842 ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
843                 const ldns_output_format* fmt, const ldns_rdf *rdf)
844 {
845         /* Note: this code is duplicated in higher.c in
846          * ldns_nsec_type_check() function
847          */
848         uint8_t window_block_nr;
849         uint8_t bitmap_length;
850         uint16_t type;
851         uint16_t pos = 0;
852         uint16_t bit_pos;
853         uint8_t *data = ldns_rdf_data(rdf);
854
855         while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
856                 window_block_nr = data[pos];
857                 bitmap_length = data[pos + 1];
858                 pos += 2;
859                 if (ldns_rdf_size(rdf) < pos + bitmap_length) {
860                         return LDNS_STATUS_WIRE_RDATA_ERR;
861                 }
862                 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
863                         if (! ldns_get_bit(&data[pos], bit_pos)) {
864                                 continue;
865                         }
866                         type = 256 * (uint16_t) window_block_nr + bit_pos;
867
868                         if (! ldns_output_format_covers_type(fmt, type) &&
869                                         ldns_rr_descript(type) &&
870                                         ldns_rr_descript(type)->_name){
871
872                                 ldns_buffer_printf(output, "%s ",
873                                                 ldns_rr_descript(type)->_name);
874                         } else {
875                                 ldns_buffer_printf(output, "TYPE%u ", type);
876                         }
877                 }
878                 pos += (uint16_t) bitmap_length;
879         }
880         return ldns_buffer_status(output);
881 }
882
883 ldns_status
884 ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
885 {
886         return ldns_rdf2buffer_str_nsec_fmt(output,
887                         ldns_output_format_default, rdf);
888 }
889
890 ldns_status
891 ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
892 {
893         uint8_t salt_length;
894         uint8_t salt_pos;
895
896         uint8_t *data = ldns_rdf_data(rdf);
897
898         if(ldns_rdf_size(rdf) < 1) {
899                 return LDNS_STATUS_WIRE_RDATA_ERR;
900         }
901         salt_length = data[0];
902         /* from now there are variable length entries so remember pos */
903         if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
904                 ldns_buffer_printf(output, "- ");
905         } else {
906                 for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
907                         ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
908                 }
909                 ldns_buffer_printf(output, " ");
910         }
911
912         return ldns_buffer_status(output);
913 }
914
915 ldns_status
916 ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
917 {
918         /* period is the number of seconds */
919         if (ldns_rdf_size(rdf) != 4) {
920                 return LDNS_STATUS_WIRE_RDATA_ERR;
921         }
922         ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
923         return ldns_buffer_status(output);
924 }
925
926 ldns_status
927 ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
928 {
929         /* tsigtime is 48 bits network order unsigned integer */
930         uint64_t tsigtime = 0;
931         uint8_t *data = ldns_rdf_data(rdf);
932         uint64_t d0, d1, d2, d3, d4, d5;
933
934         if (ldns_rdf_size(rdf) < 6) {
935                 return LDNS_STATUS_WIRE_RDATA_ERR;
936         }
937         d0 = data[0]; /* cast to uint64 for shift operations */
938         d1 = data[1];
939         d2 = data[2];
940         d3 = data[3];
941         d4 = data[4];
942         d5 = data[5];
943         tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
944
945         ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
946
947         return ldns_buffer_status(output);
948 }
949
950 ldns_status
951 ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
952 {
953         uint8_t *data = ldns_rdf_data(rdf);
954         uint16_t address_family;
955         uint8_t prefix;
956         bool negation;
957         uint8_t adf_length;
958         size_t i;
959         size_t pos = 0;
960
961         while (pos < (unsigned int) ldns_rdf_size(rdf)) {
962                 if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
963                         return LDNS_STATUS_WIRE_RDATA_ERR;
964                 address_family = ldns_read_uint16(&data[pos]);
965                 prefix = data[pos + 2];
966                 negation = data[pos + 3] & LDNS_APL_NEGATION;
967                 adf_length = data[pos + 3] & LDNS_APL_MASK;
968                 if (address_family == LDNS_APL_IP4) {
969                         /* check if prefix < 32? */
970                         if (negation) {
971                                 ldns_buffer_printf(output, "!");
972                         }
973                         ldns_buffer_printf(output, "%u:", address_family);
974                         /* address is variable length 0 - 4 */
975                         for (i = 0; i < 4; i++) {
976                                 if (i > 0) {
977                                         ldns_buffer_printf(output, ".");
978                                 }
979                                 if (i < (unsigned short) adf_length) {
980                                         if(pos+i+4 >= ldns_rdf_size(rdf))
981                                             return LDNS_STATUS_WIRE_RDATA_ERR;
982                                         ldns_buffer_printf(output, "%d",
983                                                            data[pos + i + 4]);
984                                 } else {
985                                         ldns_buffer_printf(output, "0");
986                                 }
987                         }
988                         ldns_buffer_printf(output, "/%u ", prefix);
989                 } else if (address_family == LDNS_APL_IP6) {
990                         /* check if prefix < 128? */
991                         if (negation) {
992                                 ldns_buffer_printf(output, "!");
993                         }
994                         ldns_buffer_printf(output, "%u:", address_family);
995                         /* address is variable length 0 - 16 */
996                         for (i = 0; i < 16; i++) {
997                                 if (i % 2 == 0 && 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, "%02x",
1004                                                            data[pos + i + 4]);
1005                                 } else {
1006                                         ldns_buffer_printf(output, "00");
1007                                 }
1008                         }
1009                         ldns_buffer_printf(output, "/%u ", prefix);
1010
1011                 } else {
1012                         /* unknown address family */
1013                         ldns_buffer_printf(output,
1014                                         "Unknown address family: %u data: ",
1015                                         address_family);
1016                         for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
1017                                 if(pos+i >= ldns_rdf_size(rdf))
1018                                         return LDNS_STATUS_WIRE_RDATA_ERR;
1019                                 ldns_buffer_printf(output, "%02x", data[i]);
1020                         }
1021                 }
1022                 pos += 4 + adf_length;
1023         }
1024         return ldns_buffer_status(output);
1025 }
1026
1027 ldns_status
1028 ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
1029 {
1030         size_t size;
1031         char *b64;
1032         if (ldns_rdf_size(rdf) < 2) {
1033                 return LDNS_STATUS_WIRE_RDATA_ERR;
1034         }
1035         /* Subtract the size (2) of the number that specifies the length */
1036         size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
1037         ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
1038         if (ldns_rdf_size(rdf) > 2) {
1039                 b64 = LDNS_XMALLOC(char, size);
1040                 if(!b64)
1041                         return LDNS_STATUS_MEM_ERR;
1042
1043                 if (ldns_rdf_size(rdf) > 2 &&
1044                 ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
1045                                         ldns_rdf_size(rdf) - 2,
1046                                         b64, size)) {
1047                         ldns_buffer_printf(output, "%s", b64);
1048                 }
1049                 LDNS_FREE(b64);
1050         }
1051         return ldns_buffer_status(output);
1052 }
1053
1054 ldns_status
1055 ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
1056 {
1057         /* wire format from
1058            http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
1059         */
1060         uint8_t *data = ldns_rdf_data(rdf);
1061         uint8_t precedence;
1062         uint8_t gateway_type;
1063         uint8_t algorithm;
1064
1065         ldns_rdf *gateway = NULL;
1066         uint8_t *gateway_data;
1067
1068         size_t public_key_size;
1069         uint8_t *public_key_data;
1070         ldns_rdf *public_key;
1071
1072         size_t offset = 0;
1073         ldns_status status;
1074
1075         if (ldns_rdf_size(rdf) < 3) {
1076                 return LDNS_STATUS_WIRE_RDATA_ERR;
1077         }
1078         precedence = data[0];
1079         gateway_type = data[1];
1080         algorithm = data[2];
1081         offset = 3;
1082
1083         switch (gateway_type) {
1084                 case 0:
1085                         /* no gateway */
1086                         break;
1087                 case 1:
1088                         gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1089                         if(!gateway_data)
1090                                 return LDNS_STATUS_MEM_ERR;
1091                         if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1092                                 return LDNS_STATUS_ERR;
1093                         }
1094                         memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
1095                         gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
1096                                         LDNS_IP4ADDRLEN , gateway_data);
1097                         offset += LDNS_IP4ADDRLEN;
1098                         if(!gateway) {
1099                                 LDNS_FREE(gateway_data);
1100                                 return LDNS_STATUS_MEM_ERR;
1101                         }
1102                         break;
1103                 case 2:
1104                         gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1105                         if(!gateway_data)
1106                                 return LDNS_STATUS_MEM_ERR;
1107                         if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1108                                 return LDNS_STATUS_ERR;
1109                         }
1110                         memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
1111                         offset += LDNS_IP6ADDRLEN;
1112                         gateway =
1113                                 ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1114                                                 LDNS_IP6ADDRLEN, gateway_data);
1115                         if(!gateway) {
1116                                 LDNS_FREE(gateway_data);
1117                                 return LDNS_STATUS_MEM_ERR;
1118                         }
1119                         break;
1120                 case 3:
1121                         status = ldns_wire2dname(&gateway, data,
1122                                         ldns_rdf_size(rdf), &offset);
1123                         if(status != LDNS_STATUS_OK)
1124                                 return status;
1125                         break;
1126                 default:
1127                         /* error? */
1128                         break;
1129         }
1130
1131         if (ldns_rdf_size(rdf) <= offset) {
1132                 return LDNS_STATUS_ERR;
1133         }
1134         public_key_size = ldns_rdf_size(rdf) - offset;
1135         public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1136         if(!public_key_data) {
1137                 ldns_rdf_deep_free(gateway);
1138                 return LDNS_STATUS_MEM_ERR;
1139         }
1140         memcpy(public_key_data, &data[offset], public_key_size);
1141         public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
1142                         public_key_size, public_key_data);
1143         if(!public_key) {
1144                 LDNS_FREE(public_key_data);
1145                 ldns_rdf_deep_free(gateway);
1146                 return LDNS_STATUS_MEM_ERR;
1147         }
1148
1149         ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1150         if (gateway)
1151                 (void) ldns_rdf2buffer_str(output, gateway);
1152         else
1153                 ldns_buffer_printf(output, ".");
1154         ldns_buffer_printf(output, " ");
1155         (void) ldns_rdf2buffer_str(output, public_key);
1156
1157         ldns_rdf_deep_free(gateway);
1158         ldns_rdf_deep_free(public_key);
1159
1160         return ldns_buffer_status(output);
1161 }
1162
1163 ldns_status
1164 ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
1165 {
1166         if (ldns_rdf_size(rdf) != 8) {
1167                 return LDNS_STATUS_WIRE_RDATA_ERR;
1168         }
1169         ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
1170                                 ldns_read_uint16(ldns_rdf_data(rdf)),
1171                                 ldns_read_uint16(ldns_rdf_data(rdf)+2),
1172                                 ldns_read_uint16(ldns_rdf_data(rdf)+4),
1173                                 ldns_read_uint16(ldns_rdf_data(rdf)+6));
1174         return ldns_buffer_status(output);
1175 }
1176
1177 ldns_status
1178 ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
1179 {
1180         if (ldns_rdf_size(rdf) != 6) {
1181                 return LDNS_STATUS_WIRE_RDATA_ERR;
1182         }
1183         ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1184                                 ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1185                                 ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1186                                 ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
1187         return ldns_buffer_status(output);
1188 }
1189
1190 ldns_status
1191 ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
1192 {
1193         if (ldns_rdf_size(rdf) != 8) {
1194                 return LDNS_STATUS_WIRE_RDATA_ERR;
1195         }
1196         ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1197                                 ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1198                                 ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1199                                 ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
1200                                 ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
1201         return ldns_buffer_status(output);
1202 }
1203
1204 ldns_status
1205 ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
1206 {
1207         size_t nchars;
1208         const uint8_t* chars;
1209         char ch;
1210         if (ldns_rdf_size(rdf) < 2) {
1211                 return LDNS_STATUS_WIRE_RDATA_ERR;
1212         }
1213         nchars = ldns_rdf_data(rdf)[0];
1214         if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
1215                         nchars < 1) {
1216                 return LDNS_STATUS_WIRE_RDATA_ERR;
1217         }
1218         chars = ldns_rdf_data(rdf) + 1;
1219         while (nchars > 0) {
1220                 ch = (char)*chars++;
1221                 if (! isalnum((unsigned char)ch)) {
1222                         return LDNS_STATUS_WIRE_RDATA_ERR;
1223                 }
1224                 ldns_buffer_printf(output, "%c", ch);
1225                 nchars--;
1226         }
1227         return ldns_buffer_status(output);
1228 }
1229
1230 ldns_status
1231 ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
1232 {
1233
1234         ldns_buffer_printf(output, "\"");
1235         ldns_characters2buffer_str(output,
1236                         ldns_rdf_size(rdf), ldns_rdf_data(rdf));
1237         ldns_buffer_printf(output, "\"");
1238         return ldns_buffer_status(output);
1239 }
1240
1241 ldns_status
1242 ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
1243 {
1244         uint8_t *data = ldns_rdf_data(rdf);
1245         size_t rdf_size = ldns_rdf_size(rdf);
1246         uint8_t hit_size;
1247         uint16_t pk_size;
1248         int written;
1249         
1250         if (rdf_size < 6) {
1251                 return LDNS_STATUS_WIRE_RDATA_ERR;
1252         }
1253         if ((hit_size = data[0]) == 0 ||
1254                         (pk_size = ldns_read_uint16(data + 2)) == 0 ||
1255                         rdf_size < (size_t) hit_size + pk_size + 4) {
1256
1257                 return LDNS_STATUS_WIRE_RDATA_ERR;
1258         }
1259
1260         ldns_buffer_printf(output, "%d ", (int) data[1]);
1261
1262         for (data += 4; hit_size > 0; hit_size--, data++) {
1263
1264                 ldns_buffer_printf(output, "%02x", (int) *data);
1265         }
1266         ldns_buffer_write_u8(output, (uint8_t) ' ');
1267
1268         if (ldns_buffer_reserve(output,
1269                                 ldns_b64_ntop_calculate_size(pk_size))) {
1270
1271                 written = ldns_b64_ntop(data, pk_size,
1272                                 (char *) ldns_buffer_current(output),
1273                                 ldns_buffer_remaining(output));
1274
1275                 if (written > 0 &&
1276                                 written < (int) ldns_buffer_remaining(output)) {
1277
1278                         output->_position += written;
1279                 }
1280         }
1281         return ldns_buffer_status(output);
1282 }
1283
1284 static ldns_status
1285 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
1286                 const ldns_output_format* fmt, const ldns_rdf *rdf)
1287 {
1288         ldns_status res = LDNS_STATUS_OK;
1289
1290         /*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1291         if (rdf) {
1292                 switch(ldns_rdf_get_type(rdf)) {
1293                 case LDNS_RDF_TYPE_NONE:
1294                         break;
1295                 case LDNS_RDF_TYPE_DNAME:
1296                         res = ldns_rdf2buffer_str_dname(buffer, rdf);
1297                         break;
1298                 case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
1299                 case LDNS_RDF_TYPE_ALG:
1300                 case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
1301                 case LDNS_RDF_TYPE_SELECTOR:
1302                 case LDNS_RDF_TYPE_MATCHING_TYPE:
1303                         res = ldns_rdf2buffer_str_int8(buffer, rdf);
1304                         break;
1305                 case LDNS_RDF_TYPE_INT16:
1306                         res = ldns_rdf2buffer_str_int16(buffer, rdf);
1307                         break;
1308                 case LDNS_RDF_TYPE_INT32:
1309                         res = ldns_rdf2buffer_str_int32(buffer, rdf);
1310                         break;
1311                 case LDNS_RDF_TYPE_PERIOD:
1312                         res = ldns_rdf2buffer_str_period(buffer, rdf);
1313                         break;
1314                 case LDNS_RDF_TYPE_TSIGTIME:
1315                         res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1316                         break;
1317                 case LDNS_RDF_TYPE_A:
1318                         res = ldns_rdf2buffer_str_a(buffer, rdf);
1319                         break;
1320                 case LDNS_RDF_TYPE_AAAA:
1321                         res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1322                         break;
1323                 case LDNS_RDF_TYPE_STR:
1324                         res = ldns_rdf2buffer_str_str(buffer, rdf);
1325                         break;
1326                 case LDNS_RDF_TYPE_APL:
1327                         res = ldns_rdf2buffer_str_apl(buffer, rdf);
1328                         break;
1329                 case LDNS_RDF_TYPE_B32_EXT:
1330                         res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1331                         break;
1332                 case LDNS_RDF_TYPE_B64:
1333                         res = ldns_rdf2buffer_str_b64(buffer, rdf);
1334                         break;
1335                 case LDNS_RDF_TYPE_HEX:
1336                         res = ldns_rdf2buffer_str_hex(buffer, rdf);
1337                         break;
1338                 case LDNS_RDF_TYPE_NSEC:
1339                         res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
1340                         break;
1341                 case LDNS_RDF_TYPE_NSEC3_SALT:
1342                         res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1343                         break;
1344                 case LDNS_RDF_TYPE_TYPE:
1345                         res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
1346                         break;
1347                 case LDNS_RDF_TYPE_CLASS:
1348                         res = ldns_rdf2buffer_str_class(buffer, rdf);
1349                         break;
1350                 case LDNS_RDF_TYPE_CERT_ALG:
1351                         res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1352                         break;
1353                 case LDNS_RDF_TYPE_UNKNOWN:
1354                         res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1355                         break;
1356                 case LDNS_RDF_TYPE_TIME:
1357                         res = ldns_rdf2buffer_str_time(buffer, rdf);
1358                         break;
1359                 case LDNS_RDF_TYPE_HIP:
1360                         res = ldns_rdf2buffer_str_hip(buffer, rdf);
1361                         break;
1362                 case LDNS_RDF_TYPE_LOC:
1363                         res = ldns_rdf2buffer_str_loc(buffer, rdf);
1364                         break;
1365                 case LDNS_RDF_TYPE_WKS:
1366                 case LDNS_RDF_TYPE_SERVICE:
1367                         res = ldns_rdf2buffer_str_wks(buffer, rdf);
1368                         break;
1369                 case LDNS_RDF_TYPE_NSAP:
1370                         res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1371                         break;
1372                 case LDNS_RDF_TYPE_ATMA:
1373                         res = ldns_rdf2buffer_str_atma(buffer, rdf);
1374                         break;
1375                 case LDNS_RDF_TYPE_IPSECKEY:
1376                         res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1377                         break;
1378                 case LDNS_RDF_TYPE_INT16_DATA:
1379                         res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1380                         break;
1381                 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1382                         res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1383                         break;
1384                 case LDNS_RDF_TYPE_ILNP64:
1385                         res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
1386                         break;
1387                 case LDNS_RDF_TYPE_EUI48:
1388                         res = ldns_rdf2buffer_str_eui48(buffer, rdf);
1389                         break;
1390                 case LDNS_RDF_TYPE_EUI64:
1391                         res = ldns_rdf2buffer_str_eui64(buffer, rdf);
1392                         break;
1393                 case LDNS_RDF_TYPE_TAG:
1394                         res = ldns_rdf2buffer_str_tag(buffer, rdf);
1395                         break;
1396                 case LDNS_RDF_TYPE_LONG_STR:
1397                         res = ldns_rdf2buffer_str_long_str(buffer, rdf);
1398                         break;
1399                 }
1400         } else {
1401                 /** This will write mangled RRs */
1402                 ldns_buffer_printf(buffer, "(null) ");
1403                 res = LDNS_STATUS_ERR;
1404         }
1405         return res;
1406 }
1407
1408 ldns_status
1409 ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1410 {
1411         return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
1412 }
1413
1414 static ldns_rdf *
1415 ldns_b32_ext2dname(const ldns_rdf *rdf)
1416 {
1417         size_t size;
1418         char *b32;
1419         ldns_rdf *out;
1420         if(ldns_rdf_size(rdf) == 0)
1421                 return NULL;
1422         /* remove -1 for the b32-hash-len octet */
1423         size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1424         /* add one for the end nul for the string */
1425         b32 = LDNS_XMALLOC(char, size + 2);
1426         if (b32) {
1427                 if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, 
1428                                 ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1429                         b32[size] = '.';
1430                         b32[size+1] = '\0';
1431                         if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1432                                 LDNS_FREE(b32);
1433                                 return out;
1434                         }
1435                 }
1436                 LDNS_FREE(b32);
1437         }
1438         return NULL;
1439 }
1440
1441 static ldns_status
1442 ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
1443 {
1444         size_t total_rdfsize = 0;
1445         size_t i, j;
1446
1447         ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
1448         for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1449                 total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
1450         }
1451         if (total_rdfsize == 0) {
1452                 ldns_buffer_printf(output, "\\# 0\n");
1453                 return ldns_buffer_status(output);
1454         }
1455         ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
1456         for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1457                 for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
1458                         ldns_buffer_printf(output, "%.2x",
1459                                         ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
1460                 }
1461         }
1462         ldns_buffer_printf(output, "\n");
1463         return ldns_buffer_status(output);
1464 }
1465
1466 ldns_status
1467 ldns_rr2buffer_str_fmt(ldns_buffer *output, 
1468                 const ldns_output_format *fmt, const ldns_rr *rr)
1469 {
1470         uint16_t i, flags;
1471         ldns_status status = LDNS_STATUS_OK;
1472         ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
1473
1474         if (fmt_st == NULL) {
1475                 fmt_st = (ldns_output_format_storage*)
1476                           ldns_output_format_default;
1477         }
1478         if (!rr) {
1479                 if (LDNS_COMMENT_NULLS & fmt_st->flags) {
1480                         ldns_buffer_printf(output, "; (null)\n");
1481                 }
1482                 return ldns_buffer_status(output);
1483         }
1484         if (ldns_rr_owner(rr)) {
1485                 status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1486         }
1487         if (status != LDNS_STATUS_OK) {
1488                 return status;
1489         }
1490
1491         /* TTL should NOT be printed if it is a question */
1492         if (!ldns_rr_is_question(rr)) {
1493                 ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
1494         }
1495
1496         ldns_buffer_printf(output, "\t");
1497         status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1498         if (status != LDNS_STATUS_OK) {
1499                 return status;
1500         }
1501         ldns_buffer_printf(output, "\t");
1502
1503         if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
1504                 return ldns_rr2buffer_str_rfc3597(output, rr);
1505         }
1506         status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1507         if (status != LDNS_STATUS_OK) {
1508                 return status;
1509         }
1510
1511         if (ldns_rr_rd_count(rr) > 0) {
1512                 ldns_buffer_printf(output, "\t");
1513         } else if (!ldns_rr_is_question(rr)) {
1514                 ldns_buffer_printf(output, "\t\\# 0");
1515         }
1516
1517         for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1518                 /* ldns_rdf2buffer_str handles NULL input fine! */
1519                 if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1520                                 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1521                                 ((/* inception  */ i == 4 &&
1522                                   ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) == 
1523                                                         LDNS_RDF_TYPE_TIME) ||
1524                                   (/* expiration */ i == 5 &&
1525                                    ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1526                                                         LDNS_RDF_TYPE_TIME) ||
1527                                   (/* signature  */ i == 8 &&
1528                                    ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1529                                                         LDNS_RDF_TYPE_B64))) {
1530
1531                         ldns_buffer_printf(output, "(null)");
1532                         status = ldns_buffer_status(output);
1533                 } else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1534                                 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1535                                 /* serial */ i == 2 &&
1536                                 ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1537                                                         LDNS_RDF_TYPE_INT32) {
1538                         ldns_buffer_printf(output, "%10lu",
1539                                 (unsigned long) ldns_read_uint32(
1540                                         ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1541                         status = ldns_buffer_status(output);
1542                 } else {
1543                         status = ldns_rdf2buffer_str_fmt(output,
1544                                         fmt, ldns_rr_rdf(rr, i));
1545                 }
1546                 if(status != LDNS_STATUS_OK)
1547                         return status;
1548                 if (i < ldns_rr_rd_count(rr) - 1) {
1549                         ldns_buffer_printf(output, " ");
1550                 }
1551         }
1552         /* per RR special comments - handy for DNSSEC types */
1553         /* check to prevent question sec. rr from
1554          * getting here */
1555         if (ldns_rr_rd_count(rr) > 0) {
1556                 switch (ldns_rr_get_type(rr)) {
1557                 case LDNS_RR_TYPE_DNSKEY:
1558                         /* if ldns_rr_rd_count(rr) > 0
1559                                 then ldns_rr_rdf(rr, 0) exists! */
1560                         if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
1561                                 break;
1562                         }
1563                         flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
1564                         ldns_buffer_printf(output, " ;{");
1565                         if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
1566                                 ldns_buffer_printf(output, "id = %u",
1567                                         (unsigned int) ldns_calc_keytag(rr));
1568                         }
1569                         if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
1570                                         (flags & LDNS_KEY_ZONE_KEY)){
1571
1572                                 if (flags & LDNS_KEY_SEP_KEY) {
1573                                         ldns_buffer_printf(output, " (ksk)");
1574                                 } else {
1575                                         ldns_buffer_printf(output, " (zsk)");
1576                                 }
1577                                 if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
1578                                         ldns_buffer_printf(output, ", ");
1579                                 }
1580                         } else if (fmt_st->flags
1581                                         & (LDNS_COMMENT_KEY_ID
1582                                                 |LDNS_COMMENT_KEY_SIZE)) {
1583                                 ldns_buffer_printf( output, ", ");
1584                         }
1585                         if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
1586                                 ldns_buffer_printf(output, "size = %db",
1587                                         ldns_rr_dnskey_key_size(rr));
1588                         }
1589                         ldns_buffer_printf(output, "}");
1590                         break;
1591                 case LDNS_RR_TYPE_RRSIG:
1592                         if ((fmt_st->flags & LDNS_COMMENT_KEY)
1593                                         && (fmt_st->flags& LDNS_COMMENT_RRSIGS)
1594                                         && ldns_rr_rdf(rr, 6) != NULL) {
1595                                 ldns_buffer_printf(output, " ;{id = %d}",
1596                                                 ldns_rdf2native_int16(
1597                                                         ldns_rr_rdf(rr, 6)));
1598                         }
1599                         break;
1600                 case LDNS_RR_TYPE_DS:
1601                         if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
1602                                         ldns_rr_rdf(rr, 3) != NULL) {
1603
1604                                 uint8_t *data = ldns_rdf_data(
1605                                                 ldns_rr_rdf(rr, 3));
1606                                 size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
1607                                 char *babble = ldns_bubblebabble(data, len);
1608                                 if(babble) {
1609                                         ldns_buffer_printf(output,
1610                                                         " ;{%s}", babble);
1611                                 }
1612                                 LDNS_FREE(babble);
1613                         }
1614                         break;
1615                 case LDNS_RR_TYPE_NSEC3:
1616                         if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
1617                                 ! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
1618                                 break;
1619                         }
1620                         ldns_buffer_printf(output, " ;{");
1621                         if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
1622                                 if (ldns_nsec3_optout(rr)) {
1623                                         ldns_buffer_printf(output,
1624                                                 " flags: optout");
1625                                 } else {
1626                                         ldns_buffer_printf(output," flags: -");
1627                                 }
1628                                 if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1629                                                 fmt_st->hashmap != NULL) {
1630                                         ldns_buffer_printf(output, ", ");
1631                                 }
1632                         }
1633                         if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1634                                         fmt_st->hashmap != NULL) {
1635                                 ldns_rbnode_t *node;
1636                                 ldns_rdf *key = ldns_dname_label(
1637                                                 ldns_rr_owner(rr), 0);
1638                                 if (key) {
1639                                         node = ldns_rbtree_search(
1640                                                 fmt_st->hashmap,
1641                                                 (void *) key);
1642                                         if (node->data) {
1643                                                 ldns_buffer_printf(output,
1644                                                         "from: ");
1645                                                 (void) ldns_rdf2buffer_str(
1646                                                         output,
1647                                                         ldns_dnssec_name_name(
1648                                                            (ldns_dnssec_name*)
1649                                                            node->data
1650                                                         ));
1651                                         }
1652                                         ldns_rdf_free(key);
1653                                 }
1654                                 key = ldns_b32_ext2dname(
1655                                                 ldns_nsec3_next_owner(rr));
1656                                 if (key) {
1657                                         node = ldns_rbtree_search(
1658                                                 fmt_st->hashmap,
1659                                                 (void *) key);
1660                                         if (node->data) {
1661                                                 ldns_buffer_printf(output,
1662                                                         " to: ");
1663                                                 (void) ldns_rdf2buffer_str(
1664                                                         output,
1665                                                         ldns_dnssec_name_name(
1666                                                            (ldns_dnssec_name*)
1667                                                            node->data
1668                                                         ));
1669                                         }
1670                                         ldns_rdf_free(key);
1671                                 }
1672                         }
1673                         ldns_buffer_printf(output, "}");
1674                         break;
1675                 default:
1676                         break;
1677
1678                 }
1679         }
1680         /* last */
1681         ldns_buffer_printf(output, "\n");
1682         return ldns_buffer_status(output);
1683 }
1684
1685 ldns_status
1686 ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
1687 {
1688         return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
1689 }
1690
1691 ldns_status
1692 ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
1693                 const ldns_output_format *fmt, const ldns_rr_list *list)
1694 {
1695         uint16_t i;
1696
1697         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
1698                 (void) ldns_rr2buffer_str_fmt(output, fmt, 
1699                                 ldns_rr_list_rr(list, i));
1700         }
1701         return ldns_buffer_status(output);
1702 }
1703
1704 ldns_status
1705 ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
1706 {
1707         return ldns_rr_list2buffer_str_fmt(
1708                         output, ldns_output_format_default, list);
1709 }
1710
1711 ldns_status
1712 ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1713 {
1714         ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
1715                                             (int) ldns_pkt_get_opcode(pkt));
1716         ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
1717                                             (int) ldns_pkt_get_rcode(pkt));
1718
1719         ldns_buffer_printf(output, ";; ->>HEADER<<- ");
1720         if (opcode) {
1721                 ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
1722         } else {
1723                 ldns_buffer_printf(output, "opcode: ?? (%u), ",
1724                                 ldns_pkt_get_opcode(pkt));
1725         }
1726         if (rcode) {
1727                 ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
1728         } else {
1729                 ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
1730         }
1731         ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
1732         ldns_buffer_printf(output, ";; flags: ");
1733
1734         if (ldns_pkt_qr(pkt)) {
1735                 ldns_buffer_printf(output, "qr ");
1736         }
1737         if (ldns_pkt_aa(pkt)) {
1738                 ldns_buffer_printf(output, "aa ");
1739         }
1740         if (ldns_pkt_tc(pkt)) {
1741                 ldns_buffer_printf(output, "tc ");
1742         }
1743         if (ldns_pkt_rd(pkt)) {
1744                 ldns_buffer_printf(output, "rd ");
1745         }
1746         if (ldns_pkt_cd(pkt)) {
1747                 ldns_buffer_printf(output, "cd ");
1748         }
1749         if (ldns_pkt_ra(pkt)) {
1750                 ldns_buffer_printf(output, "ra ");
1751         }
1752         if (ldns_pkt_ad(pkt)) {
1753                 ldns_buffer_printf(output, "ad ");
1754         }
1755         ldns_buffer_printf(output, "; ");
1756         ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
1757         ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
1758         ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
1759         ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
1760         return ldns_buffer_status(output);
1761 }
1762
1763 ldns_status
1764 ldns_pkt2buffer_str_fmt(ldns_buffer *output, 
1765                 const ldns_output_format *fmt, const ldns_pkt *pkt)
1766 {
1767         uint16_t i;
1768         ldns_status status = LDNS_STATUS_OK;
1769         char *tmp;
1770         struct timeval time;
1771         time_t time_tt;
1772
1773         if (!pkt) {
1774                 ldns_buffer_printf(output, "null");
1775                 return LDNS_STATUS_OK;
1776         }
1777
1778         if (ldns_buffer_status_ok(output)) {
1779                 status = ldns_pktheader2buffer_str(output, pkt);
1780                 if (status != LDNS_STATUS_OK) {
1781                         return status;
1782                 }
1783
1784                 ldns_buffer_printf(output, "\n");
1785
1786                 ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
1787
1788
1789                 for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
1790                         status = ldns_rr2buffer_str_fmt(output, fmt,
1791                                        ldns_rr_list_rr(
1792                                                ldns_pkt_question(pkt), i));
1793                         if (status != LDNS_STATUS_OK) {
1794                                 return status;
1795                         }
1796                 }
1797                 ldns_buffer_printf(output, "\n");
1798
1799                 ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
1800                 for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
1801                         status = ldns_rr2buffer_str_fmt(output, fmt,
1802                                        ldns_rr_list_rr(
1803                                                ldns_pkt_answer(pkt), i));
1804                         if (status != LDNS_STATUS_OK) {
1805                                 return status;
1806                         }
1807
1808                 }
1809                 ldns_buffer_printf(output, "\n");
1810
1811                 ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
1812
1813                 for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
1814                         status = ldns_rr2buffer_str_fmt(output, fmt,
1815                                        ldns_rr_list_rr(
1816                                                ldns_pkt_authority(pkt), i));
1817                         if (status != LDNS_STATUS_OK) {
1818                                 return status;
1819                         }
1820                 }
1821                 ldns_buffer_printf(output, "\n");
1822
1823                 ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
1824                 for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
1825                         status = ldns_rr2buffer_str_fmt(output, fmt,
1826                                        ldns_rr_list_rr(
1827                                                ldns_pkt_additional(pkt), i));
1828                         if (status != LDNS_STATUS_OK) {
1829                                 return status;
1830                         }
1831
1832                 }
1833                 ldns_buffer_printf(output, "\n");
1834                 /* add some futher fields */
1835                 ldns_buffer_printf(output, ";; Query time: %d msec\n",
1836                                 ldns_pkt_querytime(pkt));
1837                 if (ldns_pkt_edns(pkt)) {
1838                         ldns_buffer_printf(output,
1839                                    ";; EDNS: version %u; flags:",
1840                                    ldns_pkt_edns_version(pkt));
1841                         if (ldns_pkt_edns_do(pkt)) {
1842                                 ldns_buffer_printf(output, " do");
1843                         }
1844                         /* the extended rcode is the value set, shifted four bits,
1845                          * and or'd with the original rcode */
1846                         if (ldns_pkt_edns_extended_rcode(pkt)) {
1847                                 ldns_buffer_printf(output, " ; ext-rcode: %d",
1848                                         (ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
1849                         }
1850                         ldns_buffer_printf(output, " ; udp: %u\n",
1851                                            ldns_pkt_edns_udp_size(pkt));
1852
1853                         if (ldns_pkt_edns_data(pkt)) {
1854                                 ldns_buffer_printf(output, ";; Data: ");
1855                                 (void)ldns_rdf2buffer_str(output,
1856                                                           ldns_pkt_edns_data(pkt));
1857                                 ldns_buffer_printf(output, "\n");
1858                         }
1859                 }
1860                 if (ldns_pkt_tsig(pkt)) {
1861                         ldns_buffer_printf(output, ";; TSIG:\n;; ");
1862                         (void) ldns_rr2buffer_str_fmt(
1863                                         output, fmt, ldns_pkt_tsig(pkt));
1864                         ldns_buffer_printf(output, "\n");
1865                 }
1866                 if (ldns_pkt_answerfrom(pkt)) {
1867                         tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
1868                         ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
1869                         LDNS_FREE(tmp);
1870                 }
1871                 time = ldns_pkt_timestamp(pkt);
1872                 time_tt = (time_t)time.tv_sec;
1873                 ldns_buffer_printf(output, ";; WHEN: %s",
1874                                 (char*)ctime(&time_tt));
1875
1876                 ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
1877                                 (int)ldns_pkt_size(pkt));
1878         } else {
1879                 return ldns_buffer_status(output);
1880         }
1881         return status;
1882 }
1883
1884 ldns_status
1885 ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1886 {
1887         return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
1888 }
1889
1890
1891 #ifdef HAVE_SSL
1892 static ldns_status
1893 ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1894 {
1895         ldns_status status;
1896         size_t i;
1897         ldns_rdf *b64_bignum;
1898
1899         ldns_buffer_printf(output, "Key: ");
1900
1901         i = ldns_key_hmac_size(k);
1902         b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
1903         status = ldns_rdf2buffer_str(output, b64_bignum);
1904         ldns_rdf_deep_free(b64_bignum);
1905         ldns_buffer_printf(output, "\n");
1906         return status;
1907 }
1908 #endif
1909
1910 #if defined(HAVE_SSL) && defined(USE_GOST)
1911 static ldns_status
1912 ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
1913 {
1914         unsigned char* pp = NULL;
1915         int ret;
1916         ldns_rdf *b64_bignum;
1917         ldns_status status;
1918
1919         ldns_buffer_printf(output, "GostAsn1: ");
1920
1921         ret = i2d_PrivateKey(p, &pp);
1922         b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
1923         status = ldns_rdf2buffer_str(output, b64_bignum);
1924
1925         ldns_rdf_deep_free(b64_bignum);
1926         OPENSSL_free(pp);
1927         ldns_buffer_printf(output, "\n");
1928         return status;
1929 }
1930 #endif
1931
1932 /** print one b64 encoded bignum to a line in the keybuffer */
1933 static int
1934 ldns_print_bignum_b64_line(ldns_buffer* output, const char* label, const BIGNUM* num)
1935 {
1936         unsigned char  *bignumbuf = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1937         if(!bignumbuf) return 0;
1938
1939         ldns_buffer_printf(output, "%s: ", label);
1940         if(num) {
1941                 ldns_rdf *b64_bignum = NULL;
1942                 int i = BN_bn2bin(num, bignumbuf);
1943                 if (i > LDNS_MAX_KEYLEN) {
1944                         LDNS_FREE(bignumbuf);
1945                         return 0;
1946                 }
1947                 b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)i, bignumbuf);
1948                 if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1949                         ldns_rdf_deep_free(b64_bignum);
1950                         LDNS_FREE(bignumbuf);
1951                         return 0;
1952                 }
1953                 ldns_rdf_deep_free(b64_bignum);
1954                 ldns_buffer_printf(output, "\n");
1955         } else {
1956                 ldns_buffer_printf(output, "(Not available)\n");
1957         }
1958         LDNS_FREE(bignumbuf);
1959         return 1;
1960 }
1961
1962 ldns_status
1963 ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1964 {
1965         ldns_status status = LDNS_STATUS_OK;
1966         unsigned char  *bignum;
1967 #ifdef HAVE_SSL
1968         RSA *rsa;
1969         DSA *dsa;
1970 #endif /* HAVE_SSL */
1971
1972         if (!k) {
1973                 return LDNS_STATUS_ERR;
1974         }
1975
1976         bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1977         if (!bignum) {
1978                 return LDNS_STATUS_ERR;
1979         }
1980
1981         if (ldns_buffer_status_ok(output)) {
1982 #ifdef HAVE_SSL
1983                 switch(ldns_key_algorithm(k)) {
1984                         case LDNS_SIGN_RSASHA1:
1985                         case LDNS_SIGN_RSASHA1_NSEC3:
1986                         case LDNS_SIGN_RSASHA256:
1987                         case LDNS_SIGN_RSASHA512:
1988                         case LDNS_SIGN_RSAMD5:
1989                                 /* copied by looking at dnssec-keygen output */
1990                                 /* header */
1991                                 rsa = ldns_key_rsa_key(k);
1992
1993                                 ldns_buffer_printf(output,"Private-key-format: v1.2\n");
1994                                 switch(ldns_key_algorithm(k)) {
1995                                 case LDNS_SIGN_RSAMD5:
1996                                         ldns_buffer_printf(output,
1997                                                                     "Algorithm: %u (RSA)\n",
1998                                                                     LDNS_RSAMD5);
1999                                         break;
2000                                 case LDNS_SIGN_RSASHA1:
2001                                         ldns_buffer_printf(output,
2002                                                                     "Algorithm: %u (RSASHA1)\n",
2003                                                                     LDNS_RSASHA1);
2004                                         break;
2005                                 case LDNS_SIGN_RSASHA1_NSEC3:
2006                                         ldns_buffer_printf(output,
2007                                                                     "Algorithm: %u (RSASHA1_NSEC3)\n",
2008                                                                     LDNS_RSASHA1_NSEC3);
2009                                         break;
2010 #ifdef USE_SHA2
2011                                 case LDNS_SIGN_RSASHA256:
2012                                         ldns_buffer_printf(output,
2013                                                                     "Algorithm: %u (RSASHA256)\n",
2014                                                                     LDNS_RSASHA256);
2015                                         break;
2016                                 case LDNS_SIGN_RSASHA512:
2017                                         ldns_buffer_printf(output,
2018                                                                     "Algorithm: %u (RSASHA512)\n",
2019                                                                     LDNS_RSASHA512);
2020                                         break;
2021 #endif
2022                                 default:
2023 #ifdef STDERR_MSGS
2024                                         fprintf(stderr, "Warning: unknown signature ");
2025                                         fprintf(stderr,
2026                                                    "algorithm type %u\n",
2027                                                    ldns_key_algorithm(k));
2028 #endif
2029                                         ldns_buffer_printf(output,
2030                                                                     "Algorithm: %u (Unknown)\n",
2031                                                                     ldns_key_algorithm(k));
2032                                         break;
2033                                 }
2034
2035                                 /* print to buf, convert to bin, convert to b64,
2036                                  * print to buf */
2037
2038 #ifndef S_SPLINT_S
2039                                 if(1) {
2040                                         const BIGNUM *n=NULL, *e=NULL, *d=NULL,
2041                                                 *p=NULL, *q=NULL, *dmp1=NULL,
2042                                                 *dmq1=NULL, *iqmp=NULL;
2043 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
2044                                         n = rsa->n;
2045                                         e = rsa->e;
2046                                         d = rsa->d;
2047                                         p = rsa->p;
2048                                         q = rsa->q;
2049                                         dmp1 = rsa->dmp1;
2050                                         dmq1 = rsa->dmq1;
2051                                         iqmp = rsa->iqmp;
2052 #else
2053                                         RSA_get0_key(rsa, &n, &e, &d);
2054                                         RSA_get0_factors(rsa, &p, &q);
2055                                         RSA_get0_crt_params(rsa, &dmp1,
2056                                                 &dmq1, &iqmp);
2057 #endif
2058                                         if(!ldns_print_bignum_b64_line(output, "Modulus", n))
2059                                                 goto error;
2060                                         if(!ldns_print_bignum_b64_line(output, "PublicExponent", e))
2061                                                 goto error;
2062                                         if(!ldns_print_bignum_b64_line(output, "PrivateExponent", d))
2063                                                 goto error;
2064                                         if(!ldns_print_bignum_b64_line(output, "Prime1", p))
2065                                                 goto error;
2066                                         if(!ldns_print_bignum_b64_line(output, "Prime2", q))
2067                                                 goto error;
2068                                         if(!ldns_print_bignum_b64_line(output, "Exponent1", dmp1))
2069                                                 goto error;
2070                                         if(!ldns_print_bignum_b64_line(output, "Exponent2", dmq1))
2071                                                 goto error;
2072                                         if(!ldns_print_bignum_b64_line(output, "Coefficient", iqmp))
2073                                                 goto error;
2074                                 }
2075 #endif /* splint */
2076
2077                                 RSA_free(rsa);
2078                                 break;
2079                         case LDNS_SIGN_DSA:
2080                         case LDNS_SIGN_DSA_NSEC3:
2081                                 dsa = ldns_key_dsa_key(k);
2082
2083                                 ldns_buffer_printf(output,"Private-key-format: v1.2\n");
2084                                 if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
2085                                         ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
2086                                 } else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
2087                                         ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
2088                                 }
2089
2090                                 /* print to buf, convert to bin, convert to b64,
2091                                  * print to buf */
2092                                 if(1) {
2093                                         const BIGNUM *p=NULL, *q=NULL, *g=NULL,
2094                                                 *priv_key=NULL, *pub_key=NULL;
2095 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
2096 #ifndef S_SPLINT_S
2097                                         p = dsa->p;
2098                                         q = dsa->q;
2099                                         g = dsa->g;
2100                                         priv_key = dsa->priv_key;
2101                                         pub_key = dsa->pub_key;
2102 #endif /* splint */
2103 #else
2104                                         DSA_get0_pqg(dsa, &p, &q, &g);
2105                                         DSA_get0_key(dsa, &pub_key, &priv_key);
2106 #endif
2107                                         if(!ldns_print_bignum_b64_line(output, "Prime(p)", p))
2108                                                 goto error;
2109                                         if(!ldns_print_bignum_b64_line(output, "Subprime(q)", q))
2110                                                 goto error;
2111                                         if(!ldns_print_bignum_b64_line(output, "Base(g)", g))
2112                                                 goto error;
2113                                         if(!ldns_print_bignum_b64_line(output, "Private_value(x)", priv_key))
2114                                                 goto error;
2115                                         if(!ldns_print_bignum_b64_line(output, "Public_value(y)", pub_key))
2116                                                 goto error;
2117                                 }
2118                                 break;
2119                         case LDNS_SIGN_ECC_GOST:
2120                                 /* no format defined, use blob */
2121 #if defined(HAVE_SSL) && defined(USE_GOST)
2122                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2123                                 ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
2124                                 status = ldns_gost_key2buffer_str(output, 
2125 #ifndef S_SPLINT_S
2126                                         k->_key.key
2127 #else
2128                                         NULL
2129 #endif
2130                                 );
2131 #else
2132                                 goto error;
2133 #endif /* GOST */
2134                                 break;
2135                         case LDNS_SIGN_ECDSAP256SHA256:
2136                         case LDNS_SIGN_ECDSAP384SHA384:
2137 #ifdef USE_ECDSA
2138                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2139                                 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2140                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2141 #ifndef S_SPLINT_S
2142                                 ldns_buffer_printf(output, ")\n");
2143                                 if(k->_key.key) {
2144                                         EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2145                                         const BIGNUM* b = EC_KEY_get0_private_key(ec);
2146                                         if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2147                                                 goto error;
2148                                         /* down reference count in EC_KEY
2149                                          * its still assigned to the PKEY */
2150                                         EC_KEY_free(ec);
2151                                 }
2152 #endif /* splint */
2153 #else
2154                                 goto error;
2155 #endif /* ECDSA */
2156                                 break;
2157 #ifdef USE_ED25519
2158                         case LDNS_SIGN_ED25519:
2159                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2160                                 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2161                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2162                                 ldns_buffer_printf(output, ")\n");
2163                                 if(k->_key.key) {
2164                                         EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2165                                         const BIGNUM* b = EC_KEY_get0_private_key(ec);
2166                                         if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2167                                                 goto error;
2168                                         /* down reference count in EC_KEY
2169                                          * its still assigned to the PKEY */
2170                                         EC_KEY_free(ec);
2171                                 }
2172                                 ldns_buffer_printf(output, "\n");
2173                                 break;
2174 #endif /* USE_ED25519 */
2175 #ifdef USE_ED448
2176                         case LDNS_SIGN_ED448:
2177                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2178                                 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2179                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2180                                 ldns_buffer_printf(output, ")\n");
2181                                 if(k->_key.key) {
2182                                         EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2183                                         const BIGNUM* b = EC_KEY_get0_private_key(ec);
2184                                         if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2185                                                 goto error;
2186                                         /* down reference count in EC_KEY
2187                                          * its still assigned to the PKEY */
2188                                         EC_KEY_free(ec);
2189                                 }
2190                                 ldns_buffer_printf(output, "\n");
2191                                 break;
2192 #endif /* USE_ED448 */
2193                         case LDNS_SIGN_HMACMD5:
2194                                 /* there's not much of a format defined for TSIG */
2195                                 /* It's just a binary blob, Same for all algorithms */
2196                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2197                 ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
2198                                 status = ldns_hmac_key2buffer_str(output, k);
2199                                 break;
2200                         case LDNS_SIGN_HMACSHA1:
2201                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2202                         ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
2203                                 status = ldns_hmac_key2buffer_str(output, k);
2204                                 break;
2205                         case LDNS_SIGN_HMACSHA224:
2206                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2207                         ldns_buffer_printf(output, "Algorithm: 162 (HMAC_SHA224)\n");
2208                                 status = ldns_hmac_key2buffer_str(output, k);
2209                                 break;
2210                         case LDNS_SIGN_HMACSHA256:
2211                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2212                         ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
2213                                 status = ldns_hmac_key2buffer_str(output, k);
2214                                 break;
2215                         case LDNS_SIGN_HMACSHA384:
2216                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2217                         ldns_buffer_printf(output, "Algorithm: 164 (HMAC_SHA384)\n");
2218                                 status = ldns_hmac_key2buffer_str(output, k);
2219                                 break;
2220                         case LDNS_SIGN_HMACSHA512:
2221                         ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2222                         ldns_buffer_printf(output, "Algorithm: 165 (HMAC_SHA512)\n");
2223                                 status = ldns_hmac_key2buffer_str(output, k);
2224                                 break;
2225                 }
2226 #endif /* HAVE_SSL */
2227         } else {
2228                 LDNS_FREE(bignum);
2229                 return ldns_buffer_status(output);
2230         }
2231         LDNS_FREE(bignum);
2232         return status;
2233
2234 #ifdef HAVE_SSL
2235         /* compiles warn the label isn't used */
2236 error:
2237         LDNS_FREE(bignum);
2238         return LDNS_STATUS_ERR;
2239 #endif /* HAVE_SSL */
2240
2241 }
2242
2243 /*
2244  * Zero terminate the buffer and copy data.
2245  */
2246 char *
2247 ldns_buffer2str(ldns_buffer *buffer)
2248 {
2249         char *str;
2250
2251         /* check if buffer ends with \0, if not, and
2252            if there is space, add it */
2253         if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
2254                 if (!ldns_buffer_reserve(buffer, 1)) {
2255                         return NULL;
2256                 }
2257                 ldns_buffer_write_u8(buffer, (uint8_t) '\0');
2258                 if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
2259                         return NULL;
2260                 }
2261         }
2262
2263         str = strdup((const char *)ldns_buffer_begin(buffer));
2264         if(!str) {
2265                 return NULL;
2266         }
2267         return str;
2268 }
2269
2270 /*
2271  * Zero terminate the buffer and export data.
2272  */
2273 char *
2274 ldns_buffer_export2str(ldns_buffer *buffer)
2275 {
2276         /* Append '\0' as string terminator */
2277         if (! ldns_buffer_reserve(buffer, 1)) {
2278                 return NULL;
2279         }
2280         ldns_buffer_write_u8(buffer, 0);
2281
2282         /* reallocate memory to the size of the string and export */
2283         ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
2284         return ldns_buffer_export(buffer);
2285 }
2286
2287 char *
2288 ldns_rdf2str(const ldns_rdf *rdf)
2289 {
2290         char *result = NULL;
2291         ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2292
2293         if (!tmp_buffer) {
2294                 return NULL;
2295         }
2296         if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
2297                 /* export and return string, destroy rest */
2298                 result = ldns_buffer_export2str(tmp_buffer);
2299         }
2300         ldns_buffer_free(tmp_buffer);
2301         return result;
2302 }
2303
2304 char *
2305 ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
2306 {
2307         char *result = NULL;
2308         ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2309
2310         if (!tmp_buffer) {
2311                 return NULL;
2312         }
2313         if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
2314                         == LDNS_STATUS_OK) {
2315                 /* export and return string, destroy rest */
2316                 result = ldns_buffer_export2str(tmp_buffer);
2317         }
2318         ldns_buffer_free(tmp_buffer);
2319         return result;
2320 }
2321
2322 char *
2323 ldns_rr2str(const ldns_rr *rr)
2324 {
2325         return ldns_rr2str_fmt(ldns_output_format_default, rr);
2326 }
2327
2328 char *
2329 ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
2330 {
2331         char *result = NULL;
2332         ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2333
2334         if (!tmp_buffer) {
2335                 return NULL;
2336         }
2337         if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
2338                         == LDNS_STATUS_OK) {
2339                 /* export and return string, destroy rest */
2340                 result = ldns_buffer_export2str(tmp_buffer);
2341         }
2342
2343         ldns_buffer_free(tmp_buffer);
2344         return result;
2345 }
2346
2347 char *
2348 ldns_pkt2str(const ldns_pkt *pkt)
2349 {
2350         return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
2351 }
2352
2353 char *
2354 ldns_key2str(const ldns_key *k)
2355 {
2356         char *result = NULL;
2357         ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2358
2359         if (!tmp_buffer) {
2360                 return NULL;
2361         }
2362         if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
2363                 /* export and return string, destroy rest */
2364                 result = ldns_buffer_export2str(tmp_buffer);
2365         }
2366         ldns_buffer_free(tmp_buffer);
2367         return result;
2368 }
2369
2370 char *
2371 ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
2372 {
2373         char *result = NULL;
2374         ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2375
2376         if (!tmp_buffer) {
2377                 return NULL;
2378         }
2379         if (list) {
2380                 if (ldns_rr_list2buffer_str_fmt(
2381                                    tmp_buffer, fmt, list)
2382                                 == LDNS_STATUS_OK) {
2383                 }
2384         } else {
2385                 if (fmt == NULL) {
2386                         fmt = ldns_output_format_default;
2387                 }
2388                 if (fmt->flags & LDNS_COMMENT_NULLS) {
2389                         ldns_buffer_printf(tmp_buffer, "; (null)\n");
2390                 }
2391         }
2392
2393         /* export and return string, destroy rest */
2394         result = ldns_buffer_export2str(tmp_buffer);
2395         ldns_buffer_free(tmp_buffer);
2396         return result;
2397 }
2398
2399 char *
2400 ldns_rr_list2str(const ldns_rr_list *list)
2401 {
2402         return ldns_rr_list2str_fmt(ldns_output_format_default, list);
2403 }
2404
2405 void
2406 ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
2407 {
2408         char *str = ldns_rdf2str(rdf);
2409         if (str) {
2410                 fprintf(output, "%s", str);
2411         } else {
2412                 fprintf(output, ";Unable to convert rdf to string\n");
2413         }
2414         LDNS_FREE(str);
2415 }
2416
2417 void
2418 ldns_rr_print_fmt(FILE *output,
2419                 const ldns_output_format *fmt, const ldns_rr *rr)
2420 {
2421         char *str = ldns_rr2str_fmt(fmt, rr);
2422         if (str) {
2423                 fprintf(output, "%s", str);
2424         } else {
2425                 fprintf(output, ";Unable to convert rr to string\n");
2426         }
2427         LDNS_FREE(str);
2428 }
2429
2430 void
2431 ldns_rr_print(FILE *output, const ldns_rr *rr)
2432 {
2433         ldns_rr_print_fmt(output, ldns_output_format_default, rr);
2434 }
2435
2436 void
2437 ldns_pkt_print_fmt(FILE *output, 
2438                 const ldns_output_format *fmt, const ldns_pkt *pkt)
2439 {
2440         char *str = ldns_pkt2str_fmt(fmt, pkt);
2441         if (str) {
2442                 fprintf(output, "%s", str);
2443         } else {
2444                 fprintf(output, ";Unable to convert packet to string\n");
2445         }
2446         LDNS_FREE(str);
2447 }
2448
2449 void
2450 ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
2451 {
2452         ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
2453 }
2454
2455 void
2456 ldns_rr_list_print_fmt(FILE *output, 
2457                 const ldns_output_format *fmt, const ldns_rr_list *lst)
2458 {
2459         size_t i;
2460         for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
2461                 ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
2462         }
2463 }
2464
2465 void
2466 ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
2467 {
2468         ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
2469 }
2470
2471 void
2472 ldns_resolver_print_fmt(FILE *output, 
2473                 const ldns_output_format *fmt, const ldns_resolver *r)
2474 {
2475         uint16_t i;
2476         ldns_rdf **n;
2477         ldns_rdf **s;
2478         size_t *rtt;
2479         if (!r) {
2480                 return;
2481         }
2482         n = ldns_resolver_nameservers(r);
2483         s = ldns_resolver_searchlist(r);
2484         rtt = ldns_resolver_rtt(r);
2485
2486         fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
2487         fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
2488         fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
2489
2490         fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
2491         fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
2492         fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
2493         fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
2494         fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
2495         fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
2496         fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
2497         fprintf(output, "random: %d\n", ldns_resolver_random(r));
2498         fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
2499         fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
2500         fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
2501         fprintf(output, "trust anchors (%d listed):\n",
2502                 (int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
2503         ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
2504         fprintf(output, "tsig: %s %s\n",
2505                 ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
2506                 ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
2507         fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
2508
2509         fprintf(output, "default domain: ");
2510         ldns_rdf_print(output, ldns_resolver_domain(r));
2511         fprintf(output, "\n");
2512         fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
2513
2514         fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
2515         for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
2516                 fprintf(output, "\t");
2517                 ldns_rdf_print(output, s[i]);
2518                 fprintf(output, "\n");
2519         }
2520         fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
2521
2522         fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
2523         for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
2524                 fprintf(output, "\t");
2525                 ldns_rdf_print(output, n[i]);
2526
2527                 switch ((int)rtt[i]) {
2528                         case LDNS_RESOLV_RTT_MIN:
2529                         fprintf(output, " - reachable\n");
2530                         break;
2531                         case LDNS_RESOLV_RTT_INF:
2532                         fprintf(output, " - unreachable\n");
2533                         break;
2534                 }
2535         }
2536 }
2537
2538 void
2539 ldns_resolver_print(FILE *output, const ldns_resolver *r)
2540 {
2541         ldns_resolver_print_fmt(output, ldns_output_format_default, r);
2542 }
2543
2544 void
2545 ldns_zone_print_fmt(FILE *output, 
2546                 const ldns_output_format *fmt, const ldns_zone *z)
2547 {
2548         if(ldns_zone_soa(z))
2549                 ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
2550         ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
2551 }
2552 void
2553 ldns_zone_print(FILE *output, const ldns_zone *z)
2554 {
2555         ldns_zone_print_fmt(output, ldns_output_format_default, z);
2556 }