1238104Sdes/*
2238104Sdes * host2str.c
3238104Sdes *
4238104Sdes * conversion routines from the host format
5238104Sdes * to the presentation format (strings)
6238104Sdes *
7238104Sdes * a Net::DNS like library for C
8238104Sdes *
9238104Sdes * (c) NLnet Labs, 2004-2006
10238104Sdes *
11238104Sdes * See the file LICENSE for the license
12238104Sdes */
13238104Sdes#include <ldns/config.h>
14238104Sdes
15238104Sdes#include <ldns/ldns.h>
16238104Sdes
17238104Sdes#include <limits.h>
18238104Sdes
19238104Sdes#ifdef HAVE_SYS_SOCKET_H
20238104Sdes#include <sys/socket.h>
21238104Sdes#endif
22238104Sdes#ifdef HAVE_ARPA_INET_H
23238104Sdes#include <arpa/inet.h>
24238104Sdes#endif
25238104Sdes#ifdef HAVE_NETDB_H
26238104Sdes#include <netdb.h>
27238104Sdes#endif
28238104Sdes#include <time.h>
29238104Sdes#include <sys/time.h>
30238104Sdes
31238104Sdes#ifndef INET_ADDRSTRLEN
32238104Sdes#define INET_ADDRSTRLEN 16
33238104Sdes#endif
34238104Sdes#ifndef INET6_ADDRSTRLEN
35238104Sdes#define INET6_ADDRSTRLEN 46
36238104Sdes#endif
37238104Sdes
38238104Sdes/* lookup tables for standard DNS stuff  */
39238104Sdes
40238104Sdes/* Taken from RFC 2535, section 7.  */
41238104Sdesldns_lookup_table ldns_algorithms[] = {
42238104Sdes        { LDNS_RSAMD5, "RSAMD5" },
43238104Sdes        { LDNS_DH, "DH" },
44238104Sdes        { LDNS_DSA, "DSA" },
45238104Sdes        { LDNS_ECC, "ECC" },
46238104Sdes        { LDNS_RSASHA1, "RSASHA1" },
47238104Sdes        { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
48238104Sdes        { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
49238104Sdes#ifdef USE_SHA2
50238104Sdes	{ LDNS_RSASHA256, "RSASHA256"},
51238104Sdes	{ LDNS_RSASHA512, "RSASHA512"},
52238104Sdes#endif
53238104Sdes#ifdef USE_GOST
54238104Sdes	{ LDNS_ECC_GOST, "ECC-GOST"},
55238104Sdes#endif
56238104Sdes#ifdef USE_ECDSA
57238104Sdes        { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
58238104Sdes        { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
59238104Sdes#endif
60238104Sdes        { LDNS_INDIRECT, "INDIRECT" },
61238104Sdes        { LDNS_PRIVATEDNS, "PRIVATEDNS" },
62238104Sdes        { LDNS_PRIVATEOID, "PRIVATEOID" },
63238104Sdes        { 0, NULL }
64238104Sdes};
65238104Sdes
66238104Sdes/* Taken from RFC 4398  */
67238104Sdesldns_lookup_table ldns_cert_algorithms[] = {
68238104Sdes        { LDNS_CERT_PKIX, "PKIX" },
69238104Sdes        { LDNS_CERT_SPKI, "SPKI" },
70238104Sdes        { LDNS_CERT_PGP, "PGP" },
71238104Sdes        { LDNS_CERT_IPKIX, "IPKIX" },
72238104Sdes        { LDNS_CERT_ISPKI, "ISPKI" },
73238104Sdes        { LDNS_CERT_IPGP, "IPGP" },
74238104Sdes        { LDNS_CERT_ACPKIX, "ACPKIX" },
75238104Sdes        { LDNS_CERT_IACPKIX, "IACPKIX" },
76238104Sdes        { LDNS_CERT_URI, "URI" },
77238104Sdes        { LDNS_CERT_OID, "OID" },
78238104Sdes        { 0, NULL }
79238104Sdes};
80238104Sdes
81238104Sdes/* classes  */
82238104Sdesldns_lookup_table ldns_rr_classes[] = {
83238104Sdes        { LDNS_RR_CLASS_IN, "IN" },
84238104Sdes        { LDNS_RR_CLASS_CH, "CH" },
85238104Sdes        { LDNS_RR_CLASS_HS, "HS" },
86238104Sdes        { LDNS_RR_CLASS_NONE, "NONE" },
87238104Sdes        { LDNS_RR_CLASS_ANY, "ANY" },
88238104Sdes        { 0, NULL }
89238104Sdes};
90238104Sdes
91238104Sdes/* if these are used elsewhere */
92238104Sdesldns_lookup_table ldns_rcodes[] = {
93238104Sdes        { LDNS_RCODE_NOERROR, "NOERROR" },
94238104Sdes        { LDNS_RCODE_FORMERR, "FORMERR" },
95238104Sdes        { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
96238104Sdes        { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
97238104Sdes        { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
98238104Sdes        { LDNS_RCODE_REFUSED, "REFUSED" },
99238104Sdes        { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
100238104Sdes        { LDNS_RCODE_YXRRSET, "YXRRSET" },
101238104Sdes        { LDNS_RCODE_NXRRSET, "NXRRSET" },
102238104Sdes        { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
103238104Sdes        { LDNS_RCODE_NOTZONE, "NOTZONE" },
104238104Sdes        { 0, NULL }
105238104Sdes};
106238104Sdes
107238104Sdesldns_lookup_table ldns_opcodes[] = {
108238104Sdes        { LDNS_PACKET_QUERY, "QUERY" },
109238104Sdes        { LDNS_PACKET_IQUERY, "IQUERY" },
110238104Sdes        { LDNS_PACKET_STATUS, "STATUS" },
111238104Sdes	{ LDNS_PACKET_NOTIFY, "NOTIFY" },
112238104Sdes	{ LDNS_PACKET_UPDATE, "UPDATE" },
113238104Sdes        { 0, NULL }
114238104Sdes};
115238104Sdes
116238104Sdesconst ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
117238104Sdesconst ldns_output_format  *ldns_output_format_nocomments
118238104Sdes			= &ldns_output_format_nocomments_record;
119238104Sdesconst ldns_output_format   ldns_output_format_onlykeyids_record = {
120238104Sdes	LDNS_COMMENT_KEY, NULL
121238104Sdes};
122238104Sdesconst ldns_output_format  *ldns_output_format_onlykeyids
123238104Sdes			= &ldns_output_format_onlykeyids_record;
124238104Sdesconst ldns_output_format  *ldns_output_format_default
125238104Sdes			= &ldns_output_format_onlykeyids_record;
126246854Sdes
127238104Sdesconst ldns_output_format   ldns_output_format_bubblebabble_record = {
128238104Sdes	LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
129238104Sdes};
130238104Sdesconst ldns_output_format  *ldns_output_format_bubblebabble
131238104Sdes			= &ldns_output_format_bubblebabble_record;
132238104Sdes
133238104Sdesldns_status
134238104Sdesldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
135238104Sdes{
136238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
137238104Sdes	if (lt && lt->name) {
138238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
139238104Sdes	} else {
140238104Sdes		ldns_buffer_printf(output, "OPCODE%u", opcode);
141238104Sdes	}
142238104Sdes	return ldns_buffer_status(output);
143238104Sdes}
144238104Sdes
145238104Sdesldns_status
146238104Sdesldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
147238104Sdes{
148238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
149238104Sdes	if (lt && lt->name) {
150238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
151238104Sdes	} else {
152238104Sdes		ldns_buffer_printf(output, "RCODE%u", rcode);
153238104Sdes	}
154238104Sdes	return ldns_buffer_status(output);
155238104Sdes}
156238104Sdes
157238104Sdesldns_status
158238104Sdesldns_algorithm2buffer_str(ldns_buffer *output,
159238104Sdes                          ldns_algorithm algorithm)
160238104Sdes{
161238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
162238104Sdes	                                          algorithm);
163238104Sdes	if (lt && lt->name) {
164238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
165238104Sdes	} else {
166238104Sdes		ldns_buffer_printf(output, "ALG%u", algorithm);
167238104Sdes	}
168238104Sdes	return ldns_buffer_status(output);
169238104Sdes}
170238104Sdes
171238104Sdesldns_status
172238104Sdesldns_cert_algorithm2buffer_str(ldns_buffer *output,
173238104Sdes                               ldns_cert_algorithm cert_algorithm)
174238104Sdes{
175238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
176238104Sdes	                                          cert_algorithm);
177238104Sdes	if (lt && lt->name) {
178238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
179238104Sdes	} else {
180238104Sdes		ldns_buffer_printf(output, "CERT_ALG%u",
181238104Sdes		                   cert_algorithm);
182238104Sdes	}
183238104Sdes	return ldns_buffer_status(output);
184238104Sdes}
185238104Sdes
186238104Sdeschar *
187238104Sdesldns_pkt_opcode2str(ldns_pkt_opcode opcode)
188238104Sdes{
189238104Sdes	char *str;
190238104Sdes	ldns_buffer *buf;
191238104Sdes
192238104Sdes	buf = ldns_buffer_new(12);
193238104Sdes	if (!buf) {
194238104Sdes		return NULL;
195238104Sdes	}
196238104Sdes
197238104Sdes	str = NULL;
198238104Sdes	if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
199246854Sdes		str = ldns_buffer_export2str(buf);
200238104Sdes	}
201238104Sdes
202238104Sdes	ldns_buffer_free(buf);
203238104Sdes	return str;
204238104Sdes}
205238104Sdes
206238104Sdeschar *
207238104Sdesldns_pkt_rcode2str(ldns_pkt_rcode rcode)
208238104Sdes{
209238104Sdes	char *str;
210238104Sdes	ldns_buffer *buf;
211238104Sdes
212238104Sdes	buf = ldns_buffer_new(10);
213238104Sdes	if (!buf) {
214238104Sdes		return NULL;
215238104Sdes	}
216238104Sdes
217238104Sdes	str = NULL;
218238104Sdes	if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
219246854Sdes		str = ldns_buffer_export2str(buf);
220238104Sdes	}
221238104Sdes
222238104Sdes	ldns_buffer_free(buf);
223238104Sdes	return str;
224238104Sdes}
225238104Sdes
226238104Sdeschar *
227238104Sdesldns_pkt_algorithm2str(ldns_algorithm algorithm)
228238104Sdes{
229238104Sdes	char *str;
230238104Sdes	ldns_buffer *buf;
231238104Sdes
232238104Sdes	buf = ldns_buffer_new(10);
233238104Sdes	if (!buf) {
234238104Sdes		return NULL;
235238104Sdes	}
236238104Sdes
237238104Sdes	str = NULL;
238238104Sdes	if (ldns_algorithm2buffer_str(buf, algorithm)
239238104Sdes	    == LDNS_STATUS_OK) {
240246854Sdes		str = ldns_buffer_export2str(buf);
241238104Sdes	}
242238104Sdes
243238104Sdes	ldns_buffer_free(buf);
244238104Sdes	return str;
245238104Sdes}
246238104Sdes
247238104Sdeschar *
248238104Sdesldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
249238104Sdes{
250238104Sdes	char *str;
251238104Sdes	ldns_buffer *buf;
252238104Sdes
253238104Sdes	buf = ldns_buffer_new(10);
254238104Sdes	if (!buf) {
255238104Sdes		return NULL;
256238104Sdes	}
257238104Sdes
258238104Sdes	str = NULL;
259238104Sdes	if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
260238104Sdes	    == LDNS_STATUS_OK) {
261246854Sdes		str = ldns_buffer_export2str(buf);
262238104Sdes	}
263238104Sdes
264238104Sdes	ldns_buffer_free(buf);
265238104Sdes	return str;
266238104Sdes}
267238104Sdes
268238104Sdes
269238104Sdes/* do NOT pass compressed data here :p */
270238104Sdesldns_status
271238104Sdesldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
272238104Sdes{
273238104Sdes	/* can we do with 1 pos var? or without at all? */
274238104Sdes	uint8_t src_pos = 0;
275238104Sdes	uint8_t len;
276238104Sdes	uint8_t *data;
277238104Sdes	uint8_t i;
278238104Sdes	unsigned char c;
279238104Sdes
280238104Sdes	data = (uint8_t*)ldns_rdf_data(dname);
281238104Sdes	len = data[src_pos];
282238104Sdes
283238104Sdes	if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
284238104Sdes		/* too large, return */
285238104Sdes		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
286238104Sdes	}
287238104Sdes
288238104Sdes	/* special case: root label */
289238104Sdes	if (1 == ldns_rdf_size(dname)) {
290238104Sdes		ldns_buffer_printf(output, ".");
291238104Sdes	} else {
292238104Sdes		while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
293238104Sdes			src_pos++;
294238104Sdes			for(i = 0; i < len; i++) {
295238104Sdes				/* paranoia check for various 'strange'
296238104Sdes				   characters in dnames
297238104Sdes				*/
298238104Sdes				c = (unsigned char) data[src_pos];
299238104Sdes				if(c == '.' || c == ';' ||
300238104Sdes				   c == '(' || c == ')' ||
301238104Sdes				   c == '\\') {
302238104Sdes					ldns_buffer_printf(output, "\\%c",
303238104Sdes							data[src_pos]);
304238104Sdes				} else if (!(isascii(c) && isgraph(c))) {
305238104Sdes					ldns_buffer_printf(output, "\\%03u",
306238104Sdes						        data[src_pos]);
307238104Sdes				} else {
308238104Sdes					ldns_buffer_printf(output, "%c", data[src_pos]);
309238104Sdes				}
310238104Sdes				src_pos++;
311238104Sdes			}
312238104Sdes
313238104Sdes			if (src_pos < ldns_rdf_size(dname)) {
314238104Sdes				ldns_buffer_printf(output, ".");
315238104Sdes			}
316238104Sdes			len = data[src_pos];
317238104Sdes		}
318238104Sdes	}
319238104Sdes	return ldns_buffer_status(output);
320238104Sdes}
321238104Sdes
322238104Sdesldns_status
323238104Sdesldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
324238104Sdes{
325238104Sdes	uint8_t data = ldns_rdf_data(rdf)[0];
326238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
327238104Sdes	return ldns_buffer_status(output);
328238104Sdes}
329238104Sdes
330238104Sdesldns_status
331238104Sdesldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
332238104Sdes{
333238104Sdes	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
334238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
335238104Sdes	return ldns_buffer_status(output);
336238104Sdes}
337238104Sdes
338238104Sdesldns_status
339238104Sdesldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
340238104Sdes{
341238104Sdes	uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
342238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
343238104Sdes	return ldns_buffer_status(output);
344238104Sdes}
345238104Sdes
346238104Sdesldns_status
347238104Sdesldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
348238104Sdes{
349238104Sdes	/* create a YYYYMMDDHHMMSS string if possible */
350238104Sdes	struct tm tm;
351238104Sdes	char date_buf[16];
352238104Sdes
353238104Sdes	memset(&tm, 0, sizeof(tm));
354238104Sdes	if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
355238104Sdes	    && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
356238104Sdes		ldns_buffer_printf(output, "%s", date_buf);
357238104Sdes	}
358238104Sdes	return ldns_buffer_status(output);
359238104Sdes}
360238104Sdes
361238104Sdesldns_status
362238104Sdesldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
363238104Sdes{
364238104Sdes	char str[INET_ADDRSTRLEN];
365238104Sdes
366238104Sdes	if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
367238104Sdes		ldns_buffer_printf(output, "%s", str);
368238104Sdes	}
369238104Sdes	return ldns_buffer_status(output);
370238104Sdes}
371238104Sdes
372238104Sdesldns_status
373238104Sdesldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
374238104Sdes{
375238104Sdes	char str[INET6_ADDRSTRLEN];
376238104Sdes
377238104Sdes	if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
378238104Sdes		ldns_buffer_printf(output, "%s", str);
379238104Sdes	}
380238104Sdes
381238104Sdes	return ldns_buffer_status(output);
382238104Sdes}
383238104Sdes
384238104Sdesldns_status
385238104Sdesldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
386238104Sdes{
387238104Sdes	const uint8_t *data = ldns_rdf_data(rdf);
388238104Sdes	uint8_t length = data[0];
389238104Sdes	size_t i;
390238104Sdes
391238104Sdes	ldns_buffer_printf(output, "\"");
392238104Sdes	for (i = 1; i <= length; ++i) {
393238104Sdes		char ch = (char) data[i];
394238104Sdes		if (isprint((int)ch) || ch=='\t') {
395238104Sdes			if (ch=='\"'||ch=='\\')
396238104Sdes				ldns_buffer_printf(output, "\\%c", ch);
397238104Sdes			else
398238104Sdes				ldns_buffer_printf(output, "%c", ch);
399238104Sdes		} else {
400238104Sdes			ldns_buffer_printf(output, "\\%03u",
401238104Sdes                                (unsigned)(uint8_t) ch);
402238104Sdes		}
403238104Sdes	}
404238104Sdes	ldns_buffer_printf(output, "\"");
405238104Sdes	return ldns_buffer_status(output);
406238104Sdes}
407238104Sdes
408238104Sdesldns_status
409238104Sdesldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
410238104Sdes{
411238104Sdes	size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
412238104Sdes	char *b64 = LDNS_XMALLOC(char, size);
413238104Sdes	if(!b64) return LDNS_STATUS_MEM_ERR;
414238104Sdes	if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
415238104Sdes		ldns_buffer_printf(output, "%s", b64);
416238104Sdes	}
417238104Sdes	LDNS_FREE(b64);
418238104Sdes	return ldns_buffer_status(output);
419238104Sdes}
420238104Sdes
421238104Sdesldns_status
422238104Sdesldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
423238104Sdes{
424238104Sdes	size_t size;
425238104Sdes	char *b32;
426238104Sdes	if(ldns_rdf_size(rdf) == 0)
427238104Sdes		return LDNS_STATUS_OK;
428238104Sdes        /* remove -1 for the b32-hash-len octet */
429238104Sdes	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
430238104Sdes        /* add one for the end nul for the string */
431238104Sdes	b32 = LDNS_XMALLOC(char, size + 1);
432238104Sdes	if(!b32) return LDNS_STATUS_MEM_ERR;
433238104Sdes	size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
434238104Sdes		ldns_rdf_size(rdf) - 1, b32, size+1);
435238104Sdes	if (size > 0) {
436238104Sdes		ldns_buffer_printf(output, "%s", b32);
437238104Sdes	}
438238104Sdes	LDNS_FREE(b32);
439238104Sdes	return ldns_buffer_status(output);
440238104Sdes}
441238104Sdes
442238104Sdesldns_status
443238104Sdesldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
444238104Sdes{
445238104Sdes	size_t i;
446238104Sdes	for (i = 0; i < ldns_rdf_size(rdf); i++) {
447238104Sdes		ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
448238104Sdes	}
449238104Sdes
450238104Sdes	return ldns_buffer_status(output);
451238104Sdes}
452238104Sdes
453238104Sdesldns_status
454238104Sdesldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
455238104Sdes{
456238104Sdes        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
457238104Sdes	const ldns_rr_descriptor *descriptor;
458238104Sdes
459238104Sdes	descriptor = ldns_rr_descript(data);
460238104Sdes	if (descriptor && descriptor->_name) {
461238104Sdes		ldns_buffer_printf(output, "%s", descriptor->_name);
462238104Sdes	} else {
463238104Sdes		ldns_buffer_printf(output, "TYPE%u", data);
464238104Sdes	}
465238104Sdes	return ldns_buffer_status(output);
466238104Sdes}
467238104Sdes
468238104Sdesldns_status
469238104Sdesldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
470238104Sdes{
471238104Sdes	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
472238104Sdes	ldns_lookup_table *lt;
473238104Sdes
474238104Sdes 	lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
475238104Sdes	if (lt) {
476238104Sdes		ldns_buffer_printf(output, "\t%s", lt->name);
477238104Sdes	} else {
478238104Sdes		ldns_buffer_printf(output, "\tCLASS%d", data);
479238104Sdes	}
480238104Sdes	return ldns_buffer_status(output);
481238104Sdes}
482238104Sdes
483238104Sdesldns_status
484238104Sdesldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
485238104Sdes{
486238104Sdes        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
487238104Sdes	ldns_lookup_table *lt;
488238104Sdes 	lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
489238104Sdes	if (lt) {
490238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
491238104Sdes	} else {
492238104Sdes		ldns_buffer_printf(output, "%d", data);
493238104Sdes	}
494238104Sdes	return ldns_buffer_status(output);
495238104Sdes}
496238104Sdes
497238104Sdesldns_status
498238104Sdesldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
499238104Sdes{
500238104Sdes	/* don't use algorithm mnemonics in the presentation format
501238104Sdes	   this kind of got sneaked into the rfc's */
502238104Sdes        uint8_t data = ldns_rdf_data(rdf)[0];
503238104Sdes		ldns_buffer_printf(output, "%d", data);
504238104Sdes	return ldns_buffer_status(output);
505238104Sdes}
506238104Sdes
507238104Sdesstatic void
508238104Sdesloc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
509238104Sdes{
510238104Sdes	uint8_t i;
511238104Sdes	/* is it 0.<two digits> ? */
512238104Sdes	if(exponent < 2) {
513238104Sdes		if(exponent == 1)
514238104Sdes			mantissa *= 10;
515238104Sdes		ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
516238104Sdes		return;
517238104Sdes	}
518238104Sdes	/* always <digit><string of zeros> */
519238104Sdes	ldns_buffer_printf(output, "%d", (int)mantissa);
520238104Sdes	for(i=0; i<exponent-2; i++)
521238104Sdes		ldns_buffer_printf(output, "0");
522238104Sdes}
523238104Sdes
524238104Sdesldns_status
525238104Sdesldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
526238104Sdes{
527238104Sdes	const ldns_rr_descriptor *descriptor;
528238104Sdes
529238104Sdes	descriptor = ldns_rr_descript(type);
530238104Sdes
531238104Sdes	if (descriptor && descriptor->_name) {
532238104Sdes		ldns_buffer_printf(output, "%s", descriptor->_name);
533238104Sdes	} else {
534238104Sdes		/* exceptions for pseudotypes */
535238104Sdes		switch (type) {
536238104Sdes			case LDNS_RR_TYPE_IXFR:
537238104Sdes				ldns_buffer_printf(output, "IXFR");
538238104Sdes				break;
539238104Sdes			case LDNS_RR_TYPE_AXFR:
540238104Sdes				ldns_buffer_printf(output, "AXFR");
541238104Sdes				break;
542238104Sdes			case LDNS_RR_TYPE_MAILA:
543238104Sdes				ldns_buffer_printf(output, "MAILA");
544238104Sdes				break;
545238104Sdes			case LDNS_RR_TYPE_MAILB:
546238104Sdes				ldns_buffer_printf(output, "MAILB");
547238104Sdes				break;
548238104Sdes			case LDNS_RR_TYPE_ANY:
549238104Sdes				ldns_buffer_printf(output, "ANY");
550238104Sdes				break;
551238104Sdes			default:
552238104Sdes				ldns_buffer_printf(output, "TYPE%u", type);
553238104Sdes		}
554238104Sdes	}
555238104Sdes	return ldns_buffer_status(output);
556238104Sdes}
557238104Sdes
558238104Sdeschar *
559238104Sdesldns_rr_type2str(const ldns_rr_type type)
560238104Sdes{
561238104Sdes	char *str;
562238104Sdes	ldns_buffer *buf;
563238104Sdes
564238104Sdes	buf = ldns_buffer_new(10);
565238104Sdes	if (!buf) {
566238104Sdes		return NULL;
567238104Sdes	}
568238104Sdes
569238104Sdes	str = NULL;
570238104Sdes	if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
571246854Sdes		str = ldns_buffer_export2str(buf);
572238104Sdes	}
573238104Sdes
574238104Sdes	ldns_buffer_free(buf);
575238104Sdes	return str;
576238104Sdes}
577238104Sdes
578238104Sdes
579238104Sdesldns_status
580238104Sdesldns_rr_class2buffer_str(ldns_buffer *output,
581238104Sdes                         const ldns_rr_class klass)
582238104Sdes{
583238104Sdes	ldns_lookup_table *lt;
584238104Sdes
585238104Sdes	lt = ldns_lookup_by_id(ldns_rr_classes, klass);
586238104Sdes	if (lt) {
587238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
588238104Sdes	} else {
589238104Sdes		ldns_buffer_printf(output, "CLASS%d", klass);
590238104Sdes	}
591238104Sdes	return ldns_buffer_status(output);
592238104Sdes}
593238104Sdes
594238104Sdeschar *
595238104Sdesldns_rr_class2str(const ldns_rr_class klass)
596238104Sdes{
597238104Sdes	ldns_buffer *buf;
598238104Sdes	char *str;
599238104Sdes
600238104Sdes	buf = ldns_buffer_new(10);
601238104Sdes	if (!buf) {
602238104Sdes		return NULL;
603238104Sdes	}
604238104Sdes
605238104Sdes	str = NULL;
606238104Sdes	if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
607246854Sdes		str = ldns_buffer_export2str(buf);
608238104Sdes	}
609238104Sdes	ldns_buffer_free(buf);
610238104Sdes	return str;
611238104Sdes}
612238104Sdes
613238104Sdesldns_status
614238104Sdesldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
615238104Sdes{
616238104Sdes	/* we could do checking (ie degrees < 90 etc)? */
617238104Sdes	uint8_t version = ldns_rdf_data(rdf)[0];
618238104Sdes	uint8_t size;
619238104Sdes	uint8_t horizontal_precision;
620238104Sdes	uint8_t vertical_precision;
621238104Sdes	uint32_t longitude;
622238104Sdes	uint32_t latitude;
623238104Sdes	uint32_t altitude;
624238104Sdes	char northerness;
625238104Sdes	char easterness;
626238104Sdes	uint32_t h;
627238104Sdes	uint32_t m;
628238104Sdes	double s;
629238104Sdes
630238104Sdes	uint32_t equator = (uint32_t) ldns_power(2, 31);
631238104Sdes
632238104Sdes	if (version == 0) {
633238104Sdes		size = ldns_rdf_data(rdf)[1];
634238104Sdes		horizontal_precision = ldns_rdf_data(rdf)[2];
635238104Sdes		vertical_precision = ldns_rdf_data(rdf)[3];
636238104Sdes
637238104Sdes		latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
638238104Sdes		longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
639238104Sdes		altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
640238104Sdes
641238104Sdes		if (latitude > equator) {
642238104Sdes			northerness = 'N';
643238104Sdes			latitude = latitude - equator;
644238104Sdes		} else {
645238104Sdes			northerness = 'S';
646238104Sdes			latitude = equator - latitude;
647238104Sdes		}
648238104Sdes		h = latitude / (1000 * 60 * 60);
649238104Sdes		latitude = latitude % (1000 * 60 * 60);
650238104Sdes		m = latitude / (1000 * 60);
651238104Sdes		latitude = latitude % (1000 * 60);
652238104Sdes		s = (double) latitude / 1000.0;
653238104Sdes		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
654238104Sdes			h, m, s, northerness);
655238104Sdes
656238104Sdes		if (longitude > equator) {
657238104Sdes			easterness = 'E';
658238104Sdes			longitude = longitude - equator;
659238104Sdes		} else {
660238104Sdes			easterness = 'W';
661238104Sdes			longitude = equator - longitude;
662238104Sdes		}
663238104Sdes		h = longitude / (1000 * 60 * 60);
664238104Sdes		longitude = longitude % (1000 * 60 * 60);
665238104Sdes		m = longitude / (1000 * 60);
666238104Sdes		longitude = longitude % (1000 * 60);
667238104Sdes		s = (double) longitude / (1000.0);
668238104Sdes		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
669238104Sdes			h, m, s, easterness);
670238104Sdes
671238104Sdes
672238104Sdes        s = ((double) altitude) / 100;
673238104Sdes        s -= 100000;
674238104Sdes
675238104Sdes		if(altitude%100 != 0)
676238104Sdes			ldns_buffer_printf(output, "%.2f", s);
677238104Sdes        else
678238104Sdes			ldns_buffer_printf(output, "%.0f", s);
679238104Sdes
680238104Sdes		ldns_buffer_printf(output, "m ");
681238104Sdes
682238104Sdes		loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
683238104Sdes		ldns_buffer_printf(output, "m ");
684238104Sdes
685238104Sdes		loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
686238104Sdes			horizontal_precision & 0x0f);
687238104Sdes		ldns_buffer_printf(output, "m ");
688238104Sdes
689238104Sdes		loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
690238104Sdes			vertical_precision & 0x0f);
691238104Sdes		ldns_buffer_printf(output, "m");
692238104Sdes
693238104Sdes		return ldns_buffer_status(output);
694238104Sdes	} else {
695238104Sdes		return ldns_rdf2buffer_str_hex(output, rdf);
696238104Sdes	}
697238104Sdes}
698238104Sdes
699238104Sdesldns_status
700238104Sdesldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
701238104Sdes{
702238104Sdes	ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
703238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
704238104Sdes}
705238104Sdes
706238104Sdesldns_status
707238104Sdesldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
708238104Sdes{
709238104Sdes	ldns_buffer_printf(output, "0x");
710238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
711238104Sdes}
712238104Sdes
713238104Sdesldns_status
714238104Sdesldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
715238104Sdes{
716238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
717238104Sdes}
718238104Sdes
719238104Sdesldns_status
720238104Sdesldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
721238104Sdes{
722238104Sdes	/* protocol, followed by bitmap of services */
723238104Sdes	struct protoent *protocol;
724238104Sdes	char *proto_name = NULL;
725238104Sdes	uint8_t protocol_nr;
726238104Sdes	struct servent *service;
727238104Sdes	uint16_t current_service;
728238104Sdes
729238104Sdes	protocol_nr = ldns_rdf_data(rdf)[0];
730238104Sdes	protocol = getprotobynumber((int) protocol_nr);
731238104Sdes	if (protocol && (protocol->p_name != NULL)) {
732238104Sdes		proto_name = protocol->p_name;
733238104Sdes		ldns_buffer_printf(output, "%s ", protocol->p_name);
734238104Sdes	} else {
735238104Sdes		ldns_buffer_printf(output, "%u ", protocol_nr);
736238104Sdes	}
737238104Sdes
738238104Sdes#ifdef HAVE_ENDPROTOENT
739238104Sdes	endprotoent();
740238104Sdes#endif
741238104Sdes
742238104Sdes	for (current_service = 0;
743238104Sdes	     current_service < ldns_rdf_size(rdf) * 7; current_service++) {
744238104Sdes		if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
745238104Sdes			service = getservbyport((int) htons(current_service),
746238104Sdes			                        proto_name);
747238104Sdes			if (service && service->s_name) {
748238104Sdes				ldns_buffer_printf(output, "%s ", service->s_name);
749238104Sdes			} else {
750238104Sdes				ldns_buffer_printf(output, "%u ", current_service);
751238104Sdes			}
752238104Sdes#ifdef HAVE_ENDSERVENT
753238104Sdes			endservent();
754238104Sdes#endif
755238104Sdes		}
756238104Sdes	}
757238104Sdes	return ldns_buffer_status(output);
758238104Sdes}
759238104Sdes
760238104Sdesldns_status
761238104Sdesldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
762238104Sdes{
763238104Sdes	/* Note: this code is duplicated in higher.c in
764238104Sdes	 * ldns_nsec_type_check() function
765238104Sdes	 */
766238104Sdes	uint8_t window_block_nr;
767238104Sdes	uint8_t bitmap_length;
768238104Sdes	uint16_t type;
769238104Sdes	uint16_t pos = 0;
770238104Sdes	uint16_t bit_pos;
771238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
772238104Sdes	const ldns_rr_descriptor *descriptor;
773238104Sdes
774238104Sdes	while(pos < ldns_rdf_size(rdf)) {
775238104Sdes		window_block_nr = data[pos];
776238104Sdes		bitmap_length = data[pos + 1];
777238104Sdes		pos += 2;
778238104Sdes
779238104Sdes		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
780238104Sdes			if (ldns_get_bit(&data[pos], bit_pos)) {
781238104Sdes				type = 256 * (uint16_t) window_block_nr + bit_pos;
782238104Sdes				descriptor = ldns_rr_descript(type);
783238104Sdes
784238104Sdes				if (descriptor && descriptor->_name) {
785238104Sdes					ldns_buffer_printf(output, "%s ",
786238104Sdes							descriptor->_name);
787238104Sdes				} else {
788238104Sdes					ldns_buffer_printf(output, "TYPE%u ", type);
789238104Sdes				}
790238104Sdes			}
791238104Sdes		}
792238104Sdes
793238104Sdes		pos += (uint16_t) bitmap_length;
794238104Sdes	}
795238104Sdes
796238104Sdes	return ldns_buffer_status(output);
797238104Sdes}
798238104Sdes
799238104Sdesldns_status
800238104Sdesldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
801238104Sdes{
802238104Sdes	uint8_t salt_length;
803238104Sdes	uint8_t salt_pos;
804238104Sdes
805238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
806238104Sdes
807238104Sdes        if(ldns_rdf_size(rdf) == 0) {
808238104Sdes                output->_status = LDNS_STATUS_ERR;
809238104Sdes	        return ldns_buffer_status(output);
810238104Sdes        }
811238104Sdes	salt_length = data[0];
812238104Sdes	/* from now there are variable length entries so remember pos */
813238104Sdes	if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
814238104Sdes		ldns_buffer_printf(output, "- ");
815238104Sdes	} else {
816238104Sdes		for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
817238104Sdes			ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
818238104Sdes		}
819238104Sdes		ldns_buffer_printf(output, " ");
820238104Sdes	}
821238104Sdes
822238104Sdes	return ldns_buffer_status(output);
823238104Sdes}
824238104Sdes
825238104Sdesldns_status
826238104Sdesldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
827238104Sdes{
828238104Sdes	/* period is the number of seconds */
829238104Sdes	uint32_t p = ldns_read_uint32(ldns_rdf_data(rdf));
830238104Sdes	ldns_buffer_printf(output, "%u", p);
831238104Sdes	return ldns_buffer_status(output);
832238104Sdes}
833238104Sdes
834238104Sdesldns_status
835238104Sdesldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
836238104Sdes{
837238104Sdes	/* tsigtime is 48 bits network order unsigned integer */
838238104Sdes	uint64_t tsigtime = 0;
839238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
840238104Sdes
841238104Sdes	if (ldns_rdf_size(rdf) != 6) {
842238104Sdes		return LDNS_STATUS_ERR;
843238104Sdes	}
844238104Sdes
845238104Sdes	tsigtime = ldns_read_uint16(data);
846238104Sdes	tsigtime *= 65536;
847238104Sdes	tsigtime += ldns_read_uint16(data+2);
848238104Sdes	tsigtime *= 65536;
849238104Sdes
850238104Sdes	ldns_buffer_printf(output, "%llu ", tsigtime);
851238104Sdes
852238104Sdes	return ldns_buffer_status(output);
853238104Sdes}
854238104Sdes
855238104Sdesldns_status
856238104Sdesldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
857238104Sdes{
858238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
859238104Sdes	uint16_t address_family;
860238104Sdes	uint8_t prefix;
861238104Sdes	bool negation;
862238104Sdes	uint8_t adf_length;
863238104Sdes	size_t i;
864238104Sdes	size_t pos = 0;
865238104Sdes
866238104Sdes	while (pos < (unsigned int) ldns_rdf_size(rdf)) {
867238104Sdes                if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
868238104Sdes                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
869238104Sdes		address_family = ldns_read_uint16(&data[pos]);
870238104Sdes		prefix = data[pos + 2];
871238104Sdes		negation = data[pos + 3] & LDNS_APL_NEGATION;
872238104Sdes		adf_length = data[pos + 3] & LDNS_APL_MASK;
873238104Sdes		if (address_family == LDNS_APL_IP4) {
874238104Sdes			/* check if prefix < 32? */
875238104Sdes			if (negation) {
876238104Sdes				ldns_buffer_printf(output, "!");
877238104Sdes			}
878238104Sdes			ldns_buffer_printf(output, "%u:", address_family);
879238104Sdes			/* address is variable length 0 - 4 */
880238104Sdes			for (i = 0; i < 4; i++) {
881238104Sdes				if (i > 0) {
882238104Sdes					ldns_buffer_printf(output, ".");
883238104Sdes				}
884238104Sdes				if (i < (unsigned short) adf_length) {
885238104Sdes                                        if(pos+i+4 >= ldns_rdf_size(rdf))
886238104Sdes                                                return LDNS_STATUS_SYNTAX_RDATA_ERR;
887238104Sdes					ldns_buffer_printf(output, "%d",
888238104Sdes					                   data[pos + i + 4]);
889238104Sdes				} else {
890238104Sdes					ldns_buffer_printf(output, "0");
891238104Sdes				}
892238104Sdes			}
893238104Sdes			ldns_buffer_printf(output, "/%u ", prefix);
894238104Sdes		} else if (address_family == LDNS_APL_IP6) {
895238104Sdes			/* check if prefix < 128? */
896238104Sdes			if (negation) {
897238104Sdes				ldns_buffer_printf(output, "!");
898238104Sdes			}
899238104Sdes			ldns_buffer_printf(output, "%u:", address_family);
900238104Sdes			/* address is variable length 0 - 16 */
901238104Sdes			for (i = 0; i < 16; i++) {
902238104Sdes				if (i % 2 == 0 && i > 0) {
903238104Sdes					ldns_buffer_printf(output, ":");
904238104Sdes				}
905238104Sdes				if (i < (unsigned short) adf_length) {
906238104Sdes                                        if(pos+i+4 >= ldns_rdf_size(rdf))
907238104Sdes                                                return LDNS_STATUS_SYNTAX_RDATA_ERR;
908238104Sdes					ldns_buffer_printf(output, "%02x",
909238104Sdes					                   data[pos + i + 4]);
910238104Sdes				} else {
911238104Sdes					ldns_buffer_printf(output, "00");
912238104Sdes				}
913238104Sdes			}
914238104Sdes			ldns_buffer_printf(output, "/%u ", prefix);
915238104Sdes
916238104Sdes		} else {
917238104Sdes			/* unknown address family */
918238104Sdes			ldns_buffer_printf(output, "Unknown address family: %u data: ",
919238104Sdes					address_family);
920238104Sdes			for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
921238104Sdes                                if(pos+i >= ldns_rdf_size(rdf))
922238104Sdes                                        return LDNS_STATUS_SYNTAX_RDATA_ERR;
923238104Sdes				ldns_buffer_printf(output, "%02x", data[i]);
924238104Sdes			}
925238104Sdes		}
926238104Sdes		pos += 4 + adf_length;
927238104Sdes	}
928238104Sdes	return ldns_buffer_status(output);
929238104Sdes}
930238104Sdes
931238104Sdesldns_status
932238104Sdesldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
933238104Sdes{
934238104Sdes	/* Subtract the size (2) of the number that specifies the length */
935238104Sdes	size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
936238104Sdes	char *b64 = LDNS_XMALLOC(char, size);
937238104Sdes        if(!b64)
938238104Sdes                return LDNS_STATUS_MEM_ERR;
939238104Sdes
940238104Sdes	ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
941238104Sdes
942238104Sdes	if (ldns_rdf_size(rdf) > 2 &&
943238104Sdes	    ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
944238104Sdes				   ldns_rdf_size(rdf) - 2,
945238104Sdes				   b64, size)) {
946238104Sdes		ldns_buffer_printf(output, "%s", b64);
947238104Sdes	}
948238104Sdes	LDNS_FREE(b64);
949238104Sdes	return ldns_buffer_status(output);
950238104Sdes}
951238104Sdes
952238104Sdesldns_status
953238104Sdesldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
954238104Sdes{
955238104Sdes	/* wire format from
956238104Sdes	   http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
957238104Sdes	*/
958238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
959238104Sdes	uint8_t precedence;
960238104Sdes	uint8_t gateway_type;
961238104Sdes	uint8_t algorithm;
962238104Sdes
963238104Sdes	ldns_rdf *gateway = NULL;
964238104Sdes	uint8_t *gateway_data;
965238104Sdes
966238104Sdes	size_t public_key_size;
967238104Sdes	uint8_t *public_key_data;
968238104Sdes	ldns_rdf *public_key;
969238104Sdes
970238104Sdes	size_t offset = 0;
971238104Sdes	ldns_status status;
972238104Sdes
973238104Sdes	precedence = data[0];
974238104Sdes	gateway_type = data[1];
975238104Sdes	algorithm = data[2];
976238104Sdes	offset = 3;
977238104Sdes
978238104Sdes	switch (gateway_type) {
979238104Sdes		case 0:
980238104Sdes			/* no gateway */
981238104Sdes			break;
982238104Sdes		case 1:
983238104Sdes			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
984238104Sdes                        if(!gateway_data)
985238104Sdes                                return LDNS_STATUS_MEM_ERR;
986238104Sdes			memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
987238104Sdes			gateway = ldns_rdf_new(LDNS_RDF_TYPE_A, LDNS_IP4ADDRLEN , gateway_data);
988238104Sdes			offset += LDNS_IP4ADDRLEN;
989238104Sdes                        if(!gateway) {
990238104Sdes                                LDNS_FREE(gateway_data);
991238104Sdes                                return LDNS_STATUS_MEM_ERR;
992238104Sdes                        }
993238104Sdes			break;
994238104Sdes		case 2:
995238104Sdes			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
996238104Sdes                        if(!gateway_data)
997238104Sdes                                return LDNS_STATUS_MEM_ERR;
998238104Sdes			memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
999238104Sdes			offset += LDNS_IP6ADDRLEN;
1000238104Sdes			gateway =
1001238104Sdes				ldns_rdf_new(LDNS_RDF_TYPE_AAAA, LDNS_IP6ADDRLEN, gateway_data);
1002238104Sdes                        if(!gateway) {
1003238104Sdes                                LDNS_FREE(gateway_data);
1004238104Sdes                                return LDNS_STATUS_MEM_ERR;
1005238104Sdes                        }
1006238104Sdes			break;
1007238104Sdes		case 3:
1008238104Sdes			status = ldns_wire2dname(&gateway, data, ldns_rdf_size(rdf), &offset);
1009238104Sdes                        if(status != LDNS_STATUS_OK)
1010238104Sdes                                return status;
1011238104Sdes			break;
1012238104Sdes		default:
1013238104Sdes			/* error? */
1014238104Sdes			break;
1015238104Sdes	}
1016238104Sdes
1017238104Sdes	public_key_size = ldns_rdf_size(rdf) - offset;
1018238104Sdes	public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1019238104Sdes        if(!public_key_data) {
1020238104Sdes                ldns_rdf_free(gateway);
1021238104Sdes                return LDNS_STATUS_MEM_ERR;
1022238104Sdes        }
1023238104Sdes	memcpy(public_key_data, &data[offset], public_key_size);
1024238104Sdes	public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64, public_key_size, public_key_data);
1025238104Sdes        if(!public_key) {
1026238104Sdes                LDNS_FREE(public_key_data);
1027238104Sdes                ldns_rdf_free(gateway);
1028238104Sdes                return LDNS_STATUS_MEM_ERR;
1029238104Sdes        }
1030238104Sdes
1031238104Sdes	ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1032238104Sdes    if (gateway)
1033238104Sdes	  	(void) ldns_rdf2buffer_str(output, gateway);
1034238104Sdes	else
1035238104Sdes		ldns_buffer_printf(output, ".");
1036238104Sdes	ldns_buffer_printf(output, " ");
1037238104Sdes	(void) ldns_rdf2buffer_str(output, public_key);
1038238104Sdes
1039238104Sdes	ldns_rdf_free(gateway);
1040238104Sdes	ldns_rdf_free(public_key);
1041238104Sdes
1042238104Sdes	return ldns_buffer_status(output);
1043238104Sdes}
1044238104Sdes
1045238104Sdesldns_status
1046238104Sdesldns_rdf2buffer_str_tsig(ldns_buffer *output, const ldns_rdf *rdf)
1047238104Sdes{
1048238104Sdes	/* TSIG RRs have no presentation format, make them #size <data> */
1049238104Sdes	return ldns_rdf2buffer_str_unknown(output, rdf);
1050238104Sdes}
1051238104Sdes
1052238104Sdes
1053238104Sdesldns_status
1054238104Sdesldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1055238104Sdes{
1056238104Sdes	ldns_status res = LDNS_STATUS_OK;
1057238104Sdes
1058238104Sdes	/*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1059238104Sdes	if (rdf) {
1060238104Sdes		switch(ldns_rdf_get_type(rdf)) {
1061238104Sdes		case LDNS_RDF_TYPE_NONE:
1062238104Sdes			break;
1063238104Sdes		case LDNS_RDF_TYPE_DNAME:
1064238104Sdes			res = ldns_rdf2buffer_str_dname(buffer, rdf);
1065238104Sdes			break;
1066238104Sdes		case LDNS_RDF_TYPE_INT8:
1067238104Sdes			res = ldns_rdf2buffer_str_int8(buffer, rdf);
1068238104Sdes			break;
1069238104Sdes		case LDNS_RDF_TYPE_INT16:
1070238104Sdes			res = ldns_rdf2buffer_str_int16(buffer, rdf);
1071238104Sdes			break;
1072238104Sdes		case LDNS_RDF_TYPE_INT32:
1073238104Sdes			res = ldns_rdf2buffer_str_int32(buffer, rdf);
1074238104Sdes			break;
1075238104Sdes		case LDNS_RDF_TYPE_PERIOD:
1076238104Sdes			res = ldns_rdf2buffer_str_period(buffer, rdf);
1077238104Sdes			break;
1078238104Sdes		case LDNS_RDF_TYPE_TSIGTIME:
1079238104Sdes			res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1080238104Sdes			break;
1081238104Sdes		case LDNS_RDF_TYPE_A:
1082238104Sdes			res = ldns_rdf2buffer_str_a(buffer, rdf);
1083238104Sdes			break;
1084238104Sdes		case LDNS_RDF_TYPE_AAAA:
1085238104Sdes			res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1086238104Sdes			break;
1087238104Sdes		case LDNS_RDF_TYPE_STR:
1088238104Sdes			res = ldns_rdf2buffer_str_str(buffer, rdf);
1089238104Sdes			break;
1090238104Sdes		case LDNS_RDF_TYPE_APL:
1091238104Sdes			res = ldns_rdf2buffer_str_apl(buffer, rdf);
1092238104Sdes			break;
1093238104Sdes		case LDNS_RDF_TYPE_B32_EXT:
1094238104Sdes			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1095238104Sdes			break;
1096238104Sdes		case LDNS_RDF_TYPE_B64:
1097238104Sdes			res = ldns_rdf2buffer_str_b64(buffer, rdf);
1098238104Sdes			break;
1099238104Sdes		case LDNS_RDF_TYPE_HEX:
1100238104Sdes			res = ldns_rdf2buffer_str_hex(buffer, rdf);
1101238104Sdes			break;
1102238104Sdes		case LDNS_RDF_TYPE_NSEC:
1103238104Sdes			res = ldns_rdf2buffer_str_nsec(buffer, rdf);
1104238104Sdes			break;
1105238104Sdes		case LDNS_RDF_TYPE_NSEC3_SALT:
1106238104Sdes			res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1107238104Sdes			break;
1108238104Sdes		case LDNS_RDF_TYPE_TYPE:
1109238104Sdes			res = ldns_rdf2buffer_str_type(buffer, rdf);
1110238104Sdes			break;
1111238104Sdes		case LDNS_RDF_TYPE_CLASS:
1112238104Sdes			res = ldns_rdf2buffer_str_class(buffer, rdf);
1113238104Sdes			break;
1114238104Sdes		case LDNS_RDF_TYPE_CERT_ALG:
1115238104Sdes			res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1116238104Sdes			break;
1117238104Sdes		case LDNS_RDF_TYPE_ALG:
1118238104Sdes			res = ldns_rdf2buffer_str_alg(buffer, rdf);
1119238104Sdes			break;
1120238104Sdes		case LDNS_RDF_TYPE_UNKNOWN:
1121238104Sdes			res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1122238104Sdes			break;
1123238104Sdes		case LDNS_RDF_TYPE_TIME:
1124238104Sdes			res = ldns_rdf2buffer_str_time(buffer, rdf);
1125238104Sdes			break;
1126238104Sdes		case LDNS_RDF_TYPE_LOC:
1127238104Sdes			res = ldns_rdf2buffer_str_loc(buffer, rdf);
1128238104Sdes			break;
1129238104Sdes		case LDNS_RDF_TYPE_WKS:
1130238104Sdes		case LDNS_RDF_TYPE_SERVICE:
1131238104Sdes			res = ldns_rdf2buffer_str_wks(buffer, rdf);
1132238104Sdes			break;
1133238104Sdes		case LDNS_RDF_TYPE_NSAP:
1134238104Sdes			res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1135238104Sdes			break;
1136238104Sdes		case LDNS_RDF_TYPE_ATMA:
1137238104Sdes			res = ldns_rdf2buffer_str_atma(buffer, rdf);
1138238104Sdes			break;
1139238104Sdes		case LDNS_RDF_TYPE_IPSECKEY:
1140238104Sdes			res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1141238104Sdes			break;
1142238104Sdes		case LDNS_RDF_TYPE_TSIG:
1143238104Sdes			res = ldns_rdf2buffer_str_tsig(buffer, rdf);
1144238104Sdes			break;
1145238104Sdes		case LDNS_RDF_TYPE_INT16_DATA:
1146238104Sdes			res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1147238104Sdes			break;
1148238104Sdes		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1149238104Sdes			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1150238104Sdes			break;
1151238104Sdes		}
1152238104Sdes	} else {
1153246854Sdes		/** This will write mangled RRs */
1154238104Sdes		ldns_buffer_printf(buffer, "(null) ");
1155246854Sdes		res = LDNS_STATUS_ERR;
1156238104Sdes	}
1157238104Sdes	return res;
1158238104Sdes}
1159238104Sdes
1160246827Sdesstatic ldns_rdf *
1161238104Sdesldns_b32_ext2dname(const ldns_rdf *rdf)
1162238104Sdes{
1163238104Sdes	size_t size;
1164238104Sdes	char *b32;
1165238104Sdes	ldns_rdf *out;
1166238104Sdes	if(ldns_rdf_size(rdf) == 0)
1167238104Sdes		return NULL;
1168238104Sdes        /* remove -1 for the b32-hash-len octet */
1169238104Sdes	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1170238104Sdes        /* add one for the end nul for the string */
1171238104Sdes	b32 = LDNS_XMALLOC(char, size + 2);
1172238104Sdes	if (b32) {
1173238104Sdes		if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
1174238104Sdes				ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1175238104Sdes			b32[size] = '.';
1176238104Sdes			b32[size+1] = '\0';
1177238104Sdes			if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1178238104Sdes				LDNS_FREE(b32);
1179238104Sdes				return out;
1180238104Sdes			}
1181238104Sdes		}
1182238104Sdes		LDNS_FREE(b32);
1183238104Sdes	}
1184238104Sdes	return NULL;
1185238104Sdes}
1186238104Sdes
1187238104Sdesldns_status
1188238104Sdesldns_rr2buffer_str_fmt(ldns_buffer *output,
1189238104Sdes		const ldns_output_format *fmt, const ldns_rr *rr)
1190238104Sdes{
1191238104Sdes	uint16_t i, flags;
1192238104Sdes	ldns_status status = LDNS_STATUS_OK;
1193238104Sdes
1194238104Sdes	if (fmt == NULL) {
1195238104Sdes		fmt = ldns_output_format_default;
1196238104Sdes	}
1197238104Sdes	if (!rr) {
1198238104Sdes		if (LDNS_COMMENT_NULLS & fmt->flags) {
1199238104Sdes			ldns_buffer_printf(output, "; (null)\n");
1200238104Sdes		}
1201238104Sdes		return ldns_buffer_status(output);
1202238104Sdes	}
1203238104Sdes	if (ldns_rr_owner(rr)) {
1204238104Sdes		status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1205238104Sdes	}
1206238104Sdes	if (status != LDNS_STATUS_OK) {
1207238104Sdes		return status;
1208238104Sdes	}
1209238104Sdes
1210238104Sdes	/* TTL should NOT be printed if it is a question */
1211238104Sdes	if (!ldns_rr_is_question(rr)) {
1212238104Sdes		ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
1213238104Sdes	}
1214238104Sdes
1215238104Sdes	ldns_buffer_printf(output, "\t");
1216238104Sdes	status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1217238104Sdes	if (status != LDNS_STATUS_OK) {
1218238104Sdes		return status;
1219238104Sdes	}
1220238104Sdes	ldns_buffer_printf(output, "\t");
1221238104Sdes
1222238104Sdes	status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1223238104Sdes	if (status != LDNS_STATUS_OK) {
1224238104Sdes		return status;
1225238104Sdes	}
1226238104Sdes
1227238104Sdes	if (ldns_rr_rd_count(rr) > 0) {
1228238104Sdes		ldns_buffer_printf(output, "\t");
1229238104Sdes	} else if (!ldns_rr_is_question(rr)) {
1230238104Sdes		ldns_buffer_printf(output, "\t\\# 0");
1231238104Sdes	}
1232238104Sdes
1233238104Sdes	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1234238104Sdes		/* ldns_rdf2buffer_str handles NULL input fine! */
1235246854Sdes		if ((fmt->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1236246854Sdes				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1237246854Sdes				((/* inception  */ i == 4 &&
1238246854Sdes				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
1239246854Sdes							LDNS_RDF_TYPE_TIME) ||
1240246854Sdes				  (/* expiration */ i == 5 &&
1241246854Sdes				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1242246854Sdes				   			LDNS_RDF_TYPE_TIME) ||
1243246854Sdes				  (/* signature  */ i == 8 &&
1244246854Sdes				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1245246854Sdes				   			LDNS_RDF_TYPE_B64))) {
1246246854Sdes
1247246854Sdes			ldns_buffer_printf(output, "(null)");
1248246854Sdes			status = ldns_buffer_status(output);
1249246854Sdes		} else if ((fmt->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1250246854Sdes				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1251246854Sdes				/* serial */ i == 2 &&
1252246854Sdes			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1253246854Sdes			 				LDNS_RDF_TYPE_INT32) {
1254246854Sdes			ldns_buffer_printf(output, "%10lu",
1255246854Sdes				(unsigned long) ldns_read_uint32(
1256246854Sdes					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1257246854Sdes			status = ldns_buffer_status(output);
1258246854Sdes		} else {
1259246854Sdes			status = ldns_rdf2buffer_str(output,
1260246854Sdes					ldns_rr_rdf(rr, i));
1261246854Sdes		}
1262238104Sdes		if(status != LDNS_STATUS_OK)
1263238104Sdes			return status;
1264238104Sdes		if (i < ldns_rr_rd_count(rr) - 1) {
1265238104Sdes			ldns_buffer_printf(output, " ");
1266238104Sdes		}
1267238104Sdes	}
1268238104Sdes	/* per RR special comments - handy for DNSSEC types */
1269238104Sdes	/* check to prevent question sec. rr from
1270238104Sdes	 * getting here */
1271238104Sdes	if (ldns_rr_rd_count(rr) > 0) {
1272238104Sdes		switch (ldns_rr_get_type(rr)) {
1273238104Sdes			case LDNS_RR_TYPE_DNSKEY:
1274238104Sdes				/* if ldns_rr_rd_count(rr) > 0
1275238104Sdes				   then ldns_rr_rdf(rr, 0) exists! */
1276238104Sdes				if (! (fmt->flags & LDNS_COMMENT_KEY)) {
1277238104Sdes					break;
1278238104Sdes				}
1279238104Sdes				flags = ldns_rdf2native_int16(
1280238104Sdes						ldns_rr_rdf(rr, 0));
1281238104Sdes				ldns_buffer_printf(output, " ;{");
1282238104Sdes				if (fmt->flags & LDNS_COMMENT_KEY_ID) {
1283238104Sdes					ldns_buffer_printf(output, "id = %u",
1284238104Sdes							(unsigned int)
1285238104Sdes							ldns_calc_keytag(rr));
1286238104Sdes				}
1287238104Sdes				if ((fmt->flags & LDNS_COMMENT_KEY_TYPE)
1288238104Sdes						&& (flags & LDNS_KEY_ZONE_KEY)){
1289238104Sdes					if (flags & LDNS_KEY_SEP_KEY) {
1290238104Sdes						ldns_buffer_printf(
1291238104Sdes							output, " (ksk)");
1292238104Sdes					}
1293238104Sdes					else {
1294238104Sdes						ldns_buffer_printf(
1295238104Sdes							output, " (zsk)");
1296238104Sdes					}
1297238104Sdes					if (fmt->flags & LDNS_COMMENT_KEY_SIZE){
1298238104Sdes						ldns_buffer_printf(
1299238104Sdes							output, ", ");
1300238104Sdes					}
1301238104Sdes				} else if (fmt->flags
1302238104Sdes						& (LDNS_COMMENT_KEY_ID
1303238104Sdes						  |LDNS_COMMENT_KEY_SIZE)) {
1304238104Sdes					ldns_buffer_printf( output, ", ");
1305238104Sdes				}
1306238104Sdes				if (fmt->flags & LDNS_COMMENT_KEY_SIZE) {
1307238104Sdes					ldns_buffer_printf(output, "size = %db",
1308238104Sdes						ldns_rr_dnskey_key_size(rr));
1309238104Sdes				}
1310238104Sdes				ldns_buffer_printf(output, "}");
1311238104Sdes				break;
1312238104Sdes			case LDNS_RR_TYPE_RRSIG:
1313238104Sdes				if ((fmt->flags & LDNS_COMMENT_KEY)
1314238104Sdes						&& (fmt->flags
1315238104Sdes							& LDNS_COMMENT_RRSIGS)
1316238104Sdes						&& ldns_rr_rdf(rr, 6) != NULL) {
1317238104Sdes					ldns_buffer_printf(output
1318238104Sdes						, " ;{id = %d}"
1319238104Sdes						, ldns_rdf2native_int16(
1320238104Sdes							ldns_rr_rdf(rr, 6)));
1321238104Sdes				}
1322238104Sdes				break;
1323238104Sdes			case LDNS_RR_TYPE_DS:
1324238104Sdes				if ((fmt->flags & LDNS_COMMENT_BUBBLEBABBLE)
1325238104Sdes						&& ldns_rr_rdf(rr, 3) != NULL) {
1326238104Sdes					uint8_t *data = ldns_rdf_data(
1327238104Sdes							ldns_rr_rdf(rr, 3));
1328238104Sdes					size_t len = ldns_rdf_size(
1329238104Sdes							ldns_rr_rdf(rr, 3));
1330238104Sdes					char *babble = ldns_bubblebabble(
1331238104Sdes							data, len);
1332238104Sdes					if(babble) {
1333238104Sdes						ldns_buffer_printf(output
1334238104Sdes							, " ;{%s}", babble);
1335238104Sdes					}
1336238104Sdes					LDNS_FREE(babble);
1337238104Sdes				}
1338238104Sdes				break;
1339238104Sdes			case LDNS_RR_TYPE_NSEC3:
1340238104Sdes				if (! (fmt->flags & LDNS_COMMENT_FLAGS) &&
1341238104Sdes				    ! (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
1342238104Sdes					break;
1343238104Sdes				}
1344238104Sdes				ldns_buffer_printf(output, " ;{");
1345238104Sdes				if ((fmt->flags & LDNS_COMMENT_FLAGS)) {
1346238104Sdes					if (ldns_nsec3_optout(rr)) {
1347238104Sdes						ldns_buffer_printf(output,
1348238104Sdes							" flags: optout");
1349238104Sdes					} else {
1350238104Sdes						ldns_buffer_printf(output,
1351238104Sdes							" flags: -");
1352238104Sdes					}
1353238104Sdes					if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
1354238104Sdes							&& fmt->data != NULL) {
1355238104Sdes						ldns_buffer_printf(output, ", ");
1356238104Sdes					}
1357238104Sdes				}
1358238104Sdes				if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
1359238104Sdes						&& fmt->data != NULL) {
1360238104Sdes					ldns_rbnode_t *node;
1361238104Sdes					ldns_rdf *key = ldns_dname_label(
1362238104Sdes							ldns_rr_owner(rr), 0);
1363238104Sdes					if (key) {
1364238104Sdes				       		node = ldns_rbtree_search(
1365238104Sdes							(ldns_rbtree_t *)
1366238104Sdes								fmt->data,
1367238104Sdes							(void *) key);
1368238104Sdes						if (node->data) {
1369238104Sdes							ldns_buffer_printf(
1370238104Sdes								output,
1371238104Sdes							       	"from: ");
1372238104Sdes							(void)
1373238104Sdes							ldns_rdf2buffer_str(
1374238104Sdes								output,
1375238104Sdes								(ldns_rdf *)
1376238104Sdes								node->data);
1377238104Sdes						}
1378238104Sdes						ldns_rdf_free(key);
1379238104Sdes					}
1380238104Sdes					key = ldns_b32_ext2dname(
1381238104Sdes						ldns_nsec3_next_owner(rr));
1382238104Sdes					if (key) {
1383238104Sdes						node = ldns_rbtree_search(
1384238104Sdes							(ldns_rbtree_t *)
1385238104Sdes								fmt->data,
1386238104Sdes							(void *) key);
1387238104Sdes						if (node->data) {
1388238104Sdes							ldns_buffer_printf(
1389238104Sdes								output,
1390238104Sdes								" to: ");
1391238104Sdes							(void)
1392238104Sdes							ldns_rdf2buffer_str(
1393238104Sdes								output,
1394238104Sdes								(ldns_rdf *)
1395238104Sdes								node->data);
1396238104Sdes						}
1397238104Sdes						ldns_rdf_free(key);
1398238104Sdes					}
1399238104Sdes				}
1400238104Sdes				ldns_buffer_printf(output, "}");
1401238104Sdes				break;
1402238104Sdes			default:
1403238104Sdes				break;
1404238104Sdes
1405238104Sdes		}
1406238104Sdes	}
1407238104Sdes	/* last */
1408238104Sdes	ldns_buffer_printf(output, "\n");
1409238104Sdes	return ldns_buffer_status(output);
1410238104Sdes}
1411238104Sdes
1412238104Sdesldns_status
1413238104Sdesldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
1414238104Sdes{
1415238104Sdes	return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
1416238104Sdes}
1417238104Sdes
1418238104Sdesldns_status
1419238104Sdesldns_rr_list2buffer_str_fmt(ldns_buffer *output,
1420238104Sdes		const ldns_output_format *fmt, const ldns_rr_list *list)
1421238104Sdes{
1422238104Sdes	uint16_t i;
1423238104Sdes
1424238104Sdes	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
1425238104Sdes		(void) ldns_rr2buffer_str_fmt(output, fmt,
1426238104Sdes				ldns_rr_list_rr(list, i));
1427238104Sdes	}
1428238104Sdes	return ldns_buffer_status(output);
1429238104Sdes}
1430238104Sdes
1431238104Sdesldns_status
1432238104Sdesldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
1433238104Sdes{
1434238104Sdes	return ldns_rr_list2buffer_str_fmt(
1435238104Sdes			output, ldns_output_format_default, list);
1436238104Sdes}
1437238104Sdes
1438238104Sdesldns_status
1439238104Sdesldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1440238104Sdes{
1441238104Sdes	ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
1442238104Sdes			                    (int) ldns_pkt_get_opcode(pkt));
1443238104Sdes	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
1444238104Sdes			                    (int) ldns_pkt_get_rcode(pkt));
1445238104Sdes
1446238104Sdes	ldns_buffer_printf(output, ";; ->>HEADER<<- ");
1447238104Sdes	if (opcode) {
1448238104Sdes		ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
1449238104Sdes	} else {
1450238104Sdes		ldns_buffer_printf(output, "opcode: ?? (%u), ",
1451238104Sdes				ldns_pkt_get_opcode(pkt));
1452238104Sdes	}
1453238104Sdes	if (rcode) {
1454238104Sdes		ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
1455238104Sdes	} else {
1456238104Sdes		ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
1457238104Sdes	}
1458238104Sdes	ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
1459238104Sdes	ldns_buffer_printf(output, ";; flags: ");
1460238104Sdes
1461238104Sdes	if (ldns_pkt_qr(pkt)) {
1462238104Sdes		ldns_buffer_printf(output, "qr ");
1463238104Sdes	}
1464238104Sdes	if (ldns_pkt_aa(pkt)) {
1465238104Sdes		ldns_buffer_printf(output, "aa ");
1466238104Sdes	}
1467238104Sdes	if (ldns_pkt_tc(pkt)) {
1468238104Sdes		ldns_buffer_printf(output, "tc ");
1469238104Sdes	}
1470238104Sdes	if (ldns_pkt_rd(pkt)) {
1471238104Sdes		ldns_buffer_printf(output, "rd ");
1472238104Sdes	}
1473238104Sdes	if (ldns_pkt_cd(pkt)) {
1474238104Sdes		ldns_buffer_printf(output, "cd ");
1475238104Sdes	}
1476238104Sdes	if (ldns_pkt_ra(pkt)) {
1477238104Sdes		ldns_buffer_printf(output, "ra ");
1478238104Sdes	}
1479238104Sdes	if (ldns_pkt_ad(pkt)) {
1480238104Sdes		ldns_buffer_printf(output, "ad ");
1481238104Sdes	}
1482238104Sdes	ldns_buffer_printf(output, "; ");
1483238104Sdes	ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
1484238104Sdes	ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
1485238104Sdes	ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
1486238104Sdes	ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
1487238104Sdes	return ldns_buffer_status(output);
1488238104Sdes}
1489238104Sdes
1490238104Sdesldns_status
1491238104Sdesldns_pkt2buffer_str_fmt(ldns_buffer *output,
1492238104Sdes		const ldns_output_format *fmt, const ldns_pkt *pkt)
1493238104Sdes{
1494238104Sdes	uint16_t i;
1495238104Sdes	ldns_status status = LDNS_STATUS_OK;
1496238104Sdes	char *tmp;
1497238104Sdes	struct timeval time;
1498238104Sdes	time_t time_tt;
1499238104Sdes
1500238104Sdes	if (!pkt) {
1501238104Sdes		ldns_buffer_printf(output, "null");
1502238104Sdes		return LDNS_STATUS_OK;
1503238104Sdes	}
1504238104Sdes
1505238104Sdes	if (ldns_buffer_status_ok(output)) {
1506238104Sdes		status = ldns_pktheader2buffer_str(output, pkt);
1507238104Sdes		if (status != LDNS_STATUS_OK) {
1508238104Sdes			return status;
1509238104Sdes		}
1510238104Sdes
1511238104Sdes		ldns_buffer_printf(output, "\n");
1512238104Sdes
1513238104Sdes		ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
1514238104Sdes
1515238104Sdes
1516238104Sdes		for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
1517238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1518238104Sdes				       ldns_rr_list_rr(
1519238104Sdes					       ldns_pkt_question(pkt), i));
1520238104Sdes			if (status != LDNS_STATUS_OK) {
1521238104Sdes				return status;
1522238104Sdes			}
1523238104Sdes		}
1524238104Sdes		ldns_buffer_printf(output, "\n");
1525238104Sdes
1526238104Sdes		ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
1527238104Sdes		for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
1528238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1529238104Sdes				       ldns_rr_list_rr(
1530238104Sdes					       ldns_pkt_answer(pkt), i));
1531238104Sdes			if (status != LDNS_STATUS_OK) {
1532238104Sdes				return status;
1533238104Sdes			}
1534238104Sdes
1535238104Sdes		}
1536238104Sdes		ldns_buffer_printf(output, "\n");
1537238104Sdes
1538238104Sdes		ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
1539238104Sdes
1540238104Sdes		for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
1541238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1542238104Sdes				       ldns_rr_list_rr(
1543238104Sdes					       ldns_pkt_authority(pkt), i));
1544238104Sdes			if (status != LDNS_STATUS_OK) {
1545238104Sdes				return status;
1546238104Sdes			}
1547238104Sdes		}
1548238104Sdes		ldns_buffer_printf(output, "\n");
1549238104Sdes
1550238104Sdes		ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
1551238104Sdes		for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
1552238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1553238104Sdes				       ldns_rr_list_rr(
1554238104Sdes					       ldns_pkt_additional(pkt), i));
1555238104Sdes			if (status != LDNS_STATUS_OK) {
1556238104Sdes				return status;
1557238104Sdes			}
1558238104Sdes
1559238104Sdes		}
1560238104Sdes		ldns_buffer_printf(output, "\n");
1561238104Sdes		/* add some futher fields */
1562238104Sdes		ldns_buffer_printf(output, ";; Query time: %d msec\n",
1563238104Sdes				ldns_pkt_querytime(pkt));
1564238104Sdes		if (ldns_pkt_edns(pkt)) {
1565238104Sdes			ldns_buffer_printf(output,
1566238104Sdes				   ";; EDNS: version %u; flags:",
1567238104Sdes				   ldns_pkt_edns_version(pkt));
1568238104Sdes			if (ldns_pkt_edns_do(pkt)) {
1569238104Sdes				ldns_buffer_printf(output, " do");
1570238104Sdes			}
1571238104Sdes			/* the extended rcode is the value set, shifted four bits,
1572238104Sdes			 * and or'd with the original rcode */
1573238104Sdes			if (ldns_pkt_edns_extended_rcode(pkt)) {
1574238104Sdes				ldns_buffer_printf(output, " ; ext-rcode: %d",
1575238104Sdes					(ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
1576238104Sdes			}
1577238104Sdes			ldns_buffer_printf(output, " ; udp: %u\n",
1578238104Sdes					   ldns_pkt_edns_udp_size(pkt));
1579238104Sdes
1580238104Sdes			if (ldns_pkt_edns_data(pkt)) {
1581238104Sdes				ldns_buffer_printf(output, ";; Data: ");
1582238104Sdes				(void)ldns_rdf2buffer_str(output,
1583238104Sdes							  ldns_pkt_edns_data(pkt));
1584238104Sdes				ldns_buffer_printf(output, "\n");
1585238104Sdes			}
1586238104Sdes		}
1587238104Sdes		if (ldns_pkt_tsig(pkt)) {
1588238104Sdes			ldns_buffer_printf(output, ";; TSIG:\n;; ");
1589238104Sdes			(void) ldns_rr2buffer_str_fmt(
1590238104Sdes					output, fmt, ldns_pkt_tsig(pkt));
1591238104Sdes			ldns_buffer_printf(output, "\n");
1592238104Sdes		}
1593238104Sdes		if (ldns_pkt_answerfrom(pkt)) {
1594238104Sdes			tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
1595238104Sdes			ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
1596238104Sdes			LDNS_FREE(tmp);
1597238104Sdes		}
1598238104Sdes		time = ldns_pkt_timestamp(pkt);
1599238104Sdes		time_tt = (time_t)time.tv_sec;
1600238104Sdes		ldns_buffer_printf(output, ";; WHEN: %s",
1601238104Sdes				(char*)ctime(&time_tt));
1602238104Sdes
1603238104Sdes		ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
1604238104Sdes				(int)ldns_pkt_size(pkt));
1605238104Sdes	} else {
1606238104Sdes		return ldns_buffer_status(output);
1607238104Sdes	}
1608238104Sdes	return status;
1609238104Sdes}
1610238104Sdes
1611238104Sdesldns_status
1612238104Sdesldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1613238104Sdes{
1614238104Sdes	return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
1615238104Sdes}
1616238104Sdes
1617238104Sdes
1618238104Sdes#ifdef HAVE_SSL
1619238104Sdesstatic ldns_status
1620238104Sdesldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1621238104Sdes{
1622238104Sdes	ldns_status status;
1623238104Sdes	size_t i;
1624238104Sdes	ldns_rdf *b64_bignum;
1625238104Sdes
1626238104Sdes	ldns_buffer_printf(output, "Key: ");
1627238104Sdes
1628238104Sdes 	i = ldns_key_hmac_size(k);
1629238104Sdes	b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
1630238104Sdes	status = ldns_rdf2buffer_str(output, b64_bignum);
1631238104Sdes	ldns_rdf_deep_free(b64_bignum);
1632238104Sdes	ldns_buffer_printf(output, "\n");
1633238104Sdes	return status;
1634238104Sdes}
1635238104Sdes#endif
1636238104Sdes
1637238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST)
1638238104Sdesstatic ldns_status
1639238104Sdesldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
1640238104Sdes{
1641238104Sdes	unsigned char* pp = NULL;
1642238104Sdes	int ret;
1643238104Sdes	ldns_rdf *b64_bignum;
1644238104Sdes	ldns_status status;
1645238104Sdes
1646238104Sdes	ldns_buffer_printf(output, "GostAsn1: ");
1647238104Sdes
1648238104Sdes	ret = i2d_PrivateKey(p, &pp);
1649238104Sdes	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
1650238104Sdes	status = ldns_rdf2buffer_str(output, b64_bignum);
1651238104Sdes
1652238104Sdes	ldns_rdf_deep_free(b64_bignum);
1653238104Sdes	OPENSSL_free(pp);
1654238104Sdes	ldns_buffer_printf(output, "\n");
1655238104Sdes	return status;
1656238104Sdes}
1657238104Sdes#endif
1658238104Sdes
1659238104Sdesldns_status
1660238104Sdesldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1661238104Sdes{
1662238104Sdes	ldns_status status = LDNS_STATUS_OK;
1663238104Sdes	unsigned char  *bignum;
1664246854Sdes#ifdef HAVE_SSL
1665246854Sdes#  ifndef S_SPLINT_S
1666238104Sdes	uint16_t i;
1667246854Sdes#  endif
1668238104Sdes	/* not used when ssl is not defined */
1669246854Sdes	/*@unused@*/
1670238104Sdes	ldns_rdf *b64_bignum = NULL;
1671238104Sdes
1672238104Sdes	RSA *rsa;
1673238104Sdes	DSA *dsa;
1674238104Sdes#endif /* HAVE_SSL */
1675238104Sdes
1676238104Sdes	if (!k) {
1677238104Sdes		return LDNS_STATUS_ERR;
1678238104Sdes	}
1679238104Sdes
1680238104Sdes	bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1681238104Sdes	if (!bignum) {
1682238104Sdes		return LDNS_STATUS_ERR;
1683238104Sdes	}
1684238104Sdes
1685238104Sdes	if (ldns_buffer_status_ok(output)) {
1686238104Sdes#ifdef HAVE_SSL
1687238104Sdes		switch(ldns_key_algorithm(k)) {
1688238104Sdes			case LDNS_SIGN_RSASHA1:
1689238104Sdes			case LDNS_SIGN_RSASHA1_NSEC3:
1690238104Sdes			case LDNS_SIGN_RSASHA256:
1691238104Sdes			case LDNS_SIGN_RSASHA512:
1692238104Sdes			case LDNS_SIGN_RSAMD5:
1693238104Sdes				/* copied by looking at dnssec-keygen output */
1694238104Sdes				/* header */
1695238104Sdes				rsa = ldns_key_rsa_key(k);
1696238104Sdes
1697238104Sdes				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
1698238104Sdes				switch(ldns_key_algorithm(k)) {
1699238104Sdes				case LDNS_SIGN_RSAMD5:
1700238104Sdes					ldns_buffer_printf(output,
1701238104Sdes								    "Algorithm: %u (RSA)\n",
1702238104Sdes								    LDNS_RSAMD5);
1703238104Sdes					break;
1704238104Sdes				case LDNS_SIGN_RSASHA1:
1705238104Sdes					ldns_buffer_printf(output,
1706238104Sdes								    "Algorithm: %u (RSASHA1)\n",
1707238104Sdes								    LDNS_RSASHA1);
1708238104Sdes					break;
1709238104Sdes				case LDNS_SIGN_RSASHA1_NSEC3:
1710238104Sdes					ldns_buffer_printf(output,
1711238104Sdes								    "Algorithm: %u (RSASHA1_NSEC3)\n",
1712238104Sdes								    LDNS_RSASHA1_NSEC3);
1713238104Sdes					break;
1714238104Sdes#ifdef USE_SHA2
1715238104Sdes				case LDNS_SIGN_RSASHA256:
1716238104Sdes					ldns_buffer_printf(output,
1717238104Sdes								    "Algorithm: %u (RSASHA256)\n",
1718238104Sdes								    LDNS_RSASHA256);
1719238104Sdes					break;
1720238104Sdes				case LDNS_SIGN_RSASHA512:
1721238104Sdes					ldns_buffer_printf(output,
1722238104Sdes								    "Algorithm: %u (RSASHA512)\n",
1723238104Sdes								    LDNS_RSASHA512);
1724238104Sdes					break;
1725238104Sdes#endif
1726238104Sdes				default:
1727238104Sdes					fprintf(stderr, "Warning: unknown signature ");
1728238104Sdes					fprintf(stderr,
1729238104Sdes						   "algorithm type %u\n",
1730238104Sdes						   ldns_key_algorithm(k));
1731238104Sdes					ldns_buffer_printf(output,
1732238104Sdes								    "Algorithm: %u (Unknown)\n",
1733238104Sdes								    ldns_key_algorithm(k));
1734238104Sdes					break;
1735238104Sdes				}
1736238104Sdes
1737238104Sdes				/* print to buf, convert to bin, convert to b64,
1738238104Sdes				 * print to buf */
1739238104Sdes				ldns_buffer_printf(output, "Modulus: ");
1740238104Sdes#ifndef S_SPLINT_S
1741238104Sdes				i = (uint16_t)BN_bn2bin(rsa->n, bignum);
1742238104Sdes				if (i > LDNS_MAX_KEYLEN) {
1743238104Sdes					goto error;
1744238104Sdes				}
1745238104Sdes				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1746238104Sdes				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1747246854Sdes					ldns_rdf_deep_free(b64_bignum);
1748238104Sdes					goto error;
1749238104Sdes				}
1750238104Sdes				ldns_rdf_deep_free(b64_bignum);
1751238104Sdes				ldns_buffer_printf(output, "\n");
1752238104Sdes				ldns_buffer_printf(output, "PublicExponent: ");
1753238104Sdes				i = (uint16_t)BN_bn2bin(rsa->e, bignum);
1754238104Sdes				if (i > LDNS_MAX_KEYLEN) {
1755238104Sdes					goto error;
1756238104Sdes				}
1757238104Sdes				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1758238104Sdes				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1759246854Sdes					ldns_rdf_deep_free(b64_bignum);
1760238104Sdes					goto error;
1761238104Sdes				}
1762238104Sdes				ldns_rdf_deep_free(b64_bignum);
1763238104Sdes				ldns_buffer_printf(output, "\n");
1764238104Sdes
1765238104Sdes				ldns_buffer_printf(output, "PrivateExponent: ");
1766238104Sdes				if (rsa->d) {
1767238104Sdes					i = (uint16_t)BN_bn2bin(rsa->d, bignum);
1768238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1769238104Sdes						goto error;
1770238104Sdes					}
1771238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1772238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1773246854Sdes						ldns_rdf_deep_free(b64_bignum);
1774238104Sdes						goto error;
1775238104Sdes					}
1776238104Sdes					ldns_rdf_deep_free(b64_bignum);
1777238104Sdes					ldns_buffer_printf(output, "\n");
1778238104Sdes				} else {
1779238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1780238104Sdes				}
1781238104Sdes
1782238104Sdes				ldns_buffer_printf(output, "Prime1: ");
1783238104Sdes				if (rsa->p) {
1784238104Sdes					i = (uint16_t)BN_bn2bin(rsa->p, bignum);
1785238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1786238104Sdes						goto error;
1787238104Sdes					}
1788238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1789238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1790246854Sdes						ldns_rdf_deep_free(b64_bignum);
1791238104Sdes						goto error;
1792238104Sdes					}
1793238104Sdes					ldns_rdf_deep_free(b64_bignum);
1794238104Sdes					ldns_buffer_printf(output, "\n");
1795238104Sdes				} else {
1796238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1797238104Sdes				}
1798238104Sdes
1799238104Sdes				ldns_buffer_printf(output, "Prime2: ");
1800238104Sdes				if (rsa->q) {
1801238104Sdes					i = (uint16_t)BN_bn2bin(rsa->q, bignum);
1802238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1803238104Sdes						goto error;
1804238104Sdes					}
1805238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1806238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1807246854Sdes						ldns_rdf_deep_free(b64_bignum);
1808238104Sdes						goto error;
1809238104Sdes					}
1810238104Sdes					ldns_rdf_deep_free(b64_bignum);
1811238104Sdes					ldns_buffer_printf(output, "\n");
1812238104Sdes				} else {
1813238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1814238104Sdes				}
1815238104Sdes
1816238104Sdes				ldns_buffer_printf(output, "Exponent1: ");
1817238104Sdes				if (rsa->dmp1) {
1818238104Sdes					i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum);
1819238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1820238104Sdes						goto error;
1821238104Sdes					}
1822238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1823238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1824246854Sdes						ldns_rdf_deep_free(b64_bignum);
1825238104Sdes						goto error;
1826238104Sdes					}
1827238104Sdes					ldns_rdf_deep_free(b64_bignum);
1828238104Sdes					ldns_buffer_printf(output, "\n");
1829238104Sdes				} else {
1830238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1831238104Sdes				}
1832238104Sdes
1833238104Sdes				ldns_buffer_printf(output, "Exponent2: ");
1834238104Sdes				if (rsa->dmq1) {
1835238104Sdes					i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum);
1836238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1837238104Sdes						goto error;
1838238104Sdes					}
1839238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1840238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1841246854Sdes						ldns_rdf_deep_free(b64_bignum);
1842238104Sdes						goto error;
1843238104Sdes					}
1844238104Sdes					ldns_rdf_deep_free(b64_bignum);
1845238104Sdes					ldns_buffer_printf(output, "\n");
1846238104Sdes				} else {
1847238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1848238104Sdes				}
1849238104Sdes
1850238104Sdes				ldns_buffer_printf(output, "Coefficient: ");
1851238104Sdes				if (rsa->iqmp) {
1852238104Sdes					i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum);
1853238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1854238104Sdes						goto error;
1855238104Sdes					}
1856238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1857238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1858246854Sdes						ldns_rdf_deep_free(b64_bignum);
1859238104Sdes						goto error;
1860238104Sdes					}
1861238104Sdes					ldns_rdf_deep_free(b64_bignum);
1862238104Sdes					ldns_buffer_printf(output, "\n");
1863238104Sdes				} else {
1864238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
1865238104Sdes				}
1866238104Sdes#endif /* splint */
1867238104Sdes
1868238104Sdes				RSA_free(rsa);
1869238104Sdes				break;
1870238104Sdes			case LDNS_SIGN_DSA:
1871238104Sdes			case LDNS_SIGN_DSA_NSEC3:
1872238104Sdes				dsa = ldns_key_dsa_key(k);
1873238104Sdes
1874238104Sdes				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
1875238104Sdes				if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
1876238104Sdes					ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
1877238104Sdes				} else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
1878238104Sdes					ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
1879238104Sdes				}
1880238104Sdes
1881238104Sdes				/* print to buf, convert to bin, convert to b64,
1882238104Sdes				 * print to buf */
1883238104Sdes				ldns_buffer_printf(output, "Prime(p): ");
1884238104Sdes#ifndef S_SPLINT_S
1885238104Sdes				if (dsa->p) {
1886238104Sdes					i = (uint16_t)BN_bn2bin(dsa->p, bignum);
1887238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1888238104Sdes						goto error;
1889238104Sdes					}
1890238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1891238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1892246854Sdes						ldns_rdf_deep_free(b64_bignum);
1893238104Sdes						goto error;
1894238104Sdes					}
1895238104Sdes					ldns_rdf_deep_free(b64_bignum);
1896238104Sdes					ldns_buffer_printf(output, "\n");
1897238104Sdes				} else {
1898238104Sdes					printf("(Not available)\n");
1899238104Sdes				}
1900238104Sdes
1901238104Sdes				ldns_buffer_printf(output, "Subprime(q): ");
1902238104Sdes				if (dsa->q) {
1903238104Sdes					i = (uint16_t)BN_bn2bin(dsa->q, bignum);
1904238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1905238104Sdes						goto error;
1906238104Sdes					}
1907238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1908238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1909246854Sdes						ldns_rdf_deep_free(b64_bignum);
1910238104Sdes						goto error;
1911238104Sdes					}
1912238104Sdes					ldns_rdf_deep_free(b64_bignum);
1913238104Sdes					ldns_buffer_printf(output, "\n");
1914238104Sdes				} else {
1915238104Sdes					printf("(Not available)\n");
1916238104Sdes				}
1917238104Sdes
1918238104Sdes				ldns_buffer_printf(output, "Base(g): ");
1919238104Sdes				if (dsa->g) {
1920238104Sdes					i = (uint16_t)BN_bn2bin(dsa->g, bignum);
1921238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1922238104Sdes						goto error;
1923238104Sdes					}
1924238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1925238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1926246854Sdes						ldns_rdf_deep_free(b64_bignum);
1927238104Sdes						goto error;
1928238104Sdes					}
1929238104Sdes					ldns_rdf_deep_free(b64_bignum);
1930238104Sdes					ldns_buffer_printf(output, "\n");
1931238104Sdes				} else {
1932238104Sdes					printf("(Not available)\n");
1933238104Sdes				}
1934238104Sdes
1935238104Sdes				ldns_buffer_printf(output, "Private_value(x): ");
1936238104Sdes				if (dsa->priv_key) {
1937238104Sdes					i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum);
1938238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1939238104Sdes						goto error;
1940238104Sdes					}
1941238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1942238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1943246854Sdes						ldns_rdf_deep_free(b64_bignum);
1944238104Sdes						goto error;
1945238104Sdes					}
1946238104Sdes					ldns_rdf_deep_free(b64_bignum);
1947238104Sdes					ldns_buffer_printf(output, "\n");
1948238104Sdes				} else {
1949238104Sdes					printf("(Not available)\n");
1950238104Sdes				}
1951238104Sdes
1952238104Sdes				ldns_buffer_printf(output, "Public_value(y): ");
1953238104Sdes				if (dsa->pub_key) {
1954238104Sdes					i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum);
1955238104Sdes					if (i > LDNS_MAX_KEYLEN) {
1956238104Sdes						goto error;
1957238104Sdes					}
1958238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
1959238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1960246854Sdes						ldns_rdf_deep_free(b64_bignum);
1961238104Sdes						goto error;
1962238104Sdes					}
1963238104Sdes					ldns_rdf_deep_free(b64_bignum);
1964238104Sdes					ldns_buffer_printf(output, "\n");
1965238104Sdes				} else {
1966238104Sdes					printf("(Not available)\n");
1967238104Sdes				}
1968238104Sdes#endif /* splint */
1969238104Sdes				break;
1970238104Sdes			case LDNS_SIGN_ECC_GOST:
1971238104Sdes				/* no format defined, use blob */
1972238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST)
1973238104Sdes				ldns_buffer_printf(output, "Private-key-format: v1.2\n");
1974238104Sdes				ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
1975238104Sdes				status = ldns_gost_key2buffer_str(output,
1976238104Sdes#ifndef S_SPLINT_S
1977238104Sdes					k->_key.key
1978238104Sdes#else
1979238104Sdes					NULL
1980238104Sdes#endif
1981238104Sdes				);
1982238104Sdes#else
1983238104Sdes				goto error;
1984238104Sdes#endif /* GOST */
1985238104Sdes				break;
1986238104Sdes			case LDNS_SIGN_ECDSAP256SHA256:
1987238104Sdes			case LDNS_SIGN_ECDSAP384SHA384:
1988238104Sdes#ifdef USE_ECDSA
1989238104Sdes                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
1990238104Sdes				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
1991238104Sdes                                status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
1992238104Sdes#ifndef S_SPLINT_S
1993238104Sdes				ldns_buffer_printf(output, ")\n");
1994238104Sdes                                if(k->_key.key) {
1995238104Sdes                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
1996238104Sdes                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
1997238104Sdes                                        ldns_buffer_printf(output, "PrivateKey: ");
1998238104Sdes                                        i = (uint16_t)BN_bn2bin(b, bignum);
1999238104Sdes                                        if (i > LDNS_MAX_KEYLEN) {
2000238104Sdes                                                goto error;
2001238104Sdes                                        }
2002238104Sdes                                        b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2003238104Sdes                                        if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2004246854Sdes						ldns_rdf_deep_free(b64_bignum);
2005238104Sdes                                                goto error;
2006238104Sdes                                        }
2007238104Sdes                                        ldns_rdf_deep_free(b64_bignum);
2008238104Sdes				        ldns_buffer_printf(output, "\n");
2009238104Sdes                                        /* down reference count in EC_KEY
2010238104Sdes                                         * its still assigned to the PKEY */
2011238104Sdes                                        EC_KEY_free(ec);
2012238104Sdes                                }
2013238104Sdes#endif /* splint */
2014238104Sdes#else
2015238104Sdes				goto error;
2016238104Sdes#endif /* ECDSA */
2017238104Sdes                                break;
2018238104Sdes			case LDNS_SIGN_HMACMD5:
2019238104Sdes				/* there's not much of a format defined for TSIG */
2020238104Sdes				/* It's just a binary blob, Same for all algorithms */
2021238104Sdes                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2022238104Sdes                ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
2023238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2024238104Sdes				break;
2025238104Sdes			case LDNS_SIGN_HMACSHA1:
2026238104Sdes		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2027238104Sdes		        ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
2028238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2029238104Sdes				break;
2030238104Sdes			case LDNS_SIGN_HMACSHA256:
2031238104Sdes		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2032238104Sdes		        ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
2033238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2034238104Sdes				break;
2035238104Sdes		}
2036238104Sdes#endif /* HAVE_SSL */
2037238104Sdes	} else {
2038238104Sdes		LDNS_FREE(bignum);
2039238104Sdes		return ldns_buffer_status(output);
2040238104Sdes	}
2041238104Sdes	LDNS_FREE(bignum);
2042238104Sdes	return status;
2043238104Sdes
2044238104Sdes#ifdef HAVE_SSL
2045238104Sdes	/* compiles warn the label isn't used */
2046238104Sdeserror:
2047238104Sdes	LDNS_FREE(bignum);
2048238104Sdes	return LDNS_STATUS_ERR;
2049238104Sdes#endif /* HAVE_SSL */
2050238104Sdes
2051238104Sdes}
2052238104Sdes
2053238104Sdes/*
2054246854Sdes * Zero terminate the buffer and copy data.
2055238104Sdes */
2056238104Sdeschar *
2057238104Sdesldns_buffer2str(ldns_buffer *buffer)
2058238104Sdes{
2059238104Sdes	char *str;
2060238104Sdes
2061238104Sdes	/* check if buffer ends with \0, if not, and
2062238104Sdes	   if there is space, add it */
2063238104Sdes	if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
2064238104Sdes		if (!ldns_buffer_reserve(buffer, 1)) {
2065238104Sdes			return NULL;
2066238104Sdes		}
2067238104Sdes		ldns_buffer_write_u8(buffer, (uint8_t) '\0');
2068238104Sdes		if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
2069238104Sdes			return NULL;
2070238104Sdes		}
2071238104Sdes	}
2072238104Sdes
2073246854Sdes	str = strdup((const char *)ldns_buffer_begin(buffer));
2074238104Sdes        if(!str) {
2075238104Sdes                return NULL;
2076238104Sdes        }
2077238104Sdes	return str;
2078238104Sdes}
2079238104Sdes
2080246854Sdes/*
2081246854Sdes * Zero terminate the buffer and export data.
2082246854Sdes */
2083238104Sdeschar *
2084246854Sdesldns_buffer_export2str(ldns_buffer *buffer)
2085246854Sdes{
2086246854Sdes	/* Append '\0' as string terminator */
2087246854Sdes	if (! ldns_buffer_reserve(buffer, 1)) {
2088246854Sdes		return NULL;
2089246854Sdes	}
2090246854Sdes	ldns_buffer_write_u8(buffer, 0);
2091246854Sdes
2092246854Sdes	/* reallocate memory to the size of the string and export */
2093246854Sdes	ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
2094246854Sdes	return ldns_buffer_export(buffer);
2095246854Sdes}
2096246854Sdes
2097246854Sdeschar *
2098238104Sdesldns_rdf2str(const ldns_rdf *rdf)
2099238104Sdes{
2100238104Sdes	char *result = NULL;
2101238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2102238104Sdes
2103238104Sdes	if (!tmp_buffer) {
2104238104Sdes		return NULL;
2105238104Sdes	}
2106238104Sdes	if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
2107238104Sdes		/* export and return string, destroy rest */
2108246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2109238104Sdes	}
2110238104Sdes	ldns_buffer_free(tmp_buffer);
2111238104Sdes	return result;
2112238104Sdes}
2113238104Sdes
2114238104Sdeschar *
2115238104Sdesldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
2116238104Sdes{
2117238104Sdes	char *result = NULL;
2118238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2119238104Sdes
2120238104Sdes	if (!tmp_buffer) {
2121238104Sdes		return NULL;
2122238104Sdes	}
2123238104Sdes	if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
2124238104Sdes		       	== LDNS_STATUS_OK) {
2125238104Sdes		/* export and return string, destroy rest */
2126246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2127238104Sdes	}
2128238104Sdes	ldns_buffer_free(tmp_buffer);
2129238104Sdes	return result;
2130238104Sdes}
2131238104Sdes
2132238104Sdeschar *
2133238104Sdesldns_rr2str(const ldns_rr *rr)
2134238104Sdes{
2135238104Sdes	return ldns_rr2str_fmt(ldns_output_format_default, rr);
2136238104Sdes}
2137238104Sdes
2138238104Sdeschar *
2139238104Sdesldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
2140238104Sdes{
2141238104Sdes	char *result = NULL;
2142238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2143238104Sdes
2144238104Sdes	if (!tmp_buffer) {
2145238104Sdes		return NULL;
2146238104Sdes	}
2147238104Sdes	if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
2148238104Sdes		       	== LDNS_STATUS_OK) {
2149238104Sdes		/* export and return string, destroy rest */
2150246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2151238104Sdes	}
2152238104Sdes
2153238104Sdes	ldns_buffer_free(tmp_buffer);
2154238104Sdes	return result;
2155238104Sdes}
2156238104Sdes
2157238104Sdeschar *
2158238104Sdesldns_pkt2str(const ldns_pkt *pkt)
2159238104Sdes{
2160238104Sdes	return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
2161238104Sdes}
2162238104Sdes
2163238104Sdeschar *
2164238104Sdesldns_key2str(const ldns_key *k)
2165238104Sdes{
2166238104Sdes	char *result = NULL;
2167238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2168238104Sdes
2169238104Sdes	if (!tmp_buffer) {
2170238104Sdes		return NULL;
2171238104Sdes	}
2172238104Sdes	if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
2173238104Sdes		/* export and return string, destroy rest */
2174246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2175238104Sdes	}
2176238104Sdes	ldns_buffer_free(tmp_buffer);
2177238104Sdes	return result;
2178238104Sdes}
2179238104Sdes
2180238104Sdeschar *
2181238104Sdesldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
2182238104Sdes{
2183238104Sdes	char *result = NULL;
2184238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2185238104Sdes
2186238104Sdes	if (!tmp_buffer) {
2187238104Sdes		return NULL;
2188238104Sdes	}
2189238104Sdes	if (list) {
2190238104Sdes		if (ldns_rr_list2buffer_str_fmt(
2191238104Sdes				   tmp_buffer, fmt, list)
2192238104Sdes			       	== LDNS_STATUS_OK) {
2193238104Sdes		}
2194238104Sdes	} else {
2195238104Sdes		if (fmt == NULL) {
2196238104Sdes			fmt = ldns_output_format_default;
2197238104Sdes		}
2198238104Sdes		if (fmt->flags & LDNS_COMMENT_NULLS) {
2199238104Sdes			ldns_buffer_printf(tmp_buffer, "; (null)\n");
2200238104Sdes		}
2201238104Sdes	}
2202238104Sdes
2203238104Sdes	/* export and return string, destroy rest */
2204246854Sdes	result = ldns_buffer_export2str(tmp_buffer);
2205238104Sdes	ldns_buffer_free(tmp_buffer);
2206238104Sdes	return result;
2207238104Sdes}
2208238104Sdes
2209238104Sdeschar *
2210238104Sdesldns_rr_list2str(const ldns_rr_list *list)
2211238104Sdes{
2212238104Sdes	return ldns_rr_list2str_fmt(ldns_output_format_default, list);
2213238104Sdes}
2214238104Sdes
2215238104Sdesvoid
2216238104Sdesldns_rdf_print(FILE *output, const ldns_rdf *rdf)
2217238104Sdes{
2218238104Sdes	char *str = ldns_rdf2str(rdf);
2219238104Sdes	if (str) {
2220238104Sdes		fprintf(output, "%s", str);
2221238104Sdes	} else {
2222246854Sdes		fprintf(output, ";Unable to convert rdf to string\n");
2223238104Sdes	}
2224238104Sdes	LDNS_FREE(str);
2225238104Sdes}
2226238104Sdes
2227238104Sdesvoid
2228246854Sdesldns_rr_print_fmt(FILE *output,
2229238104Sdes		const ldns_output_format *fmt, const ldns_rr *rr)
2230238104Sdes{
2231238104Sdes	char *str = ldns_rr2str_fmt(fmt, rr);
2232238104Sdes	if (str) {
2233238104Sdes		fprintf(output, "%s", str);
2234238104Sdes	} else {
2235246854Sdes		fprintf(output, ";Unable to convert rr to string\n");
2236238104Sdes	}
2237238104Sdes	LDNS_FREE(str);
2238238104Sdes}
2239238104Sdes
2240238104Sdesvoid
2241238104Sdesldns_rr_print(FILE *output, const ldns_rr *rr)
2242238104Sdes{
2243238104Sdes	ldns_rr_print_fmt(output, ldns_output_format_default, rr);
2244238104Sdes}
2245238104Sdes
2246238104Sdesvoid
2247238104Sdesldns_pkt_print_fmt(FILE *output,
2248238104Sdes		const ldns_output_format *fmt, const ldns_pkt *pkt)
2249238104Sdes{
2250238104Sdes	char *str = ldns_pkt2str_fmt(fmt, pkt);
2251238104Sdes	if (str) {
2252238104Sdes		fprintf(output, "%s", str);
2253238104Sdes	} else {
2254246854Sdes		fprintf(output, ";Unable to convert packet to string\n");
2255238104Sdes	}
2256238104Sdes	LDNS_FREE(str);
2257238104Sdes}
2258238104Sdes
2259238104Sdesvoid
2260238104Sdesldns_pkt_print(FILE *output, const ldns_pkt *pkt)
2261238104Sdes{
2262238104Sdes	ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
2263238104Sdes}
2264238104Sdes
2265238104Sdesvoid
2266238104Sdesldns_rr_list_print_fmt(FILE *output,
2267238104Sdes		const ldns_output_format *fmt, const ldns_rr_list *lst)
2268238104Sdes{
2269238104Sdes	size_t i;
2270238104Sdes	for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
2271238104Sdes		ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
2272238104Sdes	}
2273238104Sdes}
2274238104Sdes
2275238104Sdesvoid
2276238104Sdesldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
2277238104Sdes{
2278238104Sdes	ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
2279238104Sdes}
2280238104Sdes
2281238104Sdesvoid
2282238104Sdesldns_resolver_print_fmt(FILE *output,
2283238104Sdes		const ldns_output_format *fmt, const ldns_resolver *r)
2284238104Sdes{
2285238104Sdes	uint16_t i;
2286238104Sdes	ldns_rdf **n;
2287238104Sdes	ldns_rdf **s;
2288238104Sdes	size_t *rtt;
2289238104Sdes	if (!r) {
2290238104Sdes		return;
2291238104Sdes	}
2292238104Sdes	n = ldns_resolver_nameservers(r);
2293238104Sdes	s = ldns_resolver_searchlist(r);
2294238104Sdes	rtt = ldns_resolver_rtt(r);
2295238104Sdes
2296238104Sdes	fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
2297238104Sdes	fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
2298238104Sdes	fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
2299238104Sdes
2300238104Sdes	fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
2301238104Sdes	fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
2302238104Sdes	fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
2303238104Sdes	fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
2304238104Sdes	fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
2305238104Sdes	fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
2306238104Sdes	fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
2307238104Sdes	fprintf(output, "random: %d\n", ldns_resolver_random(r));
2308238104Sdes	fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
2309238104Sdes	fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
2310238104Sdes	fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
2311238104Sdes	fprintf(output, "trust anchors (%d listed):\n",
2312238104Sdes		(int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
2313238104Sdes	ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
2314238104Sdes	fprintf(output, "tsig: %s %s\n",
2315238104Sdes                ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
2316238104Sdes                ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
2317238104Sdes	fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
2318238104Sdes
2319238104Sdes	fprintf(output, "default domain: ");
2320238104Sdes	ldns_rdf_print(output, ldns_resolver_domain(r));
2321238104Sdes	fprintf(output, "\n");
2322238104Sdes	fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
2323238104Sdes
2324238104Sdes	fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
2325238104Sdes	for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
2326238104Sdes		fprintf(output, "\t");
2327238104Sdes		ldns_rdf_print(output, s[i]);
2328238104Sdes		fprintf(output, "\n");
2329238104Sdes	}
2330238104Sdes	fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
2331238104Sdes
2332238104Sdes	fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
2333238104Sdes	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
2334238104Sdes		fprintf(output, "\t");
2335238104Sdes		ldns_rdf_print(output, n[i]);
2336238104Sdes
2337238104Sdes		switch ((int)rtt[i]) {
2338238104Sdes			case LDNS_RESOLV_RTT_MIN:
2339238104Sdes			fprintf(output, " - reachable\n");
2340238104Sdes			break;
2341238104Sdes			case LDNS_RESOLV_RTT_INF:
2342238104Sdes			fprintf(output, " - unreachable\n");
2343238104Sdes			break;
2344238104Sdes		}
2345238104Sdes	}
2346238104Sdes}
2347238104Sdes
2348238104Sdesvoid
2349238104Sdesldns_resolver_print(FILE *output, const ldns_resolver *r)
2350238104Sdes{
2351238104Sdes	ldns_resolver_print_fmt(output, ldns_output_format_default, r);
2352238104Sdes}
2353238104Sdes
2354238104Sdesvoid
2355238104Sdesldns_zone_print_fmt(FILE *output,
2356238104Sdes		const ldns_output_format *fmt, const ldns_zone *z)
2357238104Sdes{
2358238104Sdes	if(ldns_zone_soa(z))
2359238104Sdes		ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
2360238104Sdes	ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
2361238104Sdes}
2362238104Sdesvoid
2363238104Sdesldns_zone_print(FILE *output, const ldns_zone *z)
2364238104Sdes{
2365238104Sdes	ldns_zone_print_fmt(output, ldns_output_format_default, z);
2366238104Sdes}
2367