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