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