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