1 /*
2 * host2str.c
3 *
4 * conversion routines from the host format
5 * to the presentation format (strings)
6 *
7 * a Net::DNS like library for C
8 *
9 * (c) NLnet Labs, 2004-2006
10 *
11 * See the file LICENSE for the license
12 */
13 #include <ldns/config.h>
14
15 #include <ldns/ldns.h>
16
17 #include <limits.h>
18
19 #ifdef HAVE_SYS_SOCKET_H
20 #include <sys/socket.h>
21 #endif
22 #ifdef HAVE_ARPA_INET_H
23 #include <arpa/inet.h>
24 #endif
25 #ifdef HAVE_NETDB_H
26 #include <netdb.h>
27 #endif
28 #include <time.h>
29 #include <sys/time.h>
30
31 #ifndef INET_ADDRSTRLEN
32 #define INET_ADDRSTRLEN 16
33 #endif
34 #ifndef INET6_ADDRSTRLEN
35 #define INET6_ADDRSTRLEN 46
36 #endif
37
38 /* lookup tables for standard DNS stuff */
39
40 /* Taken from RFC 2535, section 7. */
41 ldns_lookup_table ldns_algorithms[] = {
42 { LDNS_RSAMD5, "RSAMD5" },
43 { LDNS_DH, "DH" },
44 { LDNS_DSA, "DSA" },
45 { LDNS_ECC, "ECC" },
46 { LDNS_RSASHA1, "RSASHA1" },
47 { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
48 { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
49 #ifdef USE_SHA2
50 { LDNS_RSASHA256, "RSASHA256"},
51 { LDNS_RSASHA512, "RSASHA512"},
52 #endif
53 #ifdef USE_GOST
54 { LDNS_ECC_GOST, "ECC-GOST"},
55 #endif
56 #ifdef USE_ECDSA
57 { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
58 { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
59 #endif
60 #ifdef USE_ED25519
61 { LDNS_ED25519, "ED25519"},
62 #endif
63 #ifdef USE_ED448
64 { LDNS_ED448, "ED448"},
65 #endif
66 { LDNS_INDIRECT, "INDIRECT" },
67 { LDNS_PRIVATEDNS, "PRIVATEDNS" },
68 { LDNS_PRIVATEOID, "PRIVATEOID" },
69 { 0, NULL }
70 };
71
72 /* Taken from RFC 4398 */
73 ldns_lookup_table ldns_cert_algorithms[] = {
74 { LDNS_CERT_PKIX, "PKIX" },
75 { LDNS_CERT_SPKI, "SPKI" },
76 { LDNS_CERT_PGP, "PGP" },
77 { LDNS_CERT_IPKIX, "IPKIX" },
78 { LDNS_CERT_ISPKI, "ISPKI" },
79 { LDNS_CERT_IPGP, "IPGP" },
80 { LDNS_CERT_ACPKIX, "ACPKIX" },
81 { LDNS_CERT_IACPKIX, "IACPKIX" },
82 { LDNS_CERT_URI, "URI" },
83 { LDNS_CERT_OID, "OID" },
84 { 0, NULL }
85 };
86
87 /* classes */
88 ldns_lookup_table ldns_rr_classes[] = {
89 { LDNS_RR_CLASS_IN, "IN" },
90 { LDNS_RR_CLASS_CH, "CH" },
91 { LDNS_RR_CLASS_HS, "HS" },
92 { LDNS_RR_CLASS_NONE, "NONE" },
93 { LDNS_RR_CLASS_ANY, "ANY" },
94 { 0, NULL }
95 };
96
97 /* if these are used elsewhere */
98 ldns_lookup_table ldns_rcodes[] = {
99 { LDNS_RCODE_NOERROR, "NOERROR" },
100 { LDNS_RCODE_FORMERR, "FORMERR" },
101 { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
102 { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
103 { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
104 { LDNS_RCODE_REFUSED, "REFUSED" },
105 { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
106 { LDNS_RCODE_YXRRSET, "YXRRSET" },
107 { LDNS_RCODE_NXRRSET, "NXRRSET" },
108 { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
109 { LDNS_RCODE_NOTZONE, "NOTZONE" },
110 { 0, NULL }
111 };
112
113 ldns_lookup_table ldns_opcodes[] = {
114 { LDNS_PACKET_QUERY, "QUERY" },
115 { LDNS_PACKET_IQUERY, "IQUERY" },
116 { LDNS_PACKET_STATUS, "STATUS" },
117 { LDNS_PACKET_NOTIFY, "NOTIFY" },
118 { LDNS_PACKET_UPDATE, "UPDATE" },
119 { 0, NULL }
120 };
121
122 const ldns_output_format ldns_output_format_nocomments_record = { 0, NULL };
123 const ldns_output_format *ldns_output_format_nocomments
124 = &ldns_output_format_nocomments_record;
125 const ldns_output_format ldns_output_format_onlykeyids_record = {
126 LDNS_COMMENT_KEY, NULL
127 };
128 const ldns_output_format *ldns_output_format_onlykeyids
129 = &ldns_output_format_onlykeyids_record;
130 const ldns_output_format *ldns_output_format_default
131 = &ldns_output_format_onlykeyids_record;
132
133 const ldns_output_format ldns_output_format_bubblebabble_record = {
134 LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
135 };
136 const ldns_output_format *ldns_output_format_bubblebabble
137 = &ldns_output_format_bubblebabble_record;
138
139 static bool
ldns_output_format_covers_type(const ldns_output_format * fmt,ldns_rr_type t)140 ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
141 {
142 return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
143 ((ldns_output_format_storage*)fmt)->bitmap &&
144 ldns_nsec_bitmap_covers_type(
145 ((ldns_output_format_storage*)fmt)->bitmap, t);
146 }
147
148 ldns_status
ldns_output_format_set_type(ldns_output_format * fmt,ldns_rr_type t)149 ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
150 {
151 ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
152 ldns_status s;
153
154 assert(fmt != NULL);
155
156 if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
157 ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
158 }
159 if (! fmt_st->bitmap) {
160 s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
161 if (s != LDNS_STATUS_OK) {
162 return s;
163 }
164 }
165 return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
166 }
167
168 ldns_status
ldns_output_format_clear_type(ldns_output_format * fmt,ldns_rr_type t)169 ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
170 {
171 ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
172 ldns_status s;
173
174 assert(fmt != NULL);
175
176 if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
177 ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
178 }
179 if (! fmt_st->bitmap) {
180 s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
181 if (s != LDNS_STATUS_OK) {
182 return s;
183 }
184 }
185 return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
186 }
187
188 ldns_status
ldns_pkt_opcode2buffer_str(ldns_buffer * output,ldns_pkt_opcode opcode)189 ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
190 {
191 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
192 if (lt && lt->name) {
193 ldns_buffer_printf(output, "%s", lt->name);
194 } else {
195 ldns_buffer_printf(output, "OPCODE%u", opcode);
196 }
197 return ldns_buffer_status(output);
198 }
199
200 ldns_status
ldns_pkt_rcode2buffer_str(ldns_buffer * output,ldns_pkt_rcode rcode)201 ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
202 {
203 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
204 if (lt && lt->name) {
205 ldns_buffer_printf(output, "%s", lt->name);
206 } else {
207 ldns_buffer_printf(output, "RCODE%u", rcode);
208 }
209 return ldns_buffer_status(output);
210 }
211
212 ldns_status
ldns_algorithm2buffer_str(ldns_buffer * output,ldns_algorithm algorithm)213 ldns_algorithm2buffer_str(ldns_buffer *output,
214 ldns_algorithm algorithm)
215 {
216 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
217 algorithm);
218 if (lt && lt->name) {
219 ldns_buffer_printf(output, "%s", lt->name);
220 } else {
221 ldns_buffer_printf(output, "ALG%u", algorithm);
222 }
223 return ldns_buffer_status(output);
224 }
225
226 ldns_status
ldns_cert_algorithm2buffer_str(ldns_buffer * output,ldns_cert_algorithm cert_algorithm)227 ldns_cert_algorithm2buffer_str(ldns_buffer *output,
228 ldns_cert_algorithm cert_algorithm)
229 {
230 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
231 cert_algorithm);
232 if (lt && lt->name) {
233 ldns_buffer_printf(output, "%s", lt->name);
234 } else {
235 ldns_buffer_printf(output, "CERT_ALG%u",
236 cert_algorithm);
237 }
238 return ldns_buffer_status(output);
239 }
240
241 char *
ldns_pkt_opcode2str(ldns_pkt_opcode opcode)242 ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
243 {
244 char *str;
245 ldns_buffer *buf;
246
247 buf = ldns_buffer_new(12);
248 if (!buf) {
249 return NULL;
250 }
251
252 str = NULL;
253 if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
254 str = ldns_buffer_export2str(buf);
255 }
256
257 ldns_buffer_free(buf);
258 return str;
259 }
260
261 char *
ldns_pkt_rcode2str(ldns_pkt_rcode rcode)262 ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
263 {
264 char *str;
265 ldns_buffer *buf;
266
267 buf = ldns_buffer_new(10);
268 if (!buf) {
269 return NULL;
270 }
271
272 str = NULL;
273 if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
274 str = ldns_buffer_export2str(buf);
275 }
276
277 ldns_buffer_free(buf);
278 return str;
279 }
280
281 char *
ldns_pkt_algorithm2str(ldns_algorithm algorithm)282 ldns_pkt_algorithm2str(ldns_algorithm algorithm)
283 {
284 char *str;
285 ldns_buffer *buf;
286
287 buf = ldns_buffer_new(10);
288 if (!buf) {
289 return NULL;
290 }
291
292 str = NULL;
293 if (ldns_algorithm2buffer_str(buf, algorithm)
294 == LDNS_STATUS_OK) {
295 str = ldns_buffer_export2str(buf);
296 }
297
298 ldns_buffer_free(buf);
299 return str;
300 }
301
302 char *
ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)303 ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
304 {
305 char *str;
306 ldns_buffer *buf;
307
308 buf = ldns_buffer_new(10);
309 if (!buf) {
310 return NULL;
311 }
312
313 str = NULL;
314 if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
315 == LDNS_STATUS_OK) {
316 str = ldns_buffer_export2str(buf);
317 }
318
319 ldns_buffer_free(buf);
320 return str;
321 }
322
323
324 /* do NOT pass compressed data here :p */
325 ldns_status
ldns_rdf2buffer_str_dname(ldns_buffer * output,const ldns_rdf * dname)326 ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
327 {
328 /* can we do with 1 pos var? or without at all? */
329 uint8_t src_pos = 0;
330 uint8_t len;
331 uint8_t *data;
332 uint8_t i;
333 unsigned char c;
334
335 data = (uint8_t*)ldns_rdf_data(dname);
336 len = data[src_pos];
337
338 if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
339 /* too large, return */
340 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
341 }
342
343 /* special case: root label */
344 if (1 == ldns_rdf_size(dname)) {
345 ldns_buffer_printf(output, ".");
346 } else {
347 while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
348 src_pos++;
349 for(i = 0; i < len; i++) {
350 /* paranoia check for various 'strange'
351 characters in dnames
352 */
353 c = (unsigned char) data[src_pos];
354 if(c == '.' || c == ';' ||
355 c == '(' || c == ')' ||
356 c == '\\') {
357 ldns_buffer_printf(output, "\\%c",
358 data[src_pos]);
359 } else if (!(isascii(c) && isgraph(c))) {
360 ldns_buffer_printf(output, "\\%03u",
361 data[src_pos]);
362 } else {
363 ldns_buffer_printf(output, "%c", data[src_pos]);
364 }
365 src_pos++;
366 }
367
368 if (src_pos < ldns_rdf_size(dname)) {
369 ldns_buffer_printf(output, ".");
370 }
371 len = data[src_pos];
372 }
373 }
374 return ldns_buffer_status(output);
375 }
376
377 ldns_status
ldns_rdf2buffer_str_int8(ldns_buffer * output,const ldns_rdf * rdf)378 ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
379 {
380 uint8_t data = ldns_rdf_data(rdf)[0];
381 ldns_buffer_printf(output, "%lu", (unsigned long) data);
382 return ldns_buffer_status(output);
383 }
384
385 ldns_status
ldns_rdf2buffer_str_int16(ldns_buffer * output,const ldns_rdf * rdf)386 ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
387 {
388 uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
389 ldns_buffer_printf(output, "%lu", (unsigned long) data);
390 return ldns_buffer_status(output);
391 }
392
393 ldns_status
ldns_rdf2buffer_str_int32(ldns_buffer * output,const ldns_rdf * rdf)394 ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
395 {
396 uint32_t data = ldns_read_uint32(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_time(ldns_buffer * output,const ldns_rdf * rdf)402 ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
403 {
404 /* create a YYYYMMDDHHMMSS string if possible */
405 struct tm tm;
406 char date_buf[16];
407
408 memset(&tm, 0, sizeof(tm));
409 if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
410 && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
411 ldns_buffer_printf(output, "%s", date_buf);
412 }
413 return ldns_buffer_status(output);
414 }
415
416 ldns_status
ldns_rdf2buffer_str_a(ldns_buffer * output,const ldns_rdf * rdf)417 ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
418 {
419 char str[INET_ADDRSTRLEN];
420
421 if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
422 ldns_buffer_printf(output, "%s", str);
423 }
424 return ldns_buffer_status(output);
425 }
426
427 ldns_status
ldns_rdf2buffer_str_aaaa(ldns_buffer * output,const ldns_rdf * rdf)428 ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
429 {
430 char str[INET6_ADDRSTRLEN];
431
432 if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
433 ldns_buffer_printf(output, "%s", str);
434 }
435
436 return ldns_buffer_status(output);
437 }
438
439 static void
ldns_characters2buffer_str(ldns_buffer * output,size_t amount,const uint8_t * characters)440 ldns_characters2buffer_str(ldns_buffer* output,
441 size_t amount, const uint8_t* characters)
442 {
443 uint8_t ch;
444 while (amount > 0) {
445 ch = *characters++;
446 if (isprint((int)ch) || ch == '\t') {
447 if (ch == '\"' || ch == '\\')
448 ldns_buffer_printf(output, "\\%c", ch);
449 else
450 ldns_buffer_printf(output, "%c", ch);
451 } else {
452 ldns_buffer_printf(output, "\\%03u",
453 (unsigned)(uint8_t) ch);
454 }
455 amount--;
456 }
457 }
458
459 ldns_status
ldns_rdf2buffer_str_str(ldns_buffer * output,const ldns_rdf * rdf)460 ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
461 {
462 if(ldns_rdf_size(rdf) < 1) {
463 return LDNS_STATUS_WIRE_RDATA_ERR;
464 }
465 if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
466 return LDNS_STATUS_WIRE_RDATA_ERR;
467 }
468 ldns_buffer_printf(output, "\"");
469 ldns_characters2buffer_str(output,
470 ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
471 ldns_buffer_printf(output, "\"");
472 return ldns_buffer_status(output);
473 }
474
475 ldns_status
ldns_rdf2buffer_str_b64(ldns_buffer * output,const ldns_rdf * rdf)476 ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
477 {
478 size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
479 char *b64 = LDNS_XMALLOC(char, size);
480 if(!b64) return LDNS_STATUS_MEM_ERR;
481 if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
482 ldns_buffer_printf(output, "%s", b64);
483 }
484 LDNS_FREE(b64);
485 return ldns_buffer_status(output);
486 }
487
488 ldns_status
ldns_rdf2buffer_str_b32_ext(ldns_buffer * output,const ldns_rdf * rdf)489 ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
490 {
491 size_t size;
492 char *b32;
493 if(ldns_rdf_size(rdf) == 0)
494 return LDNS_STATUS_OK;
495 /* remove -1 for the b32-hash-len octet */
496 size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
497 /* add one for the end nul for the string */
498 b32 = LDNS_XMALLOC(char, size + 1);
499 if(!b32) return LDNS_STATUS_MEM_ERR;
500 size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
501 ldns_rdf_size(rdf) - 1, b32, size+1);
502 if (size > 0) {
503 ldns_buffer_printf(output, "%s", b32);
504 }
505 LDNS_FREE(b32);
506 return ldns_buffer_status(output);
507 }
508
509 ldns_status
ldns_rdf2buffer_str_hex(ldns_buffer * output,const ldns_rdf * rdf)510 ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
511 {
512 size_t i;
513 for (i = 0; i < ldns_rdf_size(rdf); i++) {
514 ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
515 }
516
517 return ldns_buffer_status(output);
518 }
519
520 static ldns_status
ldns_rdf2buffer_str_type_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)521 ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
522 const ldns_output_format* fmt, const ldns_rdf *rdf)
523 {
524 uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
525
526 if (! ldns_output_format_covers_type(fmt, data) &&
527 ldns_rr_descript(data) &&
528 ldns_rr_descript(data)->_name) {
529
530 ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
531 } else {
532 ldns_buffer_printf(output, "TYPE%u", data);
533 }
534 return ldns_buffer_status(output);
535 }
536
537 ldns_status
ldns_rdf2buffer_str_type(ldns_buffer * output,const ldns_rdf * rdf)538 ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
539 {
540 return ldns_rdf2buffer_str_type_fmt(output,
541 ldns_output_format_default, rdf);
542 }
543
544 ldns_status
ldns_rdf2buffer_str_class(ldns_buffer * output,const ldns_rdf * rdf)545 ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
546 {
547 uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
548 ldns_lookup_table *lt;
549
550 lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
551 if (lt) {
552 ldns_buffer_printf(output, "\t%s", lt->name);
553 } else {
554 ldns_buffer_printf(output, "\tCLASS%d", data);
555 }
556 return ldns_buffer_status(output);
557 }
558
559 ldns_status
ldns_rdf2buffer_str_cert_alg(ldns_buffer * output,const ldns_rdf * rdf)560 ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
561 {
562 uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
563 ldns_lookup_table *lt;
564 lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
565 if (lt) {
566 ldns_buffer_printf(output, "%s", lt->name);
567 } else {
568 ldns_buffer_printf(output, "%d", data);
569 }
570 return ldns_buffer_status(output);
571 }
572
573 ldns_status
ldns_rdf2buffer_str_alg(ldns_buffer * output,const ldns_rdf * rdf)574 ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
575 {
576 return ldns_rdf2buffer_str_int8(output, rdf);
577 }
578
579 static void
loc_cm_print(ldns_buffer * output,uint8_t mantissa,uint8_t exponent)580 loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
581 {
582 uint8_t i;
583 /* is it 0.<two digits> ? */
584 if(exponent < 2) {
585 if(exponent == 1)
586 mantissa *= 10;
587 ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
588 return;
589 }
590 /* always <digit><string of zeros> */
591 ldns_buffer_printf(output, "%d", (int)mantissa);
592 for(i=0; i<exponent-2; i++)
593 ldns_buffer_printf(output, "0");
594 }
595
596 ldns_status
ldns_rr_type2buffer_str(ldns_buffer * output,const ldns_rr_type type)597 ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
598 {
599 const ldns_rr_descriptor *descriptor;
600
601 descriptor = ldns_rr_descript(type);
602
603 switch (type) {
604 case LDNS_RR_TYPE_IXFR:
605 ldns_buffer_printf(output, "IXFR");
606 break;
607 case LDNS_RR_TYPE_AXFR:
608 ldns_buffer_printf(output, "AXFR");
609 break;
610 case LDNS_RR_TYPE_MAILA:
611 ldns_buffer_printf(output, "MAILA");
612 break;
613 case LDNS_RR_TYPE_MAILB:
614 ldns_buffer_printf(output, "MAILB");
615 break;
616 case LDNS_RR_TYPE_ANY:
617 ldns_buffer_printf(output, "ANY");
618 break;
619 default:
620 if (descriptor && descriptor->_name) {
621 ldns_buffer_printf(output, "%s", descriptor->_name);
622 } else {
623 ldns_buffer_printf(output, "TYPE%u", type);
624 }
625 }
626 return ldns_buffer_status(output);
627 }
628
629 char *
ldns_rr_type2str(const ldns_rr_type type)630 ldns_rr_type2str(const ldns_rr_type type)
631 {
632 char *str;
633 ldns_buffer *buf;
634
635 buf = ldns_buffer_new(10);
636 if (!buf) {
637 return NULL;
638 }
639
640 str = NULL;
641 if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
642 str = ldns_buffer_export2str(buf);
643 }
644
645 ldns_buffer_free(buf);
646 return str;
647 }
648
649
650 ldns_status
ldns_rr_class2buffer_str(ldns_buffer * output,const ldns_rr_class klass)651 ldns_rr_class2buffer_str(ldns_buffer *output,
652 const ldns_rr_class klass)
653 {
654 ldns_lookup_table *lt;
655
656 lt = ldns_lookup_by_id(ldns_rr_classes, klass);
657 if (lt) {
658 ldns_buffer_printf(output, "%s", lt->name);
659 } else {
660 ldns_buffer_printf(output, "CLASS%d", klass);
661 }
662 return ldns_buffer_status(output);
663 }
664
665 char *
ldns_rr_class2str(const ldns_rr_class klass)666 ldns_rr_class2str(const ldns_rr_class klass)
667 {
668 ldns_buffer *buf;
669 char *str;
670
671 buf = ldns_buffer_new(10);
672 if (!buf) {
673 return NULL;
674 }
675
676 str = NULL;
677 if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
678 str = ldns_buffer_export2str(buf);
679 }
680 ldns_buffer_free(buf);
681 return str;
682 }
683
684 ldns_status
ldns_rdf2buffer_str_loc(ldns_buffer * output,const ldns_rdf * rdf)685 ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
686 {
687 /* we could do checking (ie degrees < 90 etc)? */
688 uint8_t version;
689 uint8_t size;
690 uint8_t horizontal_precision;
691 uint8_t vertical_precision;
692 uint32_t longitude;
693 uint32_t latitude;
694 uint32_t altitude;
695 char northerness;
696 char easterness;
697 uint32_t h;
698 uint32_t m;
699 double s;
700
701 uint32_t equator = (uint32_t) ldns_power(2, 31);
702
703 if(ldns_rdf_size(rdf) < 1) {
704 return LDNS_STATUS_WIRE_RDATA_ERR;
705 }
706 version = ldns_rdf_data(rdf)[0];
707 if (version == 0) {
708 if(ldns_rdf_size(rdf) < 16) {
709 return LDNS_STATUS_WIRE_RDATA_ERR;
710 }
711 size = ldns_rdf_data(rdf)[1];
712 horizontal_precision = ldns_rdf_data(rdf)[2];
713 vertical_precision = ldns_rdf_data(rdf)[3];
714
715 latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
716 longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
717 altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
718
719 if (latitude > equator) {
720 northerness = 'N';
721 latitude = latitude - equator;
722 } else {
723 northerness = 'S';
724 latitude = equator - latitude;
725 }
726 h = latitude / (1000 * 60 * 60);
727 latitude = latitude % (1000 * 60 * 60);
728 m = latitude / (1000 * 60);
729 latitude = latitude % (1000 * 60);
730 s = (double) latitude / 1000.0;
731 ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
732 h, m, s, northerness);
733
734 if (longitude > equator) {
735 easterness = 'E';
736 longitude = longitude - equator;
737 } else {
738 easterness = 'W';
739 longitude = equator - longitude;
740 }
741 h = longitude / (1000 * 60 * 60);
742 longitude = longitude % (1000 * 60 * 60);
743 m = longitude / (1000 * 60);
744 longitude = longitude % (1000 * 60);
745 s = (double) longitude / (1000.0);
746 ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
747 h, m, s, easterness);
748
749
750 s = ((double) altitude) / 100;
751 s -= 100000;
752
753 if(altitude%100 != 0)
754 ldns_buffer_printf(output, "%.2f", s);
755 else
756 ldns_buffer_printf(output, "%.0f", s);
757
758 ldns_buffer_printf(output, "m ");
759
760 loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
761 ldns_buffer_printf(output, "m ");
762
763 loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
764 horizontal_precision & 0x0f);
765 ldns_buffer_printf(output, "m ");
766
767 loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
768 vertical_precision & 0x0f);
769 ldns_buffer_printf(output, "m");
770
771 return ldns_buffer_status(output);
772 } else {
773 return ldns_rdf2buffer_str_hex(output, rdf);
774 }
775 }
776
777 ldns_status
ldns_rdf2buffer_str_unknown(ldns_buffer * output,const ldns_rdf * rdf)778 ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
779 {
780 ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
781 return ldns_rdf2buffer_str_hex(output, rdf);
782 }
783
784 ldns_status
ldns_rdf2buffer_str_nsap(ldns_buffer * output,const ldns_rdf * rdf)785 ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
786 {
787 ldns_buffer_printf(output, "0x");
788 return ldns_rdf2buffer_str_hex(output, rdf);
789 }
790
791 ldns_status
ldns_rdf2buffer_str_atma(ldns_buffer * output,const ldns_rdf * rdf)792 ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
793 {
794 return ldns_rdf2buffer_str_hex(output, rdf);
795 }
796
797 ldns_status
ldns_rdf2buffer_str_wks(ldns_buffer * output,const ldns_rdf * rdf)798 ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
799 {
800 /* protocol, followed by bitmap of services */
801 struct protoent *protocol;
802 char *proto_name = NULL;
803 uint8_t protocol_nr;
804 struct servent *service;
805 uint16_t current_service;
806
807 if(ldns_rdf_size(rdf) < 1) {
808 return LDNS_STATUS_WIRE_RDATA_ERR;
809 }
810 protocol_nr = ldns_rdf_data(rdf)[0];
811 protocol = getprotobynumber((int) protocol_nr);
812 if (protocol && (protocol->p_name != NULL)) {
813 proto_name = protocol->p_name;
814 ldns_buffer_printf(output, "%s ", protocol->p_name);
815 } else {
816 ldns_buffer_printf(output, "%u ", protocol_nr);
817 }
818
819 #ifdef HAVE_ENDPROTOENT
820 endprotoent();
821 #endif
822
823 for (current_service = 0;
824 current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
825 if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
826 service = getservbyport((int) htons(current_service),
827 proto_name);
828 if (service && service->s_name) {
829 ldns_buffer_printf(output, "%s ", service->s_name);
830 } else {
831 ldns_buffer_printf(output, "%u ", current_service);
832 }
833 #ifdef HAVE_ENDSERVENT
834 endservent();
835 #endif
836 }
837 }
838 return ldns_buffer_status(output);
839 }
840
841 static ldns_status
ldns_rdf2buffer_str_nsec_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rdf * rdf)842 ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
843 const ldns_output_format* fmt, const ldns_rdf *rdf)
844 {
845 /* Note: this code is duplicated in higher.c in
846 * ldns_nsec_type_check() function
847 */
848 uint8_t window_block_nr;
849 uint8_t bitmap_length;
850 uint16_t type;
851 uint16_t pos = 0;
852 uint16_t bit_pos;
853 uint8_t *data = ldns_rdf_data(rdf);
854
855 while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
856 window_block_nr = data[pos];
857 bitmap_length = data[pos + 1];
858 pos += 2;
859 if (ldns_rdf_size(rdf) < pos + bitmap_length) {
860 return LDNS_STATUS_WIRE_RDATA_ERR;
861 }
862 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
863 if (! ldns_get_bit(&data[pos], bit_pos)) {
864 continue;
865 }
866 type = 256 * (uint16_t) window_block_nr + bit_pos;
867
868 if (! ldns_output_format_covers_type(fmt, type) &&
869 ldns_rr_descript(type) &&
870 ldns_rr_descript(type)->_name){
871
872 ldns_buffer_printf(output, "%s ",
873 ldns_rr_descript(type)->_name);
874 } else {
875 ldns_buffer_printf(output, "TYPE%u ", type);
876 }
877 }
878 pos += (uint16_t) bitmap_length;
879 }
880 return ldns_buffer_status(output);
881 }
882
883 ldns_status
ldns_rdf2buffer_str_nsec(ldns_buffer * output,const ldns_rdf * rdf)884 ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
885 {
886 return ldns_rdf2buffer_str_nsec_fmt(output,
887 ldns_output_format_default, rdf);
888 }
889
890 ldns_status
ldns_rdf2buffer_str_nsec3_salt(ldns_buffer * output,const ldns_rdf * rdf)891 ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
892 {
893 uint8_t salt_length;
894 uint8_t salt_pos;
895
896 uint8_t *data = ldns_rdf_data(rdf);
897
898 if(ldns_rdf_size(rdf) < 1) {
899 return LDNS_STATUS_WIRE_RDATA_ERR;
900 }
901 salt_length = data[0];
902 /* from now there are variable length entries so remember pos */
903 if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
904 ldns_buffer_printf(output, "- ");
905 } else {
906 for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
907 ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
908 }
909 ldns_buffer_printf(output, " ");
910 }
911
912 return ldns_buffer_status(output);
913 }
914
915 ldns_status
ldns_rdf2buffer_str_period(ldns_buffer * output,const ldns_rdf * rdf)916 ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
917 {
918 /* period is the number of seconds */
919 if (ldns_rdf_size(rdf) != 4) {
920 return LDNS_STATUS_WIRE_RDATA_ERR;
921 }
922 ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
923 return ldns_buffer_status(output);
924 }
925
926 ldns_status
ldns_rdf2buffer_str_tsigtime(ldns_buffer * output,const ldns_rdf * rdf)927 ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const ldns_rdf *rdf)
928 {
929 /* tsigtime is 48 bits network order unsigned integer */
930 uint64_t tsigtime = 0;
931 uint8_t *data = ldns_rdf_data(rdf);
932 uint64_t d0, d1, d2, d3, d4, d5;
933
934 if (ldns_rdf_size(rdf) < 6) {
935 return LDNS_STATUS_WIRE_RDATA_ERR;
936 }
937 d0 = data[0]; /* cast to uint64 for shift operations */
938 d1 = data[1];
939 d2 = data[2];
940 d3 = data[3];
941 d4 = data[4];
942 d5 = data[5];
943 tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
944
945 ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
946
947 return ldns_buffer_status(output);
948 }
949
950 ldns_status
ldns_rdf2buffer_str_apl(ldns_buffer * output,const ldns_rdf * rdf)951 ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
952 {
953 uint8_t *data = ldns_rdf_data(rdf);
954 uint16_t address_family;
955 uint8_t prefix;
956 bool negation;
957 uint8_t adf_length;
958 size_t i;
959 size_t pos = 0;
960
961 while (pos < (unsigned int) ldns_rdf_size(rdf)) {
962 if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
963 return LDNS_STATUS_WIRE_RDATA_ERR;
964 address_family = ldns_read_uint16(&data[pos]);
965 prefix = data[pos + 2];
966 negation = data[pos + 3] & LDNS_APL_NEGATION;
967 adf_length = data[pos + 3] & LDNS_APL_MASK;
968 if (address_family == LDNS_APL_IP4) {
969 /* check if prefix < 32? */
970 if (negation) {
971 ldns_buffer_printf(output, "!");
972 }
973 ldns_buffer_printf(output, "%u:", address_family);
974 /* address is variable length 0 - 4 */
975 for (i = 0; i < 4; i++) {
976 if (i > 0) {
977 ldns_buffer_printf(output, ".");
978 }
979 if (i < (unsigned short) adf_length) {
980 if(pos+i+4 >= ldns_rdf_size(rdf))
981 return LDNS_STATUS_WIRE_RDATA_ERR;
982 ldns_buffer_printf(output, "%d",
983 data[pos + i + 4]);
984 } else {
985 ldns_buffer_printf(output, "0");
986 }
987 }
988 ldns_buffer_printf(output, "/%u ", prefix);
989 } else if (address_family == LDNS_APL_IP6) {
990 /* check if prefix < 128? */
991 if (negation) {
992 ldns_buffer_printf(output, "!");
993 }
994 ldns_buffer_printf(output, "%u:", address_family);
995 /* address is variable length 0 - 16 */
996 for (i = 0; i < 16; i++) {
997 if (i % 2 == 0 && i > 0) {
998 ldns_buffer_printf(output, ":");
999 }
1000 if (i < (unsigned short) adf_length) {
1001 if(pos+i+4 >= ldns_rdf_size(rdf))
1002 return LDNS_STATUS_WIRE_RDATA_ERR;
1003 ldns_buffer_printf(output, "%02x",
1004 data[pos + i + 4]);
1005 } else {
1006 ldns_buffer_printf(output, "00");
1007 }
1008 }
1009 ldns_buffer_printf(output, "/%u ", prefix);
1010
1011 } else {
1012 /* unknown address family */
1013 ldns_buffer_printf(output,
1014 "Unknown address family: %u data: ",
1015 address_family);
1016 for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
1017 if(pos+i >= ldns_rdf_size(rdf))
1018 return LDNS_STATUS_WIRE_RDATA_ERR;
1019 ldns_buffer_printf(output, "%02x", data[i]);
1020 }
1021 }
1022 pos += 4 + adf_length;
1023 }
1024 return ldns_buffer_status(output);
1025 }
1026
1027 ldns_status
ldns_rdf2buffer_str_int16_data(ldns_buffer * output,const ldns_rdf * rdf)1028 ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
1029 {
1030 size_t size;
1031 char *b64;
1032 if (ldns_rdf_size(rdf) < 2) {
1033 return LDNS_STATUS_WIRE_RDATA_ERR;
1034 }
1035 /* Subtract the size (2) of the number that specifies the length */
1036 size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
1037 ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
1038 if (ldns_rdf_size(rdf) > 2) {
1039 b64 = LDNS_XMALLOC(char, size);
1040 if(!b64)
1041 return LDNS_STATUS_MEM_ERR;
1042
1043 if (ldns_rdf_size(rdf) > 2 &&
1044 ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
1045 ldns_rdf_size(rdf) - 2,
1046 b64, size)) {
1047 ldns_buffer_printf(output, "%s", b64);
1048 }
1049 LDNS_FREE(b64);
1050 }
1051 return ldns_buffer_status(output);
1052 }
1053
1054 ldns_status
ldns_rdf2buffer_str_ipseckey(ldns_buffer * output,const ldns_rdf * rdf)1055 ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
1056 {
1057 /* wire format from
1058 http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
1059 */
1060 uint8_t *data = ldns_rdf_data(rdf);
1061 uint8_t precedence;
1062 uint8_t gateway_type;
1063 uint8_t algorithm;
1064
1065 ldns_rdf *gateway = NULL;
1066 uint8_t *gateway_data;
1067
1068 size_t public_key_size;
1069 uint8_t *public_key_data;
1070 ldns_rdf *public_key;
1071
1072 size_t offset = 0;
1073 ldns_status status;
1074
1075 if (ldns_rdf_size(rdf) < 3) {
1076 return LDNS_STATUS_WIRE_RDATA_ERR;
1077 }
1078 precedence = data[0];
1079 gateway_type = data[1];
1080 algorithm = data[2];
1081 offset = 3;
1082
1083 switch (gateway_type) {
1084 case 0:
1085 /* no gateway */
1086 break;
1087 case 1:
1088 gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
1089 if(!gateway_data)
1090 return LDNS_STATUS_MEM_ERR;
1091 if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
1092 return LDNS_STATUS_ERR;
1093 }
1094 memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
1095 gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
1096 LDNS_IP4ADDRLEN , gateway_data);
1097 offset += LDNS_IP4ADDRLEN;
1098 if(!gateway) {
1099 LDNS_FREE(gateway_data);
1100 return LDNS_STATUS_MEM_ERR;
1101 }
1102 break;
1103 case 2:
1104 gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
1105 if(!gateway_data)
1106 return LDNS_STATUS_MEM_ERR;
1107 if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
1108 return LDNS_STATUS_ERR;
1109 }
1110 memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
1111 offset += LDNS_IP6ADDRLEN;
1112 gateway =
1113 ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
1114 LDNS_IP6ADDRLEN, gateway_data);
1115 if(!gateway) {
1116 LDNS_FREE(gateway_data);
1117 return LDNS_STATUS_MEM_ERR;
1118 }
1119 break;
1120 case 3:
1121 status = ldns_wire2dname(&gateway, data,
1122 ldns_rdf_size(rdf), &offset);
1123 if(status != LDNS_STATUS_OK)
1124 return status;
1125 break;
1126 default:
1127 /* error? */
1128 break;
1129 }
1130
1131 if (ldns_rdf_size(rdf) <= offset) {
1132 return LDNS_STATUS_ERR;
1133 }
1134 public_key_size = ldns_rdf_size(rdf) - offset;
1135 public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
1136 if(!public_key_data) {
1137 ldns_rdf_deep_free(gateway);
1138 return LDNS_STATUS_MEM_ERR;
1139 }
1140 memcpy(public_key_data, &data[offset], public_key_size);
1141 public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
1142 public_key_size, public_key_data);
1143 if(!public_key) {
1144 LDNS_FREE(public_key_data);
1145 ldns_rdf_deep_free(gateway);
1146 return LDNS_STATUS_MEM_ERR;
1147 }
1148
1149 ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
1150 if (gateway)
1151 (void) ldns_rdf2buffer_str(output, gateway);
1152 else
1153 ldns_buffer_printf(output, ".");
1154 ldns_buffer_printf(output, " ");
1155 (void) ldns_rdf2buffer_str(output, public_key);
1156
1157 ldns_rdf_deep_free(gateway);
1158 ldns_rdf_deep_free(public_key);
1159
1160 return ldns_buffer_status(output);
1161 }
1162
1163 ldns_status
ldns_rdf2buffer_str_ilnp64(ldns_buffer * output,const ldns_rdf * rdf)1164 ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
1165 {
1166 if (ldns_rdf_size(rdf) != 8) {
1167 return LDNS_STATUS_WIRE_RDATA_ERR;
1168 }
1169 ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
1170 ldns_read_uint16(ldns_rdf_data(rdf)),
1171 ldns_read_uint16(ldns_rdf_data(rdf)+2),
1172 ldns_read_uint16(ldns_rdf_data(rdf)+4),
1173 ldns_read_uint16(ldns_rdf_data(rdf)+6));
1174 return ldns_buffer_status(output);
1175 }
1176
1177 ldns_status
ldns_rdf2buffer_str_eui48(ldns_buffer * output,const ldns_rdf * rdf)1178 ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
1179 {
1180 if (ldns_rdf_size(rdf) != 6) {
1181 return LDNS_STATUS_WIRE_RDATA_ERR;
1182 }
1183 ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1184 ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1185 ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1186 ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
1187 return ldns_buffer_status(output);
1188 }
1189
1190 ldns_status
ldns_rdf2buffer_str_eui64(ldns_buffer * output,const ldns_rdf * rdf)1191 ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
1192 {
1193 if (ldns_rdf_size(rdf) != 8) {
1194 return LDNS_STATUS_WIRE_RDATA_ERR;
1195 }
1196 ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1197 ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
1198 ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
1199 ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
1200 ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
1201 return ldns_buffer_status(output);
1202 }
1203
1204 ldns_status
ldns_rdf2buffer_str_tag(ldns_buffer * output,const ldns_rdf * rdf)1205 ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
1206 {
1207 size_t nchars;
1208 const uint8_t* chars;
1209 char ch;
1210 if (ldns_rdf_size(rdf) < 2) {
1211 return LDNS_STATUS_WIRE_RDATA_ERR;
1212 }
1213 nchars = ldns_rdf_data(rdf)[0];
1214 if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
1215 nchars < 1) {
1216 return LDNS_STATUS_WIRE_RDATA_ERR;
1217 }
1218 chars = ldns_rdf_data(rdf) + 1;
1219 while (nchars > 0) {
1220 ch = (char)*chars++;
1221 if (! isalnum((unsigned char)ch)) {
1222 return LDNS_STATUS_WIRE_RDATA_ERR;
1223 }
1224 ldns_buffer_printf(output, "%c", ch);
1225 nchars--;
1226 }
1227 return ldns_buffer_status(output);
1228 }
1229
1230 ldns_status
ldns_rdf2buffer_str_long_str(ldns_buffer * output,const ldns_rdf * rdf)1231 ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
1232 {
1233
1234 ldns_buffer_printf(output, "\"");
1235 ldns_characters2buffer_str(output,
1236 ldns_rdf_size(rdf), ldns_rdf_data(rdf));
1237 ldns_buffer_printf(output, "\"");
1238 return ldns_buffer_status(output);
1239 }
1240
1241 ldns_status
ldns_rdf2buffer_str_hip(ldns_buffer * output,const ldns_rdf * rdf)1242 ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
1243 {
1244 uint8_t *data = ldns_rdf_data(rdf);
1245 size_t rdf_size = ldns_rdf_size(rdf);
1246 uint8_t hit_size;
1247 uint16_t pk_size;
1248 int written;
1249
1250 if (rdf_size < 6) {
1251 return LDNS_STATUS_WIRE_RDATA_ERR;
1252 }
1253 if ((hit_size = data[0]) == 0 ||
1254 (pk_size = ldns_read_uint16(data + 2)) == 0 ||
1255 rdf_size < (size_t) hit_size + pk_size + 4) {
1256
1257 return LDNS_STATUS_WIRE_RDATA_ERR;
1258 }
1259
1260 ldns_buffer_printf(output, "%d ", (int) data[1]);
1261
1262 for (data += 4; hit_size > 0; hit_size--, data++) {
1263
1264 ldns_buffer_printf(output, "%02x", (int) *data);
1265 }
1266 ldns_buffer_write_u8(output, (uint8_t) ' ');
1267
1268 if (ldns_buffer_reserve(output,
1269 ldns_b64_ntop_calculate_size(pk_size))) {
1270
1271 written = ldns_b64_ntop(data, pk_size,
1272 (char *) ldns_buffer_current(output),
1273 ldns_buffer_remaining(output));
1274
1275 if (written > 0 &&
1276 written < (int) ldns_buffer_remaining(output)) {
1277
1278 output->_position += written;
1279 }
1280 }
1281 return ldns_buffer_status(output);
1282 }
1283
1284 static ldns_status
ldns_rdf2buffer_str_fmt(ldns_buffer * buffer,const ldns_output_format * fmt,const ldns_rdf * rdf)1285 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
1286 const ldns_output_format* fmt, const ldns_rdf *rdf)
1287 {
1288 ldns_status res = LDNS_STATUS_OK;
1289
1290 /*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
1291 if (rdf) {
1292 switch(ldns_rdf_get_type(rdf)) {
1293 case LDNS_RDF_TYPE_NONE:
1294 break;
1295 case LDNS_RDF_TYPE_DNAME:
1296 res = ldns_rdf2buffer_str_dname(buffer, rdf);
1297 break;
1298 case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
1299 case LDNS_RDF_TYPE_ALG:
1300 case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
1301 case LDNS_RDF_TYPE_SELECTOR:
1302 case LDNS_RDF_TYPE_MATCHING_TYPE:
1303 res = ldns_rdf2buffer_str_int8(buffer, rdf);
1304 break;
1305 case LDNS_RDF_TYPE_INT16:
1306 res = ldns_rdf2buffer_str_int16(buffer, rdf);
1307 break;
1308 case LDNS_RDF_TYPE_INT32:
1309 res = ldns_rdf2buffer_str_int32(buffer, rdf);
1310 break;
1311 case LDNS_RDF_TYPE_PERIOD:
1312 res = ldns_rdf2buffer_str_period(buffer, rdf);
1313 break;
1314 case LDNS_RDF_TYPE_TSIGTIME:
1315 res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
1316 break;
1317 case LDNS_RDF_TYPE_A:
1318 res = ldns_rdf2buffer_str_a(buffer, rdf);
1319 break;
1320 case LDNS_RDF_TYPE_AAAA:
1321 res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
1322 break;
1323 case LDNS_RDF_TYPE_STR:
1324 res = ldns_rdf2buffer_str_str(buffer, rdf);
1325 break;
1326 case LDNS_RDF_TYPE_APL:
1327 res = ldns_rdf2buffer_str_apl(buffer, rdf);
1328 break;
1329 case LDNS_RDF_TYPE_B32_EXT:
1330 res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1331 break;
1332 case LDNS_RDF_TYPE_B64:
1333 res = ldns_rdf2buffer_str_b64(buffer, rdf);
1334 break;
1335 case LDNS_RDF_TYPE_HEX:
1336 res = ldns_rdf2buffer_str_hex(buffer, rdf);
1337 break;
1338 case LDNS_RDF_TYPE_NSEC:
1339 res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
1340 break;
1341 case LDNS_RDF_TYPE_NSEC3_SALT:
1342 res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
1343 break;
1344 case LDNS_RDF_TYPE_TYPE:
1345 res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
1346 break;
1347 case LDNS_RDF_TYPE_CLASS:
1348 res = ldns_rdf2buffer_str_class(buffer, rdf);
1349 break;
1350 case LDNS_RDF_TYPE_CERT_ALG:
1351 res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
1352 break;
1353 case LDNS_RDF_TYPE_UNKNOWN:
1354 res = ldns_rdf2buffer_str_unknown(buffer, rdf);
1355 break;
1356 case LDNS_RDF_TYPE_TIME:
1357 res = ldns_rdf2buffer_str_time(buffer, rdf);
1358 break;
1359 case LDNS_RDF_TYPE_HIP:
1360 res = ldns_rdf2buffer_str_hip(buffer, rdf);
1361 break;
1362 case LDNS_RDF_TYPE_LOC:
1363 res = ldns_rdf2buffer_str_loc(buffer, rdf);
1364 break;
1365 case LDNS_RDF_TYPE_WKS:
1366 case LDNS_RDF_TYPE_SERVICE:
1367 res = ldns_rdf2buffer_str_wks(buffer, rdf);
1368 break;
1369 case LDNS_RDF_TYPE_NSAP:
1370 res = ldns_rdf2buffer_str_nsap(buffer, rdf);
1371 break;
1372 case LDNS_RDF_TYPE_ATMA:
1373 res = ldns_rdf2buffer_str_atma(buffer, rdf);
1374 break;
1375 case LDNS_RDF_TYPE_IPSECKEY:
1376 res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
1377 break;
1378 case LDNS_RDF_TYPE_INT16_DATA:
1379 res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
1380 break;
1381 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
1382 res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
1383 break;
1384 case LDNS_RDF_TYPE_ILNP64:
1385 res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
1386 break;
1387 case LDNS_RDF_TYPE_EUI48:
1388 res = ldns_rdf2buffer_str_eui48(buffer, rdf);
1389 break;
1390 case LDNS_RDF_TYPE_EUI64:
1391 res = ldns_rdf2buffer_str_eui64(buffer, rdf);
1392 break;
1393 case LDNS_RDF_TYPE_TAG:
1394 res = ldns_rdf2buffer_str_tag(buffer, rdf);
1395 break;
1396 case LDNS_RDF_TYPE_LONG_STR:
1397 res = ldns_rdf2buffer_str_long_str(buffer, rdf);
1398 break;
1399 }
1400 } else {
1401 /** This will write mangled RRs */
1402 ldns_buffer_printf(buffer, "(null) ");
1403 res = LDNS_STATUS_ERR;
1404 }
1405 return res;
1406 }
1407
1408 ldns_status
ldns_rdf2buffer_str(ldns_buffer * buffer,const ldns_rdf * rdf)1409 ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
1410 {
1411 return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
1412 }
1413
1414 static ldns_rdf *
ldns_b32_ext2dname(const ldns_rdf * rdf)1415 ldns_b32_ext2dname(const ldns_rdf *rdf)
1416 {
1417 size_t size;
1418 char *b32;
1419 ldns_rdf *out;
1420 if(ldns_rdf_size(rdf) == 0)
1421 return NULL;
1422 /* remove -1 for the b32-hash-len octet */
1423 size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
1424 /* add one for the end nul for the string */
1425 b32 = LDNS_XMALLOC(char, size + 2);
1426 if (b32) {
1427 if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
1428 ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
1429 b32[size] = '.';
1430 b32[size+1] = '\0';
1431 if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
1432 LDNS_FREE(b32);
1433 return out;
1434 }
1435 }
1436 LDNS_FREE(b32);
1437 }
1438 return NULL;
1439 }
1440
1441 static ldns_status
ldns_rr2buffer_str_rfc3597(ldns_buffer * output,const ldns_rr * rr)1442 ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
1443 {
1444 size_t total_rdfsize = 0;
1445 size_t i, j;
1446
1447 ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
1448 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1449 total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
1450 }
1451 if (total_rdfsize == 0) {
1452 ldns_buffer_printf(output, "\\# 0\n");
1453 return ldns_buffer_status(output);
1454 }
1455 ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
1456 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1457 for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
1458 ldns_buffer_printf(output, "%.2x",
1459 ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
1460 }
1461 }
1462 ldns_buffer_printf(output, "\n");
1463 return ldns_buffer_status(output);
1464 }
1465
1466 ldns_status
ldns_rr2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr * rr)1467 ldns_rr2buffer_str_fmt(ldns_buffer *output,
1468 const ldns_output_format *fmt, const ldns_rr *rr)
1469 {
1470 uint16_t i, flags;
1471 ldns_status status = LDNS_STATUS_OK;
1472 ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
1473
1474 if (fmt_st == NULL) {
1475 fmt_st = (ldns_output_format_storage*)
1476 ldns_output_format_default;
1477 }
1478 if (!rr) {
1479 if (LDNS_COMMENT_NULLS & fmt_st->flags) {
1480 ldns_buffer_printf(output, "; (null)\n");
1481 }
1482 return ldns_buffer_status(output);
1483 }
1484 if (ldns_rr_owner(rr)) {
1485 status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
1486 }
1487 if (status != LDNS_STATUS_OK) {
1488 return status;
1489 }
1490
1491 /* TTL should NOT be printed if it is a question */
1492 if (!ldns_rr_is_question(rr)) {
1493 ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
1494 }
1495
1496 ldns_buffer_printf(output, "\t");
1497 status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
1498 if (status != LDNS_STATUS_OK) {
1499 return status;
1500 }
1501 ldns_buffer_printf(output, "\t");
1502
1503 if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
1504 return ldns_rr2buffer_str_rfc3597(output, rr);
1505 }
1506 status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
1507 if (status != LDNS_STATUS_OK) {
1508 return status;
1509 }
1510
1511 if (ldns_rr_rd_count(rr) > 0) {
1512 ldns_buffer_printf(output, "\t");
1513 } else if (!ldns_rr_is_question(rr)) {
1514 ldns_buffer_printf(output, "\t\\# 0");
1515 }
1516
1517 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
1518 /* ldns_rdf2buffer_str handles NULL input fine! */
1519 if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
1520 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
1521 ((/* inception */ i == 4 &&
1522 ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
1523 LDNS_RDF_TYPE_TIME) ||
1524 (/* expiration */ i == 5 &&
1525 ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
1526 LDNS_RDF_TYPE_TIME) ||
1527 (/* signature */ i == 8 &&
1528 ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
1529 LDNS_RDF_TYPE_B64))) {
1530
1531 ldns_buffer_printf(output, "(null)");
1532 status = ldns_buffer_status(output);
1533 } else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
1534 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
1535 /* serial */ i == 2 &&
1536 ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
1537 LDNS_RDF_TYPE_INT32) {
1538 ldns_buffer_printf(output, "%10lu",
1539 (unsigned long) ldns_read_uint32(
1540 ldns_rdf_data(ldns_rr_rdf(rr, 2))));
1541 status = ldns_buffer_status(output);
1542 } else {
1543 status = ldns_rdf2buffer_str_fmt(output,
1544 fmt, ldns_rr_rdf(rr, i));
1545 }
1546 if(status != LDNS_STATUS_OK)
1547 return status;
1548 if (i < ldns_rr_rd_count(rr) - 1) {
1549 ldns_buffer_printf(output, " ");
1550 }
1551 }
1552 /* per RR special comments - handy for DNSSEC types */
1553 /* check to prevent question sec. rr from
1554 * getting here */
1555 if (ldns_rr_rd_count(rr) > 0) {
1556 switch (ldns_rr_get_type(rr)) {
1557 case LDNS_RR_TYPE_DNSKEY:
1558 /* if ldns_rr_rd_count(rr) > 0
1559 then ldns_rr_rdf(rr, 0) exists! */
1560 if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
1561 break;
1562 }
1563 flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
1564 ldns_buffer_printf(output, " ;{");
1565 if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
1566 ldns_buffer_printf(output, "id = %u",
1567 (unsigned int) ldns_calc_keytag(rr));
1568 }
1569 if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
1570 (flags & LDNS_KEY_ZONE_KEY)){
1571
1572 if (flags & LDNS_KEY_SEP_KEY) {
1573 ldns_buffer_printf(output, " (ksk)");
1574 } else {
1575 ldns_buffer_printf(output, " (zsk)");
1576 }
1577 if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
1578 ldns_buffer_printf(output, ", ");
1579 }
1580 } else if (fmt_st->flags
1581 & (LDNS_COMMENT_KEY_ID
1582 |LDNS_COMMENT_KEY_SIZE)) {
1583 ldns_buffer_printf( output, ", ");
1584 }
1585 if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
1586 ldns_buffer_printf(output, "size = %db",
1587 ldns_rr_dnskey_key_size(rr));
1588 }
1589 ldns_buffer_printf(output, "}");
1590 break;
1591 case LDNS_RR_TYPE_RRSIG:
1592 if ((fmt_st->flags & LDNS_COMMENT_KEY)
1593 && (fmt_st->flags& LDNS_COMMENT_RRSIGS)
1594 && ldns_rr_rdf(rr, 6) != NULL) {
1595 ldns_buffer_printf(output, " ;{id = %d}",
1596 ldns_rdf2native_int16(
1597 ldns_rr_rdf(rr, 6)));
1598 }
1599 break;
1600 case LDNS_RR_TYPE_DS:
1601 if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
1602 ldns_rr_rdf(rr, 3) != NULL) {
1603
1604 uint8_t *data = ldns_rdf_data(
1605 ldns_rr_rdf(rr, 3));
1606 size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
1607 char *babble = ldns_bubblebabble(data, len);
1608 if(babble) {
1609 ldns_buffer_printf(output,
1610 " ;{%s}", babble);
1611 }
1612 LDNS_FREE(babble);
1613 }
1614 break;
1615 case LDNS_RR_TYPE_NSEC3:
1616 if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
1617 ! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
1618 break;
1619 }
1620 ldns_buffer_printf(output, " ;{");
1621 if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
1622 if (ldns_nsec3_optout(rr)) {
1623 ldns_buffer_printf(output,
1624 " flags: optout");
1625 } else {
1626 ldns_buffer_printf(output," flags: -");
1627 }
1628 if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1629 fmt_st->hashmap != NULL) {
1630 ldns_buffer_printf(output, ", ");
1631 }
1632 }
1633 if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
1634 fmt_st->hashmap != NULL) {
1635 ldns_rbnode_t *node;
1636 ldns_rdf *key = ldns_dname_label(
1637 ldns_rr_owner(rr), 0);
1638 if (key) {
1639 node = ldns_rbtree_search(
1640 fmt_st->hashmap,
1641 (void *) key);
1642 if (node->data) {
1643 ldns_buffer_printf(output,
1644 "from: ");
1645 (void) ldns_rdf2buffer_str(
1646 output,
1647 ldns_dnssec_name_name(
1648 (ldns_dnssec_name*)
1649 node->data
1650 ));
1651 }
1652 ldns_rdf_free(key);
1653 }
1654 key = ldns_b32_ext2dname(
1655 ldns_nsec3_next_owner(rr));
1656 if (key) {
1657 node = ldns_rbtree_search(
1658 fmt_st->hashmap,
1659 (void *) key);
1660 if (node->data) {
1661 ldns_buffer_printf(output,
1662 " to: ");
1663 (void) ldns_rdf2buffer_str(
1664 output,
1665 ldns_dnssec_name_name(
1666 (ldns_dnssec_name*)
1667 node->data
1668 ));
1669 }
1670 ldns_rdf_free(key);
1671 }
1672 }
1673 ldns_buffer_printf(output, "}");
1674 break;
1675 default:
1676 break;
1677
1678 }
1679 }
1680 /* last */
1681 ldns_buffer_printf(output, "\n");
1682 return ldns_buffer_status(output);
1683 }
1684
1685 ldns_status
ldns_rr2buffer_str(ldns_buffer * output,const ldns_rr * rr)1686 ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
1687 {
1688 return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
1689 }
1690
1691 ldns_status
ldns_rr_list2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_rr_list * list)1692 ldns_rr_list2buffer_str_fmt(ldns_buffer *output,
1693 const ldns_output_format *fmt, const ldns_rr_list *list)
1694 {
1695 uint16_t i;
1696
1697 for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
1698 (void) ldns_rr2buffer_str_fmt(output, fmt,
1699 ldns_rr_list_rr(list, i));
1700 }
1701 return ldns_buffer_status(output);
1702 }
1703
1704 ldns_status
ldns_rr_list2buffer_str(ldns_buffer * output,const ldns_rr_list * list)1705 ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
1706 {
1707 return ldns_rr_list2buffer_str_fmt(
1708 output, ldns_output_format_default, list);
1709 }
1710
1711 ldns_status
ldns_pktheader2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)1712 ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1713 {
1714 ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
1715 (int) ldns_pkt_get_opcode(pkt));
1716 ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
1717 (int) ldns_pkt_get_rcode(pkt));
1718
1719 ldns_buffer_printf(output, ";; ->>HEADER<<- ");
1720 if (opcode) {
1721 ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
1722 } else {
1723 ldns_buffer_printf(output, "opcode: ?? (%u), ",
1724 ldns_pkt_get_opcode(pkt));
1725 }
1726 if (rcode) {
1727 ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
1728 } else {
1729 ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
1730 }
1731 ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
1732 ldns_buffer_printf(output, ";; flags: ");
1733
1734 if (ldns_pkt_qr(pkt)) {
1735 ldns_buffer_printf(output, "qr ");
1736 }
1737 if (ldns_pkt_aa(pkt)) {
1738 ldns_buffer_printf(output, "aa ");
1739 }
1740 if (ldns_pkt_tc(pkt)) {
1741 ldns_buffer_printf(output, "tc ");
1742 }
1743 if (ldns_pkt_rd(pkt)) {
1744 ldns_buffer_printf(output, "rd ");
1745 }
1746 if (ldns_pkt_cd(pkt)) {
1747 ldns_buffer_printf(output, "cd ");
1748 }
1749 if (ldns_pkt_ra(pkt)) {
1750 ldns_buffer_printf(output, "ra ");
1751 }
1752 if (ldns_pkt_ad(pkt)) {
1753 ldns_buffer_printf(output, "ad ");
1754 }
1755 ldns_buffer_printf(output, "; ");
1756 ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
1757 ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
1758 ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
1759 ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
1760 return ldns_buffer_status(output);
1761 }
1762
1763 ldns_status
ldns_pkt2buffer_str_fmt(ldns_buffer * output,const ldns_output_format * fmt,const ldns_pkt * pkt)1764 ldns_pkt2buffer_str_fmt(ldns_buffer *output,
1765 const ldns_output_format *fmt, const ldns_pkt *pkt)
1766 {
1767 uint16_t i;
1768 ldns_status status = LDNS_STATUS_OK;
1769 char *tmp;
1770 struct timeval time;
1771 time_t time_tt;
1772
1773 if (!pkt) {
1774 ldns_buffer_printf(output, "null");
1775 return LDNS_STATUS_OK;
1776 }
1777
1778 if (ldns_buffer_status_ok(output)) {
1779 status = ldns_pktheader2buffer_str(output, pkt);
1780 if (status != LDNS_STATUS_OK) {
1781 return status;
1782 }
1783
1784 ldns_buffer_printf(output, "\n");
1785
1786 ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
1787
1788
1789 for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
1790 status = ldns_rr2buffer_str_fmt(output, fmt,
1791 ldns_rr_list_rr(
1792 ldns_pkt_question(pkt), i));
1793 if (status != LDNS_STATUS_OK) {
1794 return status;
1795 }
1796 }
1797 ldns_buffer_printf(output, "\n");
1798
1799 ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
1800 for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
1801 status = ldns_rr2buffer_str_fmt(output, fmt,
1802 ldns_rr_list_rr(
1803 ldns_pkt_answer(pkt), i));
1804 if (status != LDNS_STATUS_OK) {
1805 return status;
1806 }
1807
1808 }
1809 ldns_buffer_printf(output, "\n");
1810
1811 ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
1812
1813 for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
1814 status = ldns_rr2buffer_str_fmt(output, fmt,
1815 ldns_rr_list_rr(
1816 ldns_pkt_authority(pkt), i));
1817 if (status != LDNS_STATUS_OK) {
1818 return status;
1819 }
1820 }
1821 ldns_buffer_printf(output, "\n");
1822
1823 ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
1824 for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
1825 status = ldns_rr2buffer_str_fmt(output, fmt,
1826 ldns_rr_list_rr(
1827 ldns_pkt_additional(pkt), i));
1828 if (status != LDNS_STATUS_OK) {
1829 return status;
1830 }
1831
1832 }
1833 ldns_buffer_printf(output, "\n");
1834 /* add some futher fields */
1835 ldns_buffer_printf(output, ";; Query time: %d msec\n",
1836 ldns_pkt_querytime(pkt));
1837 if (ldns_pkt_edns(pkt)) {
1838 ldns_buffer_printf(output,
1839 ";; EDNS: version %u; flags:",
1840 ldns_pkt_edns_version(pkt));
1841 if (ldns_pkt_edns_do(pkt)) {
1842 ldns_buffer_printf(output, " do");
1843 }
1844 /* the extended rcode is the value set, shifted four bits,
1845 * and or'd with the original rcode */
1846 if (ldns_pkt_edns_extended_rcode(pkt)) {
1847 ldns_buffer_printf(output, " ; ext-rcode: %d",
1848 (ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
1849 }
1850 ldns_buffer_printf(output, " ; udp: %u\n",
1851 ldns_pkt_edns_udp_size(pkt));
1852
1853 if (ldns_pkt_edns_data(pkt)) {
1854 ldns_buffer_printf(output, ";; Data: ");
1855 (void)ldns_rdf2buffer_str(output,
1856 ldns_pkt_edns_data(pkt));
1857 ldns_buffer_printf(output, "\n");
1858 }
1859 }
1860 if (ldns_pkt_tsig(pkt)) {
1861 ldns_buffer_printf(output, ";; TSIG:\n;; ");
1862 (void) ldns_rr2buffer_str_fmt(
1863 output, fmt, ldns_pkt_tsig(pkt));
1864 ldns_buffer_printf(output, "\n");
1865 }
1866 if (ldns_pkt_answerfrom(pkt)) {
1867 tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
1868 ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
1869 LDNS_FREE(tmp);
1870 }
1871 time = ldns_pkt_timestamp(pkt);
1872 time_tt = (time_t)time.tv_sec;
1873 ldns_buffer_printf(output, ";; WHEN: %s",
1874 (char*)ctime(&time_tt));
1875
1876 ldns_buffer_printf(output, ";; MSG SIZE rcvd: %d\n",
1877 (int)ldns_pkt_size(pkt));
1878 } else {
1879 return ldns_buffer_status(output);
1880 }
1881 return status;
1882 }
1883
1884 ldns_status
ldns_pkt2buffer_str(ldns_buffer * output,const ldns_pkt * pkt)1885 ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
1886 {
1887 return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
1888 }
1889
1890
1891 #ifdef HAVE_SSL
1892 static ldns_status
ldns_hmac_key2buffer_str(ldns_buffer * output,const ldns_key * k)1893 ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1894 {
1895 ldns_status status;
1896 size_t i;
1897 ldns_rdf *b64_bignum;
1898
1899 ldns_buffer_printf(output, "Key: ");
1900
1901 i = ldns_key_hmac_size(k);
1902 b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
1903 status = ldns_rdf2buffer_str(output, b64_bignum);
1904 ldns_rdf_deep_free(b64_bignum);
1905 ldns_buffer_printf(output, "\n");
1906 return status;
1907 }
1908 #endif
1909
1910 #if defined(HAVE_SSL) && defined(USE_GOST)
1911 static ldns_status
ldns_gost_key2buffer_str(ldns_buffer * output,EVP_PKEY * p)1912 ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
1913 {
1914 unsigned char* pp = NULL;
1915 int ret;
1916 ldns_rdf *b64_bignum;
1917 ldns_status status;
1918
1919 ldns_buffer_printf(output, "GostAsn1: ");
1920
1921 ret = i2d_PrivateKey(p, &pp);
1922 b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
1923 status = ldns_rdf2buffer_str(output, b64_bignum);
1924
1925 ldns_rdf_deep_free(b64_bignum);
1926 OPENSSL_free(pp);
1927 ldns_buffer_printf(output, "\n");
1928 return status;
1929 }
1930 #endif
1931
1932 /** print one b64 encoded bignum to a line in the keybuffer */
1933 static int
ldns_print_bignum_b64_line(ldns_buffer * output,const char * label,const BIGNUM * num)1934 ldns_print_bignum_b64_line(ldns_buffer* output, const char* label, const BIGNUM* num)
1935 {
1936 unsigned char *bignumbuf = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1937 if(!bignumbuf) return 0;
1938
1939 ldns_buffer_printf(output, "%s: ", label);
1940 if(num) {
1941 ldns_rdf *b64_bignum = NULL;
1942 int i = BN_bn2bin(num, bignumbuf);
1943 if (i > LDNS_MAX_KEYLEN) {
1944 LDNS_FREE(bignumbuf);
1945 return 0;
1946 }
1947 b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)i, bignumbuf);
1948 if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
1949 ldns_rdf_deep_free(b64_bignum);
1950 LDNS_FREE(bignumbuf);
1951 return 0;
1952 }
1953 ldns_rdf_deep_free(b64_bignum);
1954 ldns_buffer_printf(output, "\n");
1955 } else {
1956 ldns_buffer_printf(output, "(Not available)\n");
1957 }
1958 LDNS_FREE(bignumbuf);
1959 return 1;
1960 }
1961
1962 ldns_status
ldns_key2buffer_str(ldns_buffer * output,const ldns_key * k)1963 ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
1964 {
1965 ldns_status status = LDNS_STATUS_OK;
1966 unsigned char *bignum;
1967 #ifdef HAVE_SSL
1968 RSA *rsa;
1969 DSA *dsa;
1970 #endif /* HAVE_SSL */
1971
1972 if (!k) {
1973 return LDNS_STATUS_ERR;
1974 }
1975
1976 bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1977 if (!bignum) {
1978 return LDNS_STATUS_ERR;
1979 }
1980
1981 if (ldns_buffer_status_ok(output)) {
1982 #ifdef HAVE_SSL
1983 switch(ldns_key_algorithm(k)) {
1984 case LDNS_SIGN_RSASHA1:
1985 case LDNS_SIGN_RSASHA1_NSEC3:
1986 case LDNS_SIGN_RSASHA256:
1987 case LDNS_SIGN_RSASHA512:
1988 case LDNS_SIGN_RSAMD5:
1989 /* copied by looking at dnssec-keygen output */
1990 /* header */
1991 rsa = ldns_key_rsa_key(k);
1992
1993 ldns_buffer_printf(output,"Private-key-format: v1.2\n");
1994 switch(ldns_key_algorithm(k)) {
1995 case LDNS_SIGN_RSAMD5:
1996 ldns_buffer_printf(output,
1997 "Algorithm: %u (RSA)\n",
1998 LDNS_RSAMD5);
1999 break;
2000 case LDNS_SIGN_RSASHA1:
2001 ldns_buffer_printf(output,
2002 "Algorithm: %u (RSASHA1)\n",
2003 LDNS_RSASHA1);
2004 break;
2005 case LDNS_SIGN_RSASHA1_NSEC3:
2006 ldns_buffer_printf(output,
2007 "Algorithm: %u (RSASHA1_NSEC3)\n",
2008 LDNS_RSASHA1_NSEC3);
2009 break;
2010 #ifdef USE_SHA2
2011 case LDNS_SIGN_RSASHA256:
2012 ldns_buffer_printf(output,
2013 "Algorithm: %u (RSASHA256)\n",
2014 LDNS_RSASHA256);
2015 break;
2016 case LDNS_SIGN_RSASHA512:
2017 ldns_buffer_printf(output,
2018 "Algorithm: %u (RSASHA512)\n",
2019 LDNS_RSASHA512);
2020 break;
2021 #endif
2022 default:
2023 #ifdef STDERR_MSGS
2024 fprintf(stderr, "Warning: unknown signature ");
2025 fprintf(stderr,
2026 "algorithm type %u\n",
2027 ldns_key_algorithm(k));
2028 #endif
2029 ldns_buffer_printf(output,
2030 "Algorithm: %u (Unknown)\n",
2031 ldns_key_algorithm(k));
2032 break;
2033 }
2034
2035 /* print to buf, convert to bin, convert to b64,
2036 * print to buf */
2037
2038 #ifndef S_SPLINT_S
2039 if(1) {
2040 const BIGNUM *n=NULL, *e=NULL, *d=NULL,
2041 *p=NULL, *q=NULL, *dmp1=NULL,
2042 *dmq1=NULL, *iqmp=NULL;
2043 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
2044 n = rsa->n;
2045 e = rsa->e;
2046 d = rsa->d;
2047 p = rsa->p;
2048 q = rsa->q;
2049 dmp1 = rsa->dmp1;
2050 dmq1 = rsa->dmq1;
2051 iqmp = rsa->iqmp;
2052 #else
2053 RSA_get0_key(rsa, &n, &e, &d);
2054 RSA_get0_factors(rsa, &p, &q);
2055 RSA_get0_crt_params(rsa, &dmp1,
2056 &dmq1, &iqmp);
2057 #endif
2058 if(!ldns_print_bignum_b64_line(output, "Modulus", n))
2059 goto error;
2060 if(!ldns_print_bignum_b64_line(output, "PublicExponent", e))
2061 goto error;
2062 if(!ldns_print_bignum_b64_line(output, "PrivateExponent", d))
2063 goto error;
2064 if(!ldns_print_bignum_b64_line(output, "Prime1", p))
2065 goto error;
2066 if(!ldns_print_bignum_b64_line(output, "Prime2", q))
2067 goto error;
2068 if(!ldns_print_bignum_b64_line(output, "Exponent1", dmp1))
2069 goto error;
2070 if(!ldns_print_bignum_b64_line(output, "Exponent2", dmq1))
2071 goto error;
2072 if(!ldns_print_bignum_b64_line(output, "Coefficient", iqmp))
2073 goto error;
2074 }
2075 #endif /* splint */
2076
2077 RSA_free(rsa);
2078 break;
2079 case LDNS_SIGN_DSA:
2080 case LDNS_SIGN_DSA_NSEC3:
2081 dsa = ldns_key_dsa_key(k);
2082
2083 ldns_buffer_printf(output,"Private-key-format: v1.2\n");
2084 if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
2085 ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
2086 } else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
2087 ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
2088 }
2089
2090 /* print to buf, convert to bin, convert to b64,
2091 * print to buf */
2092 if(1) {
2093 const BIGNUM *p=NULL, *q=NULL, *g=NULL,
2094 *priv_key=NULL, *pub_key=NULL;
2095 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
2096 #ifndef S_SPLINT_S
2097 p = dsa->p;
2098 q = dsa->q;
2099 g = dsa->g;
2100 priv_key = dsa->priv_key;
2101 pub_key = dsa->pub_key;
2102 #endif /* splint */
2103 #else
2104 DSA_get0_pqg(dsa, &p, &q, &g);
2105 DSA_get0_key(dsa, &pub_key, &priv_key);
2106 #endif
2107 if(!ldns_print_bignum_b64_line(output, "Prime(p)", p))
2108 goto error;
2109 if(!ldns_print_bignum_b64_line(output, "Subprime(q)", q))
2110 goto error;
2111 if(!ldns_print_bignum_b64_line(output, "Base(g)", g))
2112 goto error;
2113 if(!ldns_print_bignum_b64_line(output, "Private_value(x)", priv_key))
2114 goto error;
2115 if(!ldns_print_bignum_b64_line(output, "Public_value(y)", pub_key))
2116 goto error;
2117 }
2118 break;
2119 case LDNS_SIGN_ECC_GOST:
2120 /* no format defined, use blob */
2121 #if defined(HAVE_SSL) && defined(USE_GOST)
2122 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2123 ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
2124 status = ldns_gost_key2buffer_str(output,
2125 #ifndef S_SPLINT_S
2126 k->_key.key
2127 #else
2128 NULL
2129 #endif
2130 );
2131 #else
2132 goto error;
2133 #endif /* GOST */
2134 break;
2135 case LDNS_SIGN_ECDSAP256SHA256:
2136 case LDNS_SIGN_ECDSAP384SHA384:
2137 #ifdef USE_ECDSA
2138 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2139 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2140 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2141 #ifndef S_SPLINT_S
2142 ldns_buffer_printf(output, ")\n");
2143 if(k->_key.key) {
2144 EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2145 const BIGNUM* b = EC_KEY_get0_private_key(ec);
2146 if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2147 goto error;
2148 /* down reference count in EC_KEY
2149 * its still assigned to the PKEY */
2150 EC_KEY_free(ec);
2151 }
2152 #endif /* splint */
2153 #else
2154 goto error;
2155 #endif /* ECDSA */
2156 break;
2157 #ifdef USE_ED25519
2158 case LDNS_SIGN_ED25519:
2159 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2160 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2161 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2162 ldns_buffer_printf(output, ")\n");
2163 if(k->_key.key) {
2164 EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2165 const BIGNUM* b = EC_KEY_get0_private_key(ec);
2166 if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2167 goto error;
2168 /* down reference count in EC_KEY
2169 * its still assigned to the PKEY */
2170 EC_KEY_free(ec);
2171 }
2172 ldns_buffer_printf(output, "\n");
2173 break;
2174 #endif /* USE_ED25519 */
2175 #ifdef USE_ED448
2176 case LDNS_SIGN_ED448:
2177 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2178 ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
2179 status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
2180 ldns_buffer_printf(output, ")\n");
2181 if(k->_key.key) {
2182 EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2183 const BIGNUM* b = EC_KEY_get0_private_key(ec);
2184 if(!ldns_print_bignum_b64_line(output, "PrivateKey", b))
2185 goto error;
2186 /* down reference count in EC_KEY
2187 * its still assigned to the PKEY */
2188 EC_KEY_free(ec);
2189 }
2190 ldns_buffer_printf(output, "\n");
2191 break;
2192 #endif /* USE_ED448 */
2193 case LDNS_SIGN_HMACMD5:
2194 /* there's not much of a format defined for TSIG */
2195 /* It's just a binary blob, Same for all algorithms */
2196 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2197 ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
2198 status = ldns_hmac_key2buffer_str(output, k);
2199 break;
2200 case LDNS_SIGN_HMACSHA1:
2201 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2202 ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
2203 status = ldns_hmac_key2buffer_str(output, k);
2204 break;
2205 case LDNS_SIGN_HMACSHA224:
2206 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2207 ldns_buffer_printf(output, "Algorithm: 162 (HMAC_SHA224)\n");
2208 status = ldns_hmac_key2buffer_str(output, k);
2209 break;
2210 case LDNS_SIGN_HMACSHA256:
2211 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2212 ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
2213 status = ldns_hmac_key2buffer_str(output, k);
2214 break;
2215 case LDNS_SIGN_HMACSHA384:
2216 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2217 ldns_buffer_printf(output, "Algorithm: 164 (HMAC_SHA384)\n");
2218 status = ldns_hmac_key2buffer_str(output, k);
2219 break;
2220 case LDNS_SIGN_HMACSHA512:
2221 ldns_buffer_printf(output, "Private-key-format: v1.2\n");
2222 ldns_buffer_printf(output, "Algorithm: 165 (HMAC_SHA512)\n");
2223 status = ldns_hmac_key2buffer_str(output, k);
2224 break;
2225 }
2226 #endif /* HAVE_SSL */
2227 } else {
2228 LDNS_FREE(bignum);
2229 return ldns_buffer_status(output);
2230 }
2231 LDNS_FREE(bignum);
2232 return status;
2233
2234 #ifdef HAVE_SSL
2235 /* compiles warn the label isn't used */
2236 error:
2237 LDNS_FREE(bignum);
2238 return LDNS_STATUS_ERR;
2239 #endif /* HAVE_SSL */
2240
2241 }
2242
2243 /*
2244 * Zero terminate the buffer and copy data.
2245 */
2246 char *
ldns_buffer2str(ldns_buffer * buffer)2247 ldns_buffer2str(ldns_buffer *buffer)
2248 {
2249 char *str;
2250
2251 /* check if buffer ends with \0, if not, and
2252 if there is space, add it */
2253 if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
2254 if (!ldns_buffer_reserve(buffer, 1)) {
2255 return NULL;
2256 }
2257 ldns_buffer_write_u8(buffer, (uint8_t) '\0');
2258 if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
2259 return NULL;
2260 }
2261 }
2262
2263 str = strdup((const char *)ldns_buffer_begin(buffer));
2264 if(!str) {
2265 return NULL;
2266 }
2267 return str;
2268 }
2269
2270 /*
2271 * Zero terminate the buffer and export data.
2272 */
2273 char *
ldns_buffer_export2str(ldns_buffer * buffer)2274 ldns_buffer_export2str(ldns_buffer *buffer)
2275 {
2276 /* Append '\0' as string terminator */
2277 if (! ldns_buffer_reserve(buffer, 1)) {
2278 return NULL;
2279 }
2280 ldns_buffer_write_u8(buffer, 0);
2281
2282 /* reallocate memory to the size of the string and export */
2283 ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
2284 return ldns_buffer_export(buffer);
2285 }
2286
2287 char *
ldns_rdf2str(const ldns_rdf * rdf)2288 ldns_rdf2str(const ldns_rdf *rdf)
2289 {
2290 char *result = NULL;
2291 ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2292
2293 if (!tmp_buffer) {
2294 return NULL;
2295 }
2296 if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
2297 /* export and return string, destroy rest */
2298 result = ldns_buffer_export2str(tmp_buffer);
2299 }
2300 ldns_buffer_free(tmp_buffer);
2301 return result;
2302 }
2303
2304 char *
ldns_rr2str_fmt(const ldns_output_format * fmt,const ldns_rr * rr)2305 ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
2306 {
2307 char *result = NULL;
2308 ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2309
2310 if (!tmp_buffer) {
2311 return NULL;
2312 }
2313 if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
2314 == LDNS_STATUS_OK) {
2315 /* export and return string, destroy rest */
2316 result = ldns_buffer_export2str(tmp_buffer);
2317 }
2318 ldns_buffer_free(tmp_buffer);
2319 return result;
2320 }
2321
2322 char *
ldns_rr2str(const ldns_rr * rr)2323 ldns_rr2str(const ldns_rr *rr)
2324 {
2325 return ldns_rr2str_fmt(ldns_output_format_default, rr);
2326 }
2327
2328 char *
ldns_pkt2str_fmt(const ldns_output_format * fmt,const ldns_pkt * pkt)2329 ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
2330 {
2331 char *result = NULL;
2332 ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2333
2334 if (!tmp_buffer) {
2335 return NULL;
2336 }
2337 if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
2338 == LDNS_STATUS_OK) {
2339 /* export and return string, destroy rest */
2340 result = ldns_buffer_export2str(tmp_buffer);
2341 }
2342
2343 ldns_buffer_free(tmp_buffer);
2344 return result;
2345 }
2346
2347 char *
ldns_pkt2str(const ldns_pkt * pkt)2348 ldns_pkt2str(const ldns_pkt *pkt)
2349 {
2350 return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
2351 }
2352
2353 char *
ldns_key2str(const ldns_key * k)2354 ldns_key2str(const ldns_key *k)
2355 {
2356 char *result = NULL;
2357 ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2358
2359 if (!tmp_buffer) {
2360 return NULL;
2361 }
2362 if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
2363 /* export and return string, destroy rest */
2364 result = ldns_buffer_export2str(tmp_buffer);
2365 }
2366 ldns_buffer_free(tmp_buffer);
2367 return result;
2368 }
2369
2370 char *
ldns_rr_list2str_fmt(const ldns_output_format * fmt,const ldns_rr_list * list)2371 ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
2372 {
2373 char *result = NULL;
2374 ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2375
2376 if (!tmp_buffer) {
2377 return NULL;
2378 }
2379 if (list) {
2380 if (ldns_rr_list2buffer_str_fmt(
2381 tmp_buffer, fmt, list)
2382 == LDNS_STATUS_OK) {
2383 }
2384 } else {
2385 if (fmt == NULL) {
2386 fmt = ldns_output_format_default;
2387 }
2388 if (fmt->flags & LDNS_COMMENT_NULLS) {
2389 ldns_buffer_printf(tmp_buffer, "; (null)\n");
2390 }
2391 }
2392
2393 /* export and return string, destroy rest */
2394 result = ldns_buffer_export2str(tmp_buffer);
2395 ldns_buffer_free(tmp_buffer);
2396 return result;
2397 }
2398
2399 char *
ldns_rr_list2str(const ldns_rr_list * list)2400 ldns_rr_list2str(const ldns_rr_list *list)
2401 {
2402 return ldns_rr_list2str_fmt(ldns_output_format_default, list);
2403 }
2404
2405 void
ldns_rdf_print(FILE * output,const ldns_rdf * rdf)2406 ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
2407 {
2408 char *str = ldns_rdf2str(rdf);
2409 if (str) {
2410 fprintf(output, "%s", str);
2411 } else {
2412 fprintf(output, ";Unable to convert rdf to string\n");
2413 }
2414 LDNS_FREE(str);
2415 }
2416
2417 void
ldns_rr_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr * rr)2418 ldns_rr_print_fmt(FILE *output,
2419 const ldns_output_format *fmt, const ldns_rr *rr)
2420 {
2421 char *str = ldns_rr2str_fmt(fmt, rr);
2422 if (str) {
2423 fprintf(output, "%s", str);
2424 } else {
2425 fprintf(output, ";Unable to convert rr to string\n");
2426 }
2427 LDNS_FREE(str);
2428 }
2429
2430 void
ldns_rr_print(FILE * output,const ldns_rr * rr)2431 ldns_rr_print(FILE *output, const ldns_rr *rr)
2432 {
2433 ldns_rr_print_fmt(output, ldns_output_format_default, rr);
2434 }
2435
2436 void
ldns_pkt_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_pkt * pkt)2437 ldns_pkt_print_fmt(FILE *output,
2438 const ldns_output_format *fmt, const ldns_pkt *pkt)
2439 {
2440 char *str = ldns_pkt2str_fmt(fmt, pkt);
2441 if (str) {
2442 fprintf(output, "%s", str);
2443 } else {
2444 fprintf(output, ";Unable to convert packet to string\n");
2445 }
2446 LDNS_FREE(str);
2447 }
2448
2449 void
ldns_pkt_print(FILE * output,const ldns_pkt * pkt)2450 ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
2451 {
2452 ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
2453 }
2454
2455 void
ldns_rr_list_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_rr_list * lst)2456 ldns_rr_list_print_fmt(FILE *output,
2457 const ldns_output_format *fmt, const ldns_rr_list *lst)
2458 {
2459 size_t i;
2460 for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
2461 ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
2462 }
2463 }
2464
2465 void
ldns_rr_list_print(FILE * output,const ldns_rr_list * lst)2466 ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
2467 {
2468 ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
2469 }
2470
2471 void
ldns_resolver_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_resolver * r)2472 ldns_resolver_print_fmt(FILE *output,
2473 const ldns_output_format *fmt, const ldns_resolver *r)
2474 {
2475 uint16_t i;
2476 ldns_rdf **n;
2477 ldns_rdf **s;
2478 size_t *rtt;
2479 if (!r) {
2480 return;
2481 }
2482 n = ldns_resolver_nameservers(r);
2483 s = ldns_resolver_searchlist(r);
2484 rtt = ldns_resolver_rtt(r);
2485
2486 fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
2487 fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
2488 fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
2489
2490 fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
2491 fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
2492 fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
2493 fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
2494 fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
2495 fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
2496 fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
2497 fprintf(output, "random: %d\n", ldns_resolver_random(r));
2498 fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
2499 fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
2500 fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
2501 fprintf(output, "trust anchors (%d listed):\n",
2502 (int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
2503 ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
2504 fprintf(output, "tsig: %s %s\n",
2505 ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
2506 ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
2507 fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
2508
2509 fprintf(output, "default domain: ");
2510 ldns_rdf_print(output, ldns_resolver_domain(r));
2511 fprintf(output, "\n");
2512 fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
2513
2514 fprintf(output, "searchlist (%d listed):\n", (int)ldns_resolver_searchlist_count(r));
2515 for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
2516 fprintf(output, "\t");
2517 ldns_rdf_print(output, s[i]);
2518 fprintf(output, "\n");
2519 }
2520 fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
2521
2522 fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
2523 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
2524 fprintf(output, "\t");
2525 ldns_rdf_print(output, n[i]);
2526
2527 switch ((int)rtt[i]) {
2528 case LDNS_RESOLV_RTT_MIN:
2529 fprintf(output, " - reachable\n");
2530 break;
2531 case LDNS_RESOLV_RTT_INF:
2532 fprintf(output, " - unreachable\n");
2533 break;
2534 }
2535 }
2536 }
2537
2538 void
ldns_resolver_print(FILE * output,const ldns_resolver * r)2539 ldns_resolver_print(FILE *output, const ldns_resolver *r)
2540 {
2541 ldns_resolver_print_fmt(output, ldns_output_format_default, r);
2542 }
2543
2544 void
ldns_zone_print_fmt(FILE * output,const ldns_output_format * fmt,const ldns_zone * z)2545 ldns_zone_print_fmt(FILE *output,
2546 const ldns_output_format *fmt, const ldns_zone *z)
2547 {
2548 if(ldns_zone_soa(z))
2549 ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
2550 ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
2551 }
2552 void
ldns_zone_print(FILE * output,const ldns_zone * z)2553 ldns_zone_print(FILE *output, const ldns_zone *z)
2554 {
2555 ldns_zone_print_fmt(output, ldns_output_format_default, z);
2556 }
2557