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