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