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