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