xref: /freebsd/contrib/ldns/host2str.c (revision 9ed998a81bab54203604d08293089db875758686)
1 /*
2  * host2str.c
3  *
4  * conversion routines from the host format
5  * to the presentation format (strings)
6  *
7  * a Net::DNS like library for C
8  *
9  * (c) NLnet Labs, 2004-2006
10  *
11  * See the file LICENSE for the license
12  */
13 #include <ldns/config.h>
14 
15 #include <ldns/ldns.h>
16 #include <ldns/internal.h>
17 
18 #include <limits.h>
19 
20 #ifdef HAVE_SYS_SOCKET_H
21 #include <sys/socket.h>
22 #endif
23 #ifdef HAVE_ARPA_INET_H
24 #include <arpa/inet.h>
25 #endif
26 #ifdef HAVE_NETDB_H
27 #include <netdb.h>
28 #endif
29 #include <time.h>
30 #include <sys/time.h>
31 
32 #ifdef HAVE_SSL
33 #include <openssl/bn.h>
34 #include <openssl/rsa.h>
35 #ifdef USE_DSA
36 #include <openssl/dsa.h>
37 #endif
38 #endif
39 
40 #ifndef INET_ADDRSTRLEN
41 #define INET_ADDRSTRLEN 16
42 #endif
43 #ifndef INET6_ADDRSTRLEN
44 #define INET6_ADDRSTRLEN 46
45 #endif
46 
47 /* lookup tables for standard DNS stuff  */
48 
49 /* Taken from RFC 2535, section 7.  */
50 ldns_lookup_table ldns_algorithms[] = {
51         { LDNS_RSAMD5, "RSAMD5" },
52         { LDNS_DH, "DH" },
53         { LDNS_DSA, "DSA" },
54         { LDNS_ECC, "ECC" },
55         { LDNS_RSASHA1, "RSASHA1" },
56         { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
57         { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
58 	{ LDNS_RSASHA256, "RSASHA256"},
59 	{ LDNS_RSASHA512, "RSASHA512"},
60 	{ LDNS_ECC_GOST, "ECC-GOST"},
61         { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
62         { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
63 	{ LDNS_ED25519, "ED25519"},
64 	{ LDNS_ED448, "ED448"},
65         { LDNS_INDIRECT, "INDIRECT" },
66         { LDNS_PRIVATEDNS, "PRIVATEDNS" },
67         { LDNS_PRIVATEOID, "PRIVATEOID" },
68         { 0, NULL }
69 };
70 
71 /* Hashing algorithms used in the DS record */
72 ldns_lookup_table ldns_hashes[] = {
73         {LDNS_SHA1     , "SHA1" },      /* RFC 4034 */
74         {LDNS_SHA256   , "SHA256" },    /* RFC 4509 */
75         {LDNS_HASH_GOST, "HASH-GOST" }, /* RFC 5933 */
76         {LDNS_SHA384   , "SHA384" },    /* RFC 6605 */
77         { 0, NULL }
78 };
79 
80 /* Taken from RFC 4398  */
81 ldns_lookup_table ldns_cert_algorithms[] = {
82         { LDNS_CERT_PKIX, "PKIX" },
83         { LDNS_CERT_SPKI, "SPKI" },
84         { LDNS_CERT_PGP, "PGP" },
85         { LDNS_CERT_IPKIX, "IPKIX" },
86         { LDNS_CERT_ISPKI, "ISPKI" },
87         { LDNS_CERT_IPGP, "IPGP" },
88         { LDNS_CERT_ACPKIX, "ACPKIX" },
89         { LDNS_CERT_IACPKIX, "IACPKIX" },
90         { LDNS_CERT_URI, "URI" },
91         { LDNS_CERT_OID, "OID" },
92         { 0, NULL }
93 };
94 
95 /* classes  */
96 ldns_lookup_table ldns_rr_classes[] = {
97         { LDNS_RR_CLASS_IN, "IN" },
98         { LDNS_RR_CLASS_CH, "CH" },
99         { LDNS_RR_CLASS_HS, "HS" },
100         { LDNS_RR_CLASS_NONE, "NONE" },
101         { LDNS_RR_CLASS_ANY, "ANY" },
102         { 0, NULL }
103 };
104 
105 /* if these are used elsewhere */
106 ldns_lookup_table ldns_rcodes[] = {
107         { LDNS_RCODE_NOERROR, "NOERROR" },
108         { LDNS_RCODE_FORMERR, "FORMERR" },
109         { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
110         { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
111         { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
112         { LDNS_RCODE_REFUSED, "REFUSED" },
113         { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
114         { LDNS_RCODE_YXRRSET, "YXRRSET" },
115         { LDNS_RCODE_NXRRSET, "NXRRSET" },
116         { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
117         { LDNS_RCODE_NOTZONE, "NOTZONE" },
118         { 0, NULL }
119 };
120 
121 ldns_lookup_table ldns_opcodes[] = {
122         { LDNS_PACKET_QUERY, "QUERY" },
123         { LDNS_PACKET_IQUERY, "IQUERY" },
124         { LDNS_PACKET_STATUS, "STATUS" },
125 	{ LDNS_PACKET_NOTIFY, "NOTIFY" },
126 	{ LDNS_PACKET_UPDATE, "UPDATE" },
127         { 0, NULL }
128 };
129 
130 const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
131 const ldns_output_format  *ldns_output_format_nocomments
132 			= &ldns_output_format_nocomments_record;
133 const ldns_output_format   ldns_output_format_onlykeyids_record = {
134 	LDNS_COMMENT_KEY, NULL
135 };
136 const ldns_output_format  *ldns_output_format_onlykeyids
137 			= &ldns_output_format_onlykeyids_record;
138 const ldns_output_format  *ldns_output_format_default
139 			= &ldns_output_format_onlykeyids_record;
140 
141 const ldns_output_format   ldns_output_format_bubblebabble_record = {
142 	LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
143 };
144 const ldns_output_format  *ldns_output_format_bubblebabble
145 			= &ldns_output_format_bubblebabble_record;
146 
147 static bool
ldns_output_format_covers_type(const ldns_output_format * fmt,ldns_rr_type t)148 ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
149 {
150 	return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
151 		((ldns_output_format_storage*)fmt)->bitmap &&
152 		ldns_nsec_bitmap_covers_type(
153 				((ldns_output_format_storage*)fmt)->bitmap, t);
154 }
155 
156 ldns_status
ldns_output_format_set_type(ldns_output_format * fmt,ldns_rr_type t)157 ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
158 {
159 	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
160 	ldns_status s;
161 
162 	assert(fmt != NULL);
163 
164 	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
165 		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
166 	}
167 	if (! fmt_st->bitmap) {
168 		s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
169 		if (s != LDNS_STATUS_OK) {
170 			return s;
171 		}
172 	}
173 	return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
174 }
175 
176 ldns_status
ldns_output_format_clear_type(ldns_output_format * fmt,ldns_rr_type t)177 ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
178 {
179 	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
180 	ldns_status s;
181 
182 	assert(fmt != NULL);
183 
184 	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
185 		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
186 	}
187 	if (! fmt_st->bitmap) {
188 		s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
189 		if (s != LDNS_STATUS_OK) {
190 			return s;
191 		}
192 	}
193 	return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
194 }
195 
196 ldns_status
ldns_pkt_opcode2buffer_str(ldns_buffer * output,ldns_pkt_opcode opcode)197 ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
198 {
199 	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
200 	if (lt && lt->name) {
201 		ldns_buffer_printf(output, "%s", lt->name);
202 	} else {
203 		ldns_buffer_printf(output, "OPCODE%u", opcode);
204 	}
205 	return ldns_buffer_status(output);
206 }
207 
208 ldns_status
ldns_pkt_rcode2buffer_str(ldns_buffer * output,ldns_pkt_rcode rcode)209 ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
210 {
211 	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
212 	if (lt && lt->name) {
213 		ldns_buffer_printf(output, "%s", lt->name);
214 	} else {
215 		ldns_buffer_printf(output, "RCODE%u", rcode);
216 	}
217 	return ldns_buffer_status(output);
218 }
219 
220 ldns_status
ldns_algorithm2buffer_str(ldns_buffer * output,ldns_algorithm algorithm)221 ldns_algorithm2buffer_str(ldns_buffer *output,
222                           ldns_algorithm algorithm)
223 {
224 	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
225 	                                          algorithm);
226 	if (lt && lt->name) {
227 		ldns_buffer_printf(output, "%s", lt->name);
228 	} else {
229 		ldns_buffer_printf(output, "ALG%u", algorithm);
230 	}
231 	return ldns_buffer_status(output);
232 }
233 
234 ldns_status
ldns_cert_algorithm2buffer_str(ldns_buffer * output,ldns_cert_algorithm cert_algorithm)235 ldns_cert_algorithm2buffer_str(ldns_buffer *output,
236                                ldns_cert_algorithm cert_algorithm)
237 {
238 	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
239 	                                          cert_algorithm);
240 	if (lt && lt->name) {
241 		ldns_buffer_printf(output, "%s", lt->name);
242 	} else {
243 		ldns_buffer_printf(output, "CERT_ALG%u",
244 		                   cert_algorithm);
245 	}
246 	return ldns_buffer_status(output);
247 }
248 
249 char *
ldns_pkt_opcode2str(ldns_pkt_opcode opcode)250 ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
251 {
252 	char *str;
253 	ldns_buffer *buf;
254 
255 	buf = ldns_buffer_new(12);
256 	if (!buf) {
257 		return NULL;
258 	}
259 
260 	str = NULL;
261 	if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
262 		str = ldns_buffer_export2str(buf);
263 	}
264 
265 	ldns_buffer_free(buf);
266 	return str;
267 }
268 
269 char *
ldns_pkt_rcode2str(ldns_pkt_rcode rcode)270 ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
271 {
272 	char *str;
273 	ldns_buffer *buf;
274 
275 	buf = ldns_buffer_new(10);
276 	if (!buf) {
277 		return NULL;
278 	}
279 
280 	str = NULL;
281 	if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
282 		str = ldns_buffer_export2str(buf);
283 	}
284 
285 	ldns_buffer_free(buf);
286 	return str;
287 }
288 
289 char *
ldns_pkt_algorithm2str(ldns_algorithm algorithm)290 ldns_pkt_algorithm2str(ldns_algorithm algorithm)
291 {
292 	char *str;
293 	ldns_buffer *buf;
294 
295 	buf = ldns_buffer_new(10);
296 	if (!buf) {
297 		return NULL;
298 	}
299 
300 	str = NULL;
301 	if (ldns_algorithm2buffer_str(buf, algorithm)
302 	    == LDNS_STATUS_OK) {
303 		str = ldns_buffer_export2str(buf);
304 	}
305 
306 	ldns_buffer_free(buf);
307 	return str;
308 }
309 
310 char *
ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)311 ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
312 {
313 	char *str;
314 	ldns_buffer *buf;
315 
316 	buf = ldns_buffer_new(10);
317 	if (!buf) {
318 		return NULL;
319 	}
320 
321 	str = NULL;
322 	if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
323 	    == LDNS_STATUS_OK) {
324 		str = ldns_buffer_export2str(buf);
325 	}
326 
327 	ldns_buffer_free(buf);
328 	return str;
329 }
330 
331 
332 /* do NOT pass compressed data here :p */
333 ldns_status
ldns_rdf2buffer_str_dname(ldns_buffer * output,const ldns_rdf * dname)334 ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
335 {
336 	/* can we do with 1 pos var? or without at all? */
337 	uint8_t src_pos = 0;
338 	uint8_t len;
339 	uint8_t *data;
340 	uint8_t i;
341 	unsigned char c;
342 
343 	data = (uint8_t*)ldns_rdf_data(dname);
344 	len = data[src_pos];
345 
346 	if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
347 		/* too large, return */
348 		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
349 	}
350 
351 	/* special case: root label */
352 	if (1 == ldns_rdf_size(dname)) {
353 		ldns_buffer_printf(output, ".");
354 	} else {
355 		while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
356 			src_pos++;
357 			for(i = 0; i < len; i++) {
358 				/* paranoia check for various 'strange'
359 				   characters in dnames
360 				*/
361 				c = (unsigned char) data[src_pos];
362 				if(c == '.' || c == ';' ||
363 				   c == '(' || c == ')' ||
364 				   c == '\\') {
365 					ldns_buffer_printf(output, "\\%c",
366 							data[src_pos]);
367 				} else if (!(isascii(c) && isgraph(c))) {
368 					ldns_buffer_printf(output, "\\%03u",
369 						        data[src_pos]);
370 				} else {
371 					ldns_buffer_printf(output, "%c", data[src_pos]);
372 				}
373 				src_pos++;
374 			}
375 
376 			if (src_pos < ldns_rdf_size(dname)) {
377 				ldns_buffer_printf(output, ".");
378 			}
379 			len = data[src_pos];
380 		}
381 	}
382 	return ldns_buffer_status(output);
383 }
384 
385 ldns_status
ldns_rdf2buffer_str_int8(ldns_buffer * output,const ldns_rdf * rdf)386 ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
387 {
388 	uint8_t data = ldns_rdf_data(rdf)[0];
389 	ldns_buffer_printf(output, "%lu", (unsigned long) data);
390 	return ldns_buffer_status(output);
391 }
392 
393 ldns_status
ldns_rdf2buffer_str_int16(ldns_buffer * output,const ldns_rdf * rdf)394 ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
395 {
396 	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
397 	ldns_buffer_printf(output, "%lu", (unsigned long) data);
398 	return ldns_buffer_status(output);
399 }
400 
401 ldns_status
ldns_rdf2buffer_str_int32(ldns_buffer * output,const ldns_rdf * rdf)402 ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
403 {
404 	uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
405 	ldns_buffer_printf(output, "%lu", (unsigned long) data);
406 	return ldns_buffer_status(output);
407 }
408 
409 ldns_status
ldns_rdf2buffer_str_int64(ldns_buffer * output,const ldns_rdf * rdf)410 ldns_rdf2buffer_str_int64(ldns_buffer *output, const ldns_rdf *rdf)
411 {
412 	uint64_t data = ldns_read_uint64(ldns_rdf_data(rdf));
413 	ldns_buffer_printf(output, "%llu", (unsigned long long) data);
414 	return ldns_buffer_status(output);
415 }
416 
417 ldns_status
ldns_rdf2buffer_str_time(ldns_buffer * output,const ldns_rdf * rdf)418 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
419 {
420 	/* create a YYYYMMDDHHMMSS string if possible */
421 	struct tm tm;
422 	char date_buf[16];
423 
424 	memset(&tm, 0, sizeof(tm));
425 	if (ldns_serial_arithmetics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
426 	    && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
427 		ldns_buffer_printf(output, "%s", date_buf);
428 	}
429 	return ldns_buffer_status(output);
430 }
431 
432 ldns_status
ldns_rdf2buffer_str_a(ldns_buffer * output,const ldns_rdf * rdf)433 ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
434 {
435 	char str[INET_ADDRSTRLEN];
436 
437 	if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
438 		ldns_buffer_printf(output, "%s", str);
439 	}
440 	return ldns_buffer_status(output);
441 }
442 
443 ldns_status
ldns_rdf2buffer_str_aaaa(ldns_buffer * output,const ldns_rdf * rdf)444 ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
445 {
446 	char str[INET6_ADDRSTRLEN];
447 
448 	if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
449 		ldns_buffer_printf(output, "%s", str);
450 	}
451 
452 	return ldns_buffer_status(output);
453 }
454 
455 static void
ldns_characters2buffer_str(ldns_buffer * output,size_t amount,const uint8_t * characters)456 ldns_characters2buffer_str(ldns_buffer* output,
457 		size_t amount, const uint8_t* characters)
458 {
459 	uint8_t ch;
460 	while (amount > 0) {
461 		ch = *characters++;
462 		if (isprint((int)ch) || ch == '\t') {
463 			if (ch == '\"' || ch == '\\')
464 				ldns_buffer_printf(output, "\\%c", ch);
465 			else
466 				ldns_buffer_printf(output, "%c", ch);
467 		} else {
468 			ldns_buffer_printf(output, "\\%03u",
469                                 (unsigned)(uint8_t) ch);
470 		}
471 		amount--;
472 	}
473 }
474 
475 ldns_status
ldns_rdf2buffer_str_str(ldns_buffer * output,const ldns_rdf * rdf)476 ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
477 {
478         if(ldns_rdf_size(rdf) < 1) {
479                 return LDNS_STATUS_WIRE_RDATA_ERR;
480         }
481         if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
482                 return LDNS_STATUS_WIRE_RDATA_ERR;
483         }
484 	ldns_buffer_printf(output, "\"");
485 	ldns_characters2buffer_str(output,
486 			ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
487 	ldns_buffer_printf(output, "\"");
488 	return ldns_buffer_status(output);
489 }
490 
491 ldns_status
ldns_rdf2buffer_str_b64(ldns_buffer * output,const ldns_rdf * rdf)492 ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
493 {
494 	size_t size;
495 	char *b64;
496 
497 	if (ldns_rdf_size(rdf) == 0) {
498 		ldns_buffer_printf(output, "0");
499 		return ldns_buffer_status(output);
500 	} else
501 		size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
502 
503 	if (!(b64 = LDNS_XMALLOC(char, size)))
504 		return LDNS_STATUS_MEM_ERR;
505 
506 	if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
507 		ldns_buffer_printf(output, "%s", b64);
508 	}
509 	LDNS_FREE(b64);
510 	return ldns_buffer_status(output);
511 }
512 
513 ldns_status
ldns_rdf2buffer_str_b32_ext(ldns_buffer * output,const ldns_rdf * rdf)514 ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
515 {
516 	size_t size;
517 	char *b32;
518 	if(ldns_rdf_size(rdf) == 0)
519 		return LDNS_STATUS_OK;
520         /* remove -1 for the b32-hash-len octet */
521 	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
522         /* add one for the end nul for the string */
523 	b32 = LDNS_XMALLOC(char, size + 1);
524 	if(!b32) return LDNS_STATUS_MEM_ERR;
525 	size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
526 		ldns_rdf_size(rdf) - 1, b32, size+1);
527 	if (size > 0) {
528 		ldns_buffer_printf(output, "%s", b32);
529 	}
530 	LDNS_FREE(b32);
531 	return ldns_buffer_status(output);
532 }
533 
534 ldns_status
ldns_rdf2buffer_str_hex(ldns_buffer * output,const ldns_rdf * rdf)535 ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
536 {
537 	size_t i;
538 	for (i = 0; i < ldns_rdf_size(rdf); i++) {
539 		ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
540 	}
541 
542 	return ldns_buffer_status(output);
543 }
544 
545 static ldns_status
ldns_rdf2buffer_str_type_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)546 ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
547 		const ldns_output_format* fmt, const ldns_rdf *rdf)
548 {
549         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
550 
551 	if (! ldns_output_format_covers_type(fmt, data) &&
552 			ldns_rr_descript(data) &&
553 			ldns_rr_descript(data)->_name) {
554 
555 		ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
556 	} else {
557 		ldns_buffer_printf(output, "TYPE%u", data);
558 	}
559 	return  ldns_buffer_status(output);
560 }
561 
562 ldns_status
ldns_rdf2buffer_str_type(ldns_buffer * output,const ldns_rdf * rdf)563 ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
564 {
565 	return ldns_rdf2buffer_str_type_fmt(output,
566 			ldns_output_format_default, rdf);
567 }
568 
569 ldns_status
ldns_rdf2buffer_str_class(ldns_buffer * output,const ldns_rdf * rdf)570 ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
571 {
572 	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
573 	ldns_lookup_table *lt;
574 
575  	lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
576 	if (lt) {
577 		ldns_buffer_printf(output, "\t%s", lt->name);
578 	} else {
579 		ldns_buffer_printf(output, "\tCLASS%d", data);
580 	}
581 	return ldns_buffer_status(output);
582 }
583 
584 ldns_status
ldns_rdf2buffer_str_cert_alg(ldns_buffer * output,const ldns_rdf * rdf)585 ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
586 {
587         uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
588 	ldns_lookup_table *lt;
589  	lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
590 	if (lt) {
591 		ldns_buffer_printf(output, "%s", lt->name);
592 	} else {
593 		ldns_buffer_printf(output, "%d", data);
594 	}
595 	return ldns_buffer_status(output);
596 }
597 
598 ldns_status
ldns_rdf2buffer_str_alg(ldns_buffer * output,const ldns_rdf * rdf)599 ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
600 {
601 	return ldns_rdf2buffer_str_int8(output, rdf);
602 }
603 
604 static void
loc_cm_print(ldns_buffer * output,uint8_t mantissa,uint8_t exponent)605 loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
606 {
607 	uint8_t i;
608 	/* is it 0.<two digits> ? */
609 	if(exponent < 2) {
610 		if(exponent == 1)
611 			mantissa *= 10;
612 		ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
613 		return;
614 	}
615 	/* always <digit><string of zeros> */
616 	ldns_buffer_printf(output, "%d", (int)mantissa);
617 	for(i=0; i<exponent-2; i++)
618 		ldns_buffer_printf(output, "0");
619 }
620 
621 ldns_status
ldns_rr_type2buffer_str(ldns_buffer * output,const ldns_rr_type type)622 ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
623 {
624 	const ldns_rr_descriptor *descriptor;
625 
626 	descriptor = ldns_rr_descript(type);
627 
628 	switch (type) {
629 		case LDNS_RR_TYPE_IXFR:
630 			ldns_buffer_printf(output, "IXFR");
631 			break;
632 		case LDNS_RR_TYPE_AXFR:
633 			ldns_buffer_printf(output, "AXFR");
634 			break;
635 		case LDNS_RR_TYPE_MAILA:
636 			ldns_buffer_printf(output, "MAILA");
637 			break;
638 		case LDNS_RR_TYPE_MAILB:
639 			ldns_buffer_printf(output, "MAILB");
640 			break;
641 		case LDNS_RR_TYPE_ANY:
642 			ldns_buffer_printf(output, "ANY");
643 			break;
644 		default:
645 			if (descriptor && descriptor->_name) {
646 				ldns_buffer_printf(output, "%s", descriptor->_name);
647 			} else {
648 				ldns_buffer_printf(output, "TYPE%u", type);
649 			}
650 	}
651 	return ldns_buffer_status(output);
652 }
653 
654 char *
ldns_rr_type2str(const ldns_rr_type type)655 ldns_rr_type2str(const ldns_rr_type type)
656 {
657 	char *str;
658 	ldns_buffer *buf;
659 
660 	buf = ldns_buffer_new(10);
661 	if (!buf) {
662 		return NULL;
663 	}
664 
665 	str = NULL;
666 	if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
667 		str = ldns_buffer_export2str(buf);
668 	}
669 
670 	ldns_buffer_free(buf);
671 	return str;
672 }
673 
674 
675 ldns_status
ldns_rr_class2buffer_str(ldns_buffer * output,const ldns_rr_class klass)676 ldns_rr_class2buffer_str(ldns_buffer *output,
677                          const ldns_rr_class klass)
678 {
679 	ldns_lookup_table *lt;
680 
681 	lt = ldns_lookup_by_id(ldns_rr_classes, klass);
682 	if (lt) {
683 		ldns_buffer_printf(output, "%s", lt->name);
684 	} else {
685 		ldns_buffer_printf(output, "CLASS%d", klass);
686 	}
687 	return ldns_buffer_status(output);
688 }
689 
690 char *
ldns_rr_class2str(const ldns_rr_class klass)691 ldns_rr_class2str(const ldns_rr_class klass)
692 {
693 	ldns_buffer *buf;
694 	char *str;
695 
696 	buf = ldns_buffer_new(10);
697 	if (!buf) {
698 		return NULL;
699 	}
700 
701 	str = NULL;
702 	if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
703 		str = ldns_buffer_export2str(buf);
704 	}
705 	ldns_buffer_free(buf);
706 	return str;
707 }
708 
709 ldns_status
ldns_rdf2buffer_str_loc(ldns_buffer * output,const ldns_rdf * rdf)710 ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
711 {
712 	/* we could do checking (ie degrees < 90 etc)? */
713 	uint8_t version;
714 	uint8_t size;
715 	uint8_t horizontal_precision;
716 	uint8_t vertical_precision;
717 	uint32_t longitude;
718 	uint32_t latitude;
719 	uint32_t altitude;
720 	char latitude_hemisphere;
721 	char longitude_hemisphere;
722 	uint32_t h;
723 	uint32_t m;
724 	double s;
725 
726 	uint32_t equator = (uint32_t) ldns_power(2, 31);
727 
728         if(ldns_rdf_size(rdf) < 1) {
729                 return LDNS_STATUS_WIRE_RDATA_ERR;
730         }
731        	version = ldns_rdf_data(rdf)[0];
732 	if (version == 0) {
733 		if(ldns_rdf_size(rdf) < 16) {
734 			return LDNS_STATUS_WIRE_RDATA_ERR;
735 		}
736 		size = ldns_rdf_data(rdf)[1];
737 		horizontal_precision = ldns_rdf_data(rdf)[2];
738 		vertical_precision = ldns_rdf_data(rdf)[3];
739 
740 		latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
741 		longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
742 		altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
743 
744 		if (latitude > equator) {
745 			latitude_hemisphere = 'N';
746 			latitude = latitude - equator;
747 		} else {
748 			latitude_hemisphere = 'S';
749 			latitude = equator - latitude;
750 		}
751 		h = latitude / (1000 * 60 * 60);
752 		latitude = latitude % (1000 * 60 * 60);
753 		m = latitude / (1000 * 60);
754 		latitude = latitude % (1000 * 60);
755 		s = (double) latitude / 1000.0;
756 		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
757 			h, m, s, latitude_hemisphere);
758 
759 		if (longitude > equator) {
760 			longitude_hemisphere = 'E';
761 			longitude = longitude - equator;
762 		} else {
763 			longitude_hemisphere = 'W';
764 			longitude = equator - longitude;
765 		}
766 		h = longitude / (1000 * 60 * 60);
767 		longitude = longitude % (1000 * 60 * 60);
768 		m = longitude / (1000 * 60);
769 		longitude = longitude % (1000 * 60);
770 		s = (double) longitude / (1000.0);
771 		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
772 			h, m, s, longitude_hemisphere);
773 
774 		s = ((double) altitude) / 100;
775 		s -= 100000;
776 
777 		if(altitude%100 != 0)
778 			ldns_buffer_printf(output, "%.2f", s);
779 		else
780 			ldns_buffer_printf(output, "%.0f", s);
781 
782 		ldns_buffer_printf(output, "m ");
783 
784 		loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
785 		ldns_buffer_printf(output, "m ");
786 
787 		loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
788 			horizontal_precision & 0x0f);
789 		ldns_buffer_printf(output, "m ");
790 
791 		loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
792 			vertical_precision & 0x0f);
793 		ldns_buffer_printf(output, "m");
794 
795 		return ldns_buffer_status(output);
796 	} else {
797 		return ldns_rdf2buffer_str_hex(output, rdf);
798 	}
799 }
800 
801 ldns_status
ldns_rdf2buffer_str_unknown(ldns_buffer * output,const ldns_rdf * rdf)802 ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
803 {
804 	ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
805 	return ldns_rdf2buffer_str_hex(output, rdf);
806 }
807 
808 ldns_status
ldns_rdf2buffer_str_nsap(ldns_buffer * output,const ldns_rdf * rdf)809 ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
810 {
811 	ldns_buffer_printf(output, "0x");
812 	return ldns_rdf2buffer_str_hex(output, rdf);
813 }
814 
815 ldns_status
ldns_rdf2buffer_str_atma(ldns_buffer * output,const ldns_rdf * rdf)816 ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
817 {
818 	return ldns_rdf2buffer_str_hex(output, rdf);
819 }
820 
821 ldns_status
ldns_rdf2buffer_str_wks(ldns_buffer * output,const ldns_rdf * rdf)822 ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
823 {
824 	/* protocol, followed by bitmap of services */
825 	struct protoent *protocol;
826 	char *proto_name = NULL;
827 	uint8_t protocol_nr;
828 	struct servent *service;
829 	uint16_t current_service;
830 
831         if(ldns_rdf_size(rdf) < 1) {
832                 return LDNS_STATUS_WIRE_RDATA_ERR;
833         }
834 	protocol_nr = ldns_rdf_data(rdf)[0];
835 	protocol = getprotobynumber((int) protocol_nr);
836 	if (protocol && (protocol->p_name != NULL)) {
837 		proto_name = protocol->p_name;
838 		ldns_buffer_printf(output, "%s ", protocol->p_name);
839 	} else {
840 		ldns_buffer_printf(output, "%u ", protocol_nr);
841 	}
842 
843 	for (current_service = 0;
844 	     current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
845 		if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
846 			service = getservbyport((int) htons(current_service),
847 			                        proto_name);
848 			if (service && service->s_name) {
849 				ldns_buffer_printf(output, "%s ", service->s_name);
850 			} else {
851 				ldns_buffer_printf(output, "%u ", current_service);
852 			}
853 #ifdef HAVE_ENDSERVENT
854 			endservent();
855 #endif
856 		}
857 		/* exit from loop before integer overflow */
858 		if(current_service == 65535) { break; }
859 	}
860 
861 #ifdef HAVE_ENDPROTOENT
862 	endprotoent();
863 #endif
864 
865 	return ldns_buffer_status(output);
866 }
867 
868 static ldns_status
ldns_rdf2buffer_str_nsec_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)869 ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
870 		const ldns_output_format* fmt, const ldns_rdf *rdf)
871 {
872 	/* Note: this code is duplicated in higher.c in
873 	 * ldns_nsec_type_check() function
874 	 */
875 	uint8_t window_block_nr;
876 	uint8_t bitmap_length;
877 	uint16_t type;
878 	uint16_t pos = 0;
879 	uint16_t bit_pos;
880 	uint8_t *data = ldns_rdf_data(rdf);
881 
882 	while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
883 		window_block_nr = data[pos];
884 		bitmap_length = data[pos + 1];
885 		pos += 2;
886 		if (ldns_rdf_size(rdf) < pos + bitmap_length) {
887 			return LDNS_STATUS_WIRE_RDATA_ERR;
888 		}
889 		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
890 			if (! ldns_get_bit(&data[pos], bit_pos)) {
891 				continue;
892 			}
893 			type = 256 * (uint16_t) window_block_nr + bit_pos;
894 
895 			if (! ldns_output_format_covers_type(fmt, type) &&
896 					ldns_rr_descript(type) &&
897 					ldns_rr_descript(type)->_name){
898 
899 				ldns_buffer_printf(output, "%s ",
900 						ldns_rr_descript(type)->_name);
901 			} else {
902 				ldns_buffer_printf(output, "TYPE%u ", type);
903 			}
904 		}
905 		pos += (uint16_t) bitmap_length;
906 	}
907 	return ldns_buffer_status(output);
908 }
909 
910 ldns_status
ldns_rdf2buffer_str_nsec(ldns_buffer * output,const ldns_rdf * rdf)911 ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
912 {
913 	return ldns_rdf2buffer_str_nsec_fmt(output,
914 			ldns_output_format_default, rdf);
915 }
916 
917 ldns_status
ldns_rdf2buffer_str_nsec3_salt(ldns_buffer * output,const ldns_rdf * rdf)918 ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
919 {
920 	uint8_t salt_length;
921 	uint8_t salt_pos;
922 
923 	uint8_t *data = ldns_rdf_data(rdf);
924 
925         if(ldns_rdf_size(rdf) < 1) {
926                 return LDNS_STATUS_WIRE_RDATA_ERR;
927         }
928 	salt_length = data[0];
929 	/* from now there are variable length entries so remember pos */
930 	if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
931 		ldns_buffer_printf(output, "- ");
932 	} else {
933 		for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
934 			ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
935 		}
936 		ldns_buffer_printf(output, " ");
937 	}
938 
939 	return ldns_buffer_status(output);
940 }
941 
942 ldns_status
ldns_rdf2buffer_str_period(ldns_buffer * output,const ldns_rdf * rdf)943 ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
944 {
945 	/* period is the number of seconds */
946 	if (ldns_rdf_size(rdf) != 4) {
947 		return LDNS_STATUS_WIRE_RDATA_ERR;
948 	}
949 	ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
950 	return ldns_buffer_status(output);
951 }
952 
953 ldns_status
ldns_rdf2buffer_str_tsigtime(ldns_buffer * output,const ldns_rdf * rdf)954 ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
955 {
956 	/* tsigtime is 48 bits network order unsigned integer */
957 	uint64_t tsigtime = 0;
958 	uint8_t *data = ldns_rdf_data(rdf);
959 	uint64_t d0, d1, d2, d3, d4, d5;
960 
961 	if (ldns_rdf_size(rdf) < 6) {
962 		return LDNS_STATUS_WIRE_RDATA_ERR;
963 	}
964 	d0 = data[0]; /* cast to uint64 for shift operations */
965 	d1 = data[1];
966 	d2 = data[2];
967 	d3 = data[3];
968 	d4 = data[4];
969 	d5 = data[5];
970 	tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
971 
972 	ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
973 
974 	return ldns_buffer_status(output);
975 }
976 
977 ldns_status
ldns_rdf2buffer_str_apl(ldns_buffer * output,const ldns_rdf * rdf)978 ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
979 {
980 	uint8_t *data = ldns_rdf_data(rdf);
981 	uint16_t address_family;
982 	uint8_t prefix;
983 	bool negation;
984 	uint8_t adf_length;
985 	size_t i;
986 	size_t pos = 0;
987 
988 	while (pos < (unsigned int) ldns_rdf_size(rdf)) {
989                 if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
990                         return LDNS_STATUS_WIRE_RDATA_ERR;
991 		address_family = ldns_read_uint16(&data[pos]);
992 		prefix = data[pos + 2];
993 		negation = data[pos + 3] & LDNS_APL_NEGATION;
994 		adf_length = data[pos + 3] & LDNS_APL_MASK;
995 		if (address_family == LDNS_APL_IP4) {
996 			/* check if prefix < 32? */
997 			if (negation) {
998 				ldns_buffer_printf(output, "!");
999 			}
1000 			ldns_buffer_printf(output, "%u:", address_family);
1001 			/* address is variable length 0 - 4 */
1002 			for (i = 0; i < 4; i++) {
1003 				if (i > 0) {
1004 					ldns_buffer_printf(output, ".");
1005 				}
1006 				if (i < (unsigned short) adf_length) {
1007                                         if(pos+i+4 >= ldns_rdf_size(rdf))
1008 					    return LDNS_STATUS_WIRE_RDATA_ERR;
1009 					ldns_buffer_printf(output, "%d",
1010 					                   data[pos + i + 4]);
1011 				} else {
1012 					ldns_buffer_printf(output, "0");
1013 				}
1014 			}
1015 			ldns_buffer_printf(output, "/%u ", prefix);
1016 		} else if (address_family == LDNS_APL_IP6) {
1017 			/* check if prefix < 128? */
1018 			if (negation) {
1019 				ldns_buffer_printf(output, "!");
1020 			}
1021 			ldns_buffer_printf(output, "%u:", address_family);
1022 			/* address is variable length 0 - 16 */
1023 			for (i = 0; i < 16; i++) {
1024 				if (i % 2 == 0 && i > 0) {
1025 					ldns_buffer_printf(output, ":");
1026 				}
1027 				if (i < (unsigned short) adf_length) {
1028                                         if(pos+i+4 >= ldns_rdf_size(rdf))
1029 					    return LDNS_STATUS_WIRE_RDATA_ERR;
1030 					ldns_buffer_printf(output, "%02x",
1031 					                   data[pos + i + 4]);
1032 				} else {
1033 					ldns_buffer_printf(output, "00");
1034 				}
1035 			}
1036 			ldns_buffer_printf(output, "/%u ", prefix);
1037 
1038 		} else {
1039 			/* unknown address family */
1040 			ldns_buffer_printf(output,
1041 					"Unknown address family: %u data: ",
1042 					address_family);
1043 			for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
1044                                 if(pos+i >= ldns_rdf_size(rdf))
1045                                         return LDNS_STATUS_WIRE_RDATA_ERR;
1046 				ldns_buffer_printf(output, "%02x", data[i]);
1047 			}
1048 		}
1049 		pos += 4 + adf_length;
1050 	}
1051 	return ldns_buffer_status(output);
1052 }
1053 
1054 ldns_status
ldns_rdf2buffer_str_int16_data(ldns_buffer * output,const ldns_rdf * rdf)1055 ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
1056 {
1057 	size_t size;
1058 	char *b64;
1059 	if (ldns_rdf_size(rdf) < 2) {
1060 		return LDNS_STATUS_WIRE_RDATA_ERR;
1061 	}
1062 	/* Subtract the size (2) of the number that specifies the length */
1063 	size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
1064 	ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
1065 	if (ldns_rdf_size(rdf) > 2) {
1066 		b64 = LDNS_XMALLOC(char, size);
1067 		if(!b64)
1068 			return LDNS_STATUS_MEM_ERR;
1069 
1070 		if (ldns_rdf_size(rdf) > 2 &&
1071 		ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
1072 					ldns_rdf_size(rdf) - 2,
1073 					b64, size)) {
1074 			ldns_buffer_printf(output, "%s", b64);
1075 		}
1076 		LDNS_FREE(b64);
1077 	}
1078 	return ldns_buffer_status(output);
1079 }
1080 
1081 ldns_status
ldns_rdf2buffer_str_ipseckey(ldns_buffer * output,const ldns_rdf * rdf)1082 ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
1083 {
1084 	/* wire format from
1085 	   http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
1086 	*/
1087 	uint8_t *data = ldns_rdf_data(rdf);
1088 	uint8_t precedence;
1089 	uint8_t gateway_type;
1090 	uint8_t algorithm;
1091 
1092 	ldns_rdf *gateway = NULL;
1093 	uint8_t *gateway_data;
1094 
1095 	size_t public_key_size;
1096 	uint8_t *public_key_data;
1097 	ldns_rdf *public_key;
1098 
1099 	size_t offset = 0;
1100 	ldns_status status;
1101 
1102 	if (ldns_rdf_size(rdf) < 3) {
1103 		return LDNS_STATUS_WIRE_RDATA_ERR;
1104 	}
1105 	precedence = data[0];
1106 	gateway_type = data[1];
1107 	algorithm = data[2];
1108 	offset = 3;
1109 
1110 	switch (gateway_type) {
1111 		case 0:
1112 			/* no gateway */
1113 			break;
1114 		case 1:
1115 			if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1116 				return LDNS_STATUS_ERR;
1117 			}
1118 			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1119                         if(!gateway_data)
1120                                 return LDNS_STATUS_MEM_ERR;
1121 			memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
1122 			gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
1123 					LDNS_IP4ADDRLEN , gateway_data);
1124 			offset += LDNS_IP4ADDRLEN;
1125                         if(!gateway) {
1126                                 LDNS_FREE(gateway_data);
1127                                 return LDNS_STATUS_MEM_ERR;
1128                         }
1129 			break;
1130 		case 2:
1131 			if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1132 				return LDNS_STATUS_ERR;
1133 			}
1134 			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1135                         if(!gateway_data)
1136                                 return LDNS_STATUS_MEM_ERR;
1137 			memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
1138 			offset += LDNS_IP6ADDRLEN;
1139 			gateway =
1140 				ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1141 						LDNS_IP6ADDRLEN, gateway_data);
1142                         if(!gateway) {
1143                                 LDNS_FREE(gateway_data);
1144                                 return LDNS_STATUS_MEM_ERR;
1145                         }
1146 			break;
1147 		case 3:
1148 			status = ldns_wire2dname(&gateway, data,
1149 					ldns_rdf_size(rdf), &offset);
1150                         if(status != LDNS_STATUS_OK)
1151                                 return status;
1152 			break;
1153 		default:
1154 			/* error? */
1155 			break;
1156 	}
1157 
1158 	if (ldns_rdf_size(rdf) <= offset) {
1159                 ldns_rdf_deep_free(gateway);
1160 		return LDNS_STATUS_ERR;
1161 	}
1162 	public_key_size = ldns_rdf_size(rdf) - offset;
1163 	public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1164         if(!public_key_data) {
1165                 ldns_rdf_deep_free(gateway);
1166                 return LDNS_STATUS_MEM_ERR;
1167         }
1168 	memcpy(public_key_data, &data[offset], public_key_size);
1169 	public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
1170 			public_key_size, public_key_data);
1171         if(!public_key) {
1172                 LDNS_FREE(public_key_data);
1173                 ldns_rdf_deep_free(gateway);
1174                 return LDNS_STATUS_MEM_ERR;
1175         }
1176 
1177 	ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1178 	if (gateway)
1179 	  	(void) ldns_rdf2buffer_str(output, gateway);
1180 	else
1181 		ldns_buffer_printf(output, ".");
1182 	ldns_buffer_printf(output, " ");
1183 	(void) ldns_rdf2buffer_str(output, public_key);
1184 
1185 	ldns_rdf_deep_free(gateway);
1186 	ldns_rdf_deep_free(public_key);
1187 
1188 	return ldns_buffer_status(output);
1189 }
1190 
1191 ldns_status
ldns_rdf2buffer_str_ilnp64(ldns_buffer * output,const ldns_rdf * rdf)1192 ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
1193 {
1194 	if (ldns_rdf_size(rdf) != 8) {
1195 		return LDNS_STATUS_WIRE_RDATA_ERR;
1196 	}
1197 	ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
1198 				ldns_read_uint16(ldns_rdf_data(rdf)),
1199 				ldns_read_uint16(ldns_rdf_data(rdf)+2),
1200 				ldns_read_uint16(ldns_rdf_data(rdf)+4),
1201 				ldns_read_uint16(ldns_rdf_data(rdf)+6));
1202 	return ldns_buffer_status(output);
1203 }
1204 
1205 ldns_status
ldns_rdf2buffer_str_eui48(ldns_buffer * output,const ldns_rdf * rdf)1206 ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
1207 {
1208 	if (ldns_rdf_size(rdf) != 6) {
1209 		return LDNS_STATUS_WIRE_RDATA_ERR;
1210 	}
1211 	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1212 				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1213 				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1214 				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
1215 	return ldns_buffer_status(output);
1216 }
1217 
1218 ldns_status
ldns_rdf2buffer_str_eui64(ldns_buffer * output,const ldns_rdf * rdf)1219 ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
1220 {
1221 	if (ldns_rdf_size(rdf) != 8) {
1222 		return LDNS_STATUS_WIRE_RDATA_ERR;
1223 	}
1224 	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1225 				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1226 				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1227 				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
1228 				ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
1229 	return ldns_buffer_status(output);
1230 }
1231 
1232 ldns_status
ldns_rdf2buffer_str_unquoted(ldns_buffer * output,const ldns_rdf * rdf)1233 ldns_rdf2buffer_str_unquoted(ldns_buffer *output, const ldns_rdf *rdf)
1234 {
1235 	size_t amount, i;
1236 	uint8_t ch;
1237 	if(ldns_rdf_size(rdf) < 1) {
1238 		return LDNS_STATUS_WIRE_RDATA_ERR;
1239 	}
1240 	if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
1241 		return LDNS_STATUS_WIRE_RDATA_ERR;
1242 	}
1243 	amount = ldns_rdf_data(rdf)[0];
1244 	for(i=0; i<amount; i++) {
1245 		ch = ldns_rdf_data(rdf)[1+i];
1246 		if (isprint((int)ch) || ch == '\t') {
1247 			if (ch == '\"' || ch == '\\' || ch == '\'' ||
1248 				ch == '(' || ch == ')' || isspace((int)ch))
1249 				ldns_buffer_printf(output, "\\%c", ch);
1250 			else
1251 				ldns_buffer_printf(output, "%c", ch);
1252 		} else {
1253 			ldns_buffer_printf(output, "\\%03u",
1254                                 (unsigned)(uint8_t) ch);
1255 		}
1256 	}
1257 	return ldns_buffer_status(output);
1258 }
1259 
1260 ldns_status
ldns_rdf2buffer_str_tag(ldns_buffer * output,const ldns_rdf * rdf)1261 ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
1262 {
1263 	size_t nchars;
1264 	const uint8_t* chars;
1265 	char ch;
1266 	if (ldns_rdf_size(rdf) < 2) {
1267 		return LDNS_STATUS_WIRE_RDATA_ERR;
1268 	}
1269 	nchars = ldns_rdf_data(rdf)[0];
1270 	if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
1271 			nchars < 1) {
1272 		return LDNS_STATUS_WIRE_RDATA_ERR;
1273 	}
1274 	chars = ldns_rdf_data(rdf) + 1;
1275 	while (nchars > 0) {
1276 		ch = (char)*chars++;
1277 		if (! isalnum((unsigned char)ch)) {
1278 			return LDNS_STATUS_WIRE_RDATA_ERR;
1279 		}
1280 		ldns_buffer_printf(output, "%c", ch);
1281 		nchars--;
1282 	}
1283 	return ldns_buffer_status(output);
1284 }
1285 
1286 ldns_status
ldns_rdf2buffer_str_long_str(ldns_buffer * output,const ldns_rdf * rdf)1287 ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
1288 {
1289 
1290 	ldns_buffer_printf(output, "\"");
1291 	ldns_characters2buffer_str(output,
1292 			ldns_rdf_size(rdf), ldns_rdf_data(rdf));
1293 	ldns_buffer_printf(output, "\"");
1294 	return ldns_buffer_status(output);
1295 }
1296 
1297 ldns_status
ldns_rdf2buffer_str_hip(ldns_buffer * output,const ldns_rdf * rdf)1298 ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
1299 {
1300 	uint8_t *data = ldns_rdf_data(rdf);
1301 	size_t rdf_size = ldns_rdf_size(rdf);
1302 	uint8_t hit_size;
1303 	uint16_t pk_size;
1304 	int written;
1305 
1306 	if (rdf_size < 6) {
1307 		return LDNS_STATUS_WIRE_RDATA_ERR;
1308 	}
1309 	if ((hit_size = data[0]) == 0 ||
1310 			(pk_size = ldns_read_uint16(data + 2)) == 0 ||
1311 			rdf_size < (size_t) hit_size + pk_size + 4) {
1312 
1313 		return LDNS_STATUS_WIRE_RDATA_ERR;
1314 	}
1315 
1316 	ldns_buffer_printf(output, "%d ", (int) data[1]);
1317 
1318 	for (data += 4; hit_size > 0; hit_size--, data++) {
1319 
1320 		ldns_buffer_printf(output, "%02x", (int) *data);
1321 	}
1322 	ldns_buffer_write_char(output, (uint8_t) ' ');
1323 
1324 	if (ldns_buffer_reserve(output,
1325 				ldns_b64_ntop_calculate_size(pk_size))) {
1326 
1327 		written = ldns_b64_ntop(data, pk_size,
1328 				(char *) ldns_buffer_current(output),
1329 				ldns_buffer_remaining(output));
1330 
1331 		if (written > 0 &&
1332 				written < (int) ldns_buffer_remaining(output)) {
1333 
1334 			output->_position += written;
1335 		}
1336 	}
1337 	return ldns_buffer_status(output);
1338 }
1339 
1340 /* implementation mimicked from ldns_rdf2buffer_str_ipseckey */
1341 ldns_status
ldns_rdf2buffer_str_amtrelay(ldns_buffer * output,const ldns_rdf * rdf)1342 ldns_rdf2buffer_str_amtrelay(ldns_buffer *output, const ldns_rdf *rdf)
1343 {
1344 	/* wire format from
1345 	 * draft-ietf-mboned-driad-amt-discovery Section 4.2
1346 	 */
1347 	uint8_t *data = ldns_rdf_data(rdf);
1348 	uint8_t precedence;
1349 	uint8_t discovery_optional;
1350 	uint8_t relay_type;
1351 
1352 	ldns_rdf *relay = NULL;
1353 	uint8_t *relay_data;
1354 
1355 	size_t offset = 0;
1356 	ldns_status status;
1357 
1358 	if (ldns_rdf_size(rdf) < 2) {
1359 		return LDNS_STATUS_WIRE_RDATA_ERR;
1360 	}
1361 	precedence = data[0];
1362 	discovery_optional = ((data[1] & 0x80) >> 7);
1363 	relay_type = data[1] & 0x7F;
1364 	offset = 2;
1365 
1366 	switch (relay_type) {
1367 		case 0:
1368 			/* no relay */
1369 			break;
1370 		case 1:
1371 			if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1372 				return LDNS_STATUS_ERR;
1373 			}
1374 			relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1375                         if(!relay_data)
1376                                 return LDNS_STATUS_MEM_ERR;
1377 			memcpy(relay_data, &data[offset], LDNS_IP4ADDRLEN);
1378 			relay = ldns_rdf_new(LDNS_RDF_TYPE_A,
1379 					LDNS_IP4ADDRLEN , relay_data);
1380 			offset += LDNS_IP4ADDRLEN;
1381                         if(!relay) {
1382                                 LDNS_FREE(relay_data);
1383                                 return LDNS_STATUS_MEM_ERR;
1384                         }
1385 			break;
1386 		case 2:
1387 			if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1388 				return LDNS_STATUS_ERR;
1389 			}
1390 			relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1391                         if(!relay_data)
1392                                 return LDNS_STATUS_MEM_ERR;
1393 			memcpy(relay_data, &data[offset], LDNS_IP6ADDRLEN);
1394 			offset += LDNS_IP6ADDRLEN;
1395 			relay =
1396 				ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1397 						LDNS_IP6ADDRLEN, relay_data);
1398                         if(!relay) {
1399                                 LDNS_FREE(relay_data);
1400                                 return LDNS_STATUS_MEM_ERR;
1401                         }
1402 			break;
1403 		case 3:
1404 			status = ldns_wire2dname(&relay, data,
1405 					ldns_rdf_size(rdf), &offset);
1406                         if(status != LDNS_STATUS_OK)
1407                                 return status;
1408 			break;
1409 		default:
1410 			/* error? */
1411 			break;
1412 	}
1413 
1414 	if (ldns_rdf_size(rdf) != offset) {
1415                 ldns_rdf_deep_free(relay);
1416 		return LDNS_STATUS_ERR;
1417 	}
1418 	ldns_buffer_printf(output, "%u %u %u ",
1419 			precedence, discovery_optional, relay_type);
1420 	if (relay)
1421 	  	(void) ldns_rdf2buffer_str(output, relay);
1422 	else
1423 		ldns_buffer_printf(output, ".");
1424 
1425 	ldns_rdf_deep_free(relay);
1426 	return ldns_buffer_status(output);
1427 }
1428 
1429 #ifdef RRTYPE_SVCB_HTTPS
1430 ldns_status svcparam_key2buffer_str(ldns_buffer *output, uint16_t key);
1431 
1432 static ldns_status
svcparam_mandatory2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1433 svcparam_mandatory2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1434 {
1435 	if (sz % 2)
1436 		return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1437 
1438 	svcparam_key2buffer_str(output, ldns_read_uint16(data));
1439 	for (data += 2, sz -= 2; sz; data += 2, sz -= 2) {
1440 		ldns_buffer_write_char(output, ',');
1441 		svcparam_key2buffer_str(output, ldns_read_uint16(data));
1442 	}
1443 	return ldns_buffer_status(output);
1444 }
1445 
1446 static ldns_status
svcparam_alpn2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1447 svcparam_alpn2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1448 {
1449 	uint8_t *eod = data + sz, *dp;
1450 	bool quote = false;
1451 	size_t i;
1452 
1453 	for (dp = data; dp < eod && !quote; dp += 1 + *dp) {
1454 		if (dp + 1 + *dp > eod)
1455 			return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1456 
1457 		for (i = 0; i < *dp; i++)
1458 			if (isspace(dp[i + 1]))
1459 				break;
1460 		quote = i < *dp;
1461 	}
1462 	if (quote)
1463 		ldns_buffer_write_char(output, '"');
1464 	while (data < eod) {
1465 		uint8_t *eot = data + 1 + *data;
1466 
1467 		if (eot > eod)
1468 			return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1469 
1470 		if (eod - data < (int)sz)
1471 			ldns_buffer_write_char(output, ',');
1472 
1473 		for (data += 1; data < eot; data += 1) {
1474 			uint8_t ch = *data;
1475 
1476 			if (isprint(ch) || ch == '\t') {
1477 				if (ch == '"' ||  ch == ',' || ch == '\\')
1478 					ldns_buffer_write_char(output, '\\');
1479 				ldns_buffer_write_char(output, ch);
1480 			} else
1481 				ldns_buffer_printf(output, "\\%03u"
1482 				                         , (unsigned)ch);
1483 		}
1484 	}
1485 	if (quote)
1486 		ldns_buffer_write_char(output, '"');
1487 	return ldns_buffer_status(output);
1488 }
1489 
1490 static ldns_status
svcparam_port2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1491 svcparam_port2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1492 {
1493 	if (sz != 2)
1494 		return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1495 	ldns_buffer_printf(output, "%d", (int)ldns_read_uint16(data));
1496 	return ldns_buffer_status(output);
1497 }
1498 
1499 static ldns_status
svcparam_ipv4hint2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1500 svcparam_ipv4hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1501 {
1502 	char str[INET_ADDRSTRLEN];
1503 
1504 	if (sz % 4 || !inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
1505 		return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1506 
1507 	ldns_buffer_write_chars(output, str);
1508 
1509 	for (data += 4, sz -= 4; sz ; data += 4, sz -= 4 ) {
1510 		ldns_buffer_write_char(output, ',');
1511 		if (!inet_ntop(AF_INET, data, str, INET_ADDRSTRLEN))
1512 			return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1513 
1514 		ldns_buffer_write_chars(output, str);
1515 	}
1516 	return ldns_buffer_status(output);
1517 }
1518 
1519 static ldns_status
svcparam_ech2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1520 svcparam_ech2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1521 {
1522 	size_t str_sz = ldns_b64_ntop_calculate_size(sz);
1523 	int written;
1524 
1525 	if (!ldns_buffer_reserve(output, str_sz))
1526 		return LDNS_STATUS_MEM_ERR;
1527 
1528 	written = ldns_b64_ntop( data, sz
1529 	                       , (char *)ldns_buffer_current(output), str_sz);
1530 	if (written > 0)
1531 		ldns_buffer_skip(output, written);
1532 	else
1533 		return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1534 
1535 	return ldns_buffer_status(output);
1536 }
1537 
1538 static ldns_status
svcparam_ipv6hint2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1539 svcparam_ipv6hint2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1540 {
1541 	char str[INET6_ADDRSTRLEN];
1542 
1543 	if (sz % 16 || !inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
1544 		return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1545 
1546 	ldns_buffer_write_chars(output, str);
1547 
1548 	for (data += 16, sz -= 16; sz ; data += 16, sz -= 16) {
1549 		ldns_buffer_write_char(output, ',');
1550 		if (!inet_ntop(AF_INET6, data, str, INET6_ADDRSTRLEN))
1551 			return LDNS_STATUS_INVALID_SVCPARAM_VALUE;
1552 
1553 		ldns_buffer_write_chars(output, str);
1554 	}
1555 	return ldns_buffer_status(output);
1556 }
1557 
1558 static ldns_status
svcparam_value2buffer_str(ldns_buffer * output,size_t sz,uint8_t * data)1559 svcparam_value2buffer_str(ldns_buffer *output, size_t sz, uint8_t *data)
1560 {
1561 	uint8_t *eod = data + sz, *dp;
1562 	bool quote = false;
1563 
1564 	for (dp = data; dp < eod && !isspace(*dp); dp++)
1565 		; /* pass */
1566 
1567 	if ((quote = dp < eod))
1568 		ldns_buffer_write_char(output, '"');
1569 
1570 	for (dp = data; dp < eod; dp++) {
1571 		uint8_t ch = *dp;
1572 
1573 		if (isprint(ch) || ch == '\t') {
1574 			if (ch == '"' ||  ch == '\\')
1575 				ldns_buffer_write_char(output, '\\');
1576 			ldns_buffer_write_char(output, ch);
1577 		} else
1578 			ldns_buffer_printf(output, "\\%03u", (unsigned)ch);
1579 	}
1580 	if (quote)
1581 		ldns_buffer_write_char(output, '"');
1582 	return ldns_buffer_status(output);
1583 }
1584 
1585 ldns_status
ldns_rdf2buffer_str_svcparams(ldns_buffer * output,const ldns_rdf * rdf)1586 ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
1587 {
1588 	uint8_t    *data, *dp, *next_dp = NULL;
1589 	size_t      sz;
1590 	ldns_status st;
1591 
1592 	if (!output)
1593 		return LDNS_STATUS_NULL;
1594 
1595 	if (!rdf || !(data = ldns_rdf_data(rdf)) || !(sz = ldns_rdf_size(rdf)))
1596 		/* No svcparams is just fine. Just nothing to print. */
1597 		return LDNS_STATUS_OK;
1598 
1599 	for (dp = data; dp + 4 <= data + sz; dp = next_dp) {
1600 		ldns_svcparam_key key    = ldns_read_uint16(dp);
1601 		uint16_t          val_sz = ldns_read_uint16(dp + 2);
1602 
1603 		if ((next_dp = dp + 4 + val_sz) > data + sz)
1604 			return LDNS_STATUS_RDATA_OVERFLOW;
1605 
1606 		if (dp > data)
1607 			ldns_buffer_write_char(output, ' ');
1608 
1609 		if ((st = svcparam_key2buffer_str(output, key)))
1610 			return st;
1611 
1612 		if (val_sz == 0)
1613 			continue;
1614 		dp += 4;
1615 		ldns_buffer_write_char(output, '=');
1616 		switch (key) {
1617 		case LDNS_SVCPARAM_KEY_MANDATORY:
1618 			st = svcparam_mandatory2buffer_str(output, val_sz, dp);
1619 			break;
1620 		case LDNS_SVCPARAM_KEY_ALPN:
1621 			st = svcparam_alpn2buffer_str(output, val_sz, dp);
1622 			break;
1623 		case LDNS_SVCPARAM_KEY_NO_DEFAULT_ALPN:
1624 			return LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED;
1625 		case LDNS_SVCPARAM_KEY_PORT:
1626 			st = svcparam_port2buffer_str(output, val_sz, dp);
1627 			break;
1628 		case LDNS_SVCPARAM_KEY_IPV4HINT:
1629 			st = svcparam_ipv4hint2buffer_str(output, val_sz, dp);
1630 			break;
1631 		case LDNS_SVCPARAM_KEY_ECH:
1632 			st = svcparam_ech2buffer_str(output, val_sz, dp);
1633 			break;
1634 		case LDNS_SVCPARAM_KEY_IPV6HINT:
1635 			st = svcparam_ipv6hint2buffer_str(output, val_sz, dp);
1636 			break;
1637 		default:
1638 			st = svcparam_value2buffer_str(output, val_sz, dp);
1639 			break;
1640 		}
1641 		if (st)
1642 			return st;
1643 	}
1644 	return ldns_buffer_status(output);
1645 }
1646 #else	/* #ifdef RRTYPE_SVCB_HTTPS */
1647 ldns_status
ldns_rdf2buffer_str_svcparams(ldns_buffer * output,const ldns_rdf * rdf)1648 ldns_rdf2buffer_str_svcparams(ldns_buffer *output, const ldns_rdf *rdf)
1649 {
1650 	(void)output; (void)rdf;
1651 	return LDNS_STATUS_NOT_IMPL;
1652 }
1653 #endif	/* #ifdef RRTYPE_SVCB_HTTPS */
1654 
1655 static ldns_status
ldns_rdf2buffer_str_fmt(ldns_buffer * buffer,const ldns_output_format * fmt,const ldns_rdf * rdf)1656 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
1657 		const ldns_output_format* fmt, const ldns_rdf *rdf)
1658 {
1659 	ldns_status res = LDNS_STATUS_OK;
1660 
1661 	/*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1662 	if (rdf) {
1663 		switch(ldns_rdf_get_type(rdf)) {
1664 		case LDNS_RDF_TYPE_NONE:
1665 			break;
1666 		case LDNS_RDF_TYPE_DNAME:
1667 			res = ldns_rdf2buffer_str_dname(buffer, rdf);
1668 			break;
1669 		case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
1670 		case LDNS_RDF_TYPE_ALG:
1671 		case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
1672 		case LDNS_RDF_TYPE_SELECTOR:
1673 		case LDNS_RDF_TYPE_MATCHING_TYPE:
1674 			res = ldns_rdf2buffer_str_int8(buffer, rdf);
1675 			break;
1676 		case LDNS_RDF_TYPE_INT16:
1677 			res = ldns_rdf2buffer_str_int16(buffer, rdf);
1678 			break;
1679 		case LDNS_RDF_TYPE_INT32:
1680 			res = ldns_rdf2buffer_str_int32(buffer, rdf);
1681 			break;
1682 		case LDNS_RDF_TYPE_INT64:
1683 		case LDNS_RDF_TYPE_IPN:
1684 			res = ldns_rdf2buffer_str_int64(buffer, rdf);
1685 			break;
1686 		case LDNS_RDF_TYPE_PERIOD:
1687 			res = ldns_rdf2buffer_str_period(buffer, rdf);
1688 			break;
1689 		case LDNS_RDF_TYPE_TSIGTIME:
1690 			res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1691 			break;
1692 		case LDNS_RDF_TYPE_A:
1693 			res = ldns_rdf2buffer_str_a(buffer, rdf);
1694 			break;
1695 		case LDNS_RDF_TYPE_AAAA:
1696 			res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1697 			break;
1698 		case LDNS_RDF_TYPE_STR:
1699 			res = ldns_rdf2buffer_str_str(buffer, rdf);
1700 			break;
1701 		case LDNS_RDF_TYPE_APL:
1702 			res = ldns_rdf2buffer_str_apl(buffer, rdf);
1703 			break;
1704 		case LDNS_RDF_TYPE_B32_EXT:
1705 			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1706 			break;
1707 		case LDNS_RDF_TYPE_B64:
1708 			res = ldns_rdf2buffer_str_b64(buffer, rdf);
1709 			break;
1710 		case LDNS_RDF_TYPE_HEX:
1711 			res = ldns_rdf2buffer_str_hex(buffer, rdf);
1712 			break;
1713 		case LDNS_RDF_TYPE_NSEC:
1714 			res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
1715 			break;
1716 		case LDNS_RDF_TYPE_NSEC3_SALT:
1717 			res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1718 			break;
1719 		case LDNS_RDF_TYPE_TYPE:
1720 			res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
1721 			break;
1722 		case LDNS_RDF_TYPE_CLASS:
1723 			res = ldns_rdf2buffer_str_class(buffer, rdf);
1724 			break;
1725 		case LDNS_RDF_TYPE_CERT_ALG:
1726 			res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1727 			break;
1728 		case LDNS_RDF_TYPE_UNKNOWN:
1729 			res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1730 			break;
1731 		case LDNS_RDF_TYPE_TIME:
1732 			res = ldns_rdf2buffer_str_time(buffer, rdf);
1733 			break;
1734 		case LDNS_RDF_TYPE_HIP:
1735 			res = ldns_rdf2buffer_str_hip(buffer, rdf);
1736 			break;
1737 		case LDNS_RDF_TYPE_LOC:
1738 			res = ldns_rdf2buffer_str_loc(buffer, rdf);
1739 			break;
1740 		case LDNS_RDF_TYPE_WKS:
1741 		case LDNS_RDF_TYPE_SERVICE:
1742 			res = ldns_rdf2buffer_str_wks(buffer, rdf);
1743 			break;
1744 		case LDNS_RDF_TYPE_NSAP:
1745 			res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1746 			break;
1747 		case LDNS_RDF_TYPE_ATMA:
1748 			res = ldns_rdf2buffer_str_atma(buffer, rdf);
1749 			break;
1750 		case LDNS_RDF_TYPE_IPSECKEY:
1751 			res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1752 			break;
1753 		case LDNS_RDF_TYPE_INT16_DATA:
1754 			res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1755 			break;
1756 		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1757 			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1758 			break;
1759 		case LDNS_RDF_TYPE_ILNP64:
1760 			res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
1761 			break;
1762 		case LDNS_RDF_TYPE_EUI48:
1763 			res = ldns_rdf2buffer_str_eui48(buffer, rdf);
1764 			break;
1765 		case LDNS_RDF_TYPE_EUI64:
1766 			res = ldns_rdf2buffer_str_eui64(buffer, rdf);
1767 			break;
1768 		case LDNS_RDF_TYPE_UNQUOTED:
1769 			res = ldns_rdf2buffer_str_unquoted(buffer, rdf);
1770 			break;
1771 		case LDNS_RDF_TYPE_TAG:
1772 			res = ldns_rdf2buffer_str_tag(buffer, rdf);
1773 			break;
1774 		case LDNS_RDF_TYPE_LONG_STR:
1775 			res = ldns_rdf2buffer_str_long_str(buffer, rdf);
1776 			break;
1777 		case LDNS_RDF_TYPE_AMTRELAY:
1778 			res = ldns_rdf2buffer_str_amtrelay(buffer, rdf);
1779 			break;
1780 		case LDNS_RDF_TYPE_SVCPARAMS:
1781 			res = ldns_rdf2buffer_str_svcparams(buffer, rdf);
1782 			break;
1783 		}
1784 	} else {
1785 		/** This will write mangled RRs */
1786 		ldns_buffer_printf(buffer, "(null) ");
1787 		res = LDNS_STATUS_ERR;
1788 	}
1789 	return res;
1790 }
1791 
1792 ldns_status
ldns_rdf2buffer_str(ldns_buffer * buffer,const ldns_rdf * rdf)1793 ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1794 {
1795 	return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
1796 }
1797 
1798 static ldns_rdf *
ldns_b32_ext2dname(const ldns_rdf * rdf)1799 ldns_b32_ext2dname(const ldns_rdf *rdf)
1800 {
1801 	size_t size;
1802 	char *b32;
1803 	ldns_rdf *out;
1804 	if(ldns_rdf_size(rdf) == 0)
1805 		return NULL;
1806         /* remove -1 for the b32-hash-len octet */
1807 	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1808         /* add one for the end nul for the string */
1809 	b32 = LDNS_XMALLOC(char, size + 2);
1810 	if (b32) {
1811 		if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
1812 				ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1813 			b32[size] = '.';
1814 			b32[size+1] = '\0';
1815 			if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1816 				LDNS_FREE(b32);
1817 				return out;
1818 			}
1819 		}
1820 		LDNS_FREE(b32);
1821 	}
1822 	return NULL;
1823 }
1824 
1825 static ldns_status
ldns_rr2buffer_str_rfc3597(ldns_buffer * output,const ldns_rr * rr)1826 ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
1827 {
1828 	size_t total_rdfsize = 0;
1829 	size_t i, j;
1830 
1831 	ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
1832 	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1833 		total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
1834 	}
1835 	if (total_rdfsize == 0) {
1836 		ldns_buffer_printf(output, "\\# 0\n");
1837 		return ldns_buffer_status(output);
1838 	}
1839 	ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
1840 	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1841 		for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
1842 			ldns_buffer_printf(output, "%.2x",
1843 					ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
1844 		}
1845 	}
1846 	ldns_buffer_printf(output, "\n");
1847 	return ldns_buffer_status(output);
1848 }
1849 
1850 ldns_status
ldns_rr2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr * rr)1851 ldns_rr2buffer_str_fmt(ldns_buffer *output,
1852 		const ldns_output_format *fmt, const ldns_rr *rr)
1853 {
1854 	uint16_t i, flags;
1855 	ldns_status status = LDNS_STATUS_OK;
1856 	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
1857 
1858 	if (fmt_st == NULL) {
1859 		fmt_st = (ldns_output_format_storage*)
1860 			  ldns_output_format_default;
1861 	}
1862 	if (!(fmt_st->flags & LDNS_FMT_SHORT)) {
1863 		if (!rr) {
1864 			if (LDNS_COMMENT_NULLS & fmt_st->flags) {
1865 				ldns_buffer_printf(output, "; (null)\n");
1866 			}
1867 			return ldns_buffer_status(output);
1868 		}
1869 		if (ldns_rr_owner(rr)) {
1870 			status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1871 		}
1872 		if (status != LDNS_STATUS_OK) {
1873 			return status;
1874 		}
1875 
1876 		/* TTL should NOT be printed if it is a question */
1877 		if (!ldns_rr_is_question(rr)) {
1878 			ldns_buffer_printf(output, "\t%u", (unsigned)ldns_rr_ttl(rr));
1879 		}
1880 
1881 		ldns_buffer_printf(output, "\t");
1882 		status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1883 		if (status != LDNS_STATUS_OK) {
1884 			return status;
1885 		}
1886 		ldns_buffer_printf(output, "\t");
1887 
1888 		if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
1889 			return ldns_rr2buffer_str_rfc3597(output, rr);
1890 		}
1891 		status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1892 		if (status != LDNS_STATUS_OK) {
1893 			return status;
1894 		}
1895 
1896 		if (ldns_rr_rd_count(rr) > 0) {
1897 			ldns_buffer_printf(output, "\t");
1898 		} else if (!ldns_rr_is_question(rr)) {
1899 			ldns_buffer_printf(output, "\t\\# 0");
1900 		}
1901 	} else if (ldns_rr_rd_count(rr) == 0) {
1902 		/* assert(fmt_st->flags & LDNS_FMT_SHORT); */
1903 
1904 		ldns_buffer_printf(output, "# 0");
1905 	}
1906 	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1907 		/* ldns_rdf2buffer_str handles NULL input fine! */
1908 		if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1909 				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1910 				((/* inception  */ i == 4 &&
1911 				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
1912 							LDNS_RDF_TYPE_TIME) ||
1913 				  (/* expiration */ i == 5 &&
1914 				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1915 				   			LDNS_RDF_TYPE_TIME) ||
1916 				  (/* signature  */ i == 8 &&
1917 				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1918 				   			LDNS_RDF_TYPE_B64))) {
1919 
1920 			ldns_buffer_printf(output, "(null)");
1921 			status = ldns_buffer_status(output);
1922 		} else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1923 				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1924 				/* serial */ i == 2 &&
1925 			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1926 			 				LDNS_RDF_TYPE_INT32) {
1927 			ldns_buffer_printf(output, "%10lu",
1928 				(unsigned long) ldns_read_uint32(
1929 					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1930 			status = ldns_buffer_status(output);
1931 		} else {
1932 			status = ldns_rdf2buffer_str_fmt(output,
1933 					fmt, ldns_rr_rdf(rr, i));
1934 		}
1935 		if(status != LDNS_STATUS_OK)
1936 			return status;
1937 		if (i < ldns_rr_rd_count(rr) - 1) {
1938 			ldns_buffer_printf(output, " ");
1939 		}
1940 	}
1941 	/* per RR special comments - handy for DNSSEC types */
1942 	/* check to prevent question sec. rr from
1943 	 * getting here */
1944 	if (ldns_rr_rd_count(rr) > 0) {
1945 		switch (ldns_rr_get_type(rr)) {
1946 		case LDNS_RR_TYPE_DNSKEY:
1947 			/* if ldns_rr_rd_count(rr) > 0
1948 				then ldns_rr_rdf(rr, 0) exists! */
1949 			if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
1950 				break;
1951 			}
1952 			flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
1953 			ldns_buffer_printf(output, " ;{");
1954 			if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
1955 				ldns_buffer_printf(output, "id = %u",
1956 					(unsigned int) ldns_calc_keytag(rr));
1957 			}
1958 			if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
1959 					(flags & LDNS_KEY_ZONE_KEY)){
1960 
1961 				if (flags & LDNS_KEY_SEP_KEY) {
1962 					ldns_buffer_printf(output, " (ksk)");
1963 				} else {
1964 					ldns_buffer_printf(output, " (zsk)");
1965 				}
1966 				if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
1967 					ldns_buffer_printf(output, ", ");
1968 				}
1969 			} else if (fmt_st->flags
1970 					& (LDNS_COMMENT_KEY_ID
1971 						|LDNS_COMMENT_KEY_SIZE)) {
1972 				ldns_buffer_printf( output, ", ");
1973 			}
1974 			if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
1975 				ldns_buffer_printf(output, "size = %db",
1976 					ldns_rr_dnskey_key_size(rr));
1977 			}
1978 			ldns_buffer_printf(output, "}");
1979 			break;
1980 		case LDNS_RR_TYPE_RRSIG:
1981 			if ((fmt_st->flags & LDNS_COMMENT_KEY)
1982 					&& (fmt_st->flags& LDNS_COMMENT_RRSIGS)
1983 					&& ldns_rr_rdf(rr, 6) != NULL) {
1984 				ldns_buffer_printf(output, " ;{id = %d}",
1985 						ldns_rdf2native_int16(
1986 							ldns_rr_rdf(rr, 6)));
1987 			}
1988 			break;
1989 		case LDNS_RR_TYPE_DS:
1990 			if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
1991 					ldns_rr_rdf(rr, 3) != NULL) {
1992 
1993 				uint8_t *data = ldns_rdf_data(
1994 						ldns_rr_rdf(rr, 3));
1995 				size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
1996 				char *babble = ldns_bubblebabble(data, len);
1997 				if(babble) {
1998 					ldns_buffer_printf(output,
1999 							" ;{%s}", babble);
2000 				}
2001 				LDNS_FREE(babble);
2002 			}
2003 			break;
2004 		case LDNS_RR_TYPE_NSEC3:
2005 			if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
2006 				! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
2007 				break;
2008 			}
2009 			ldns_buffer_printf(output, " ;{");
2010 			if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
2011 				if (ldns_nsec3_optout(rr)) {
2012 					ldns_buffer_printf(output,
2013 						" flags: optout");
2014 				} else {
2015 					ldns_buffer_printf(output," flags: -");
2016 				}
2017 				if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
2018 						fmt_st->hashmap != NULL) {
2019 					ldns_buffer_printf(output, ", ");
2020 				}
2021 			}
2022 			if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
2023 					fmt_st->hashmap != NULL) {
2024 				ldns_rbnode_t *node;
2025 				ldns_rdf *key = ldns_dname_label(
2026 						ldns_rr_owner(rr), 0);
2027 				if (key) {
2028 					node = ldns_rbtree_search(
2029 						fmt_st->hashmap,
2030 						(void *) key);
2031 					if (node->data) {
2032 						ldns_buffer_printf(output,
2033 							"from: ");
2034 						(void) ldns_rdf2buffer_str(
2035 							output,
2036 							ldns_dnssec_name_name(
2037 							   (ldns_dnssec_name*)
2038 							   node->data
2039 							));
2040 					}
2041 					ldns_rdf_deep_free(key);
2042 				}
2043 				key = ldns_b32_ext2dname(
2044 						ldns_nsec3_next_owner(rr));
2045 				if (key) {
2046 					node = ldns_rbtree_search(
2047 						fmt_st->hashmap,
2048 						(void *) key);
2049 					if (node->data) {
2050 						ldns_buffer_printf(output,
2051 							" to: ");
2052 						(void) ldns_rdf2buffer_str(
2053 							output,
2054 							ldns_dnssec_name_name(
2055 							   (ldns_dnssec_name*)
2056 							   node->data
2057 							));
2058 					}
2059 					ldns_rdf_deep_free(key);
2060 				}
2061 			}
2062 			ldns_buffer_printf(output, "}");
2063 			break;
2064 		default:
2065 			break;
2066 
2067 		}
2068 	}
2069 	/* last */
2070 	ldns_buffer_printf(output, "\n");
2071 	return ldns_buffer_status(output);
2072 }
2073 
2074 ldns_status
ldns_rr2buffer_str(ldns_buffer * output,const ldns_rr * rr)2075 ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
2076 {
2077 	return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
2078 }
2079 
2080 ldns_status
ldns_rr_list2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr_list * list)2081 ldns_rr_list2buffer_str_fmt(ldns_buffer *output,
2082 		const ldns_output_format *fmt, const ldns_rr_list *list)
2083 {
2084 	uint16_t i;
2085 
2086 	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
2087 		(void) ldns_rr2buffer_str_fmt(output, fmt,
2088 				ldns_rr_list_rr(list, i));
2089 	}
2090 	return ldns_buffer_status(output);
2091 }
2092 
2093 ldns_status
ldns_rr_list2buffer_str(ldns_buffer * output,const ldns_rr_list * list)2094 ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
2095 {
2096 	return ldns_rr_list2buffer_str_fmt(
2097 			output, ldns_output_format_default, list);
2098 }
2099 
2100 ldns_status
ldns_pktheader2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)2101 ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
2102 {
2103 	ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
2104 			                    (int) ldns_pkt_get_opcode(pkt));
2105 	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
2106 			                    (int) ldns_pkt_get_rcode(pkt));
2107 
2108 	ldns_buffer_printf(output, ";; ->>HEADER<<- ");
2109 	if (opcode) {
2110 		ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
2111 	} else {
2112 		ldns_buffer_printf(output, "opcode: ?? (%u), ",
2113 				ldns_pkt_get_opcode(pkt));
2114 	}
2115 	if (rcode) {
2116 		ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
2117 	} else {
2118 		ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
2119 	}
2120 	ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
2121 	ldns_buffer_printf(output, ";; flags: ");
2122 
2123 	if (ldns_pkt_qr(pkt)) {
2124 		ldns_buffer_printf(output, "qr ");
2125 	}
2126 	if (ldns_pkt_aa(pkt)) {
2127 		ldns_buffer_printf(output, "aa ");
2128 	}
2129 	if (ldns_pkt_tc(pkt)) {
2130 		ldns_buffer_printf(output, "tc ");
2131 	}
2132 	if (ldns_pkt_rd(pkt)) {
2133 		ldns_buffer_printf(output, "rd ");
2134 	}
2135 	if (ldns_pkt_cd(pkt)) {
2136 		ldns_buffer_printf(output, "cd ");
2137 	}
2138 	if (ldns_pkt_ra(pkt)) {
2139 		ldns_buffer_printf(output, "ra ");
2140 	}
2141 	if (ldns_pkt_ad(pkt)) {
2142 		ldns_buffer_printf(output, "ad ");
2143 	}
2144 	ldns_buffer_printf(output, "; ");
2145 	ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
2146 	ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
2147 	ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
2148 	ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
2149 	return ldns_buffer_status(output);
2150 }
2151 
2152 
2153 /* print EDNS option data in the Dig format: 76 61 6c 69 ... */
2154 static void
ldns_edns_hex_data2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2155 ldns_edns_hex_data2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2156 {
2157 	size_t j;
2158 	for (j = 0; j < len; j++) {
2159 		ldns_buffer_printf(output, " %02x", data[j]);
2160 	}
2161 }
2162 
2163 static ldns_status
ldns_edns_llq2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2164 ldns_edns_llq2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2165 {
2166 	/* LLQ constants */
2167 	const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC",
2168 		"FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"};
2169 	const unsigned int llq_errors_num = 7;
2170 	const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"};
2171 	const unsigned int llq_opcodes_num = 3;
2172 
2173 	uint16_t version, llq_opcode, error_code;
2174 	uint64_t llq_id;
2175 	uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */
2176 
2177 	ldns_buffer_printf(output, "; Long-Lived Query:");
2178 
2179 	/* read the record */
2180 	if(len != 18) {
2181 		ldns_buffer_printf(output, " malformed LLQ ");
2182 		ldns_edns_hex_data2buffer_str(output, data, len);
2183 
2184 		return ldns_buffer_status(output);
2185 	}
2186 	version = ldns_read_uint16(data);
2187 	llq_opcode = ldns_read_uint16(data+2);
2188 	error_code = ldns_read_uint16(data+4);
2189 	memmove(&llq_id, data+6, sizeof(uint64_t));
2190 	lease_life = ldns_read_uint32(data+14);
2191 
2192 	/* print option field entires */
2193 	ldns_buffer_printf(output, "v%d ", (int)version);
2194 
2195 	if(llq_opcode < llq_opcodes_num) {
2196 		ldns_buffer_printf(output, "%s", llq_opcodes[llq_opcode]);
2197 	} else {
2198 		ldns_buffer_printf(output, "opcode %d", (int)llq_opcode);
2199 	}
2200 
2201 	if(error_code < llq_errors_num)
2202 		ldns_buffer_printf(output, " %s", llq_errors[error_code]);
2203 	else {
2204 		ldns_buffer_printf(output, " error %d", (int)error_code);
2205 	}
2206 
2207 #ifndef USE_WINSOCK
2208 	ldns_buffer_printf(output, " id %llx lease-life %lu",
2209 		(unsigned long long)llq_id, (unsigned long)lease_life);
2210 #else
2211 	ldns_buffer_printf(output, " id %I64x lease-life %lu",
2212 		(unsigned long long)llq_id, (unsigned long)lease_life);
2213 #endif
2214 	return ldns_buffer_status(output);
2215 }
2216 
2217 
2218 static ldns_status
ldns_edns_ul2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2219 ldns_edns_ul2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2220 {
2221 	uint32_t lease;
2222 
2223 	ldns_buffer_printf(output, "; Update Lease:");
2224 
2225 	if(len != 4) {
2226 		ldns_buffer_printf(output, " malformed UL ");
2227 		ldns_edns_hex_data2buffer_str(output, data, len);
2228 		return ldns_buffer_status(output);
2229 	}
2230 	lease = ldns_read_uint32(data);
2231 	ldns_buffer_printf(output, "lease %lu", (unsigned long)lease);
2232 
2233 	return ldns_buffer_status(output);
2234 }
2235 
2236 static ldns_status
ldns_edns_nsid2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2237 ldns_edns_nsid2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2238 {
2239 	size_t i, printed=0;
2240 
2241 	ldns_buffer_printf(output, "; NSID:");
2242 	ldns_edns_hex_data2buffer_str(output, data, len);
2243 
2244 	/* print the human-readable text string */
2245 	for(i = 0; i < len; i++) {
2246 		if(isprint((unsigned char)data[i]) || data[i] == '\t') {
2247 			if(!printed) {
2248 				ldns_buffer_printf(output, " (");
2249 				printed = 1;
2250 			}
2251 			ldns_buffer_printf(output, "%c", (char)data[i]);
2252 		}
2253 	}
2254 	if(printed)
2255 		ldns_buffer_printf(output, ")");
2256 	return ldns_buffer_status(output);
2257 }
2258 
2259 
2260 static ldns_status
ldns_edns_dau2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2261 ldns_edns_dau2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2262 {
2263 	size_t i;
2264 	ldns_lookup_table *lt;
2265 
2266 	ldns_buffer_printf(output, "; DNSSEC Algorithm Understood (DAU):");
2267 
2268 	for(i = 0; i <len; i++) {
2269 		lt = ldns_lookup_by_id(ldns_algorithms, data[i]);
2270 		if (lt && lt->name) {
2271 			ldns_buffer_printf(output, " %s", lt->name);
2272 		} else {
2273 			ldns_buffer_printf(output, " ALG%u", data[i]);
2274 		}
2275 	}
2276 	return ldns_buffer_status(output);
2277 }
2278 
2279 static ldns_status
ldns_edns_dhu2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2280 ldns_edns_dhu2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2281 {
2282 	size_t i;
2283 	ldns_lookup_table *lt;
2284 
2285 	ldns_buffer_printf(output, "; DS Hash Understood (DHU):");
2286 
2287 	for(i = 0; i < len; i++) {
2288 		lt = ldns_lookup_by_id(ldns_hashes, data[i]);
2289 		if (lt && lt->name) {
2290 			ldns_buffer_printf(output, " %s", lt->name);
2291 		} else {
2292 			ldns_buffer_printf(output, " ALG%u", data[i]);
2293 		}
2294 	}
2295 	return ldns_buffer_status(output);
2296 }
2297 
2298 static ldns_status
ldns_edns_d3u2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2299 ldns_edns_d3u2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2300 {
2301 	size_t i;
2302 
2303 	ldns_buffer_printf(output, "; NSEC3 Hash Understood (N3U):");
2304 
2305 	for(i=0; i<len; i++) {
2306 		if(data[i] == 1) {
2307 			ldns_buffer_printf(output, " SHA1");
2308 		} else {
2309 			ldns_buffer_printf(output, " %d", (int)data[i]);
2310 		}
2311 	}
2312 	return ldns_buffer_status(output);
2313 }
2314 
2315 static ldns_status
ldns_edns_subnet2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2316 ldns_edns_subnet2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2317 {
2318 	uint16_t family;
2319 	uint8_t source, scope;
2320 
2321 	ldns_buffer_printf(output, "; CLIENT SUBNET: ");
2322 
2323 	if(len < 4) {
2324 		ldns_buffer_printf(output, "malformed subnet ");
2325 		ldns_edns_hex_data2buffer_str(output, data, len);
2326 		return ldns_buffer_status(output);
2327 	}
2328 
2329 
2330 	family = ldns_read_uint16(data);
2331 	source = data[2];
2332 	scope = data[3];
2333 	if(family == 1) {
2334 		/* IPv4 */
2335 		char buf[64];
2336 		uint8_t ip4[4];
2337 		memset(ip4, 0, sizeof(ip4));
2338 		if(len-4 > 4) {
2339 			ldns_buffer_printf(output, "trailingdata:");
2340 			ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2341 			ldns_buffer_printf(output, " ");
2342 			len = 4+4;
2343 		}
2344 		memmove(ip4, data+4, len-4);
2345 		if(!inet_ntop(AF_INET, ip4, buf, (socklen_t) sizeof(buf))) {
2346 			ldns_buffer_printf(output, "ip4ntoperror ");
2347 			ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2348 		} else {
2349 			ldns_buffer_printf(output, "%s", buf);
2350 		}
2351 	} else if(family == 2) {
2352 		/* IPv6 */
2353 		char buf[64];
2354 		uint8_t ip6[16];
2355 		memset(ip6, 0, sizeof(ip6));
2356 		if(len-4 > 16) {
2357 			ldns_buffer_printf(output, "trailingdata:");
2358 			ldns_edns_hex_data2buffer_str(output, data+4+16, len-4-16);
2359 			ldns_buffer_printf(output, " ");
2360 			len = 4+16;
2361 		}
2362 		memmove(ip6, data+4, len-4);
2363 #ifdef AF_INET6
2364 		if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t) sizeof(buf))) {
2365 			ldns_buffer_printf(output, "ip6ntoperror ");
2366 			ldns_edns_hex_data2buffer_str(output, data+4+4, len-4-4);
2367 		} else {
2368 			ldns_buffer_printf(output, "%s", buf);
2369 		}
2370 #else
2371 		ldns_edns_hex_data2buffer_str(output,  data+4+4, len-4-4);
2372 #endif
2373 	} else {
2374 		/* unknown */
2375 		ldns_buffer_printf(output, "family %d ", (int)family);
2376 		ldns_edns_hex_data2buffer_str(output, data, len);
2377 	}
2378 	ldns_buffer_printf(output, "/%d scope /%d", (int)source, (int)scope);
2379 
2380 	return ldns_buffer_status(output);
2381 }
2382 
2383 static ldns_status
ldns_edns_expire2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2384 ldns_edns_expire2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2385 {
2386 
2387 	ldns_buffer_printf(output, "; EXPIRE:");
2388 
2389 	if (!(len == 0) || len == 4) {
2390 		ldns_buffer_printf(output, "malformed expire ");
2391 		ldns_edns_hex_data2buffer_str(output, data, len);
2392 
2393 		return ldns_buffer_status(output);
2394 	}
2395 
2396 	// TODO can this output be more accurate?
2397 	ldns_edns_hex_data2buffer_str(output, data, len);
2398 
2399 	return ldns_buffer_status(output);
2400 }
2401 
2402 
2403 static ldns_status
ldns_edns_cookie2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2404 ldns_edns_cookie2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2405 {
2406 	ldns_buffer_printf(output, "; COOKIE:");
2407 
2408 	/* the size of an EDNS cookie is restricted by RFC 7873 */
2409 	if (!(len == 8 || (len >= 16 && len < 40))) {
2410 		ldns_buffer_printf(output, "malformed cookie ");
2411 		ldns_edns_hex_data2buffer_str(output, data, len);
2412 	}
2413 	ldns_edns_hex_data2buffer_str(output, data, len);
2414 
2415 	return ldns_buffer_status(output);
2416 }
2417 
2418 static ldns_status
ldns_edns_keepalive2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2419 ldns_edns_keepalive2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2420 {
2421 	uint16_t timeout;
2422 
2423 	ldns_buffer_printf(output, "; KEEPALIVE:");
2424 
2425 	if(!(len == 0 || len == 2)) {
2426 		ldns_buffer_printf(output, "malformed keepalive ");
2427 		ldns_edns_hex_data2buffer_str(output, data, len);
2428 
2429 		return ldns_buffer_status(output);
2430 	}
2431 
2432 	if(len == 0) {
2433 		ldns_buffer_printf(output, "no timeout value (only valid for client option)");
2434 	} else {
2435 		timeout = ldns_read_uint16(data);
2436 		ldns_buffer_printf(output, "timeout value in units of 100ms %u", (int)timeout);
2437 	}
2438 	return ldns_buffer_status(output);
2439 }
2440 
2441 static ldns_status
ldns_edns_padding2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2442 ldns_edns_padding2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2443 {
2444 	ldns_buffer_printf(output, "; PADDING: ");
2445 	ldns_edns_hex_data2buffer_str(output, data, len);
2446 
2447 	return ldns_buffer_status(output);
2448 }
2449 
2450 static ldns_status
ldns_edns_chain2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2451 ldns_edns_chain2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2452 {
2453 	ldns_rdf* temp = NULL;
2454 
2455 	ldns_buffer_printf(output, "; CHAIN: ");
2456 
2457 	if (ldns_str2rdf_dname(&temp, (char*) data) != LDNS_STATUS_OK) {
2458 		ldns_buffer_printf(output, "malformed chain ");
2459 		ldns_edns_hex_data2buffer_str(output, data, len);
2460 
2461 		return ldns_buffer_status(output);
2462 	}
2463 
2464 	ldns_characters2buffer_str(output, len, data);
2465 
2466 	return ldns_buffer_status(output);
2467 }
2468 
2469 static ldns_status
ldns_edns_key_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2470 ldns_edns_key_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2471 {
2472 	size_t i;
2473 
2474 	ldns_buffer_printf(output, "; KEY TAG: ");
2475 
2476 	if(len < 2 || len % 2 != 0) {
2477 		ldns_buffer_printf(output, "malformed key tag ");
2478 		ldns_edns_hex_data2buffer_str(output, data, len);
2479 
2480 		return ldns_buffer_status(output);
2481 	}
2482 
2483 	for (i = 0; i < len; i += 2) {
2484 		uint16_t tag = ldns_read_uint16(data);
2485 
2486 		ldns_buffer_printf(output, " %hu", tag);
2487 	}
2488 
2489 	return ldns_buffer_status(output);
2490 }
2491 
2492 static ldns_status
ldns_edns_ede2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2493 ldns_edns_ede2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2494 {
2495 	size_t i;
2496 	uint16_t ede;
2497 	ldns_buffer_printf(output, "; EDE:");
2498 
2499 	if(len < 2) {
2500 		ldns_buffer_printf(output, "malformed ede ");
2501 		ldns_edns_hex_data2buffer_str(output, data, len);
2502 
2503 		return ldns_buffer_status(output);
2504 	}
2505 
2506 	ede = ldns_read_uint16(data);
2507 
2508 	switch (ede) {
2509 	case LDNS_EDE_OTHER:
2510 		ldns_buffer_printf(output, " 0 (Other): ");
2511 		break;
2512 	case LDNS_EDE_UNSUPPORTED_DNSKEY_ALG:
2513 		ldns_buffer_printf(output, " 1 (Unsupported DNSKEY Algorithm)");
2514 		break;
2515 	case LDNS_EDE_UNSUPPORTED_DS_DIGEST:
2516 		ldns_buffer_printf(output, " 2 (Unsupported DS Digest type)");
2517 		break;
2518 	case LDNS_EDE_STALE_ANSWER:
2519 		ldns_buffer_printf(output, " 3 (Stale Answer)");
2520 		break;
2521 	case LDNS_EDE_FORGED_ANSWER:
2522 		ldns_buffer_printf(output, " 4 (Forged Answer)");
2523 		break;
2524 	case LDNS_EDE_DNSSEC_INDETERMINATE:
2525 		ldns_buffer_printf(output, " 5 (DNSSEC Indeterminate)");
2526 		break;
2527 	case LDNS_EDE_DNSSEC_BOGUS:
2528 		ldns_buffer_printf(output, " 6 (DNSSEC Bogus)");
2529 		break;
2530 	case LDNS_EDE_SIGNATURE_EXPIRED:
2531 		ldns_buffer_printf(output, " 7 (Signature Expired)");
2532 		break;
2533 	case LDNS_EDE_SIGNATURE_NOT_YET_VALID:
2534 		ldns_buffer_printf(output, " 8 (Signature Not Yet Valid)");
2535 		break;
2536 	case LDNS_EDE_DNSKEY_MISSING:
2537 		ldns_buffer_printf(output, " 9 (DNSKEY Missing)");
2538 		break;
2539 	case LDNS_EDE_RRSIGS_MISSING:
2540 		ldns_buffer_printf(output, " 10 (RRSIGs Missing)");
2541 		break;
2542 	case LDNS_EDE_NO_ZONE_KEY_BIT_SET:
2543 		ldns_buffer_printf(output, " 11 (No Zone Key Bit Set)");
2544 		break;
2545 	case LDNS_EDE_NSEC_MISSING:
2546 		ldns_buffer_printf(output, " 12 (NSEC Missing)");
2547 		break;
2548 	case LDNS_EDE_CACHED_ERROR:
2549 		ldns_buffer_printf(output, " 13 (Cached Error)");
2550 		break;
2551 	case LDNS_EDE_NOT_READY:
2552 		ldns_buffer_printf(output, " 14 (Not Ready)");
2553 		break;
2554 	case LDNS_EDE_BLOCKED:
2555 		ldns_buffer_printf(output, " 15 (Blocked)");
2556 		break;
2557 	case LDNS_EDE_CENSORED:
2558 		ldns_buffer_printf(output, " 16 (Censored)");
2559 		break;
2560 	case LDNS_EDE_FILTERED:
2561 		ldns_buffer_printf(output, " 17 (Filtered)");
2562 		break;
2563 	case LDNS_EDE_PROHIBITED:
2564 		ldns_buffer_printf(output, " 18 (Prohibited)");
2565 		break;
2566 	case LDNS_EDE_STALE_NXDOMAIN_ANSWER:
2567 		ldns_buffer_printf(output, " 19 (NXDOMAIN Answer)");
2568 		break;
2569 	case LDNS_EDE_NOT_AUTHORITATIVE:
2570 		ldns_buffer_printf(output, " 20 (Not Authoritative)");
2571 		break;
2572 	case LDNS_EDE_NOT_SUPPORTED:
2573 		ldns_buffer_printf(output, " 21 (Not Supported)");
2574 		break;
2575 	case LDNS_EDE_NO_REACHABLE_AUTHORITY:
2576 		ldns_buffer_printf(output, " 22 (No Reachable Authority)");
2577 		break;
2578 	case LDNS_EDE_NETWORK_ERROR:
2579 		ldns_buffer_printf(output, " 23 (Network Error)");
2580 		break;
2581 	case LDNS_EDE_INVALID_DATA:
2582 		ldns_buffer_printf(output, " 24 (Invalid Data)");
2583 		break;
2584 	case LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID:
2585 		ldns_buffer_printf(output, " 25 (Signature Expired Before Valid)");
2586 		break;
2587 	case LDNS_EDE_TOO_EARLY:
2588 		ldns_buffer_printf(output, " 26 (Too Early)");
2589 		break;
2590 	case LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS_VALUE:
2591 		ldns_buffer_printf(output, " 27 (Unsupported NSEC3 Iterations Value)");
2592 		break;
2593 	case LDNS_EDE_UNABLE_TO_CONFORM_TO_POLICY:
2594 		ldns_buffer_printf(output, " 28 (Unable to conform to policy)");
2595 		break;
2596 	case LDNS_EDE_SYNTHESIZED:
2597 		ldns_buffer_printf(output, " 29 (Synthesized)");
2598 		break;
2599 	case LDNS_EDE_INVALID_QUERY_TYPE:
2600 		ldns_buffer_printf(output, " 30 (Invalid Query Type)");
2601 		break;
2602 	default:
2603 		ldns_buffer_printf(output, " %02x", data[0]);
2604 		ldns_buffer_printf(output, " %02x", data[1]);
2605 		break;
2606 	}
2607 
2608 	/* skip the EDE code in the output */
2609 	data += 2;
2610 	len -= 2;
2611 
2612 	if (len > 2) {
2613 		/* format the hex bytes */
2614 		ldns_buffer_printf(output, ":");
2615 		for (i = 0; i < len; i++) {
2616 			ldns_buffer_printf(output, " %02x", data[i]);
2617 		}
2618 
2619 		/* format the human-readable string */
2620 		ldns_buffer_printf(output, " (");
2621 		ldns_characters2buffer_str(output, len, data);
2622 		ldns_buffer_printf(output, ")");
2623 	}
2624 
2625 	return ldns_buffer_status(output);
2626 }
2627 
2628 static ldns_status
ldns_edns_client_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2629 ldns_edns_client_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2630 {
2631 	ldns_buffer_printf(output, "; CLIENT-TAG:");
2632 
2633 	if (len > 2) {
2634 		ldns_buffer_printf(output, "malformed client-tag ");
2635 		ldns_edns_hex_data2buffer_str(output, data, len);
2636 
2637 		return ldns_buffer_status(output);
2638 	}
2639 
2640 	ldns_edns_hex_data2buffer_str(output, data, len);
2641 
2642 	return ldns_buffer_status(output);
2643 }
2644 
2645 static ldns_status
ldns_edns_server_tag2buffer_str(ldns_buffer * output,uint8_t * data,size_t len)2646 ldns_edns_server_tag2buffer_str(ldns_buffer* output, uint8_t* data, size_t len)
2647 {
2648 	ldns_buffer_printf(output, "; SERVER-TAG:");
2649 
2650 	if (len > 2) {
2651 		ldns_buffer_printf(output, "malformed server-tag ");
2652 		ldns_edns_hex_data2buffer_str(output, data, len);
2653 
2654 		return ldns_buffer_status(output);
2655 	}
2656 
2657 	ldns_edns_hex_data2buffer_str(output, data, len);
2658 
2659 	return ldns_buffer_status(output);
2660 }
2661 
2662 ldns_status
ldns_edns_option_list2buffer_str(ldns_buffer * output,ldns_edns_option_list * edns_list)2663 ldns_edns_option_list2buffer_str(ldns_buffer *output, ldns_edns_option_list* edns_list)
2664 {
2665 	size_t count = ldns_edns_option_list_get_count(edns_list);
2666 	size_t i, size;
2667 	uint8_t* data;
2668 
2669 	for (i = 0; i < count; i++) {
2670 		ldns_edns_option_code code;
2671 		ldns_edns_option* edns = ldns_edns_option_list_get_option(edns_list, i);
2672 
2673 		if (!edns) {
2674 			break;
2675 		}
2676 
2677 		code = ldns_edns_get_code(edns);
2678 		size = ldns_edns_get_size(edns);
2679 		data = ldns_edns_get_data(edns);
2680 
2681 		switch(code) {
2682 		case LDNS_EDNS_LLQ:
2683 			ldns_edns_llq2buffer_str(output, data, size);
2684 			break;
2685 		case LDNS_EDNS_UL:
2686 			ldns_edns_ul2buffer_str(output, data, size);
2687 			break;
2688 		case LDNS_EDNS_NSID:
2689 			ldns_edns_nsid2buffer_str(output, data, size);
2690 			break;
2691 		case LDNS_EDNS_DAU:
2692 			ldns_edns_dau2buffer_str(output, data, size);
2693 			break;
2694 		case LDNS_EDNS_DHU:
2695 			ldns_edns_dhu2buffer_str(output, data, size);
2696 			break;
2697 		case LDNS_EDNS_N3U:
2698 			ldns_edns_d3u2buffer_str(output, data, size);
2699 			break;
2700 		case LDNS_EDNS_CLIENT_SUBNET:
2701 			ldns_edns_subnet2buffer_str(output, data, size);
2702 			break;
2703 		case LDNS_EDNS_EXPIRE:
2704 			ldns_edns_expire2buffer_str(output, data, size);
2705 			break;
2706 		case LDNS_EDNS_COOKIE:
2707 			ldns_edns_cookie2buffer_str(output, data, size);
2708 			break;
2709 		case LDNS_EDNS_KEEPALIVE:
2710 			ldns_edns_keepalive2buffer_str(output, data, size);
2711 			break;
2712 		case LDNS_EDNS_PADDING:
2713 			ldns_edns_padding2buffer_str(output, data, size);
2714 			break;
2715 		case LDNS_EDNS_CHAIN:
2716 			ldns_edns_chain2buffer_str(output, data, size);
2717 			break;
2718 		case LDNS_EDNS_KEY_TAG:
2719 			ldns_edns_key_tag2buffer_str(output, data, size);
2720 			break;
2721 		case LDNS_EDNS_EDE:
2722 			ldns_edns_ede2buffer_str(output, data, size);
2723 			break;
2724 		case LDNS_EDNS_CLIENT_TAG:
2725 			ldns_edns_client_tag2buffer_str(output, data, size);
2726 			break;
2727 		case LDNS_EDNS_SERVER_TAG:
2728 			ldns_edns_server_tag2buffer_str(output, data, size);
2729 			break;
2730 		default:
2731 			ldns_buffer_printf(output, "; OPT=%d:", code);
2732 			ldns_edns_hex_data2buffer_str(output, data, size);
2733 			break;
2734 		}
2735 		ldns_buffer_printf(output, "\n");
2736 	}
2737 
2738 	return ldns_buffer_status(output);
2739 }
2740 
2741 
2742 ldns_status
ldns_pkt2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_pkt * pkt)2743 ldns_pkt2buffer_str_fmt(ldns_buffer *output,
2744 		const ldns_output_format *fmt, const ldns_pkt *pkt)
2745 {
2746 	uint16_t i;
2747 	ldns_status status = LDNS_STATUS_OK;
2748 	char *tmp;
2749 	struct timeval time;
2750 	time_t time_tt;
2751 	int short_fmt = fmt && (fmt->flags & LDNS_FMT_SHORT);
2752 
2753 	if (!pkt) {
2754 		ldns_buffer_printf(output, "null");
2755 		return LDNS_STATUS_OK;
2756 	}
2757 
2758 	if (!ldns_buffer_status_ok(output)) {
2759 		return ldns_buffer_status(output);
2760 	}
2761 
2762 	if (!short_fmt) {
2763 		status = ldns_pktheader2buffer_str(output, pkt);
2764 		if (status != LDNS_STATUS_OK) {
2765 			return status;
2766 		}
2767 
2768 		ldns_buffer_printf(output, "\n");
2769 
2770 		ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
2771 
2772 
2773 		for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
2774 			status = ldns_rr2buffer_str_fmt(output, fmt,
2775 				       ldns_rr_list_rr(
2776 					       ldns_pkt_question(pkt), i));
2777 			if (status != LDNS_STATUS_OK) {
2778 				return status;
2779 			}
2780 		}
2781 		ldns_buffer_printf(output, "\n");
2782 
2783 		ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
2784 	}
2785 	for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
2786 		status = ldns_rr2buffer_str_fmt(output, fmt,
2787 			       ldns_rr_list_rr(
2788 				       ldns_pkt_answer(pkt), i));
2789 		if (status != LDNS_STATUS_OK) {
2790 			return status;
2791 		}
2792 	}
2793 	if (!short_fmt) {
2794 		ldns_buffer_printf(output, "\n");
2795 
2796 		ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
2797 
2798 		for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
2799 			status = ldns_rr2buffer_str_fmt(output, fmt,
2800 				       ldns_rr_list_rr(
2801 					       ldns_pkt_authority(pkt), i));
2802 			if (status != LDNS_STATUS_OK) {
2803 				return status;
2804 			}
2805 		}
2806 		ldns_buffer_printf(output, "\n");
2807 
2808 		ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
2809 
2810 		for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
2811 			status = ldns_rr2buffer_str_fmt(output, fmt,
2812 				       ldns_rr_list_rr(
2813 					       ldns_pkt_additional(pkt), i));
2814 			if (status != LDNS_STATUS_OK) {
2815 				return status;
2816 			}
2817 
2818 		}
2819 		ldns_buffer_printf(output, "\n");
2820 		/* add some further fields */
2821 		ldns_buffer_printf(output, ";; Query time: %d msec\n",
2822 				ldns_pkt_querytime(pkt));
2823 		if (ldns_pkt_edns(pkt)) {
2824 			ldns_buffer_printf(output,
2825 				   ";; EDNS: version %u; flags:",
2826 				   ldns_pkt_edns_version(pkt));
2827 			if (ldns_pkt_edns_do(pkt)) {
2828 				ldns_buffer_printf(output, " do");
2829 			}
2830 			if (ldns_pkt_edns_co(pkt)) {
2831 				ldns_buffer_printf(output, " co");
2832 			}
2833 			/* the extended rcode is the value set, shifted four bits,
2834 			 * and or'd with the original rcode */
2835 			if (ldns_pkt_edns_extended_rcode(pkt)) {
2836 				ldns_buffer_printf(output, " ; ext-rcode: %d",
2837 					(ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
2838 			}
2839 			ldns_buffer_printf(output, " ; udp: %u\n",
2840 					   ldns_pkt_edns_udp_size(pkt));
2841 
2842 			if (pkt->_edns_list)
2843 				ldns_edns_option_list2buffer_str(output, pkt->_edns_list);
2844 
2845 			else if (ldns_pkt_edns_data(pkt)) {
2846 				ldns_edns_option_list* edns_list;
2847 				/* parse the EDNS data into separate EDNS options
2848 				 * and add them to the list */
2849 				if ((edns_list = pkt_edns_data2edns_option_list(ldns_pkt_edns_data(pkt)))) {
2850 					ldns_edns_option_list2buffer_str(output, edns_list);
2851 					ldns_edns_option_list_deep_free(edns_list);
2852 				} else {
2853 					ldns_buffer_printf(output, ";; Data: ");
2854 					(void)ldns_rdf2buffer_str(output, ldns_pkt_edns_data(pkt));
2855 					ldns_buffer_printf(output, "\n");
2856 				}
2857 			}
2858 		}
2859 		if (ldns_pkt_tsig(pkt)) {
2860 			ldns_buffer_printf(output, ";; TSIG:\n;; ");
2861 			(void) ldns_rr2buffer_str_fmt(
2862 					output, fmt, ldns_pkt_tsig(pkt));
2863 			ldns_buffer_printf(output, "\n");
2864 		}
2865 		if (ldns_pkt_answerfrom(pkt)) {
2866 			tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
2867 			ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
2868 			LDNS_FREE(tmp);
2869 		}
2870 		time = ldns_pkt_timestamp(pkt);
2871 		time_tt = (time_t)time.tv_sec;
2872 		ldns_buffer_printf(output, ";; WHEN: %s",
2873 				(char*)ctime(&time_tt));
2874 
2875 		ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
2876 				(int)ldns_pkt_size(pkt));
2877 	}
2878 	return status;
2879 }
2880 
2881 ldns_status
ldns_pkt2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)2882 ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
2883 {
2884 	return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
2885 }
2886 
2887 
2888 #ifdef HAVE_SSL
2889 static ldns_status
ldns_hmac_key2buffer_str(ldns_buffer * output,const ldns_key * k)2890 ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
2891 {
2892 	ldns_status status;
2893 	size_t i;
2894 	ldns_rdf *b64_bignum;
2895 
2896 	ldns_buffer_printf(output, "Key: ");
2897 
2898  	i = ldns_key_hmac_size(k);
2899 	b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
2900 	status = ldns_rdf2buffer_str(output, b64_bignum);
2901 	ldns_rdf_deep_free(b64_bignum);
2902 	ldns_buffer_printf(output, "\n");
2903 	return status;
2904 }
2905 #endif
2906 
2907 #if defined(HAVE_SSL) && defined(USE_GOST)
2908 static ldns_status
ldns_gost_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2909 ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2910 {
2911 	unsigned char* pp = NULL;
2912 	int ret;
2913 	ldns_rdf *b64_bignum;
2914 	ldns_status status;
2915 
2916 	ldns_buffer_printf(output, "GostAsn1: ");
2917 
2918 	ret = i2d_PrivateKey(p, &pp);
2919 	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
2920 	status = ldns_rdf2buffer_str(output, b64_bignum);
2921 
2922 	ldns_rdf_deep_free(b64_bignum);
2923 	OPENSSL_free(pp);
2924 	ldns_buffer_printf(output, "\n");
2925 	return status;
2926 }
2927 #endif
2928 
2929 #if defined(HAVE_SSL) && defined(USE_ED25519)
2930 static ldns_status
ldns_ed25519_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2931 ldns_ed25519_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2932 {
2933 	unsigned char* pp = NULL;
2934 	int ret;
2935 	ldns_rdf *b64_bignum;
2936 	ldns_status status;
2937 
2938 	ldns_buffer_printf(output, "PrivateKey: ");
2939 
2940 	ret = i2d_PrivateKey(p, &pp);
2941 	/* 16 byte asn (302e020100300506032b657004220420) + 32byte key */
2942 	if(ret != 16 + 32) {
2943 		OPENSSL_free(pp);
2944 		return LDNS_STATUS_ERR;
2945 	}
2946 	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2947 		(size_t)ret-16, pp+16);
2948 	status = ldns_rdf2buffer_str(output, b64_bignum);
2949 
2950 	ldns_rdf_deep_free(b64_bignum);
2951 	OPENSSL_free(pp);
2952 	ldns_buffer_printf(output, "\n");
2953 	return status;
2954 }
2955 #endif
2956 
2957 #if defined(HAVE_SSL) && defined(USE_ED448)
2958 static ldns_status
ldns_ed448_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)2959 ldns_ed448_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
2960 {
2961 	unsigned char* pp = NULL;
2962 	int ret;
2963 	ldns_rdf *b64_bignum;
2964 	ldns_status status;
2965 
2966 	ldns_buffer_printf(output, "PrivateKey: ");
2967 
2968 	ret = i2d_PrivateKey(p, &pp);
2969 	/* some-ASN + 57byte key */
2970 	if(ret != 16 + 57) {
2971 		OPENSSL_free(pp);
2972 		return LDNS_STATUS_ERR;
2973 	}
2974 	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
2975 		(size_t)ret-16, pp+16);
2976 	status = ldns_rdf2buffer_str(output, b64_bignum);
2977 
2978 	ldns_rdf_deep_free(b64_bignum);
2979 	OPENSSL_free(pp);
2980 	ldns_buffer_printf(output, "\n");
2981 	return status;
2982 }
2983 #endif
2984 
2985 #if defined(HAVE_SSL)
2986 /** print one b64 encoded bignum to a line in the keybuffer */
2987 static int
ldns_print_bignum_b64_line(ldns_buffer * output,const char * label,const BIGNUM * num)2988 ldns_print_bignum_b64_line(ldns_buffer* output, const char* label, const BIGNUM* num)
2989 {
2990 	unsigned char  *bignumbuf = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
2991 	if(!bignumbuf) return 0;
2992 
2993 	ldns_buffer_printf(output, "%s: ", label);
2994 	if(num) {
2995 		ldns_rdf *b64_bignum = NULL;
2996 		int i = BN_bn2bin(num, bignumbuf);
2997 		if (i > LDNS_MAX_KEYLEN) {
2998 			LDNS_FREE(bignumbuf);
2999 			return 0;
3000 		}
3001 		b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)i, bignumbuf);
3002 		if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
3003 			ldns_rdf_deep_free(b64_bignum);
3004 			LDNS_FREE(bignumbuf);
3005 			return 0;
3006 		}
3007 		ldns_rdf_deep_free(b64_bignum);
3008 		ldns_buffer_printf(output, "\n");
3009 	} else {
3010 		ldns_buffer_printf(output, "(Not available)\n");
3011 	}
3012 	LDNS_FREE(bignumbuf);
3013 	return 1;
3014 }
3015 #endif
3016 
3017 ldns_status
ldns_key2buffer_str(ldns_buffer * output,const ldns_key * k)3018 ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
3019 {
3020 	ldns_status status = LDNS_STATUS_OK;
3021 	unsigned char  *bignum;
3022 #ifdef HAVE_SSL
3023 	RSA *rsa;
3024 #ifdef USE_DSA
3025 	DSA *dsa;
3026 #endif /* USE_DSA */
3027 #endif /* HAVE_SSL */
3028 
3029 	if (!k) {
3030 		return LDNS_STATUS_ERR;
3031 	}
3032 
3033 	bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
3034 	if (!bignum) {
3035 		return LDNS_STATUS_ERR;
3036 	}
3037 
3038 	if (ldns_buffer_status_ok(output)) {
3039 #ifdef HAVE_SSL
3040 		switch(ldns_key_algorithm(k)) {
3041 			case LDNS_SIGN_RSASHA1:
3042 			case LDNS_SIGN_RSASHA1_NSEC3:
3043 			case LDNS_SIGN_RSASHA256:
3044 			case LDNS_SIGN_RSASHA512:
3045 			case LDNS_SIGN_RSAMD5:
3046 				/* copied by looking at dnssec-keygen output */
3047 				/* header */
3048 				rsa = ldns_key_rsa_key(k);
3049 
3050 				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
3051 				switch(ldns_key_algorithm(k)) {
3052 				case LDNS_SIGN_RSAMD5:
3053 					ldns_buffer_printf(output,
3054 								    "Algorithm: %u (RSA)\n",
3055 								    LDNS_RSAMD5);
3056 					break;
3057 				case LDNS_SIGN_RSASHA1:
3058 					ldns_buffer_printf(output,
3059 								    "Algorithm: %u (RSASHA1)\n",
3060 								    LDNS_RSASHA1);
3061 					break;
3062 				case LDNS_SIGN_RSASHA1_NSEC3:
3063 					ldns_buffer_printf(output,
3064 								    "Algorithm: %u (RSASHA1_NSEC3)\n",
3065 								    LDNS_RSASHA1_NSEC3);
3066 					break;
3067 #ifdef USE_SHA2
3068 				case LDNS_SIGN_RSASHA256:
3069 					ldns_buffer_printf(output,
3070 								    "Algorithm: %u (RSASHA256)\n",
3071 								    LDNS_RSASHA256);
3072 					break;
3073 				case LDNS_SIGN_RSASHA512:
3074 					ldns_buffer_printf(output,
3075 								    "Algorithm: %u (RSASHA512)\n",
3076 								    LDNS_RSASHA512);
3077 					break;
3078 #endif
3079 				default:
3080 #ifdef STDERR_MSGS
3081 					fprintf(stderr, "Warning: unknown signature ");
3082 					fprintf(stderr,
3083 						   "algorithm type %u\n",
3084 						   ldns_key_algorithm(k));
3085 #endif
3086 					ldns_buffer_printf(output,
3087 								    "Algorithm: %u (Unknown)\n",
3088 								    ldns_key_algorithm(k));
3089 					break;
3090 				}
3091 
3092 				/* print to buf, convert to bin, convert to b64,
3093 				 * print to buf */
3094 
3095 #ifndef S_SPLINT_S
3096 				if(1) {
3097 					const BIGNUM *n=NULL, *e=NULL, *d=NULL,
3098 						*p=NULL, *q=NULL, *dmp1=NULL,
3099 						*dmq1=NULL, *iqmp=NULL;
3100 #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
3101 					n = rsa->n;
3102 					e = rsa->e;
3103 					d = rsa->d;
3104 					p = rsa->p;
3105 					q = rsa->q;
3106 					dmp1 = rsa->dmp1;
3107 					dmq1 = rsa->dmq1;
3108 					iqmp = rsa->iqmp;
3109 #else
3110 					RSA_get0_key(rsa, &n, &e, &d);
3111 					RSA_get0_factors(rsa, &p, &q);
3112 					RSA_get0_crt_params(rsa, &dmp1,
3113 						&dmq1, &iqmp);
3114 #endif
3115 					if(!ldns_print_bignum_b64_line(output, "Modulus", n))
3116 						goto error;
3117 					if(!ldns_print_bignum_b64_line(output, "PublicExponent", e))
3118 						goto error;
3119 					if(!ldns_print_bignum_b64_line(output, "PrivateExponent", d))
3120 						goto error;
3121 					if(!ldns_print_bignum_b64_line(output, "Prime1", p))
3122 						goto error;
3123 					if(!ldns_print_bignum_b64_line(output, "Prime2", q))
3124 						goto error;
3125 					if(!ldns_print_bignum_b64_line(output, "Exponent1", dmp1))
3126 						goto error;
3127 					if(!ldns_print_bignum_b64_line(output, "Exponent2", dmq1))
3128 						goto error;
3129 					if(!ldns_print_bignum_b64_line(output, "Coefficient", iqmp))
3130 						goto error;
3131 				}
3132 #endif /* splint */
3133 
3134 				RSA_free(rsa);
3135 				break;
3136 #ifdef USE_DSA
3137 			case LDNS_SIGN_DSA:
3138 			case LDNS_SIGN_DSA_NSEC3:
3139 				dsa = ldns_key_dsa_key(k);
3140 
3141 				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
3142 				if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
3143 					ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
3144 				} else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
3145 					ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
3146 				}
3147 
3148 				/* print to buf, convert to bin, convert to b64,
3149 				 * print to buf */
3150 				if(1) {
3151 					const BIGNUM *p=NULL, *q=NULL, *g=NULL,
3152 						*priv_key=NULL, *pub_key=NULL;
3153 #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
3154 #ifndef S_SPLINT_S
3155 					p = dsa->p;
3156 					q = dsa->q;
3157 					g = dsa->g;
3158 					priv_key = dsa->priv_key;
3159 					pub_key = dsa->pub_key;
3160 #endif /* splint */
3161 #else
3162 					DSA_get0_pqg(dsa, &p, &q, &g);
3163 					DSA_get0_key(dsa, &pub_key, &priv_key);
3164 #endif
3165 					if(!ldns_print_bignum_b64_line(output, "Prime(p)", p))
3166 						goto error;
3167 					if(!ldns_print_bignum_b64_line(output, "Subprime(q)", q))
3168 						goto error;
3169 					if(!ldns_print_bignum_b64_line(output, "Base(g)", g))
3170 						goto error;
3171 					if(!ldns_print_bignum_b64_line(output, "Private_value(x)", priv_key))
3172 						goto error;
3173 					if(!ldns_print_bignum_b64_line(output, "Public_value(y)", pub_key))
3174 						goto error;
3175 				}
3176 				break;
3177 #endif /* USE_DSA */
3178 			case LDNS_SIGN_ECC_GOST:
3179 				/* no format defined, use blob */
3180 #if defined(HAVE_SSL) && defined(USE_GOST)
3181 				ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3182 				ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
3183 				status = ldns_gost_key2buffer_str(output,
3184 #ifndef S_SPLINT_S
3185 					k->_key.key
3186 #else
3187 					NULL
3188 #endif
3189 				);
3190 #else
3191 				goto error;
3192 #endif /* GOST */
3193 				break;
3194 			case LDNS_SIGN_ECDSAP256SHA256:
3195 			case LDNS_SIGN_ECDSAP384SHA384:
3196 #ifdef USE_ECDSA
3197                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3198 				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3199                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3200 #ifndef S_SPLINT_S
3201 				ldns_buffer_printf(output, ")\n");
3202                                 if(k->_key.key) {
3203                                         EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
3204                                         const BIGNUM* b = EC_KEY_get0_private_key(ec);
3205 					if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
3206 						goto error;
3207                                         /* down reference count in EC_KEY
3208                                          * its still assigned to the PKEY */
3209                                         EC_KEY_free(ec);
3210                                 }
3211 #endif /* splint */
3212 #else
3213 				goto error;
3214 #endif /* ECDSA */
3215                                 break;
3216 #ifdef USE_ED25519
3217 			case LDNS_SIGN_ED25519:
3218                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3219 				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3220                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3221 				ldns_buffer_printf(output, ")\n");
3222 				if (status) break;
3223 				status = ldns_ed25519_key2buffer_str(output,
3224 					k->_key.key);
3225 				break;
3226 #endif /* USE_ED25519 */
3227 #ifdef USE_ED448
3228 			case LDNS_SIGN_ED448:
3229                                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3230 				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
3231                                 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
3232 				ldns_buffer_printf(output, ")\n");
3233 				if (status) break;
3234 				status = ldns_ed448_key2buffer_str(output,
3235 					k->_key.key);
3236 				break;
3237 #endif /* USE_ED448 */
3238 			case LDNS_SIGN_HMACMD5:
3239 				/* there's not much of a format defined for TSIG */
3240 				/* It's just a binary blob, Same for all algorithms */
3241                 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3242                 ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
3243 				status = ldns_hmac_key2buffer_str(output, k);
3244 				break;
3245 			case LDNS_SIGN_HMACSHA1:
3246 		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3247 		        ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
3248 				status = ldns_hmac_key2buffer_str(output, k);
3249 				break;
3250 			case LDNS_SIGN_HMACSHA224:
3251 		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3252 		        ldns_buffer_printf(output, "Algorithm: 162 (HMAC_SHA224)\n");
3253 				status = ldns_hmac_key2buffer_str(output, k);
3254 				break;
3255 			case LDNS_SIGN_HMACSHA256:
3256 		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3257 		        ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
3258 				status = ldns_hmac_key2buffer_str(output, k);
3259 				break;
3260 			case LDNS_SIGN_HMACSHA384:
3261 		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3262 		        ldns_buffer_printf(output, "Algorithm: 164 (HMAC_SHA384)\n");
3263 				status = ldns_hmac_key2buffer_str(output, k);
3264 				break;
3265 			case LDNS_SIGN_HMACSHA512:
3266 		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
3267 		        ldns_buffer_printf(output, "Algorithm: 165 (HMAC_SHA512)\n");
3268 				status = ldns_hmac_key2buffer_str(output, k);
3269 				break;
3270 		}
3271 #endif /* HAVE_SSL */
3272 	} else {
3273 		LDNS_FREE(bignum);
3274 		return ldns_buffer_status(output);
3275 	}
3276 	LDNS_FREE(bignum);
3277 	return status;
3278 
3279 #ifdef HAVE_SSL
3280 	/* compiles warn the label isn't used */
3281 error:
3282 	LDNS_FREE(bignum);
3283 	return LDNS_STATUS_ERR;
3284 #endif /* HAVE_SSL */
3285 
3286 }
3287 
3288 /*
3289  * Zero terminate the buffer and copy data.
3290  */
3291 char *
ldns_buffer2str(ldns_buffer * buffer)3292 ldns_buffer2str(ldns_buffer *buffer)
3293 {
3294 	char *str;
3295 
3296 	/* check if buffer ends with \0, if not, and
3297 	   if there is space, add it */
3298 	if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
3299 		if (!ldns_buffer_reserve(buffer, 1)) {
3300 			return NULL;
3301 		}
3302 		ldns_buffer_write_char(buffer, (uint8_t) '\0');
3303 		if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
3304 			return NULL;
3305 		}
3306 	}
3307 
3308 	str = strdup((const char *)ldns_buffer_begin(buffer));
3309         if(!str) {
3310                 return NULL;
3311         }
3312 	return str;
3313 }
3314 
3315 /*
3316  * Zero terminate the buffer and export data.
3317  */
3318 char *
ldns_buffer_export2str(ldns_buffer * buffer)3319 ldns_buffer_export2str(ldns_buffer *buffer)
3320 {
3321 	/* Append '\0' as string terminator */
3322 	if (! ldns_buffer_reserve(buffer, 1)) {
3323 		return NULL;
3324 	}
3325 	ldns_buffer_write_char(buffer, 0);
3326 
3327 	/* reallocate memory to the size of the string and export */
3328 	ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
3329 	return ldns_buffer_export(buffer);
3330 }
3331 
3332 char *
ldns_rdf2str(const ldns_rdf * rdf)3333 ldns_rdf2str(const ldns_rdf *rdf)
3334 {
3335 	char *result = NULL;
3336 	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3337 
3338 	if (!tmp_buffer) {
3339 		return NULL;
3340 	}
3341 	if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
3342 		/* export and return string, destroy rest */
3343 		result = ldns_buffer_export2str(tmp_buffer);
3344 	}
3345 	ldns_buffer_free(tmp_buffer);
3346 	return result;
3347 }
3348 
3349 char *
ldns_rr2str_fmt(const ldns_output_format * fmt,const ldns_rr * rr)3350 ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
3351 {
3352 	char *result = NULL;
3353 	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3354 
3355 	if (!tmp_buffer) {
3356 		return NULL;
3357 	}
3358 	if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
3359 		       	== LDNS_STATUS_OK) {
3360 		/* export and return string, destroy rest */
3361 		result = ldns_buffer_export2str(tmp_buffer);
3362 	}
3363 	ldns_buffer_free(tmp_buffer);
3364 	return result;
3365 }
3366 
3367 char *
ldns_rr2str(const ldns_rr * rr)3368 ldns_rr2str(const ldns_rr *rr)
3369 {
3370 	return ldns_rr2str_fmt(ldns_output_format_default, rr);
3371 }
3372 
3373 char *
ldns_pkt2str_fmt(const ldns_output_format * fmt,const ldns_pkt * pkt)3374 ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
3375 {
3376 	char *result = NULL;
3377 	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3378 
3379 	if (!tmp_buffer) {
3380 		return NULL;
3381 	}
3382 	if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
3383 		       	== LDNS_STATUS_OK) {
3384 		/* export and return string, destroy rest */
3385 		result = ldns_buffer_export2str(tmp_buffer);
3386 	}
3387 
3388 	ldns_buffer_free(tmp_buffer);
3389 	return result;
3390 }
3391 
3392 char *
ldns_pkt2str(const ldns_pkt * pkt)3393 ldns_pkt2str(const ldns_pkt *pkt)
3394 {
3395 	return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
3396 }
3397 
3398 char *
ldns_key2str(const ldns_key * k)3399 ldns_key2str(const ldns_key *k)
3400 {
3401 	char *result = NULL;
3402 	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3403 
3404 	if (!tmp_buffer) {
3405 		return NULL;
3406 	}
3407 	if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
3408 		/* export and return string, destroy rest */
3409 		result = ldns_buffer_export2str(tmp_buffer);
3410 	}
3411 	ldns_buffer_free(tmp_buffer);
3412 	return result;
3413 }
3414 
3415 char *
ldns_rr_list2str_fmt(const ldns_output_format * fmt,const ldns_rr_list * list)3416 ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
3417 {
3418 	char *result = NULL;
3419 	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
3420 
3421 	if (!tmp_buffer) {
3422 		return NULL;
3423 	}
3424 	if (list) {
3425 		if (ldns_rr_list2buffer_str_fmt(
3426 				   tmp_buffer, fmt, list)
3427 			       	== LDNS_STATUS_OK) {
3428 		}
3429 	} else {
3430 		if (fmt == NULL) {
3431 			fmt = ldns_output_format_default;
3432 		}
3433 		if (fmt->flags & LDNS_COMMENT_NULLS) {
3434 			ldns_buffer_printf(tmp_buffer, "; (null)\n");
3435 		}
3436 	}
3437 
3438 	/* export and return string, destroy rest */
3439 	result = ldns_buffer_export2str(tmp_buffer);
3440 	ldns_buffer_free(tmp_buffer);
3441 	return result;
3442 }
3443 
3444 char *
ldns_rr_list2str(const ldns_rr_list * list)3445 ldns_rr_list2str(const ldns_rr_list *list)
3446 {
3447 	return ldns_rr_list2str_fmt(ldns_output_format_default, list);
3448 }
3449 
3450 void
ldns_rdf_print(FILE * output,const ldns_rdf * rdf)3451 ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
3452 {
3453 	char *str = ldns_rdf2str(rdf);
3454 	if (str) {
3455 		fprintf(output, "%s", str);
3456 	} else {
3457 		fprintf(output, ";Unable to convert rdf to string\n");
3458 	}
3459 	LDNS_FREE(str);
3460 }
3461 
3462 void
ldns_rr_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr * rr)3463 ldns_rr_print_fmt(FILE *output,
3464 		const ldns_output_format *fmt, const ldns_rr *rr)
3465 {
3466 	char *str = ldns_rr2str_fmt(fmt, rr);
3467 	if (str) {
3468 		fprintf(output, "%s", str);
3469 	} else {
3470 		fprintf(output, ";Unable to convert rr to string\n");
3471 	}
3472 	LDNS_FREE(str);
3473 }
3474 
3475 void
ldns_rr_print(FILE * output,const ldns_rr * rr)3476 ldns_rr_print(FILE *output, const ldns_rr *rr)
3477 {
3478 	ldns_rr_print_fmt(output, ldns_output_format_default, rr);
3479 }
3480 
3481 void
ldns_pkt_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_pkt * pkt)3482 ldns_pkt_print_fmt(FILE *output,
3483 		const ldns_output_format *fmt, const ldns_pkt *pkt)
3484 {
3485 	char *str = ldns_pkt2str_fmt(fmt, pkt);
3486 	if (str) {
3487 		fprintf(output, "%s", str);
3488 	} else {
3489 		fprintf(output, ";Unable to convert packet to string\n");
3490 	}
3491 	LDNS_FREE(str);
3492 }
3493 
3494 void
ldns_pkt_print(FILE * output,const ldns_pkt * pkt)3495 ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
3496 {
3497 	ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
3498 }
3499 
3500 void
ldns_rr_list_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr_list * lst)3501 ldns_rr_list_print_fmt(FILE *output,
3502 		const ldns_output_format *fmt, const ldns_rr_list *lst)
3503 {
3504 	size_t i;
3505 	for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
3506 		ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
3507 	}
3508 }
3509 
3510 void
ldns_rr_list_print(FILE * output,const ldns_rr_list * lst)3511 ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
3512 {
3513 	ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
3514 }
3515 
3516 void
ldns_resolver_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_resolver * r)3517 ldns_resolver_print_fmt(FILE *output,
3518 		const ldns_output_format *fmt, const ldns_resolver *r)
3519 {
3520 	uint16_t i;
3521 	ldns_rdf **n;
3522 	ldns_rdf **s;
3523 	size_t *rtt;
3524 	if (!r) {
3525 		return;
3526 	}
3527 	n = ldns_resolver_nameservers(r);
3528 	s = ldns_resolver_searchlist(r);
3529 	rtt = ldns_resolver_rtt(r);
3530 
3531 	fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
3532 	fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
3533 	fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
3534 
3535 	fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
3536 	fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
3537 	fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
3538 	fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
3539 	fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
3540 	fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
3541 	fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
3542 	fprintf(output, "random: %d\n", ldns_resolver_random(r));
3543 	fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
3544 	fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
3545 	fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
3546 	fprintf(output, "trust anchors (%d listed):\n",
3547 		(int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
3548 	ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
3549 	fprintf(output, "tsig: %s %s\n",
3550                 ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
3551                 ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
3552 	fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
3553 
3554 	fprintf(output, "default domain: ");
3555 	ldns_rdf_print(output, ldns_resolver_domain(r));
3556 	fprintf(output, "\n");
3557 	fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
3558 
3559 	fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
3560 	for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
3561 		fprintf(output, "\t");
3562 		ldns_rdf_print(output, s[i]);
3563 		fprintf(output, "\n");
3564 	}
3565 	fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
3566 
3567 	fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
3568 	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
3569 		fprintf(output, "\t");
3570 		ldns_rdf_print(output, n[i]);
3571 
3572 		switch ((int)rtt[i]) {
3573 			case LDNS_RESOLV_RTT_MIN:
3574 			fprintf(output, " - reachable\n");
3575 			break;
3576 			case LDNS_RESOLV_RTT_INF:
3577 			fprintf(output, " - unreachable\n");
3578 			break;
3579 		}
3580 	}
3581 }
3582 
3583 void
ldns_resolver_print(FILE * output,const ldns_resolver * r)3584 ldns_resolver_print(FILE *output, const ldns_resolver *r)
3585 {
3586 	ldns_resolver_print_fmt(output, ldns_output_format_default, r);
3587 }
3588 
3589 void
ldns_zone_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_zone * z)3590 ldns_zone_print_fmt(FILE *output,
3591 		const ldns_output_format *fmt, const ldns_zone *z)
3592 {
3593 	if(ldns_zone_soa(z))
3594 		ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
3595 	ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
3596 }
3597 void
ldns_zone_print(FILE * output,const ldns_zone * z)3598 ldns_zone_print(FILE *output, const ldns_zone *z)
3599 {
3600 	ldns_zone_print_fmt(output, ldns_output_format_default, z);
3601 }
3602