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