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