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