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