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