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