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