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
133266114Sdesstatic bool
134266114Sdesldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
135266114Sdes{
136266114Sdes	return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
137266114Sdes		((ldns_output_format_storage*)fmt)->bitmap &&
138266114Sdes		ldns_nsec_bitmap_covers_type(
139266114Sdes				((ldns_output_format_storage*)fmt)->bitmap, t);
140266114Sdes}
141266114Sdes
142238104Sdesldns_status
143266114Sdesldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
144266114Sdes{
145266114Sdes	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
146266114Sdes	ldns_status s;
147266114Sdes
148266114Sdes	assert(fmt != NULL);
149266114Sdes
150266114Sdes	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
151266114Sdes		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
152266114Sdes	}
153266114Sdes	if (! fmt_st->bitmap) {
154266114Sdes		s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
155266114Sdes		if (s != LDNS_STATUS_OK) {
156266114Sdes			return s;
157266114Sdes		}
158266114Sdes	}
159266114Sdes	return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
160266114Sdes}
161266114Sdes
162266114Sdesldns_status
163266114Sdesldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
164266114Sdes{
165266114Sdes	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
166266114Sdes	ldns_status s;
167266114Sdes
168266114Sdes	assert(fmt != NULL);
169266114Sdes
170266114Sdes	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
171266114Sdes		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
172266114Sdes	}
173266114Sdes	if (! fmt_st->bitmap) {
174266114Sdes		s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
175266114Sdes		if (s != LDNS_STATUS_OK) {
176266114Sdes			return s;
177266114Sdes		}
178266114Sdes	}
179266114Sdes	return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
180266114Sdes}
181266114Sdes
182266114Sdesldns_status
183238104Sdesldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
184238104Sdes{
185238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
186238104Sdes	if (lt && lt->name) {
187238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
188238104Sdes	} else {
189238104Sdes		ldns_buffer_printf(output, "OPCODE%u", opcode);
190238104Sdes	}
191238104Sdes	return ldns_buffer_status(output);
192238104Sdes}
193238104Sdes
194238104Sdesldns_status
195238104Sdesldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
196238104Sdes{
197238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
198238104Sdes	if (lt && lt->name) {
199238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
200238104Sdes	} else {
201238104Sdes		ldns_buffer_printf(output, "RCODE%u", rcode);
202238104Sdes	}
203238104Sdes	return ldns_buffer_status(output);
204238104Sdes}
205238104Sdes
206238104Sdesldns_status
207238104Sdesldns_algorithm2buffer_str(ldns_buffer *output,
208238104Sdes                          ldns_algorithm algorithm)
209238104Sdes{
210238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
211238104Sdes	                                          algorithm);
212238104Sdes	if (lt && lt->name) {
213238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
214238104Sdes	} else {
215238104Sdes		ldns_buffer_printf(output, "ALG%u", algorithm);
216238104Sdes	}
217238104Sdes	return ldns_buffer_status(output);
218238104Sdes}
219238104Sdes
220238104Sdesldns_status
221238104Sdesldns_cert_algorithm2buffer_str(ldns_buffer *output,
222238104Sdes                               ldns_cert_algorithm cert_algorithm)
223238104Sdes{
224238104Sdes	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
225238104Sdes	                                          cert_algorithm);
226238104Sdes	if (lt && lt->name) {
227238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
228238104Sdes	} else {
229238104Sdes		ldns_buffer_printf(output, "CERT_ALG%u",
230238104Sdes		                   cert_algorithm);
231238104Sdes	}
232238104Sdes	return ldns_buffer_status(output);
233238104Sdes}
234238104Sdes
235238104Sdeschar *
236238104Sdesldns_pkt_opcode2str(ldns_pkt_opcode opcode)
237238104Sdes{
238238104Sdes	char *str;
239238104Sdes	ldns_buffer *buf;
240238104Sdes
241238104Sdes	buf = ldns_buffer_new(12);
242238104Sdes	if (!buf) {
243238104Sdes		return NULL;
244238104Sdes	}
245238104Sdes
246238104Sdes	str = NULL;
247238104Sdes	if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
248246854Sdes		str = ldns_buffer_export2str(buf);
249238104Sdes	}
250238104Sdes
251238104Sdes	ldns_buffer_free(buf);
252238104Sdes	return str;
253238104Sdes}
254238104Sdes
255238104Sdeschar *
256238104Sdesldns_pkt_rcode2str(ldns_pkt_rcode rcode)
257238104Sdes{
258238104Sdes	char *str;
259238104Sdes	ldns_buffer *buf;
260238104Sdes
261238104Sdes	buf = ldns_buffer_new(10);
262238104Sdes	if (!buf) {
263238104Sdes		return NULL;
264238104Sdes	}
265238104Sdes
266238104Sdes	str = NULL;
267238104Sdes	if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
268246854Sdes		str = ldns_buffer_export2str(buf);
269238104Sdes	}
270238104Sdes
271238104Sdes	ldns_buffer_free(buf);
272238104Sdes	return str;
273238104Sdes}
274238104Sdes
275238104Sdeschar *
276238104Sdesldns_pkt_algorithm2str(ldns_algorithm algorithm)
277238104Sdes{
278238104Sdes	char *str;
279238104Sdes	ldns_buffer *buf;
280238104Sdes
281238104Sdes	buf = ldns_buffer_new(10);
282238104Sdes	if (!buf) {
283238104Sdes		return NULL;
284238104Sdes	}
285238104Sdes
286238104Sdes	str = NULL;
287238104Sdes	if (ldns_algorithm2buffer_str(buf, algorithm)
288238104Sdes	    == LDNS_STATUS_OK) {
289246854Sdes		str = ldns_buffer_export2str(buf);
290238104Sdes	}
291238104Sdes
292238104Sdes	ldns_buffer_free(buf);
293238104Sdes	return str;
294238104Sdes}
295238104Sdes
296238104Sdeschar *
297238104Sdesldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
298238104Sdes{
299238104Sdes	char *str;
300238104Sdes	ldns_buffer *buf;
301238104Sdes
302238104Sdes	buf = ldns_buffer_new(10);
303238104Sdes	if (!buf) {
304238104Sdes		return NULL;
305238104Sdes	}
306238104Sdes
307238104Sdes	str = NULL;
308238104Sdes	if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
309238104Sdes	    == LDNS_STATUS_OK) {
310246854Sdes		str = ldns_buffer_export2str(buf);
311238104Sdes	}
312238104Sdes
313238104Sdes	ldns_buffer_free(buf);
314238104Sdes	return str;
315238104Sdes}
316238104Sdes
317238104Sdes
318238104Sdes/* do NOT pass compressed data here :p */
319238104Sdesldns_status
320238104Sdesldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
321238104Sdes{
322238104Sdes	/* can we do with 1 pos var? or without at all? */
323238104Sdes	uint8_t src_pos = 0;
324238104Sdes	uint8_t len;
325238104Sdes	uint8_t *data;
326238104Sdes	uint8_t i;
327238104Sdes	unsigned char c;
328238104Sdes
329238104Sdes	data = (uint8_t*)ldns_rdf_data(dname);
330238104Sdes	len = data[src_pos];
331238104Sdes
332238104Sdes	if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
333238104Sdes		/* too large, return */
334238104Sdes		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
335238104Sdes	}
336238104Sdes
337238104Sdes	/* special case: root label */
338238104Sdes	if (1 == ldns_rdf_size(dname)) {
339238104Sdes		ldns_buffer_printf(output, ".");
340238104Sdes	} else {
341238104Sdes		while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
342238104Sdes			src_pos++;
343238104Sdes			for(i = 0; i < len; i++) {
344238104Sdes				/* paranoia check for various 'strange'
345238104Sdes				   characters in dnames
346238104Sdes				*/
347238104Sdes				c = (unsigned char) data[src_pos];
348238104Sdes				if(c == '.' || c == ';' ||
349238104Sdes				   c == '(' || c == ')' ||
350238104Sdes				   c == '\\') {
351238104Sdes					ldns_buffer_printf(output, "\\%c",
352238104Sdes							data[src_pos]);
353238104Sdes				} else if (!(isascii(c) && isgraph(c))) {
354238104Sdes					ldns_buffer_printf(output, "\\%03u",
355238104Sdes						        data[src_pos]);
356238104Sdes				} else {
357238104Sdes					ldns_buffer_printf(output, "%c", data[src_pos]);
358238104Sdes				}
359238104Sdes				src_pos++;
360238104Sdes			}
361238104Sdes
362238104Sdes			if (src_pos < ldns_rdf_size(dname)) {
363238104Sdes				ldns_buffer_printf(output, ".");
364238104Sdes			}
365238104Sdes			len = data[src_pos];
366238104Sdes		}
367238104Sdes	}
368238104Sdes	return ldns_buffer_status(output);
369238104Sdes}
370238104Sdes
371238104Sdesldns_status
372238104Sdesldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
373238104Sdes{
374238104Sdes	uint8_t data = ldns_rdf_data(rdf)[0];
375238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
376238104Sdes	return ldns_buffer_status(output);
377238104Sdes}
378238104Sdes
379238104Sdesldns_status
380238104Sdesldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
381238104Sdes{
382238104Sdes	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
383238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
384238104Sdes	return ldns_buffer_status(output);
385238104Sdes}
386238104Sdes
387238104Sdesldns_status
388238104Sdesldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
389238104Sdes{
390238104Sdes	uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
391238104Sdes	ldns_buffer_printf(output, "%lu", (unsigned long) data);
392238104Sdes	return ldns_buffer_status(output);
393238104Sdes}
394238104Sdes
395238104Sdesldns_status
396238104Sdesldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
397238104Sdes{
398238104Sdes	/* create a YYYYMMDDHHMMSS string if possible */
399238104Sdes	struct tm tm;
400238104Sdes	char date_buf[16];
401238104Sdes
402238104Sdes	memset(&tm, 0, sizeof(tm));
403238104Sdes	if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
404238104Sdes	    && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
405238104Sdes		ldns_buffer_printf(output, "%s", date_buf);
406238104Sdes	}
407238104Sdes	return ldns_buffer_status(output);
408238104Sdes}
409238104Sdes
410238104Sdesldns_status
411238104Sdesldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
412238104Sdes{
413238104Sdes	char str[INET_ADDRSTRLEN];
414238104Sdes
415238104Sdes	if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
416238104Sdes		ldns_buffer_printf(output, "%s", str);
417238104Sdes	}
418238104Sdes	return ldns_buffer_status(output);
419238104Sdes}
420238104Sdes
421238104Sdesldns_status
422238104Sdesldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
423238104Sdes{
424238104Sdes	char str[INET6_ADDRSTRLEN];
425238104Sdes
426238104Sdes	if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
427238104Sdes		ldns_buffer_printf(output, "%s", str);
428238104Sdes	}
429238104Sdes
430238104Sdes	return ldns_buffer_status(output);
431238104Sdes}
432238104Sdes
433266114Sdesstatic void
434266114Sdesldns_characters2buffer_str(ldns_buffer* output,
435266114Sdes		size_t amount, const uint8_t* characters)
436238104Sdes{
437266114Sdes	uint8_t ch;
438266114Sdes	while (amount > 0) {
439266114Sdes		ch = *characters++;
440266114Sdes		if (isprint((int)ch) || ch == '\t') {
441266114Sdes			if (ch == '\"' || ch == '\\')
442238104Sdes				ldns_buffer_printf(output, "\\%c", ch);
443238104Sdes			else
444238104Sdes				ldns_buffer_printf(output, "%c", ch);
445238104Sdes		} else {
446238104Sdes			ldns_buffer_printf(output, "\\%03u",
447238104Sdes                                (unsigned)(uint8_t) ch);
448238104Sdes		}
449266114Sdes		amount--;
450238104Sdes	}
451266114Sdes}
452266114Sdes
453266114Sdesldns_status
454266114Sdesldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
455266114Sdes{
456266114Sdes        if(ldns_rdf_size(rdf) < 1) {
457266114Sdes                return LDNS_STATUS_WIRE_RDATA_ERR;
458266114Sdes        }
459266114Sdes        if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
460266114Sdes                return LDNS_STATUS_WIRE_RDATA_ERR;
461266114Sdes        }
462238104Sdes	ldns_buffer_printf(output, "\"");
463266114Sdes	ldns_characters2buffer_str(output,
464266114Sdes			ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
465266114Sdes	ldns_buffer_printf(output, "\"");
466238104Sdes	return ldns_buffer_status(output);
467238104Sdes}
468238104Sdes
469238104Sdesldns_status
470238104Sdesldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
471238104Sdes{
472238104Sdes	size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
473238104Sdes	char *b64 = LDNS_XMALLOC(char, size);
474238104Sdes	if(!b64) return LDNS_STATUS_MEM_ERR;
475238104Sdes	if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
476238104Sdes		ldns_buffer_printf(output, "%s", b64);
477238104Sdes	}
478238104Sdes	LDNS_FREE(b64);
479238104Sdes	return ldns_buffer_status(output);
480238104Sdes}
481238104Sdes
482238104Sdesldns_status
483238104Sdesldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
484238104Sdes{
485238104Sdes	size_t size;
486238104Sdes	char *b32;
487238104Sdes	if(ldns_rdf_size(rdf) == 0)
488238104Sdes		return LDNS_STATUS_OK;
489238104Sdes        /* remove -1 for the b32-hash-len octet */
490238104Sdes	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
491238104Sdes        /* add one for the end nul for the string */
492238104Sdes	b32 = LDNS_XMALLOC(char, size + 1);
493238104Sdes	if(!b32) return LDNS_STATUS_MEM_ERR;
494238104Sdes	size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
495238104Sdes		ldns_rdf_size(rdf) - 1, b32, size+1);
496238104Sdes	if (size > 0) {
497238104Sdes		ldns_buffer_printf(output, "%s", b32);
498238104Sdes	}
499238104Sdes	LDNS_FREE(b32);
500238104Sdes	return ldns_buffer_status(output);
501238104Sdes}
502238104Sdes
503238104Sdesldns_status
504238104Sdesldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
505238104Sdes{
506238104Sdes	size_t i;
507238104Sdes	for (i = 0; i < ldns_rdf_size(rdf); i++) {
508238104Sdes		ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
509238104Sdes	}
510238104Sdes
511238104Sdes	return ldns_buffer_status(output);
512238104Sdes}
513238104Sdes
514266114Sdesstatic ldns_status
515266114Sdesldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
516266114Sdes		const ldns_output_format* fmt, const ldns_rdf *rdf)
517238104Sdes{
518238104Sdes        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
519238104Sdes
520266114Sdes	if (! ldns_output_format_covers_type(fmt, data) &&
521266114Sdes			ldns_rr_descript(data) &&
522266114Sdes			ldns_rr_descript(data)->_name) {
523266114Sdes
524266114Sdes		ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
525238104Sdes	} else {
526238104Sdes		ldns_buffer_printf(output, "TYPE%u", data);
527238104Sdes	}
528266114Sdes	return  ldns_buffer_status(output);
529238104Sdes}
530238104Sdes
531238104Sdesldns_status
532266114Sdesldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
533266114Sdes{
534266114Sdes	return ldns_rdf2buffer_str_type_fmt(output,
535266114Sdes			ldns_output_format_default, rdf);
536266114Sdes}
537266114Sdes
538266114Sdesldns_status
539238104Sdesldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
540238104Sdes{
541238104Sdes	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
542238104Sdes	ldns_lookup_table *lt;
543238104Sdes
544238104Sdes 	lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
545238104Sdes	if (lt) {
546238104Sdes		ldns_buffer_printf(output, "\t%s", lt->name);
547238104Sdes	} else {
548238104Sdes		ldns_buffer_printf(output, "\tCLASS%d", data);
549238104Sdes	}
550238104Sdes	return ldns_buffer_status(output);
551238104Sdes}
552238104Sdes
553238104Sdesldns_status
554238104Sdesldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
555238104Sdes{
556238104Sdes        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
557238104Sdes	ldns_lookup_table *lt;
558238104Sdes 	lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
559238104Sdes	if (lt) {
560238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
561238104Sdes	} else {
562238104Sdes		ldns_buffer_printf(output, "%d", data);
563238104Sdes	}
564238104Sdes	return ldns_buffer_status(output);
565238104Sdes}
566238104Sdes
567238104Sdesldns_status
568238104Sdesldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
569238104Sdes{
570238104Sdes	/* don't use algorithm mnemonics in the presentation format
571238104Sdes	   this kind of got sneaked into the rfc's */
572238104Sdes        uint8_t data = ldns_rdf_data(rdf)[0];
573238104Sdes		ldns_buffer_printf(output, "%d", data);
574238104Sdes	return ldns_buffer_status(output);
575238104Sdes}
576238104Sdes
577238104Sdesstatic void
578238104Sdesloc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
579238104Sdes{
580238104Sdes	uint8_t i;
581238104Sdes	/* is it 0.<two digits> ? */
582238104Sdes	if(exponent < 2) {
583238104Sdes		if(exponent == 1)
584238104Sdes			mantissa *= 10;
585238104Sdes		ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
586238104Sdes		return;
587238104Sdes	}
588238104Sdes	/* always <digit><string of zeros> */
589238104Sdes	ldns_buffer_printf(output, "%d", (int)mantissa);
590238104Sdes	for(i=0; i<exponent-2; i++)
591238104Sdes		ldns_buffer_printf(output, "0");
592238104Sdes}
593238104Sdes
594238104Sdesldns_status
595238104Sdesldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
596238104Sdes{
597238104Sdes	const ldns_rr_descriptor *descriptor;
598238104Sdes
599238104Sdes	descriptor = ldns_rr_descript(type);
600238104Sdes
601238104Sdes	if (descriptor && descriptor->_name) {
602238104Sdes		ldns_buffer_printf(output, "%s", descriptor->_name);
603238104Sdes	} else {
604238104Sdes		/* exceptions for pseudotypes */
605238104Sdes		switch (type) {
606238104Sdes			case LDNS_RR_TYPE_IXFR:
607238104Sdes				ldns_buffer_printf(output, "IXFR");
608238104Sdes				break;
609238104Sdes			case LDNS_RR_TYPE_AXFR:
610238104Sdes				ldns_buffer_printf(output, "AXFR");
611238104Sdes				break;
612238104Sdes			case LDNS_RR_TYPE_MAILA:
613238104Sdes				ldns_buffer_printf(output, "MAILA");
614238104Sdes				break;
615238104Sdes			case LDNS_RR_TYPE_MAILB:
616238104Sdes				ldns_buffer_printf(output, "MAILB");
617238104Sdes				break;
618238104Sdes			case LDNS_RR_TYPE_ANY:
619238104Sdes				ldns_buffer_printf(output, "ANY");
620238104Sdes				break;
621238104Sdes			default:
622238104Sdes				ldns_buffer_printf(output, "TYPE%u", type);
623238104Sdes		}
624238104Sdes	}
625238104Sdes	return ldns_buffer_status(output);
626238104Sdes}
627238104Sdes
628238104Sdeschar *
629238104Sdesldns_rr_type2str(const ldns_rr_type type)
630238104Sdes{
631238104Sdes	char *str;
632238104Sdes	ldns_buffer *buf;
633238104Sdes
634238104Sdes	buf = ldns_buffer_new(10);
635238104Sdes	if (!buf) {
636238104Sdes		return NULL;
637238104Sdes	}
638238104Sdes
639238104Sdes	str = NULL;
640238104Sdes	if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
641246854Sdes		str = ldns_buffer_export2str(buf);
642238104Sdes	}
643238104Sdes
644238104Sdes	ldns_buffer_free(buf);
645238104Sdes	return str;
646238104Sdes}
647238104Sdes
648238104Sdes
649238104Sdesldns_status
650238104Sdesldns_rr_class2buffer_str(ldns_buffer *output,
651238104Sdes                         const ldns_rr_class klass)
652238104Sdes{
653238104Sdes	ldns_lookup_table *lt;
654238104Sdes
655238104Sdes	lt = ldns_lookup_by_id(ldns_rr_classes, klass);
656238104Sdes	if (lt) {
657238104Sdes		ldns_buffer_printf(output, "%s", lt->name);
658238104Sdes	} else {
659238104Sdes		ldns_buffer_printf(output, "CLASS%d", klass);
660238104Sdes	}
661238104Sdes	return ldns_buffer_status(output);
662238104Sdes}
663238104Sdes
664238104Sdeschar *
665238104Sdesldns_rr_class2str(const ldns_rr_class klass)
666238104Sdes{
667238104Sdes	ldns_buffer *buf;
668238104Sdes	char *str;
669238104Sdes
670238104Sdes	buf = ldns_buffer_new(10);
671238104Sdes	if (!buf) {
672238104Sdes		return NULL;
673238104Sdes	}
674238104Sdes
675238104Sdes	str = NULL;
676238104Sdes	if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
677246854Sdes		str = ldns_buffer_export2str(buf);
678238104Sdes	}
679238104Sdes	ldns_buffer_free(buf);
680238104Sdes	return str;
681238104Sdes}
682238104Sdes
683238104Sdesldns_status
684238104Sdesldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
685238104Sdes{
686238104Sdes	/* we could do checking (ie degrees < 90 etc)? */
687266114Sdes	uint8_t version;
688238104Sdes	uint8_t size;
689238104Sdes	uint8_t horizontal_precision;
690238104Sdes	uint8_t vertical_precision;
691238104Sdes	uint32_t longitude;
692238104Sdes	uint32_t latitude;
693238104Sdes	uint32_t altitude;
694238104Sdes	char northerness;
695238104Sdes	char easterness;
696238104Sdes	uint32_t h;
697238104Sdes	uint32_t m;
698238104Sdes	double s;
699238104Sdes
700238104Sdes	uint32_t equator = (uint32_t) ldns_power(2, 31);
701238104Sdes
702266114Sdes        if(ldns_rdf_size(rdf) < 1) {
703266114Sdes                return LDNS_STATUS_WIRE_RDATA_ERR;
704266114Sdes        }
705266114Sdes       	version = ldns_rdf_data(rdf)[0];
706238104Sdes	if (version == 0) {
707266114Sdes		if(ldns_rdf_size(rdf) < 16) {
708266114Sdes			return LDNS_STATUS_WIRE_RDATA_ERR;
709266114Sdes		}
710238104Sdes		size = ldns_rdf_data(rdf)[1];
711238104Sdes		horizontal_precision = ldns_rdf_data(rdf)[2];
712238104Sdes		vertical_precision = ldns_rdf_data(rdf)[3];
713238104Sdes
714238104Sdes		latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
715238104Sdes		longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
716238104Sdes		altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
717238104Sdes
718238104Sdes		if (latitude > equator) {
719238104Sdes			northerness = 'N';
720238104Sdes			latitude = latitude - equator;
721238104Sdes		} else {
722238104Sdes			northerness = 'S';
723238104Sdes			latitude = equator - latitude;
724238104Sdes		}
725238104Sdes		h = latitude / (1000 * 60 * 60);
726238104Sdes		latitude = latitude % (1000 * 60 * 60);
727238104Sdes		m = latitude / (1000 * 60);
728238104Sdes		latitude = latitude % (1000 * 60);
729238104Sdes		s = (double) latitude / 1000.0;
730238104Sdes		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
731238104Sdes			h, m, s, northerness);
732238104Sdes
733238104Sdes		if (longitude > equator) {
734238104Sdes			easterness = 'E';
735238104Sdes			longitude = longitude - equator;
736238104Sdes		} else {
737238104Sdes			easterness = 'W';
738238104Sdes			longitude = equator - longitude;
739238104Sdes		}
740238104Sdes		h = longitude / (1000 * 60 * 60);
741238104Sdes		longitude = longitude % (1000 * 60 * 60);
742238104Sdes		m = longitude / (1000 * 60);
743238104Sdes		longitude = longitude % (1000 * 60);
744238104Sdes		s = (double) longitude / (1000.0);
745238104Sdes		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
746238104Sdes			h, m, s, easterness);
747238104Sdes
748238104Sdes
749266114Sdes		s = ((double) altitude) / 100;
750266114Sdes		s -= 100000;
751238104Sdes
752238104Sdes		if(altitude%100 != 0)
753238104Sdes			ldns_buffer_printf(output, "%.2f", s);
754266114Sdes		else
755238104Sdes			ldns_buffer_printf(output, "%.0f", s);
756238104Sdes
757238104Sdes		ldns_buffer_printf(output, "m ");
758238104Sdes
759238104Sdes		loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
760238104Sdes		ldns_buffer_printf(output, "m ");
761238104Sdes
762238104Sdes		loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
763238104Sdes			horizontal_precision & 0x0f);
764238104Sdes		ldns_buffer_printf(output, "m ");
765238104Sdes
766238104Sdes		loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
767238104Sdes			vertical_precision & 0x0f);
768238104Sdes		ldns_buffer_printf(output, "m");
769238104Sdes
770238104Sdes		return ldns_buffer_status(output);
771238104Sdes	} else {
772238104Sdes		return ldns_rdf2buffer_str_hex(output, rdf);
773238104Sdes	}
774238104Sdes}
775238104Sdes
776238104Sdesldns_status
777238104Sdesldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
778238104Sdes{
779238104Sdes	ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
780238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
781238104Sdes}
782238104Sdes
783238104Sdesldns_status
784238104Sdesldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
785238104Sdes{
786238104Sdes	ldns_buffer_printf(output, "0x");
787238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
788238104Sdes}
789238104Sdes
790238104Sdesldns_status
791238104Sdesldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
792238104Sdes{
793238104Sdes	return ldns_rdf2buffer_str_hex(output, rdf);
794238104Sdes}
795238104Sdes
796238104Sdesldns_status
797238104Sdesldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
798238104Sdes{
799238104Sdes	/* protocol, followed by bitmap of services */
800238104Sdes	struct protoent *protocol;
801238104Sdes	char *proto_name = NULL;
802238104Sdes	uint8_t protocol_nr;
803238104Sdes	struct servent *service;
804238104Sdes	uint16_t current_service;
805238104Sdes
806266114Sdes        if(ldns_rdf_size(rdf) < 1) {
807266114Sdes                return LDNS_STATUS_WIRE_RDATA_ERR;
808266114Sdes        }
809238104Sdes	protocol_nr = ldns_rdf_data(rdf)[0];
810238104Sdes	protocol = getprotobynumber((int) protocol_nr);
811238104Sdes	if (protocol && (protocol->p_name != NULL)) {
812238104Sdes		proto_name = protocol->p_name;
813238104Sdes		ldns_buffer_printf(output, "%s ", protocol->p_name);
814238104Sdes	} else {
815238104Sdes		ldns_buffer_printf(output, "%u ", protocol_nr);
816238104Sdes	}
817238104Sdes
818238104Sdes#ifdef HAVE_ENDPROTOENT
819238104Sdes	endprotoent();
820238104Sdes#endif
821238104Sdes
822238104Sdes	for (current_service = 0;
823238104Sdes	     current_service < ldns_rdf_size(rdf) * 7; current_service++) {
824238104Sdes		if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
825238104Sdes			service = getservbyport((int) htons(current_service),
826238104Sdes			                        proto_name);
827238104Sdes			if (service && service->s_name) {
828238104Sdes				ldns_buffer_printf(output, "%s ", service->s_name);
829238104Sdes			} else {
830238104Sdes				ldns_buffer_printf(output, "%u ", current_service);
831238104Sdes			}
832238104Sdes#ifdef HAVE_ENDSERVENT
833238104Sdes			endservent();
834238104Sdes#endif
835238104Sdes		}
836238104Sdes	}
837238104Sdes	return ldns_buffer_status(output);
838238104Sdes}
839238104Sdes
840266114Sdesstatic ldns_status
841266114Sdesldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
842266114Sdes		const ldns_output_format* fmt, const ldns_rdf *rdf)
843238104Sdes{
844238104Sdes	/* Note: this code is duplicated in higher.c in
845238104Sdes	 * ldns_nsec_type_check() function
846238104Sdes	 */
847238104Sdes	uint8_t window_block_nr;
848238104Sdes	uint8_t bitmap_length;
849238104Sdes	uint16_t type;
850238104Sdes	uint16_t pos = 0;
851238104Sdes	uint16_t bit_pos;
852238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
853238104Sdes
854266114Sdes	while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
855238104Sdes		window_block_nr = data[pos];
856238104Sdes		bitmap_length = data[pos + 1];
857238104Sdes		pos += 2;
858266114Sdes		if (ldns_rdf_size(rdf) < pos + bitmap_length) {
859266114Sdes			return LDNS_STATUS_WIRE_RDATA_ERR;
860266114Sdes		}
861238104Sdes		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
862266114Sdes			if (! ldns_get_bit(&data[pos], bit_pos)) {
863266114Sdes				continue;
864266114Sdes			}
865266114Sdes			type = 256 * (uint16_t) window_block_nr + bit_pos;
866238104Sdes
867266114Sdes			if (! ldns_output_format_covers_type(fmt, type) &&
868266114Sdes					ldns_rr_descript(type) &&
869266114Sdes					ldns_rr_descript(type)->_name){
870266114Sdes
871266114Sdes				ldns_buffer_printf(output, "%s ",
872266114Sdes						ldns_rr_descript(type)->_name);
873266114Sdes			} else {
874266114Sdes				ldns_buffer_printf(output, "TYPE%u ", type);
875238104Sdes			}
876238104Sdes		}
877238104Sdes		pos += (uint16_t) bitmap_length;
878238104Sdes	}
879238104Sdes	return ldns_buffer_status(output);
880238104Sdes}
881238104Sdes
882238104Sdesldns_status
883266114Sdesldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
884266114Sdes{
885266114Sdes	return ldns_rdf2buffer_str_nsec_fmt(output,
886266114Sdes			ldns_output_format_default, rdf);
887266114Sdes}
888266114Sdes
889266114Sdesldns_status
890238104Sdesldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
891238104Sdes{
892238104Sdes	uint8_t salt_length;
893238104Sdes	uint8_t salt_pos;
894238104Sdes
895238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
896238104Sdes
897266114Sdes        if(ldns_rdf_size(rdf) < 1) {
898266114Sdes                return LDNS_STATUS_WIRE_RDATA_ERR;
899238104Sdes        }
900238104Sdes	salt_length = data[0];
901238104Sdes	/* from now there are variable length entries so remember pos */
902238104Sdes	if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
903238104Sdes		ldns_buffer_printf(output, "- ");
904238104Sdes	} else {
905238104Sdes		for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
906238104Sdes			ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
907238104Sdes		}
908238104Sdes		ldns_buffer_printf(output, " ");
909238104Sdes	}
910238104Sdes
911238104Sdes	return ldns_buffer_status(output);
912238104Sdes}
913238104Sdes
914238104Sdesldns_status
915238104Sdesldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
916238104Sdes{
917238104Sdes	/* period is the number of seconds */
918266114Sdes	if (ldns_rdf_size(rdf) != 4) {
919266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
920266114Sdes	}
921266114Sdes	ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
922238104Sdes	return ldns_buffer_status(output);
923238104Sdes}
924238104Sdes
925238104Sdesldns_status
926238104Sdesldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
927238104Sdes{
928238104Sdes	/* tsigtime is 48 bits network order unsigned integer */
929238104Sdes	uint64_t tsigtime = 0;
930238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
931266114Sdes	uint64_t d0, d1, d2, d3, d4, d5;
932238104Sdes
933266114Sdes	if (ldns_rdf_size(rdf) < 6) {
934266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
935238104Sdes	}
936266114Sdes	d0 = data[0]; /* cast to uint64 for shift operations */
937266114Sdes	d1 = data[1];
938266114Sdes	d2 = data[2];
939266114Sdes	d3 = data[3];
940266114Sdes	d4 = data[4];
941266114Sdes	d5 = data[5];
942266114Sdes	tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
943238104Sdes
944266114Sdes	ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
945238104Sdes
946238104Sdes	return ldns_buffer_status(output);
947238104Sdes}
948238104Sdes
949238104Sdesldns_status
950238104Sdesldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
951238104Sdes{
952238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
953238104Sdes	uint16_t address_family;
954238104Sdes	uint8_t prefix;
955238104Sdes	bool negation;
956238104Sdes	uint8_t adf_length;
957238104Sdes	size_t i;
958238104Sdes	size_t pos = 0;
959238104Sdes
960238104Sdes	while (pos < (unsigned int) ldns_rdf_size(rdf)) {
961238104Sdes                if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
962266114Sdes                        return LDNS_STATUS_WIRE_RDATA_ERR;
963238104Sdes		address_family = ldns_read_uint16(&data[pos]);
964238104Sdes		prefix = data[pos + 2];
965238104Sdes		negation = data[pos + 3] & LDNS_APL_NEGATION;
966238104Sdes		adf_length = data[pos + 3] & LDNS_APL_MASK;
967238104Sdes		if (address_family == LDNS_APL_IP4) {
968238104Sdes			/* check if prefix < 32? */
969238104Sdes			if (negation) {
970238104Sdes				ldns_buffer_printf(output, "!");
971238104Sdes			}
972238104Sdes			ldns_buffer_printf(output, "%u:", address_family);
973238104Sdes			/* address is variable length 0 - 4 */
974238104Sdes			for (i = 0; i < 4; i++) {
975238104Sdes				if (i > 0) {
976238104Sdes					ldns_buffer_printf(output, ".");
977238104Sdes				}
978238104Sdes				if (i < (unsigned short) adf_length) {
979238104Sdes                                        if(pos+i+4 >= ldns_rdf_size(rdf))
980266114Sdes					    return LDNS_STATUS_WIRE_RDATA_ERR;
981238104Sdes					ldns_buffer_printf(output, "%d",
982238104Sdes					                   data[pos + i + 4]);
983238104Sdes				} else {
984238104Sdes					ldns_buffer_printf(output, "0");
985238104Sdes				}
986238104Sdes			}
987238104Sdes			ldns_buffer_printf(output, "/%u ", prefix);
988238104Sdes		} else if (address_family == LDNS_APL_IP6) {
989238104Sdes			/* check if prefix < 128? */
990238104Sdes			if (negation) {
991238104Sdes				ldns_buffer_printf(output, "!");
992238104Sdes			}
993238104Sdes			ldns_buffer_printf(output, "%u:", address_family);
994238104Sdes			/* address is variable length 0 - 16 */
995238104Sdes			for (i = 0; i < 16; i++) {
996238104Sdes				if (i % 2 == 0 && i > 0) {
997238104Sdes					ldns_buffer_printf(output, ":");
998238104Sdes				}
999238104Sdes				if (i < (unsigned short) adf_length) {
1000238104Sdes                                        if(pos+i+4 >= ldns_rdf_size(rdf))
1001266114Sdes					    return LDNS_STATUS_WIRE_RDATA_ERR;
1002238104Sdes					ldns_buffer_printf(output, "%02x",
1003238104Sdes					                   data[pos + i + 4]);
1004238104Sdes				} else {
1005238104Sdes					ldns_buffer_printf(output, "00");
1006238104Sdes				}
1007238104Sdes			}
1008238104Sdes			ldns_buffer_printf(output, "/%u ", prefix);
1009238104Sdes
1010238104Sdes		} else {
1011238104Sdes			/* unknown address family */
1012266114Sdes			ldns_buffer_printf(output,
1013266114Sdes					"Unknown address family: %u data: ",
1014238104Sdes					address_family);
1015238104Sdes			for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
1016238104Sdes                                if(pos+i >= ldns_rdf_size(rdf))
1017266114Sdes                                        return LDNS_STATUS_WIRE_RDATA_ERR;
1018238104Sdes				ldns_buffer_printf(output, "%02x", data[i]);
1019238104Sdes			}
1020238104Sdes		}
1021238104Sdes		pos += 4 + adf_length;
1022238104Sdes	}
1023238104Sdes	return ldns_buffer_status(output);
1024238104Sdes}
1025238104Sdes
1026238104Sdesldns_status
1027238104Sdesldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
1028238104Sdes{
1029266114Sdes	size_t size;
1030266114Sdes	char *b64;
1031266114Sdes	if (ldns_rdf_size(rdf) < 2) {
1032266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1033266114Sdes	}
1034238104Sdes	/* Subtract the size (2) of the number that specifies the length */
1035266114Sdes	size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
1036238104Sdes	ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
1037266114Sdes	if (ldns_rdf_size(rdf) > 2) {
1038266114Sdes		b64 = LDNS_XMALLOC(char, size);
1039266114Sdes		if(!b64)
1040266114Sdes			return LDNS_STATUS_MEM_ERR;
1041238104Sdes
1042266114Sdes		if (ldns_rdf_size(rdf) > 2 &&
1043266114Sdes		ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
1044266114Sdes					ldns_rdf_size(rdf) - 2,
1045266114Sdes					b64, size)) {
1046266114Sdes			ldns_buffer_printf(output, "%s", b64);
1047266114Sdes		}
1048266114Sdes		LDNS_FREE(b64);
1049238104Sdes	}
1050238104Sdes	return ldns_buffer_status(output);
1051238104Sdes}
1052238104Sdes
1053238104Sdesldns_status
1054238104Sdesldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
1055238104Sdes{
1056238104Sdes	/* wire format from
1057238104Sdes	   http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
1058238104Sdes	*/
1059238104Sdes	uint8_t *data = ldns_rdf_data(rdf);
1060238104Sdes	uint8_t precedence;
1061238104Sdes	uint8_t gateway_type;
1062238104Sdes	uint8_t algorithm;
1063238104Sdes
1064238104Sdes	ldns_rdf *gateway = NULL;
1065238104Sdes	uint8_t *gateway_data;
1066238104Sdes
1067238104Sdes	size_t public_key_size;
1068238104Sdes	uint8_t *public_key_data;
1069238104Sdes	ldns_rdf *public_key;
1070238104Sdes
1071238104Sdes	size_t offset = 0;
1072238104Sdes	ldns_status status;
1073238104Sdes
1074266114Sdes	if (ldns_rdf_size(rdf) < 3) {
1075266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1076266114Sdes	}
1077238104Sdes	precedence = data[0];
1078238104Sdes	gateway_type = data[1];
1079238104Sdes	algorithm = data[2];
1080238104Sdes	offset = 3;
1081238104Sdes
1082238104Sdes	switch (gateway_type) {
1083238104Sdes		case 0:
1084238104Sdes			/* no gateway */
1085238104Sdes			break;
1086238104Sdes		case 1:
1087238104Sdes			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1088238104Sdes                        if(!gateway_data)
1089238104Sdes                                return LDNS_STATUS_MEM_ERR;
1090266114Sdes			if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1091266114Sdes				return LDNS_STATUS_ERR;
1092266114Sdes			}
1093238104Sdes			memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
1094266114Sdes			gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
1095266114Sdes					LDNS_IP4ADDRLEN , gateway_data);
1096238104Sdes			offset += LDNS_IP4ADDRLEN;
1097238104Sdes                        if(!gateway) {
1098238104Sdes                                LDNS_FREE(gateway_data);
1099238104Sdes                                return LDNS_STATUS_MEM_ERR;
1100238104Sdes                        }
1101238104Sdes			break;
1102238104Sdes		case 2:
1103238104Sdes			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1104238104Sdes                        if(!gateway_data)
1105238104Sdes                                return LDNS_STATUS_MEM_ERR;
1106266114Sdes			if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1107266114Sdes				return LDNS_STATUS_ERR;
1108266114Sdes			}
1109238104Sdes			memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
1110238104Sdes			offset += LDNS_IP6ADDRLEN;
1111238104Sdes			gateway =
1112266114Sdes				ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1113266114Sdes						LDNS_IP6ADDRLEN, gateway_data);
1114238104Sdes                        if(!gateway) {
1115238104Sdes                                LDNS_FREE(gateway_data);
1116238104Sdes                                return LDNS_STATUS_MEM_ERR;
1117238104Sdes                        }
1118238104Sdes			break;
1119238104Sdes		case 3:
1120266114Sdes			status = ldns_wire2dname(&gateway, data,
1121266114Sdes					ldns_rdf_size(rdf), &offset);
1122238104Sdes                        if(status != LDNS_STATUS_OK)
1123238104Sdes                                return status;
1124238104Sdes			break;
1125238104Sdes		default:
1126238104Sdes			/* error? */
1127238104Sdes			break;
1128238104Sdes	}
1129238104Sdes
1130266114Sdes	if (ldns_rdf_size(rdf) <= offset) {
1131266114Sdes		return LDNS_STATUS_ERR;
1132266114Sdes	}
1133238104Sdes	public_key_size = ldns_rdf_size(rdf) - offset;
1134238104Sdes	public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1135238104Sdes        if(!public_key_data) {
1136238104Sdes                ldns_rdf_free(gateway);
1137238104Sdes                return LDNS_STATUS_MEM_ERR;
1138238104Sdes        }
1139238104Sdes	memcpy(public_key_data, &data[offset], public_key_size);
1140266114Sdes	public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
1141266114Sdes			public_key_size, public_key_data);
1142238104Sdes        if(!public_key) {
1143238104Sdes                LDNS_FREE(public_key_data);
1144238104Sdes                ldns_rdf_free(gateway);
1145238104Sdes                return LDNS_STATUS_MEM_ERR;
1146238104Sdes        }
1147238104Sdes
1148238104Sdes	ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1149266114Sdes	if (gateway)
1150238104Sdes	  	(void) ldns_rdf2buffer_str(output, gateway);
1151238104Sdes	else
1152238104Sdes		ldns_buffer_printf(output, ".");
1153238104Sdes	ldns_buffer_printf(output, " ");
1154238104Sdes	(void) ldns_rdf2buffer_str(output, public_key);
1155238104Sdes
1156238104Sdes	ldns_rdf_free(gateway);
1157238104Sdes	ldns_rdf_free(public_key);
1158238104Sdes
1159238104Sdes	return ldns_buffer_status(output);
1160238104Sdes}
1161238104Sdes
1162238104Sdesldns_status
1163266114Sdesldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
1164238104Sdes{
1165266114Sdes	if (ldns_rdf_size(rdf) != 8) {
1166266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1167266114Sdes	}
1168266114Sdes	ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
1169266114Sdes				ldns_read_uint16(ldns_rdf_data(rdf)),
1170266114Sdes				ldns_read_uint16(ldns_rdf_data(rdf)+2),
1171266114Sdes				ldns_read_uint16(ldns_rdf_data(rdf)+4),
1172266114Sdes				ldns_read_uint16(ldns_rdf_data(rdf)+6));
1173266114Sdes	return ldns_buffer_status(output);
1174238104Sdes}
1175238104Sdes
1176266114Sdesldns_status
1177266114Sdesldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
1178266114Sdes{
1179266114Sdes	if (ldns_rdf_size(rdf) != 6) {
1180266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1181266114Sdes	}
1182266114Sdes	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1183266114Sdes				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1184266114Sdes				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1185266114Sdes				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
1186266114Sdes	return ldns_buffer_status(output);
1187266114Sdes}
1188238104Sdes
1189238104Sdesldns_status
1190266114Sdesldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
1191238104Sdes{
1192266114Sdes	if (ldns_rdf_size(rdf) != 8) {
1193266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1194266114Sdes	}
1195266114Sdes	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1196266114Sdes				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1197266114Sdes				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1198266114Sdes				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
1199266114Sdes				ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
1200266114Sdes	return ldns_buffer_status(output);
1201266114Sdes}
1202266114Sdes
1203266114Sdesldns_status
1204266114Sdesldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
1205266114Sdes{
1206266114Sdes	size_t nchars;
1207266114Sdes	const uint8_t* chars;
1208266114Sdes	char ch;
1209266114Sdes	if (ldns_rdf_size(rdf) < 2) {
1210266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1211266114Sdes	}
1212266114Sdes	nchars = ldns_rdf_data(rdf)[0];
1213266114Sdes	if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
1214266114Sdes			nchars < 1) {
1215266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1216266114Sdes	}
1217266114Sdes	chars = ldns_rdf_data(rdf) + 1;
1218266114Sdes	while (nchars > 0) {
1219266114Sdes		ch = (char)*chars++;
1220266114Sdes		if (! isalnum(ch)) {
1221266114Sdes			return LDNS_STATUS_WIRE_RDATA_ERR;
1222266114Sdes		}
1223266114Sdes		ldns_buffer_printf(output, "%c", ch);
1224266114Sdes		nchars--;
1225266114Sdes	}
1226266114Sdes	return ldns_buffer_status(output);
1227266114Sdes}
1228266114Sdes
1229266114Sdesldns_status
1230266114Sdesldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
1231266114Sdes{
1232266114Sdes
1233266114Sdes	ldns_buffer_printf(output, "\"");
1234266114Sdes	ldns_characters2buffer_str(output,
1235266114Sdes			ldns_rdf_size(rdf), ldns_rdf_data(rdf));
1236266114Sdes	ldns_buffer_printf(output, "\"");
1237266114Sdes	return ldns_buffer_status(output);
1238266114Sdes}
1239266114Sdes
1240266114Sdesldns_status
1241266114Sdesldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
1242266114Sdes{
1243266114Sdes	uint8_t *data = ldns_rdf_data(rdf);
1244266114Sdes	size_t rdf_size = ldns_rdf_size(rdf);
1245266114Sdes	uint8_t hit_size;
1246266114Sdes	uint16_t pk_size;
1247266114Sdes	int written;
1248266114Sdes
1249266114Sdes	if (rdf_size < 6) {
1250266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1251266114Sdes	}
1252266114Sdes	if ((hit_size = data[0]) == 0 ||
1253266114Sdes			(pk_size = ldns_read_uint16(data + 2)) == 0 ||
1254266114Sdes			rdf_size < (size_t) hit_size + pk_size + 4) {
1255266114Sdes
1256266114Sdes		return LDNS_STATUS_WIRE_RDATA_ERR;
1257266114Sdes	}
1258266114Sdes
1259266114Sdes	ldns_buffer_printf(output, "%d ", (int) data[1]);
1260266114Sdes
1261266114Sdes	for (data += 4; hit_size > 0; hit_size--, data++) {
1262266114Sdes
1263266114Sdes		ldns_buffer_printf(output, "%02x", (int) *data);
1264266114Sdes	}
1265266114Sdes	ldns_buffer_write_u8(output, (uint8_t) ' ');
1266266114Sdes
1267266114Sdes	if (ldns_buffer_reserve(output,
1268266114Sdes				ldns_b64_ntop_calculate_size(pk_size))) {
1269266114Sdes
1270266114Sdes		written = ldns_b64_ntop(data, pk_size,
1271266114Sdes				(char *) ldns_buffer_current(output),
1272266114Sdes				ldns_buffer_remaining(output));
1273266114Sdes
1274266114Sdes		if (written > 0 &&
1275266114Sdes				written < (int) ldns_buffer_remaining(output)) {
1276266114Sdes
1277266114Sdes			output->_position += written;
1278266114Sdes		}
1279266114Sdes	}
1280266114Sdes	return ldns_buffer_status(output);
1281266114Sdes}
1282266114Sdes
1283266114Sdesstatic ldns_status
1284266114Sdesldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
1285266114Sdes		const ldns_output_format* fmt, const ldns_rdf *rdf)
1286266114Sdes{
1287238104Sdes	ldns_status res = LDNS_STATUS_OK;
1288238104Sdes
1289238104Sdes	/*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1290238104Sdes	if (rdf) {
1291238104Sdes		switch(ldns_rdf_get_type(rdf)) {
1292238104Sdes		case LDNS_RDF_TYPE_NONE:
1293238104Sdes			break;
1294238104Sdes		case LDNS_RDF_TYPE_DNAME:
1295238104Sdes			res = ldns_rdf2buffer_str_dname(buffer, rdf);
1296238104Sdes			break;
1297238104Sdes		case LDNS_RDF_TYPE_INT8:
1298238104Sdes			res = ldns_rdf2buffer_str_int8(buffer, rdf);
1299238104Sdes			break;
1300238104Sdes		case LDNS_RDF_TYPE_INT16:
1301238104Sdes			res = ldns_rdf2buffer_str_int16(buffer, rdf);
1302238104Sdes			break;
1303238104Sdes		case LDNS_RDF_TYPE_INT32:
1304238104Sdes			res = ldns_rdf2buffer_str_int32(buffer, rdf);
1305238104Sdes			break;
1306238104Sdes		case LDNS_RDF_TYPE_PERIOD:
1307238104Sdes			res = ldns_rdf2buffer_str_period(buffer, rdf);
1308238104Sdes			break;
1309238104Sdes		case LDNS_RDF_TYPE_TSIGTIME:
1310238104Sdes			res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1311238104Sdes			break;
1312238104Sdes		case LDNS_RDF_TYPE_A:
1313238104Sdes			res = ldns_rdf2buffer_str_a(buffer, rdf);
1314238104Sdes			break;
1315238104Sdes		case LDNS_RDF_TYPE_AAAA:
1316238104Sdes			res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1317238104Sdes			break;
1318238104Sdes		case LDNS_RDF_TYPE_STR:
1319238104Sdes			res = ldns_rdf2buffer_str_str(buffer, rdf);
1320238104Sdes			break;
1321238104Sdes		case LDNS_RDF_TYPE_APL:
1322238104Sdes			res = ldns_rdf2buffer_str_apl(buffer, rdf);
1323238104Sdes			break;
1324238104Sdes		case LDNS_RDF_TYPE_B32_EXT:
1325238104Sdes			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1326238104Sdes			break;
1327238104Sdes		case LDNS_RDF_TYPE_B64:
1328238104Sdes			res = ldns_rdf2buffer_str_b64(buffer, rdf);
1329238104Sdes			break;
1330238104Sdes		case LDNS_RDF_TYPE_HEX:
1331238104Sdes			res = ldns_rdf2buffer_str_hex(buffer, rdf);
1332238104Sdes			break;
1333238104Sdes		case LDNS_RDF_TYPE_NSEC:
1334266114Sdes			res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
1335238104Sdes			break;
1336238104Sdes		case LDNS_RDF_TYPE_NSEC3_SALT:
1337238104Sdes			res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1338238104Sdes			break;
1339238104Sdes		case LDNS_RDF_TYPE_TYPE:
1340266114Sdes			res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
1341238104Sdes			break;
1342238104Sdes		case LDNS_RDF_TYPE_CLASS:
1343238104Sdes			res = ldns_rdf2buffer_str_class(buffer, rdf);
1344238104Sdes			break;
1345238104Sdes		case LDNS_RDF_TYPE_CERT_ALG:
1346238104Sdes			res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1347238104Sdes			break;
1348238104Sdes		case LDNS_RDF_TYPE_ALG:
1349238104Sdes			res = ldns_rdf2buffer_str_alg(buffer, rdf);
1350238104Sdes			break;
1351238104Sdes		case LDNS_RDF_TYPE_UNKNOWN:
1352238104Sdes			res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1353238104Sdes			break;
1354238104Sdes		case LDNS_RDF_TYPE_TIME:
1355238104Sdes			res = ldns_rdf2buffer_str_time(buffer, rdf);
1356238104Sdes			break;
1357266114Sdes		case LDNS_RDF_TYPE_HIP:
1358266114Sdes			res = ldns_rdf2buffer_str_hip(buffer, rdf);
1359266114Sdes			break;
1360238104Sdes		case LDNS_RDF_TYPE_LOC:
1361238104Sdes			res = ldns_rdf2buffer_str_loc(buffer, rdf);
1362238104Sdes			break;
1363238104Sdes		case LDNS_RDF_TYPE_WKS:
1364238104Sdes		case LDNS_RDF_TYPE_SERVICE:
1365238104Sdes			res = ldns_rdf2buffer_str_wks(buffer, rdf);
1366238104Sdes			break;
1367238104Sdes		case LDNS_RDF_TYPE_NSAP:
1368238104Sdes			res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1369238104Sdes			break;
1370238104Sdes		case LDNS_RDF_TYPE_ATMA:
1371238104Sdes			res = ldns_rdf2buffer_str_atma(buffer, rdf);
1372238104Sdes			break;
1373238104Sdes		case LDNS_RDF_TYPE_IPSECKEY:
1374238104Sdes			res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1375238104Sdes			break;
1376238104Sdes		case LDNS_RDF_TYPE_INT16_DATA:
1377238104Sdes			res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1378238104Sdes			break;
1379238104Sdes		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1380238104Sdes			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1381238104Sdes			break;
1382266114Sdes		case LDNS_RDF_TYPE_ILNP64:
1383266114Sdes			res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
1384266114Sdes			break;
1385266114Sdes		case LDNS_RDF_TYPE_EUI48:
1386266114Sdes			res = ldns_rdf2buffer_str_eui48(buffer, rdf);
1387266114Sdes			break;
1388266114Sdes		case LDNS_RDF_TYPE_EUI64:
1389266114Sdes			res = ldns_rdf2buffer_str_eui64(buffer, rdf);
1390266114Sdes			break;
1391266114Sdes		case LDNS_RDF_TYPE_TAG:
1392266114Sdes			res = ldns_rdf2buffer_str_tag(buffer, rdf);
1393266114Sdes			break;
1394266114Sdes		case LDNS_RDF_TYPE_LONG_STR:
1395266114Sdes			res = ldns_rdf2buffer_str_long_str(buffer, rdf);
1396266114Sdes			break;
1397238104Sdes		}
1398238104Sdes	} else {
1399246854Sdes		/** This will write mangled RRs */
1400238104Sdes		ldns_buffer_printf(buffer, "(null) ");
1401246854Sdes		res = LDNS_STATUS_ERR;
1402238104Sdes	}
1403238104Sdes	return res;
1404238104Sdes}
1405238104Sdes
1406266114Sdesldns_status
1407266114Sdesldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1408266114Sdes{
1409266114Sdes	return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
1410266114Sdes}
1411266114Sdes
1412246827Sdesstatic ldns_rdf *
1413238104Sdesldns_b32_ext2dname(const ldns_rdf *rdf)
1414238104Sdes{
1415238104Sdes	size_t size;
1416238104Sdes	char *b32;
1417238104Sdes	ldns_rdf *out;
1418238104Sdes	if(ldns_rdf_size(rdf) == 0)
1419238104Sdes		return NULL;
1420238104Sdes        /* remove -1 for the b32-hash-len octet */
1421238104Sdes	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1422238104Sdes        /* add one for the end nul for the string */
1423238104Sdes	b32 = LDNS_XMALLOC(char, size + 2);
1424238104Sdes	if (b32) {
1425238104Sdes		if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
1426238104Sdes				ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1427238104Sdes			b32[size] = '.';
1428238104Sdes			b32[size+1] = '\0';
1429238104Sdes			if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1430238104Sdes				LDNS_FREE(b32);
1431238104Sdes				return out;
1432238104Sdes			}
1433238104Sdes		}
1434238104Sdes		LDNS_FREE(b32);
1435238104Sdes	}
1436238104Sdes	return NULL;
1437238104Sdes}
1438238104Sdes
1439266114Sdesstatic ldns_status
1440266114Sdesldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
1441266114Sdes{
1442266114Sdes	size_t total_rdfsize = 0;
1443266114Sdes	size_t i, j;
1444266114Sdes
1445266114Sdes	ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
1446266114Sdes	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1447266114Sdes		total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
1448266114Sdes	}
1449266114Sdes	if (total_rdfsize == 0) {
1450266114Sdes		ldns_buffer_printf(output, "\\# 0\n");
1451266114Sdes		return ldns_buffer_status(output);
1452266114Sdes	}
1453266114Sdes	ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
1454266114Sdes	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1455266114Sdes		for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
1456266114Sdes			ldns_buffer_printf(output, "%.2x",
1457266114Sdes					ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
1458266114Sdes		}
1459266114Sdes	}
1460266114Sdes	ldns_buffer_printf(output, "\n");
1461266114Sdes	return ldns_buffer_status(output);
1462266114Sdes}
1463266114Sdes
1464238104Sdesldns_status
1465238104Sdesldns_rr2buffer_str_fmt(ldns_buffer *output,
1466238104Sdes		const ldns_output_format *fmt, const ldns_rr *rr)
1467238104Sdes{
1468238104Sdes	uint16_t i, flags;
1469238104Sdes	ldns_status status = LDNS_STATUS_OK;
1470266114Sdes	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
1471238104Sdes
1472266114Sdes	if (fmt_st == NULL) {
1473266114Sdes		fmt_st = (ldns_output_format_storage*)
1474266114Sdes			  ldns_output_format_default;
1475238104Sdes	}
1476238104Sdes	if (!rr) {
1477266114Sdes		if (LDNS_COMMENT_NULLS & fmt_st->flags) {
1478238104Sdes			ldns_buffer_printf(output, "; (null)\n");
1479238104Sdes		}
1480238104Sdes		return ldns_buffer_status(output);
1481238104Sdes	}
1482238104Sdes	if (ldns_rr_owner(rr)) {
1483238104Sdes		status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1484238104Sdes	}
1485238104Sdes	if (status != LDNS_STATUS_OK) {
1486238104Sdes		return status;
1487238104Sdes	}
1488238104Sdes
1489238104Sdes	/* TTL should NOT be printed if it is a question */
1490238104Sdes	if (!ldns_rr_is_question(rr)) {
1491238104Sdes		ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
1492238104Sdes	}
1493238104Sdes
1494238104Sdes	ldns_buffer_printf(output, "\t");
1495238104Sdes	status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1496238104Sdes	if (status != LDNS_STATUS_OK) {
1497238104Sdes		return status;
1498238104Sdes	}
1499238104Sdes	ldns_buffer_printf(output, "\t");
1500238104Sdes
1501266114Sdes	if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
1502266114Sdes		return ldns_rr2buffer_str_rfc3597(output, rr);
1503266114Sdes	}
1504238104Sdes	status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1505238104Sdes	if (status != LDNS_STATUS_OK) {
1506238104Sdes		return status;
1507238104Sdes	}
1508238104Sdes
1509238104Sdes	if (ldns_rr_rd_count(rr) > 0) {
1510238104Sdes		ldns_buffer_printf(output, "\t");
1511238104Sdes	} else if (!ldns_rr_is_question(rr)) {
1512238104Sdes		ldns_buffer_printf(output, "\t\\# 0");
1513238104Sdes	}
1514238104Sdes
1515238104Sdes	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1516238104Sdes		/* ldns_rdf2buffer_str handles NULL input fine! */
1517266114Sdes		if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1518246854Sdes				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1519246854Sdes				((/* inception  */ i == 4 &&
1520246854Sdes				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
1521246854Sdes							LDNS_RDF_TYPE_TIME) ||
1522246854Sdes				  (/* expiration */ i == 5 &&
1523246854Sdes				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1524246854Sdes				   			LDNS_RDF_TYPE_TIME) ||
1525246854Sdes				  (/* signature  */ i == 8 &&
1526246854Sdes				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1527246854Sdes				   			LDNS_RDF_TYPE_B64))) {
1528246854Sdes
1529246854Sdes			ldns_buffer_printf(output, "(null)");
1530246854Sdes			status = ldns_buffer_status(output);
1531266114Sdes		} else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1532246854Sdes				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1533246854Sdes				/* serial */ i == 2 &&
1534246854Sdes			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1535246854Sdes			 				LDNS_RDF_TYPE_INT32) {
1536246854Sdes			ldns_buffer_printf(output, "%10lu",
1537246854Sdes				(unsigned long) ldns_read_uint32(
1538246854Sdes					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1539246854Sdes			status = ldns_buffer_status(output);
1540246854Sdes		} else {
1541266114Sdes			status = ldns_rdf2buffer_str_fmt(output,
1542266114Sdes					fmt, ldns_rr_rdf(rr, i));
1543246854Sdes		}
1544238104Sdes		if(status != LDNS_STATUS_OK)
1545238104Sdes			return status;
1546238104Sdes		if (i < ldns_rr_rd_count(rr) - 1) {
1547238104Sdes			ldns_buffer_printf(output, " ");
1548238104Sdes		}
1549238104Sdes	}
1550238104Sdes	/* per RR special comments - handy for DNSSEC types */
1551238104Sdes	/* check to prevent question sec. rr from
1552238104Sdes	 * getting here */
1553238104Sdes	if (ldns_rr_rd_count(rr) > 0) {
1554238104Sdes		switch (ldns_rr_get_type(rr)) {
1555266114Sdes		case LDNS_RR_TYPE_DNSKEY:
1556266114Sdes			/* if ldns_rr_rd_count(rr) > 0
1557266114Sdes				then ldns_rr_rdf(rr, 0) exists! */
1558266114Sdes			if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
1559266114Sdes				break;
1560266114Sdes			}
1561266114Sdes			flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
1562266114Sdes			ldns_buffer_printf(output, " ;{");
1563266114Sdes			if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
1564266114Sdes				ldns_buffer_printf(output, "id = %u",
1565266114Sdes					(unsigned int) ldns_calc_keytag(rr));
1566266114Sdes			}
1567266114Sdes			if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
1568266114Sdes					(flags & LDNS_KEY_ZONE_KEY)){
1569266114Sdes
1570266114Sdes				if (flags & LDNS_KEY_SEP_KEY) {
1571266114Sdes					ldns_buffer_printf(output, " (ksk)");
1572266114Sdes				} else {
1573266114Sdes					ldns_buffer_printf(output, " (zsk)");
1574238104Sdes				}
1575266114Sdes				if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
1576266114Sdes					ldns_buffer_printf(output, ", ");
1577238104Sdes				}
1578266114Sdes			} else if (fmt_st->flags
1579266114Sdes					& (LDNS_COMMENT_KEY_ID
1580266114Sdes						|LDNS_COMMENT_KEY_SIZE)) {
1581266114Sdes				ldns_buffer_printf( output, ", ");
1582266114Sdes			}
1583266114Sdes			if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
1584266114Sdes				ldns_buffer_printf(output, "size = %db",
1585266114Sdes					ldns_rr_dnskey_key_size(rr));
1586266114Sdes			}
1587266114Sdes			ldns_buffer_printf(output, "}");
1588266114Sdes			break;
1589266114Sdes		case LDNS_RR_TYPE_RRSIG:
1590266114Sdes			if ((fmt_st->flags & LDNS_COMMENT_KEY)
1591266114Sdes					&& (fmt_st->flags& LDNS_COMMENT_RRSIGS)
1592266114Sdes					&& ldns_rr_rdf(rr, 6) != NULL) {
1593266114Sdes				ldns_buffer_printf(output, " ;{id = %d}",
1594266114Sdes						ldns_rdf2native_int16(
1595238104Sdes							ldns_rr_rdf(rr, 6)));
1596266114Sdes			}
1597266114Sdes			break;
1598266114Sdes		case LDNS_RR_TYPE_DS:
1599266114Sdes			if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
1600266114Sdes					ldns_rr_rdf(rr, 3) != NULL) {
1601266114Sdes
1602266114Sdes				uint8_t *data = ldns_rdf_data(
1603266114Sdes						ldns_rr_rdf(rr, 3));
1604266114Sdes				size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
1605266114Sdes				char *babble = ldns_bubblebabble(data, len);
1606266114Sdes				if(babble) {
1607266114Sdes					ldns_buffer_printf(output,
1608266114Sdes							" ;{%s}", babble);
1609238104Sdes				}
1610266114Sdes				LDNS_FREE(babble);
1611266114Sdes			}
1612266114Sdes			break;
1613266114Sdes		case LDNS_RR_TYPE_NSEC3:
1614266114Sdes			if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
1615266114Sdes				! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
1616238104Sdes				break;
1617266114Sdes			}
1618266114Sdes			ldns_buffer_printf(output, " ;{");
1619266114Sdes			if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
1620266114Sdes				if (ldns_nsec3_optout(rr)) {
1621266114Sdes					ldns_buffer_printf(output,
1622266114Sdes						" flags: optout");
1623266114Sdes				} else {
1624266114Sdes					ldns_buffer_printf(output," flags: -");
1625238104Sdes				}
1626266114Sdes				if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1627266114Sdes						fmt_st->hashmap != NULL) {
1628266114Sdes					ldns_buffer_printf(output, ", ");
1629238104Sdes				}
1630266114Sdes			}
1631266114Sdes			if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1632266114Sdes					fmt_st->hashmap != NULL) {
1633266114Sdes				ldns_rbnode_t *node;
1634266114Sdes				ldns_rdf *key = ldns_dname_label(
1635266114Sdes						ldns_rr_owner(rr), 0);
1636266114Sdes				if (key) {
1637266114Sdes					node = ldns_rbtree_search(
1638266114Sdes						fmt_st->hashmap,
1639266114Sdes						(void *) key);
1640266114Sdes					if (node->data) {
1641238104Sdes						ldns_buffer_printf(output,
1642266114Sdes							"from: ");
1643266114Sdes						(void) ldns_rdf2buffer_str(
1644266114Sdes							output,
1645266114Sdes							ldns_dnssec_name_name(
1646266114Sdes							   (ldns_dnssec_name*)
1647266114Sdes							   node->data
1648266114Sdes							));
1649238104Sdes					}
1650266114Sdes					ldns_rdf_free(key);
1651238104Sdes				}
1652266114Sdes				key = ldns_b32_ext2dname(
1653238104Sdes						ldns_nsec3_next_owner(rr));
1654266114Sdes				if (key) {
1655266114Sdes					node = ldns_rbtree_search(
1656266114Sdes						fmt_st->hashmap,
1657266114Sdes						(void *) key);
1658266114Sdes					if (node->data) {
1659266114Sdes						ldns_buffer_printf(output,
1660266114Sdes							" to: ");
1661266114Sdes						(void) ldns_rdf2buffer_str(
1662266114Sdes							output,
1663266114Sdes							ldns_dnssec_name_name(
1664266114Sdes							   (ldns_dnssec_name*)
1665266114Sdes							   node->data
1666266114Sdes							));
1667238104Sdes					}
1668266114Sdes					ldns_rdf_free(key);
1669238104Sdes				}
1670266114Sdes			}
1671266114Sdes			ldns_buffer_printf(output, "}");
1672266114Sdes			break;
1673266114Sdes		default:
1674266114Sdes			break;
1675238104Sdes
1676238104Sdes		}
1677238104Sdes	}
1678238104Sdes	/* last */
1679238104Sdes	ldns_buffer_printf(output, "\n");
1680238104Sdes	return ldns_buffer_status(output);
1681238104Sdes}
1682238104Sdes
1683238104Sdesldns_status
1684238104Sdesldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
1685238104Sdes{
1686238104Sdes	return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
1687238104Sdes}
1688238104Sdes
1689238104Sdesldns_status
1690238104Sdesldns_rr_list2buffer_str_fmt(ldns_buffer *output,
1691238104Sdes		const ldns_output_format *fmt, const ldns_rr_list *list)
1692238104Sdes{
1693238104Sdes	uint16_t i;
1694238104Sdes
1695238104Sdes	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
1696238104Sdes		(void) ldns_rr2buffer_str_fmt(output, fmt,
1697238104Sdes				ldns_rr_list_rr(list, i));
1698238104Sdes	}
1699238104Sdes	return ldns_buffer_status(output);
1700238104Sdes}
1701238104Sdes
1702238104Sdesldns_status
1703238104Sdesldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
1704238104Sdes{
1705238104Sdes	return ldns_rr_list2buffer_str_fmt(
1706238104Sdes			output, ldns_output_format_default, list);
1707238104Sdes}
1708238104Sdes
1709238104Sdesldns_status
1710238104Sdesldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1711238104Sdes{
1712238104Sdes	ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
1713238104Sdes			                    (int) ldns_pkt_get_opcode(pkt));
1714238104Sdes	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
1715238104Sdes			                    (int) ldns_pkt_get_rcode(pkt));
1716238104Sdes
1717238104Sdes	ldns_buffer_printf(output, ";; ->>HEADER<<- ");
1718238104Sdes	if (opcode) {
1719238104Sdes		ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
1720238104Sdes	} else {
1721238104Sdes		ldns_buffer_printf(output, "opcode: ?? (%u), ",
1722238104Sdes				ldns_pkt_get_opcode(pkt));
1723238104Sdes	}
1724238104Sdes	if (rcode) {
1725238104Sdes		ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
1726238104Sdes	} else {
1727238104Sdes		ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
1728238104Sdes	}
1729238104Sdes	ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
1730238104Sdes	ldns_buffer_printf(output, ";; flags: ");
1731238104Sdes
1732238104Sdes	if (ldns_pkt_qr(pkt)) {
1733238104Sdes		ldns_buffer_printf(output, "qr ");
1734238104Sdes	}
1735238104Sdes	if (ldns_pkt_aa(pkt)) {
1736238104Sdes		ldns_buffer_printf(output, "aa ");
1737238104Sdes	}
1738238104Sdes	if (ldns_pkt_tc(pkt)) {
1739238104Sdes		ldns_buffer_printf(output, "tc ");
1740238104Sdes	}
1741238104Sdes	if (ldns_pkt_rd(pkt)) {
1742238104Sdes		ldns_buffer_printf(output, "rd ");
1743238104Sdes	}
1744238104Sdes	if (ldns_pkt_cd(pkt)) {
1745238104Sdes		ldns_buffer_printf(output, "cd ");
1746238104Sdes	}
1747238104Sdes	if (ldns_pkt_ra(pkt)) {
1748238104Sdes		ldns_buffer_printf(output, "ra ");
1749238104Sdes	}
1750238104Sdes	if (ldns_pkt_ad(pkt)) {
1751238104Sdes		ldns_buffer_printf(output, "ad ");
1752238104Sdes	}
1753238104Sdes	ldns_buffer_printf(output, "; ");
1754238104Sdes	ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
1755238104Sdes	ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
1756238104Sdes	ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
1757238104Sdes	ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
1758238104Sdes	return ldns_buffer_status(output);
1759238104Sdes}
1760238104Sdes
1761238104Sdesldns_status
1762238104Sdesldns_pkt2buffer_str_fmt(ldns_buffer *output,
1763238104Sdes		const ldns_output_format *fmt, const ldns_pkt *pkt)
1764238104Sdes{
1765238104Sdes	uint16_t i;
1766238104Sdes	ldns_status status = LDNS_STATUS_OK;
1767238104Sdes	char *tmp;
1768238104Sdes	struct timeval time;
1769238104Sdes	time_t time_tt;
1770238104Sdes
1771238104Sdes	if (!pkt) {
1772238104Sdes		ldns_buffer_printf(output, "null");
1773238104Sdes		return LDNS_STATUS_OK;
1774238104Sdes	}
1775238104Sdes
1776238104Sdes	if (ldns_buffer_status_ok(output)) {
1777238104Sdes		status = ldns_pktheader2buffer_str(output, pkt);
1778238104Sdes		if (status != LDNS_STATUS_OK) {
1779238104Sdes			return status;
1780238104Sdes		}
1781238104Sdes
1782238104Sdes		ldns_buffer_printf(output, "\n");
1783238104Sdes
1784238104Sdes		ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
1785238104Sdes
1786238104Sdes
1787238104Sdes		for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
1788238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1789238104Sdes				       ldns_rr_list_rr(
1790238104Sdes					       ldns_pkt_question(pkt), i));
1791238104Sdes			if (status != LDNS_STATUS_OK) {
1792238104Sdes				return status;
1793238104Sdes			}
1794238104Sdes		}
1795238104Sdes		ldns_buffer_printf(output, "\n");
1796238104Sdes
1797238104Sdes		ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
1798238104Sdes		for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
1799238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1800238104Sdes				       ldns_rr_list_rr(
1801238104Sdes					       ldns_pkt_answer(pkt), i));
1802238104Sdes			if (status != LDNS_STATUS_OK) {
1803238104Sdes				return status;
1804238104Sdes			}
1805238104Sdes
1806238104Sdes		}
1807238104Sdes		ldns_buffer_printf(output, "\n");
1808238104Sdes
1809238104Sdes		ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
1810238104Sdes
1811238104Sdes		for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
1812238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1813238104Sdes				       ldns_rr_list_rr(
1814238104Sdes					       ldns_pkt_authority(pkt), i));
1815238104Sdes			if (status != LDNS_STATUS_OK) {
1816238104Sdes				return status;
1817238104Sdes			}
1818238104Sdes		}
1819238104Sdes		ldns_buffer_printf(output, "\n");
1820238104Sdes
1821238104Sdes		ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
1822238104Sdes		for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
1823238104Sdes			status = ldns_rr2buffer_str_fmt(output, fmt,
1824238104Sdes				       ldns_rr_list_rr(
1825238104Sdes					       ldns_pkt_additional(pkt), i));
1826238104Sdes			if (status != LDNS_STATUS_OK) {
1827238104Sdes				return status;
1828238104Sdes			}
1829238104Sdes
1830238104Sdes		}
1831238104Sdes		ldns_buffer_printf(output, "\n");
1832238104Sdes		/* add some futher fields */
1833238104Sdes		ldns_buffer_printf(output, ";; Query time: %d msec\n",
1834238104Sdes				ldns_pkt_querytime(pkt));
1835238104Sdes		if (ldns_pkt_edns(pkt)) {
1836238104Sdes			ldns_buffer_printf(output,
1837238104Sdes				   ";; EDNS: version %u; flags:",
1838238104Sdes				   ldns_pkt_edns_version(pkt));
1839238104Sdes			if (ldns_pkt_edns_do(pkt)) {
1840238104Sdes				ldns_buffer_printf(output, " do");
1841238104Sdes			}
1842238104Sdes			/* the extended rcode is the value set, shifted four bits,
1843238104Sdes			 * and or'd with the original rcode */
1844238104Sdes			if (ldns_pkt_edns_extended_rcode(pkt)) {
1845238104Sdes				ldns_buffer_printf(output, " ; ext-rcode: %d",
1846238104Sdes					(ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
1847238104Sdes			}
1848238104Sdes			ldns_buffer_printf(output, " ; udp: %u\n",
1849238104Sdes					   ldns_pkt_edns_udp_size(pkt));
1850238104Sdes
1851238104Sdes			if (ldns_pkt_edns_data(pkt)) {
1852238104Sdes				ldns_buffer_printf(output, ";; Data: ");
1853238104Sdes				(void)ldns_rdf2buffer_str(output,
1854238104Sdes							  ldns_pkt_edns_data(pkt));
1855238104Sdes				ldns_buffer_printf(output, "\n");
1856238104Sdes			}
1857238104Sdes		}
1858238104Sdes		if (ldns_pkt_tsig(pkt)) {
1859238104Sdes			ldns_buffer_printf(output, ";; TSIG:\n;; ");
1860238104Sdes			(void) ldns_rr2buffer_str_fmt(
1861238104Sdes					output, fmt, ldns_pkt_tsig(pkt));
1862238104Sdes			ldns_buffer_printf(output, "\n");
1863238104Sdes		}
1864238104Sdes		if (ldns_pkt_answerfrom(pkt)) {
1865238104Sdes			tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
1866238104Sdes			ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
1867238104Sdes			LDNS_FREE(tmp);
1868238104Sdes		}
1869238104Sdes		time = ldns_pkt_timestamp(pkt);
1870238104Sdes		time_tt = (time_t)time.tv_sec;
1871238104Sdes		ldns_buffer_printf(output, ";; WHEN: %s",
1872238104Sdes				(char*)ctime(&time_tt));
1873238104Sdes
1874238104Sdes		ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
1875238104Sdes				(int)ldns_pkt_size(pkt));
1876238104Sdes	} else {
1877238104Sdes		return ldns_buffer_status(output);
1878238104Sdes	}
1879238104Sdes	return status;
1880238104Sdes}
1881238104Sdes
1882238104Sdesldns_status
1883238104Sdesldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1884238104Sdes{
1885238104Sdes	return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
1886238104Sdes}
1887238104Sdes
1888238104Sdes
1889238104Sdes#ifdef HAVE_SSL
1890238104Sdesstatic ldns_status
1891238104Sdesldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1892238104Sdes{
1893238104Sdes	ldns_status status;
1894238104Sdes	size_t i;
1895238104Sdes	ldns_rdf *b64_bignum;
1896238104Sdes
1897238104Sdes	ldns_buffer_printf(output, "Key: ");
1898238104Sdes
1899238104Sdes 	i = ldns_key_hmac_size(k);
1900238104Sdes	b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
1901238104Sdes	status = ldns_rdf2buffer_str(output, b64_bignum);
1902238104Sdes	ldns_rdf_deep_free(b64_bignum);
1903238104Sdes	ldns_buffer_printf(output, "\n");
1904238104Sdes	return status;
1905238104Sdes}
1906238104Sdes#endif
1907238104Sdes
1908238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST)
1909238104Sdesstatic ldns_status
1910238104Sdesldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
1911238104Sdes{
1912238104Sdes	unsigned char* pp = NULL;
1913238104Sdes	int ret;
1914238104Sdes	ldns_rdf *b64_bignum;
1915238104Sdes	ldns_status status;
1916238104Sdes
1917238104Sdes	ldns_buffer_printf(output, "GostAsn1: ");
1918238104Sdes
1919238104Sdes	ret = i2d_PrivateKey(p, &pp);
1920238104Sdes	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
1921238104Sdes	status = ldns_rdf2buffer_str(output, b64_bignum);
1922238104Sdes
1923238104Sdes	ldns_rdf_deep_free(b64_bignum);
1924238104Sdes	OPENSSL_free(pp);
1925238104Sdes	ldns_buffer_printf(output, "\n");
1926238104Sdes	return status;
1927238104Sdes}
1928238104Sdes#endif
1929238104Sdes
1930238104Sdesldns_status
1931238104Sdesldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1932238104Sdes{
1933238104Sdes	ldns_status status = LDNS_STATUS_OK;
1934238104Sdes	unsigned char  *bignum;
1935246854Sdes#ifdef HAVE_SSL
1936246854Sdes#  ifndef S_SPLINT_S
1937238104Sdes	uint16_t i;
1938246854Sdes#  endif
1939238104Sdes	/* not used when ssl is not defined */
1940246854Sdes	/*@unused@*/
1941238104Sdes	ldns_rdf *b64_bignum = NULL;
1942238104Sdes
1943238104Sdes	RSA *rsa;
1944238104Sdes	DSA *dsa;
1945238104Sdes#endif /* HAVE_SSL */
1946238104Sdes
1947238104Sdes	if (!k) {
1948238104Sdes		return LDNS_STATUS_ERR;
1949238104Sdes	}
1950238104Sdes
1951238104Sdes	bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1952238104Sdes	if (!bignum) {
1953238104Sdes		return LDNS_STATUS_ERR;
1954238104Sdes	}
1955238104Sdes
1956238104Sdes	if (ldns_buffer_status_ok(output)) {
1957238104Sdes#ifdef HAVE_SSL
1958238104Sdes		switch(ldns_key_algorithm(k)) {
1959238104Sdes			case LDNS_SIGN_RSASHA1:
1960238104Sdes			case LDNS_SIGN_RSASHA1_NSEC3:
1961238104Sdes			case LDNS_SIGN_RSASHA256:
1962238104Sdes			case LDNS_SIGN_RSASHA512:
1963238104Sdes			case LDNS_SIGN_RSAMD5:
1964238104Sdes				/* copied by looking at dnssec-keygen output */
1965238104Sdes				/* header */
1966238104Sdes				rsa = ldns_key_rsa_key(k);
1967238104Sdes
1968238104Sdes				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
1969238104Sdes				switch(ldns_key_algorithm(k)) {
1970238104Sdes				case LDNS_SIGN_RSAMD5:
1971238104Sdes					ldns_buffer_printf(output,
1972238104Sdes								    "Algorithm: %u (RSA)\n",
1973238104Sdes								    LDNS_RSAMD5);
1974238104Sdes					break;
1975238104Sdes				case LDNS_SIGN_RSASHA1:
1976238104Sdes					ldns_buffer_printf(output,
1977238104Sdes								    "Algorithm: %u (RSASHA1)\n",
1978238104Sdes								    LDNS_RSASHA1);
1979238104Sdes					break;
1980238104Sdes				case LDNS_SIGN_RSASHA1_NSEC3:
1981238104Sdes					ldns_buffer_printf(output,
1982238104Sdes								    "Algorithm: %u (RSASHA1_NSEC3)\n",
1983238104Sdes								    LDNS_RSASHA1_NSEC3);
1984238104Sdes					break;
1985238104Sdes#ifdef USE_SHA2
1986238104Sdes				case LDNS_SIGN_RSASHA256:
1987238104Sdes					ldns_buffer_printf(output,
1988238104Sdes								    "Algorithm: %u (RSASHA256)\n",
1989238104Sdes								    LDNS_RSASHA256);
1990238104Sdes					break;
1991238104Sdes				case LDNS_SIGN_RSASHA512:
1992238104Sdes					ldns_buffer_printf(output,
1993238104Sdes								    "Algorithm: %u (RSASHA512)\n",
1994238104Sdes								    LDNS_RSASHA512);
1995238104Sdes					break;
1996238104Sdes#endif
1997238104Sdes				default:
1998266114Sdes#ifdef STDERR_MSGS
1999238104Sdes					fprintf(stderr, "Warning: unknown signature ");
2000238104Sdes					fprintf(stderr,
2001238104Sdes						   "algorithm type %u\n",
2002238104Sdes						   ldns_key_algorithm(k));
2003266114Sdes#endif
2004238104Sdes					ldns_buffer_printf(output,
2005238104Sdes								    "Algorithm: %u (Unknown)\n",
2006238104Sdes								    ldns_key_algorithm(k));
2007238104Sdes					break;
2008238104Sdes				}
2009238104Sdes
2010238104Sdes				/* print to buf, convert to bin, convert to b64,
2011238104Sdes				 * print to buf */
2012238104Sdes				ldns_buffer_printf(output, "Modulus: ");
2013238104Sdes#ifndef S_SPLINT_S
2014238104Sdes				i = (uint16_t)BN_bn2bin(rsa->n, bignum);
2015238104Sdes				if (i > LDNS_MAX_KEYLEN) {
2016238104Sdes					goto error;
2017238104Sdes				}
2018238104Sdes				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2019238104Sdes				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2020246854Sdes					ldns_rdf_deep_free(b64_bignum);
2021238104Sdes					goto error;
2022238104Sdes				}
2023238104Sdes				ldns_rdf_deep_free(b64_bignum);
2024238104Sdes				ldns_buffer_printf(output, "\n");
2025238104Sdes				ldns_buffer_printf(output, "PublicExponent: ");
2026238104Sdes				i = (uint16_t)BN_bn2bin(rsa->e, bignum);
2027238104Sdes				if (i > LDNS_MAX_KEYLEN) {
2028238104Sdes					goto error;
2029238104Sdes				}
2030238104Sdes				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2031238104Sdes				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2032246854Sdes					ldns_rdf_deep_free(b64_bignum);
2033238104Sdes					goto error;
2034238104Sdes				}
2035238104Sdes				ldns_rdf_deep_free(b64_bignum);
2036238104Sdes				ldns_buffer_printf(output, "\n");
2037238104Sdes
2038238104Sdes				ldns_buffer_printf(output, "PrivateExponent: ");
2039238104Sdes				if (rsa->d) {
2040238104Sdes					i = (uint16_t)BN_bn2bin(rsa->d, bignum);
2041238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2042238104Sdes						goto error;
2043238104Sdes					}
2044238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2045238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2046246854Sdes						ldns_rdf_deep_free(b64_bignum);
2047238104Sdes						goto error;
2048238104Sdes					}
2049238104Sdes					ldns_rdf_deep_free(b64_bignum);
2050238104Sdes					ldns_buffer_printf(output, "\n");
2051238104Sdes				} else {
2052238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2053238104Sdes				}
2054238104Sdes
2055238104Sdes				ldns_buffer_printf(output, "Prime1: ");
2056238104Sdes				if (rsa->p) {
2057238104Sdes					i = (uint16_t)BN_bn2bin(rsa->p, bignum);
2058238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2059238104Sdes						goto error;
2060238104Sdes					}
2061238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2062238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2063246854Sdes						ldns_rdf_deep_free(b64_bignum);
2064238104Sdes						goto error;
2065238104Sdes					}
2066238104Sdes					ldns_rdf_deep_free(b64_bignum);
2067238104Sdes					ldns_buffer_printf(output, "\n");
2068238104Sdes				} else {
2069238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2070238104Sdes				}
2071238104Sdes
2072238104Sdes				ldns_buffer_printf(output, "Prime2: ");
2073238104Sdes				if (rsa->q) {
2074238104Sdes					i = (uint16_t)BN_bn2bin(rsa->q, bignum);
2075238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2076238104Sdes						goto error;
2077238104Sdes					}
2078238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2079238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2080246854Sdes						ldns_rdf_deep_free(b64_bignum);
2081238104Sdes						goto error;
2082238104Sdes					}
2083238104Sdes					ldns_rdf_deep_free(b64_bignum);
2084238104Sdes					ldns_buffer_printf(output, "\n");
2085238104Sdes				} else {
2086238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2087238104Sdes				}
2088238104Sdes
2089238104Sdes				ldns_buffer_printf(output, "Exponent1: ");
2090238104Sdes				if (rsa->dmp1) {
2091238104Sdes					i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum);
2092238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2093238104Sdes						goto error;
2094238104Sdes					}
2095238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2096238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2097246854Sdes						ldns_rdf_deep_free(b64_bignum);
2098238104Sdes						goto error;
2099238104Sdes					}
2100238104Sdes					ldns_rdf_deep_free(b64_bignum);
2101238104Sdes					ldns_buffer_printf(output, "\n");
2102238104Sdes				} else {
2103238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2104238104Sdes				}
2105238104Sdes
2106238104Sdes				ldns_buffer_printf(output, "Exponent2: ");
2107238104Sdes				if (rsa->dmq1) {
2108238104Sdes					i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum);
2109238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2110238104Sdes						goto error;
2111238104Sdes					}
2112238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2113238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2114246854Sdes						ldns_rdf_deep_free(b64_bignum);
2115238104Sdes						goto error;
2116238104Sdes					}
2117238104Sdes					ldns_rdf_deep_free(b64_bignum);
2118238104Sdes					ldns_buffer_printf(output, "\n");
2119238104Sdes				} else {
2120238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2121238104Sdes				}
2122238104Sdes
2123238104Sdes				ldns_buffer_printf(output, "Coefficient: ");
2124238104Sdes				if (rsa->iqmp) {
2125238104Sdes					i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum);
2126238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2127238104Sdes						goto error;
2128238104Sdes					}
2129238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2130238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2131246854Sdes						ldns_rdf_deep_free(b64_bignum);
2132238104Sdes						goto error;
2133238104Sdes					}
2134238104Sdes					ldns_rdf_deep_free(b64_bignum);
2135238104Sdes					ldns_buffer_printf(output, "\n");
2136238104Sdes				} else {
2137238104Sdes					ldns_buffer_printf(output, "(Not available)\n");
2138238104Sdes				}
2139238104Sdes#endif /* splint */
2140238104Sdes
2141238104Sdes				RSA_free(rsa);
2142238104Sdes				break;
2143238104Sdes			case LDNS_SIGN_DSA:
2144238104Sdes			case LDNS_SIGN_DSA_NSEC3:
2145238104Sdes				dsa = ldns_key_dsa_key(k);
2146238104Sdes
2147238104Sdes				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
2148238104Sdes				if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
2149238104Sdes					ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
2150238104Sdes				} else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
2151238104Sdes					ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
2152238104Sdes				}
2153238104Sdes
2154238104Sdes				/* print to buf, convert to bin, convert to b64,
2155238104Sdes				 * print to buf */
2156238104Sdes				ldns_buffer_printf(output, "Prime(p): ");
2157238104Sdes#ifndef S_SPLINT_S
2158238104Sdes				if (dsa->p) {
2159238104Sdes					i = (uint16_t)BN_bn2bin(dsa->p, bignum);
2160238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2161238104Sdes						goto error;
2162238104Sdes					}
2163238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2164238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2165246854Sdes						ldns_rdf_deep_free(b64_bignum);
2166238104Sdes						goto error;
2167238104Sdes					}
2168238104Sdes					ldns_rdf_deep_free(b64_bignum);
2169238104Sdes					ldns_buffer_printf(output, "\n");
2170238104Sdes				} else {
2171238104Sdes					printf("(Not available)\n");
2172238104Sdes				}
2173238104Sdes
2174238104Sdes				ldns_buffer_printf(output, "Subprime(q): ");
2175238104Sdes				if (dsa->q) {
2176238104Sdes					i = (uint16_t)BN_bn2bin(dsa->q, bignum);
2177238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2178238104Sdes						goto error;
2179238104Sdes					}
2180238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2181238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2182246854Sdes						ldns_rdf_deep_free(b64_bignum);
2183238104Sdes						goto error;
2184238104Sdes					}
2185238104Sdes					ldns_rdf_deep_free(b64_bignum);
2186238104Sdes					ldns_buffer_printf(output, "\n");
2187238104Sdes				} else {
2188238104Sdes					printf("(Not available)\n");
2189238104Sdes				}
2190238104Sdes
2191238104Sdes				ldns_buffer_printf(output, "Base(g): ");
2192238104Sdes				if (dsa->g) {
2193238104Sdes					i = (uint16_t)BN_bn2bin(dsa->g, bignum);
2194238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2195238104Sdes						goto error;
2196238104Sdes					}
2197238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2198238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2199246854Sdes						ldns_rdf_deep_free(b64_bignum);
2200238104Sdes						goto error;
2201238104Sdes					}
2202238104Sdes					ldns_rdf_deep_free(b64_bignum);
2203238104Sdes					ldns_buffer_printf(output, "\n");
2204238104Sdes				} else {
2205238104Sdes					printf("(Not available)\n");
2206238104Sdes				}
2207238104Sdes
2208238104Sdes				ldns_buffer_printf(output, "Private_value(x): ");
2209238104Sdes				if (dsa->priv_key) {
2210238104Sdes					i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum);
2211238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2212238104Sdes						goto error;
2213238104Sdes					}
2214238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2215238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2216246854Sdes						ldns_rdf_deep_free(b64_bignum);
2217238104Sdes						goto error;
2218238104Sdes					}
2219238104Sdes					ldns_rdf_deep_free(b64_bignum);
2220238104Sdes					ldns_buffer_printf(output, "\n");
2221238104Sdes				} else {
2222238104Sdes					printf("(Not available)\n");
2223238104Sdes				}
2224238104Sdes
2225238104Sdes				ldns_buffer_printf(output, "Public_value(y): ");
2226238104Sdes				if (dsa->pub_key) {
2227238104Sdes					i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum);
2228238104Sdes					if (i > LDNS_MAX_KEYLEN) {
2229238104Sdes						goto error;
2230238104Sdes					}
2231238104Sdes					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2232238104Sdes					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2233246854Sdes						ldns_rdf_deep_free(b64_bignum);
2234238104Sdes						goto error;
2235238104Sdes					}
2236238104Sdes					ldns_rdf_deep_free(b64_bignum);
2237238104Sdes					ldns_buffer_printf(output, "\n");
2238238104Sdes				} else {
2239238104Sdes					printf("(Not available)\n");
2240238104Sdes				}
2241238104Sdes#endif /* splint */
2242238104Sdes				break;
2243238104Sdes			case LDNS_SIGN_ECC_GOST:
2244238104Sdes				/* no format defined, use blob */
2245238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST)
2246238104Sdes				ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2247238104Sdes				ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
2248238104Sdes				status = ldns_gost_key2buffer_str(output,
2249238104Sdes#ifndef S_SPLINT_S
2250238104Sdes					k->_key.key
2251238104Sdes#else
2252238104Sdes					NULL
2253238104Sdes#endif
2254238104Sdes				);
2255238104Sdes#else
2256238104Sdes				goto error;
2257238104Sdes#endif /* GOST */
2258238104Sdes				break;
2259238104Sdes			case LDNS_SIGN_ECDSAP256SHA256:
2260238104Sdes			case LDNS_SIGN_ECDSAP384SHA384:
2261238104Sdes#ifdef USE_ECDSA
2262238104Sdes                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2263238104Sdes				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2264238104Sdes                                status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2265238104Sdes#ifndef S_SPLINT_S
2266238104Sdes				ldns_buffer_printf(output, ")\n");
2267238104Sdes                                if(k->_key.key) {
2268238104Sdes                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2269238104Sdes                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
2270238104Sdes                                        ldns_buffer_printf(output, "PrivateKey: ");
2271238104Sdes                                        i = (uint16_t)BN_bn2bin(b, bignum);
2272238104Sdes                                        if (i > LDNS_MAX_KEYLEN) {
2273238104Sdes                                                goto error;
2274238104Sdes                                        }
2275238104Sdes                                        b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
2276238104Sdes                                        if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
2277246854Sdes						ldns_rdf_deep_free(b64_bignum);
2278238104Sdes                                                goto error;
2279238104Sdes                                        }
2280238104Sdes                                        ldns_rdf_deep_free(b64_bignum);
2281238104Sdes				        ldns_buffer_printf(output, "\n");
2282238104Sdes                                        /* down reference count in EC_KEY
2283238104Sdes                                         * its still assigned to the PKEY */
2284238104Sdes                                        EC_KEY_free(ec);
2285238104Sdes                                }
2286238104Sdes#endif /* splint */
2287238104Sdes#else
2288238104Sdes				goto error;
2289238104Sdes#endif /* ECDSA */
2290238104Sdes                                break;
2291238104Sdes			case LDNS_SIGN_HMACMD5:
2292238104Sdes				/* there's not much of a format defined for TSIG */
2293238104Sdes				/* It's just a binary blob, Same for all algorithms */
2294238104Sdes                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2295238104Sdes                ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
2296238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2297238104Sdes				break;
2298238104Sdes			case LDNS_SIGN_HMACSHA1:
2299238104Sdes		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2300238104Sdes		        ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
2301238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2302238104Sdes				break;
2303238104Sdes			case LDNS_SIGN_HMACSHA256:
2304238104Sdes		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2305238104Sdes		        ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
2306238104Sdes				status = ldns_hmac_key2buffer_str(output, k);
2307238104Sdes				break;
2308238104Sdes		}
2309238104Sdes#endif /* HAVE_SSL */
2310238104Sdes	} else {
2311238104Sdes		LDNS_FREE(bignum);
2312238104Sdes		return ldns_buffer_status(output);
2313238104Sdes	}
2314238104Sdes	LDNS_FREE(bignum);
2315238104Sdes	return status;
2316238104Sdes
2317238104Sdes#ifdef HAVE_SSL
2318238104Sdes	/* compiles warn the label isn't used */
2319238104Sdeserror:
2320238104Sdes	LDNS_FREE(bignum);
2321238104Sdes	return LDNS_STATUS_ERR;
2322238104Sdes#endif /* HAVE_SSL */
2323238104Sdes
2324238104Sdes}
2325238104Sdes
2326238104Sdes/*
2327246854Sdes * Zero terminate the buffer and copy data.
2328238104Sdes */
2329238104Sdeschar *
2330238104Sdesldns_buffer2str(ldns_buffer *buffer)
2331238104Sdes{
2332238104Sdes	char *str;
2333238104Sdes
2334238104Sdes	/* check if buffer ends with \0, if not, and
2335238104Sdes	   if there is space, add it */
2336238104Sdes	if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
2337238104Sdes		if (!ldns_buffer_reserve(buffer, 1)) {
2338238104Sdes			return NULL;
2339238104Sdes		}
2340238104Sdes		ldns_buffer_write_u8(buffer, (uint8_t) '\0');
2341238104Sdes		if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
2342238104Sdes			return NULL;
2343238104Sdes		}
2344238104Sdes	}
2345238104Sdes
2346246854Sdes	str = strdup((const char *)ldns_buffer_begin(buffer));
2347238104Sdes        if(!str) {
2348238104Sdes                return NULL;
2349238104Sdes        }
2350238104Sdes	return str;
2351238104Sdes}
2352238104Sdes
2353246854Sdes/*
2354246854Sdes * Zero terminate the buffer and export data.
2355246854Sdes */
2356238104Sdeschar *
2357246854Sdesldns_buffer_export2str(ldns_buffer *buffer)
2358246854Sdes{
2359246854Sdes	/* Append '\0' as string terminator */
2360246854Sdes	if (! ldns_buffer_reserve(buffer, 1)) {
2361246854Sdes		return NULL;
2362246854Sdes	}
2363246854Sdes	ldns_buffer_write_u8(buffer, 0);
2364246854Sdes
2365246854Sdes	/* reallocate memory to the size of the string and export */
2366246854Sdes	ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
2367246854Sdes	return ldns_buffer_export(buffer);
2368246854Sdes}
2369246854Sdes
2370246854Sdeschar *
2371238104Sdesldns_rdf2str(const ldns_rdf *rdf)
2372238104Sdes{
2373238104Sdes	char *result = NULL;
2374238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2375238104Sdes
2376238104Sdes	if (!tmp_buffer) {
2377238104Sdes		return NULL;
2378238104Sdes	}
2379238104Sdes	if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
2380238104Sdes		/* export and return string, destroy rest */
2381246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2382238104Sdes	}
2383238104Sdes	ldns_buffer_free(tmp_buffer);
2384238104Sdes	return result;
2385238104Sdes}
2386238104Sdes
2387238104Sdeschar *
2388238104Sdesldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
2389238104Sdes{
2390238104Sdes	char *result = NULL;
2391238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2392238104Sdes
2393238104Sdes	if (!tmp_buffer) {
2394238104Sdes		return NULL;
2395238104Sdes	}
2396238104Sdes	if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
2397238104Sdes		       	== LDNS_STATUS_OK) {
2398238104Sdes		/* export and return string, destroy rest */
2399246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2400238104Sdes	}
2401238104Sdes	ldns_buffer_free(tmp_buffer);
2402238104Sdes	return result;
2403238104Sdes}
2404238104Sdes
2405238104Sdeschar *
2406238104Sdesldns_rr2str(const ldns_rr *rr)
2407238104Sdes{
2408238104Sdes	return ldns_rr2str_fmt(ldns_output_format_default, rr);
2409238104Sdes}
2410238104Sdes
2411238104Sdeschar *
2412238104Sdesldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
2413238104Sdes{
2414238104Sdes	char *result = NULL;
2415238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2416238104Sdes
2417238104Sdes	if (!tmp_buffer) {
2418238104Sdes		return NULL;
2419238104Sdes	}
2420238104Sdes	if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
2421238104Sdes		       	== LDNS_STATUS_OK) {
2422238104Sdes		/* export and return string, destroy rest */
2423246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2424238104Sdes	}
2425238104Sdes
2426238104Sdes	ldns_buffer_free(tmp_buffer);
2427238104Sdes	return result;
2428238104Sdes}
2429238104Sdes
2430238104Sdeschar *
2431238104Sdesldns_pkt2str(const ldns_pkt *pkt)
2432238104Sdes{
2433238104Sdes	return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
2434238104Sdes}
2435238104Sdes
2436238104Sdeschar *
2437238104Sdesldns_key2str(const ldns_key *k)
2438238104Sdes{
2439238104Sdes	char *result = NULL;
2440238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2441238104Sdes
2442238104Sdes	if (!tmp_buffer) {
2443238104Sdes		return NULL;
2444238104Sdes	}
2445238104Sdes	if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
2446238104Sdes		/* export and return string, destroy rest */
2447246854Sdes		result = ldns_buffer_export2str(tmp_buffer);
2448238104Sdes	}
2449238104Sdes	ldns_buffer_free(tmp_buffer);
2450238104Sdes	return result;
2451238104Sdes}
2452238104Sdes
2453238104Sdeschar *
2454238104Sdesldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
2455238104Sdes{
2456238104Sdes	char *result = NULL;
2457238104Sdes	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2458238104Sdes
2459238104Sdes	if (!tmp_buffer) {
2460238104Sdes		return NULL;
2461238104Sdes	}
2462238104Sdes	if (list) {
2463238104Sdes		if (ldns_rr_list2buffer_str_fmt(
2464238104Sdes				   tmp_buffer, fmt, list)
2465238104Sdes			       	== LDNS_STATUS_OK) {
2466238104Sdes		}
2467238104Sdes	} else {
2468238104Sdes		if (fmt == NULL) {
2469238104Sdes			fmt = ldns_output_format_default;
2470238104Sdes		}
2471238104Sdes		if (fmt->flags & LDNS_COMMENT_NULLS) {
2472238104Sdes			ldns_buffer_printf(tmp_buffer, "; (null)\n");
2473238104Sdes		}
2474238104Sdes	}
2475238104Sdes
2476238104Sdes	/* export and return string, destroy rest */
2477246854Sdes	result = ldns_buffer_export2str(tmp_buffer);
2478238104Sdes	ldns_buffer_free(tmp_buffer);
2479238104Sdes	return result;
2480238104Sdes}
2481238104Sdes
2482238104Sdeschar *
2483238104Sdesldns_rr_list2str(const ldns_rr_list *list)
2484238104Sdes{
2485238104Sdes	return ldns_rr_list2str_fmt(ldns_output_format_default, list);
2486238104Sdes}
2487238104Sdes
2488238104Sdesvoid
2489238104Sdesldns_rdf_print(FILE *output, const ldns_rdf *rdf)
2490238104Sdes{
2491238104Sdes	char *str = ldns_rdf2str(rdf);
2492238104Sdes	if (str) {
2493238104Sdes		fprintf(output, "%s", str);
2494238104Sdes	} else {
2495246854Sdes		fprintf(output, ";Unable to convert rdf to string\n");
2496238104Sdes	}
2497238104Sdes	LDNS_FREE(str);
2498238104Sdes}
2499238104Sdes
2500238104Sdesvoid
2501246854Sdesldns_rr_print_fmt(FILE *output,
2502238104Sdes		const ldns_output_format *fmt, const ldns_rr *rr)
2503238104Sdes{
2504238104Sdes	char *str = ldns_rr2str_fmt(fmt, rr);
2505238104Sdes	if (str) {
2506238104Sdes		fprintf(output, "%s", str);
2507238104Sdes	} else {
2508246854Sdes		fprintf(output, ";Unable to convert rr to string\n");
2509238104Sdes	}
2510238104Sdes	LDNS_FREE(str);
2511238104Sdes}
2512238104Sdes
2513238104Sdesvoid
2514238104Sdesldns_rr_print(FILE *output, const ldns_rr *rr)
2515238104Sdes{
2516238104Sdes	ldns_rr_print_fmt(output, ldns_output_format_default, rr);
2517238104Sdes}
2518238104Sdes
2519238104Sdesvoid
2520238104Sdesldns_pkt_print_fmt(FILE *output,
2521238104Sdes		const ldns_output_format *fmt, const ldns_pkt *pkt)
2522238104Sdes{
2523238104Sdes	char *str = ldns_pkt2str_fmt(fmt, pkt);
2524238104Sdes	if (str) {
2525238104Sdes		fprintf(output, "%s", str);
2526238104Sdes	} else {
2527246854Sdes		fprintf(output, ";Unable to convert packet to string\n");
2528238104Sdes	}
2529238104Sdes	LDNS_FREE(str);
2530238104Sdes}
2531238104Sdes
2532238104Sdesvoid
2533238104Sdesldns_pkt_print(FILE *output, const ldns_pkt *pkt)
2534238104Sdes{
2535238104Sdes	ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
2536238104Sdes}
2537238104Sdes
2538238104Sdesvoid
2539238104Sdesldns_rr_list_print_fmt(FILE *output,
2540238104Sdes		const ldns_output_format *fmt, const ldns_rr_list *lst)
2541238104Sdes{
2542238104Sdes	size_t i;
2543238104Sdes	for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
2544238104Sdes		ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
2545238104Sdes	}
2546238104Sdes}
2547238104Sdes
2548238104Sdesvoid
2549238104Sdesldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
2550238104Sdes{
2551238104Sdes	ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
2552238104Sdes}
2553238104Sdes
2554238104Sdesvoid
2555238104Sdesldns_resolver_print_fmt(FILE *output,
2556238104Sdes		const ldns_output_format *fmt, const ldns_resolver *r)
2557238104Sdes{
2558238104Sdes	uint16_t i;
2559238104Sdes	ldns_rdf **n;
2560238104Sdes	ldns_rdf **s;
2561238104Sdes	size_t *rtt;
2562238104Sdes	if (!r) {
2563238104Sdes		return;
2564238104Sdes	}
2565238104Sdes	n = ldns_resolver_nameservers(r);
2566238104Sdes	s = ldns_resolver_searchlist(r);
2567238104Sdes	rtt = ldns_resolver_rtt(r);
2568238104Sdes
2569238104Sdes	fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
2570238104Sdes	fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
2571238104Sdes	fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
2572238104Sdes
2573238104Sdes	fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
2574238104Sdes	fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
2575238104Sdes	fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
2576238104Sdes	fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
2577238104Sdes	fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
2578238104Sdes	fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
2579238104Sdes	fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
2580238104Sdes	fprintf(output, "random: %d\n", ldns_resolver_random(r));
2581238104Sdes	fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
2582238104Sdes	fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
2583238104Sdes	fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
2584238104Sdes	fprintf(output, "trust anchors (%d listed):\n",
2585238104Sdes		(int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
2586238104Sdes	ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
2587238104Sdes	fprintf(output, "tsig: %s %s\n",
2588238104Sdes                ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
2589238104Sdes                ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
2590238104Sdes	fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
2591238104Sdes
2592238104Sdes	fprintf(output, "default domain: ");
2593238104Sdes	ldns_rdf_print(output, ldns_resolver_domain(r));
2594238104Sdes	fprintf(output, "\n");
2595238104Sdes	fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
2596238104Sdes
2597238104Sdes	fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
2598238104Sdes	for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
2599238104Sdes		fprintf(output, "\t");
2600238104Sdes		ldns_rdf_print(output, s[i]);
2601238104Sdes		fprintf(output, "\n");
2602238104Sdes	}
2603238104Sdes	fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
2604238104Sdes
2605238104Sdes	fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
2606238104Sdes	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
2607238104Sdes		fprintf(output, "\t");
2608238104Sdes		ldns_rdf_print(output, n[i]);
2609238104Sdes
2610238104Sdes		switch ((int)rtt[i]) {
2611238104Sdes			case LDNS_RESOLV_RTT_MIN:
2612238104Sdes			fprintf(output, " - reachable\n");
2613238104Sdes			break;
2614238104Sdes			case LDNS_RESOLV_RTT_INF:
2615238104Sdes			fprintf(output, " - unreachable\n");
2616238104Sdes			break;
2617238104Sdes		}
2618238104Sdes	}
2619238104Sdes}
2620238104Sdes
2621238104Sdesvoid
2622238104Sdesldns_resolver_print(FILE *output, const ldns_resolver *r)
2623238104Sdes{
2624238104Sdes	ldns_resolver_print_fmt(output, ldns_output_format_default, r);
2625238104Sdes}
2626238104Sdes
2627238104Sdesvoid
2628238104Sdesldns_zone_print_fmt(FILE *output,
2629238104Sdes		const ldns_output_format *fmt, const ldns_zone *z)
2630238104Sdes{
2631238104Sdes	if(ldns_zone_soa(z))
2632238104Sdes		ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
2633238104Sdes	ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
2634238104Sdes}
2635238104Sdesvoid
2636238104Sdesldns_zone_print(FILE *output, const ldns_zone *z)
2637238104Sdes{
2638238104Sdes	ldns_zone_print_fmt(output, ldns_output_format_default, z);
2639238104Sdes}
2640