1 /*
2 * rdata.c -- RDATA conversion functions.
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10 #include "config.h"
11
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
16 #include <ctype.h>
17 #include <netdb.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #ifdef HAVE_STRINGS_H
21 #include <strings.h>
22 #endif
23
24 #include "rdata.h"
25 #include "zonec.h"
26
27 /* Taken from RFC 4398, section 2.1. */
28 lookup_table_type dns_certificate_types[] = {
29 /* 0 Reserved */
30 { 1, "PKIX" }, /* X.509 as per PKIX */
31 { 2, "SPKI" }, /* SPKI cert */
32 { 3, "PGP" }, /* OpenPGP packet */
33 { 4, "IPKIX" }, /* The URL of an X.509 data object */
34 { 5, "ISPKI" }, /* The URL of an SPKI certificate */
35 { 6, "IPGP" }, /* The fingerprint and URL of an OpenPGP packet */
36 { 7, "ACPKIX" }, /* Attribute Certificate */
37 { 8, "IACPKIX" }, /* The URL of an Attribute Certificate */
38 { 253, "URI" }, /* URI private */
39 { 254, "OID" }, /* OID private */
40 /* 255 Reserved */
41 /* 256-65279 Available for IANA assignment */
42 /* 65280-65534 Experimental */
43 /* 65535 Reserved */
44 { 0, NULL }
45 };
46
47 /* Taken from RFC 2535, section 7. */
48 lookup_table_type dns_algorithms[] = {
49 { 1, "RSAMD5" }, /* RFC 2537 */
50 { 2, "DH" }, /* RFC 2539 */
51 { 3, "DSA" }, /* RFC 2536 */
52 { 4, "ECC" },
53 { 5, "RSASHA1" }, /* RFC 3110 */
54 { 6, "DSA-NSEC3-SHA1" }, /* RFC 5155 */
55 { 7, "RSASHA1-NSEC3-SHA1" }, /* RFC 5155 */
56 { 8, "RSASHA256" }, /* RFC 5702 */
57 { 10, "RSASHA512" }, /* RFC 5702 */
58 { 12, "ECC-GOST" }, /* RFC 5933 */
59 { 13, "ECDSAP256SHA256" }, /* RFC 6605 */
60 { 14, "ECDSAP384SHA384" }, /* RFC 6605 */
61 { 15, "ED25519" }, /* RFC 8080 */
62 { 16, "ED448" }, /* RFC 8080 */
63 { 252, "INDIRECT" },
64 { 253, "PRIVATEDNS" },
65 { 254, "PRIVATEOID" },
66 { 0, NULL }
67 };
68
69 const char *svcparamkey_strs[] = {
70 "mandatory", "alpn", "no-default-alpn", "port",
71 "ipv4hint", "ech", "ipv6hint", "dohpath"
72 };
73
74 typedef int (*rdata_to_string_type)(buffer_type *output,
75 rdata_atom_type rdata,
76 rr_type *rr);
77
78 static int
rdata_dname_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))79 rdata_dname_to_string(buffer_type *output, rdata_atom_type rdata,
80 rr_type* ATTR_UNUSED(rr))
81 {
82 buffer_printf(output,
83 "%s",
84 dname_to_string(domain_dname(rdata_atom_domain(rdata)),
85 NULL));
86 return 1;
87 }
88
89 static int
rdata_dns_name_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))90 rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata,
91 rr_type* ATTR_UNUSED(rr))
92 {
93 const uint8_t *data = rdata_atom_data(rdata);
94 size_t offset = 0;
95 uint8_t length = data[offset];
96 size_t i;
97
98 while (length > 0)
99 {
100 if (offset) /* concat label */
101 buffer_printf(output, ".");
102
103 for (i = 1; i <= length; ++i) {
104 uint8_t ch = data[i+offset];
105
106 if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') {
107 buffer_printf(output, "\\%c", (char) ch);
108 } else if (!isgraph((unsigned char) ch)) {
109 buffer_printf(output, "\\%03u", (unsigned int) ch);
110 } else if (isprint((unsigned char) ch)) {
111 buffer_printf(output, "%c", (char) ch);
112 } else {
113 buffer_printf(output, "\\%03u", (unsigned int) ch);
114 }
115 }
116 /* next label */
117 offset = offset+length+1;
118 length = data[offset];
119 }
120
121 /* root label */
122 buffer_printf(output, ".");
123 return 1;
124 }
125
126 static int
rdata_text_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))127 rdata_text_to_string(buffer_type *output, rdata_atom_type rdata,
128 rr_type* ATTR_UNUSED(rr))
129 {
130 const uint8_t *data = rdata_atom_data(rdata);
131 uint8_t length = data[0];
132 size_t i;
133
134 buffer_printf(output, "\"");
135 for (i = 1; i <= length; ++i) {
136 char ch = (char) data[i];
137 if (isprint((unsigned char)ch)) {
138 if (ch == '"' || ch == '\\') {
139 buffer_printf(output, "\\");
140 }
141 buffer_printf(output, "%c", ch);
142 } else {
143 buffer_printf(output, "\\%03u", (unsigned) data[i]);
144 }
145 }
146 buffer_printf(output, "\"");
147 return 1;
148 }
149
150 static int
rdata_texts_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))151 rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata,
152 rr_type* ATTR_UNUSED(rr))
153 {
154 uint16_t pos = 0;
155 const uint8_t *data = rdata_atom_data(rdata);
156 uint16_t length = rdata_atom_size(rdata);
157 size_t i;
158
159 while (pos < length && pos + data[pos] < length) {
160 buffer_printf(output, "\"");
161 for (i = 1; i <= data[pos]; ++i) {
162 char ch = (char) data[pos + i];
163 if (isprint((unsigned char)ch)) {
164 if (ch == '"' || ch == '\\') {
165 buffer_printf(output, "\\");
166 }
167 buffer_printf(output, "%c", ch);
168 } else {
169 buffer_printf(output, "\\%03u", (unsigned) data[pos+i]);
170 }
171 }
172 pos += data[pos]+1;
173 buffer_printf(output, pos < length?"\" ":"\"");
174 }
175 return 1;
176 }
177
178 static int
rdata_long_text_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))179 rdata_long_text_to_string(buffer_type *output, rdata_atom_type rdata,
180 rr_type* ATTR_UNUSED(rr))
181 {
182 const uint8_t *data = rdata_atom_data(rdata);
183 uint16_t length = rdata_atom_size(rdata);
184 size_t i;
185
186 buffer_printf(output, "\"");
187 for (i = 0; i < length; ++i) {
188 char ch = (char) data[i];
189 if (isprint((unsigned char)ch)) {
190 if (ch == '"' || ch == '\\') {
191 buffer_printf(output, "\\");
192 }
193 buffer_printf(output, "%c", ch);
194 } else {
195 buffer_printf(output, "\\%03u", (unsigned) data[i]);
196 }
197 }
198 buffer_printf(output, "\"");
199 return 1;
200 }
201
202 static int
rdata_tag_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))203 rdata_tag_to_string(buffer_type *output, rdata_atom_type rdata,
204 rr_type* ATTR_UNUSED(rr))
205 {
206 const uint8_t *data = rdata_atom_data(rdata);
207 uint8_t length = data[0];
208 size_t i;
209 for (i = 1; i <= length; ++i) {
210 char ch = (char) data[i];
211 if (isdigit((unsigned char)ch) || islower((unsigned char)ch))
212 buffer_printf(output, "%c", ch);
213 else return 0;
214 }
215 return 1;
216 }
217
218 static int
rdata_byte_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))219 rdata_byte_to_string(buffer_type *output, rdata_atom_type rdata,
220 rr_type* ATTR_UNUSED(rr))
221 {
222 uint8_t data = *rdata_atom_data(rdata);
223 buffer_printf(output, "%lu", (unsigned long) data);
224 return 1;
225 }
226
227 static int
rdata_short_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))228 rdata_short_to_string(buffer_type *output, rdata_atom_type rdata,
229 rr_type* ATTR_UNUSED(rr))
230 {
231 uint16_t data = read_uint16(rdata_atom_data(rdata));
232 buffer_printf(output, "%lu", (unsigned long) data);
233 return 1;
234 }
235
236 static int
rdata_long_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))237 rdata_long_to_string(buffer_type *output, rdata_atom_type rdata,
238 rr_type* ATTR_UNUSED(rr))
239 {
240 uint32_t data = read_uint32(rdata_atom_data(rdata));
241 buffer_printf(output, "%lu", (unsigned long) data);
242 return 1;
243 }
244
245 static int
rdata_a_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))246 rdata_a_to_string(buffer_type *output, rdata_atom_type rdata,
247 rr_type* ATTR_UNUSED(rr))
248 {
249 int result = 0;
250 char str[200];
251 if (inet_ntop(AF_INET, rdata_atom_data(rdata), str, sizeof(str))) {
252 buffer_printf(output, "%s", str);
253 result = 1;
254 }
255 return result;
256 }
257
258 static int
rdata_aaaa_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))259 rdata_aaaa_to_string(buffer_type *output, rdata_atom_type rdata,
260 rr_type* ATTR_UNUSED(rr))
261 {
262 int result = 0;
263 char str[200];
264 if (inet_ntop(AF_INET6, rdata_atom_data(rdata), str, sizeof(str))) {
265 buffer_printf(output, "%s", str);
266 result = 1;
267 }
268 return result;
269 }
270
271 static int
rdata_ilnp64_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))272 rdata_ilnp64_to_string(buffer_type *output, rdata_atom_type rdata,
273 rr_type* ATTR_UNUSED(rr))
274 {
275 uint8_t* data = rdata_atom_data(rdata);
276 uint16_t a1 = read_uint16(data);
277 uint16_t a2 = read_uint16(data+2);
278 uint16_t a3 = read_uint16(data+4);
279 uint16_t a4 = read_uint16(data+6);
280
281 buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4);
282 return 1;
283 }
284
285 static int
rdata_eui48_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))286 rdata_eui48_to_string(buffer_type *output, rdata_atom_type rdata,
287 rr_type* ATTR_UNUSED(rr))
288 {
289 uint8_t* data = rdata_atom_data(rdata);
290 uint8_t a1 = data[0];
291 uint8_t a2 = data[1];
292 uint8_t a3 = data[2];
293 uint8_t a4 = data[3];
294 uint8_t a5 = data[4];
295 uint8_t a6 = data[5];
296
297 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
298 a1, a2, a3, a4, a5, a6);
299 return 1;
300 }
301
302 static int
rdata_eui64_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))303 rdata_eui64_to_string(buffer_type *output, rdata_atom_type rdata,
304 rr_type* ATTR_UNUSED(rr))
305 {
306 uint8_t* data = rdata_atom_data(rdata);
307 uint8_t a1 = data[0];
308 uint8_t a2 = data[1];
309 uint8_t a3 = data[2];
310 uint8_t a4 = data[3];
311 uint8_t a5 = data[4];
312 uint8_t a6 = data[5];
313 uint8_t a7 = data[6];
314 uint8_t a8 = data[7];
315
316 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
317 a1, a2, a3, a4, a5, a6, a7, a8);
318 return 1;
319 }
320
321 static int
rdata_rrtype_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))322 rdata_rrtype_to_string(buffer_type *output, rdata_atom_type rdata,
323 rr_type* ATTR_UNUSED(rr))
324 {
325 uint16_t type = read_uint16(rdata_atom_data(rdata));
326 buffer_printf(output, "%s", rrtype_to_string(type));
327 return 1;
328 }
329
330 static int
rdata_algorithm_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))331 rdata_algorithm_to_string(buffer_type *output, rdata_atom_type rdata,
332 rr_type* ATTR_UNUSED(rr))
333 {
334 uint8_t id = *rdata_atom_data(rdata);
335 buffer_printf(output, "%u", (unsigned) id);
336 return 1;
337 }
338
339 static int
rdata_certificate_type_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))340 rdata_certificate_type_to_string(buffer_type *output, rdata_atom_type rdata,
341 rr_type* ATTR_UNUSED(rr))
342 {
343 uint16_t id = read_uint16(rdata_atom_data(rdata));
344 lookup_table_type *type
345 = lookup_by_id(dns_certificate_types, id);
346 if (type) {
347 buffer_printf(output, "%s", type->name);
348 } else {
349 buffer_printf(output, "%u", (unsigned) id);
350 }
351 return 1;
352 }
353
354 static int
rdata_period_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))355 rdata_period_to_string(buffer_type *output, rdata_atom_type rdata,
356 rr_type* ATTR_UNUSED(rr))
357 {
358 uint32_t period = read_uint32(rdata_atom_data(rdata));
359 buffer_printf(output, "%lu", (unsigned long) period);
360 return 1;
361 }
362
363 static int
rdata_time_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))364 rdata_time_to_string(buffer_type *output, rdata_atom_type rdata,
365 rr_type* ATTR_UNUSED(rr))
366 {
367 int result = 0;
368 time_t time = (time_t) read_uint32(rdata_atom_data(rdata));
369 struct tm *tm = gmtime(&time);
370 char buf[15];
371 if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm)) {
372 buffer_printf(output, "%s", buf);
373 result = 1;
374 }
375 return result;
376 }
377
378 static int
rdata_base32_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))379 rdata_base32_to_string(buffer_type *output, rdata_atom_type rdata,
380 rr_type* ATTR_UNUSED(rr))
381 {
382 int length;
383 size_t size = rdata_atom_size(rdata);
384 if(size == 0) {
385 buffer_write(output, "-", 1);
386 return 1;
387 }
388 size -= 1; /* remove length byte from count */
389 buffer_reserve(output, size * 2 + 1);
390 length = b32_ntop(rdata_atom_data(rdata)+1, size,
391 (char *) buffer_current(output), size * 2);
392 if (length > 0) {
393 buffer_skip(output, length);
394 }
395 return length != -1;
396 }
397
398 static int
rdata_base64_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))399 rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata,
400 rr_type* ATTR_UNUSED(rr))
401 {
402 int length;
403 size_t size = rdata_atom_size(rdata);
404 if(size == 0) {
405 /* single zero represents empty buffer */
406 buffer_write(output, "0", 1);
407 return 1;
408 }
409 buffer_reserve(output, size * 2 + 1);
410 length = __b64_ntop(rdata_atom_data(rdata), size,
411 (char *) buffer_current(output), size * 2);
412 if (length > 0) {
413 buffer_skip(output, length);
414 }
415 return length != -1;
416 }
417
418 static void
hex_to_string(buffer_type * output,const uint8_t * data,size_t size)419 hex_to_string(buffer_type *output, const uint8_t *data, size_t size)
420 {
421 static const char hexdigits[] = {
422 '0', '1', '2', '3', '4', '5', '6', '7',
423 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
424 };
425 size_t i;
426
427 buffer_reserve(output, size * 2);
428 for (i = 0; i < size; ++i) {
429 uint8_t octet = *data++;
430 buffer_write_u8(output, hexdigits[octet >> 4]);
431 buffer_write_u8(output, hexdigits[octet & 0x0f]);
432 }
433 }
434
435 static int
rdata_hex_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))436 rdata_hex_to_string(buffer_type *output, rdata_atom_type rdata,
437 rr_type* ATTR_UNUSED(rr))
438 {
439 if(rdata_atom_size(rdata) == 0) {
440 /* single zero represents empty buffer, such as CDS deletes */
441 buffer_printf(output, "0");
442 } else {
443 hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata));
444 }
445 return 1;
446 }
447
448 static int
rdata_hexlen_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))449 rdata_hexlen_to_string(buffer_type *output, rdata_atom_type rdata,
450 rr_type* ATTR_UNUSED(rr))
451 {
452 if(rdata_atom_size(rdata) <= 1) {
453 /* NSEC3 salt hex can be empty */
454 buffer_printf(output, "-");
455 return 1;
456 }
457 hex_to_string(output, rdata_atom_data(rdata)+1, rdata_atom_size(rdata)-1);
458 return 1;
459 }
460
461 static int
rdata_nsap_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))462 rdata_nsap_to_string(buffer_type *output, rdata_atom_type rdata,
463 rr_type* ATTR_UNUSED(rr))
464 {
465 buffer_printf(output, "0x");
466 hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata));
467 return 1;
468 }
469
470 static int
rdata_apl_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))471 rdata_apl_to_string(buffer_type *output, rdata_atom_type rdata,
472 rr_type* ATTR_UNUSED(rr))
473 {
474 int result = 0;
475 buffer_type packet;
476
477 buffer_create_from(
478 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
479
480 if (buffer_available(&packet, 4)) {
481 uint16_t address_family = buffer_read_u16(&packet);
482 uint8_t prefix = buffer_read_u8(&packet);
483 uint8_t length = buffer_read_u8(&packet);
484 int negated = length & APL_NEGATION_MASK;
485 int af = -1;
486
487 length &= APL_LENGTH_MASK;
488 switch (address_family) {
489 case 1: af = AF_INET; break;
490 case 2: af = AF_INET6; break;
491 }
492 if (af != -1 && buffer_available(&packet, length)) {
493 char text_address[1000];
494 uint8_t address[128];
495 memset(address, 0, sizeof(address));
496 buffer_read(&packet, address, length);
497 if (inet_ntop(af, address, text_address, sizeof(text_address))) {
498 buffer_printf(output, "%s%d:%s/%d",
499 negated ? "!" : "",
500 (int) address_family,
501 text_address,
502 (int) prefix);
503 result = 1;
504 }
505 }
506 }
507 return result;
508 }
509
510 static int
rdata_services_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))511 rdata_services_to_string(buffer_type *output, rdata_atom_type rdata,
512 rr_type* ATTR_UNUSED(rr))
513 {
514 int result = 0;
515 buffer_type packet;
516
517 buffer_create_from(
518 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
519
520 if (buffer_available(&packet, 1)) {
521 uint8_t protocol_number = buffer_read_u8(&packet);
522 ssize_t bitmap_size = buffer_remaining(&packet);
523 uint8_t *bitmap = buffer_current(&packet);
524 struct protoent *proto = getprotobynumber(protocol_number);
525
526 if (proto) {
527 int i;
528
529 buffer_printf(output, "%s", proto->p_name);
530
531 for (i = 0; i < bitmap_size * 8; ++i) {
532 if (get_bit(bitmap, i)) {
533 struct servent *service = getservbyport((int)htons(i), proto->p_name);
534 if (service) {
535 buffer_printf(output, " %s", service->s_name);
536 } else {
537 buffer_printf(output, " %d", i);
538 }
539 }
540 }
541 buffer_skip(&packet, bitmap_size);
542 result = 1;
543 }
544 }
545 return result;
546 }
547
548 static int
rdata_ipsecgateway_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * rr)549 rdata_ipsecgateway_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* rr)
550 {
551 int gateway_type = rdata_atom_data(rr->rdatas[1])[0];
552 switch(gateway_type) {
553 case IPSECKEY_NOGATEWAY:
554 buffer_printf(output, ".");
555 break;
556 case IPSECKEY_IP4:
557 rdata_a_to_string(output, rdata, rr);
558 break;
559 case IPSECKEY_IP6:
560 rdata_aaaa_to_string(output, rdata, rr);
561 break;
562 case IPSECKEY_DNAME:
563 {
564 region_type* temp = region_create(xalloc, free);
565 const dname_type* d = dname_make(temp,
566 rdata_atom_data(rdata), 0);
567 if(!d) {
568 region_destroy(temp);
569 return 0;
570 }
571 buffer_printf(output, "%s", dname_to_string(d, NULL));
572 region_destroy(temp);
573 }
574 break;
575 default:
576 return 0;
577 }
578 return 1;
579 }
580
581 static int
rdata_nxt_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))582 rdata_nxt_to_string(buffer_type *output, rdata_atom_type rdata,
583 rr_type* ATTR_UNUSED(rr))
584 {
585 size_t i;
586 uint8_t *bitmap = rdata_atom_data(rdata);
587 size_t bitmap_size = rdata_atom_size(rdata);
588
589 for (i = 0; i < bitmap_size * 8; ++i) {
590 if (get_bit(bitmap, i)) {
591 buffer_printf(output, "%s ", rrtype_to_string(i));
592 }
593 }
594
595 buffer_skip(output, -1);
596
597 return 1;
598 }
599
600 static int
rdata_nsec_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))601 rdata_nsec_to_string(buffer_type *output, rdata_atom_type rdata,
602 rr_type* ATTR_UNUSED(rr))
603 {
604 size_t saved_position = buffer_position(output);
605 buffer_type packet;
606 int insert_space = 0;
607
608 buffer_create_from(
609 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata));
610
611 while (buffer_available(&packet, 2)) {
612 uint8_t window = buffer_read_u8(&packet);
613 uint8_t bitmap_size = buffer_read_u8(&packet);
614 uint8_t *bitmap = buffer_current(&packet);
615 int i;
616
617 if (!buffer_available(&packet, bitmap_size)) {
618 buffer_set_position(output, saved_position);
619 return 0;
620 }
621
622 for (i = 0; i < bitmap_size * 8; ++i) {
623 if (get_bit(bitmap, i)) {
624 buffer_printf(output,
625 "%s%s",
626 insert_space ? " " : "",
627 rrtype_to_string(
628 window * 256 + i));
629 insert_space = 1;
630 }
631 }
632 buffer_skip(&packet, bitmap_size);
633 }
634
635 return 1;
636 }
637
638 static int
rdata_loc_to_string(buffer_type * ATTR_UNUSED (output),rdata_atom_type ATTR_UNUSED (rdata),rr_type * ATTR_UNUSED (rr))639 rdata_loc_to_string(buffer_type *ATTR_UNUSED(output),
640 rdata_atom_type ATTR_UNUSED(rdata),
641 rr_type* ATTR_UNUSED(rr))
642 {
643 /*
644 * Returning 0 forces the record to be printed in unknown
645 * format.
646 */
647 return 0;
648 }
649
650 static void
buffer_print_svcparamkey(buffer_type * output,uint16_t svcparamkey)651 buffer_print_svcparamkey(buffer_type *output, uint16_t svcparamkey)
652 {
653 if (svcparamkey < SVCPARAMKEY_COUNT)
654 buffer_printf(output, "%s", svcparamkey_strs[svcparamkey]);
655 else
656 buffer_printf(output, "key%d", (int)svcparamkey);
657 }
658
659 static int
rdata_svcparam_port_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)660 rdata_svcparam_port_to_string(buffer_type *output, uint16_t val_len,
661 uint16_t *data)
662 {
663 if (val_len != 2)
664 return 0; /* wireformat error, a short is 2 bytes */
665 buffer_printf(output, "=%d", (int)ntohs(data[0]));
666 return 1;
667 }
668
669 static int
rdata_svcparam_ipv4hint_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)670 rdata_svcparam_ipv4hint_to_string(buffer_type *output, uint16_t val_len,
671 uint16_t *data)
672 {
673 char ip_str[INET_ADDRSTRLEN + 1];
674
675 assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
676
677 if ((val_len % IP4ADDRLEN) == 0) {
678 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
679 return 0; /* wireformat error, incorrect size or inet family */
680
681 buffer_printf(output, "=%s", ip_str);
682 data += IP4ADDRLEN / sizeof(uint16_t);
683
684 while ((val_len -= IP4ADDRLEN) > 0) {
685 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
686 return 0; /* wireformat error, incorrect size or inet family */
687
688 buffer_printf(output, ",%s", ip_str);
689 data += IP4ADDRLEN / sizeof(uint16_t);
690 }
691 return 1;
692 } else
693 return 0;
694 }
695
696 static int
rdata_svcparam_ipv6hint_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)697 rdata_svcparam_ipv6hint_to_string(buffer_type *output, uint16_t val_len,
698 uint16_t *data)
699 {
700 char ip_str[INET6_ADDRSTRLEN + 1];
701
702 assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
703
704 if ((val_len % IP6ADDRLEN) == 0) {
705 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
706 return 0; /* wireformat error, incorrect size or inet family */
707
708 buffer_printf(output, "=%s", ip_str);
709 data += IP6ADDRLEN / sizeof(uint16_t);
710
711 while ((val_len -= IP6ADDRLEN) > 0) {
712 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
713 return 0; /* wireformat error, incorrect size or inet family */
714
715 buffer_printf(output, ",%s", ip_str);
716 data += IP6ADDRLEN / sizeof(uint16_t);
717 }
718 return 1;
719 } else
720 return 0;
721 }
722
723 static int
rdata_svcparam_mandatory_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)724 rdata_svcparam_mandatory_to_string(buffer_type *output, uint16_t val_len,
725 uint16_t *data)
726 {
727 assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
728
729 if (val_len % sizeof(uint16_t))
730 return 0; /* wireformat error, val_len must be multiple of shorts */
731 buffer_write_u8(output, '=');
732 buffer_print_svcparamkey(output, ntohs(*data));
733 data += 1;
734
735 while ((val_len -= sizeof(uint16_t))) {
736 buffer_write_u8(output, ',');
737 buffer_print_svcparamkey(output, ntohs(*data));
738 data += 1;
739 }
740
741 return 1;
742 }
743
744 static int
rdata_svcparam_ech_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)745 rdata_svcparam_ech_to_string(buffer_type *output, uint16_t val_len,
746 uint16_t *data)
747 {
748 int length;
749
750 assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
751
752 buffer_write_u8(output, '=');
753
754 buffer_reserve(output, val_len * 2 + 1);
755 length = __b64_ntop((uint8_t*) data, val_len,
756 (char *) buffer_current(output), val_len * 2);
757 if (length > 0) {
758 buffer_skip(output, length);
759 }
760
761 return length != -1;
762 }
763
764 static int
rdata_svcparam_alpn_to_string(buffer_type * output,uint16_t val_len,uint16_t * data)765 rdata_svcparam_alpn_to_string(buffer_type *output, uint16_t val_len,
766 uint16_t *data)
767 {
768 uint8_t *dp = (void *)data;
769
770 assert(val_len > 0); /* Guaranteed by rdata_svcparam_to_string */
771
772 buffer_write_u8(output, '=');
773 buffer_write_u8(output, '"');
774 while (val_len) {
775 uint8_t i, str_len = *dp++;
776
777 if (str_len > --val_len)
778 return 0;
779
780 for (i = 0; i < str_len; i++) {
781 if (dp[i] == '"' || dp[i] == '\\')
782 buffer_printf(output, "\\\\\\%c", dp[i]);
783
784 else if (dp[i] == ',')
785 buffer_printf(output, "\\\\%c", dp[i]);
786
787 else if (!isprint(dp[i]))
788 buffer_printf(output, "\\%03u", (unsigned) dp[i]);
789
790 else
791 buffer_write_u8(output, dp[i]);
792 }
793 dp += str_len;
794 if ((val_len -= str_len))
795 buffer_write_u8(output, ',');
796 }
797 buffer_write_u8(output, '"');
798 return 1;
799 }
800
801 static int
rdata_svcparam_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))802 rdata_svcparam_to_string(buffer_type *output, rdata_atom_type rdata,
803 rr_type* ATTR_UNUSED(rr))
804 {
805 uint16_t size = rdata_atom_size(rdata);
806 uint16_t* data = (uint16_t *)rdata_atom_data(rdata);
807 uint16_t svcparamkey, val_len;
808 uint8_t* dp;
809 size_t i;
810
811 if (size < 4)
812 return 0;
813 svcparamkey = ntohs(data[0]);
814
815 buffer_print_svcparamkey(output, svcparamkey);
816 val_len = ntohs(data[1]);
817 if (size != val_len + 4)
818 return 0; /* wireformat error */
819 if (!val_len) {
820 /* Some SvcParams MUST have values */
821 switch (svcparamkey) {
822 case SVCB_KEY_ALPN:
823 case SVCB_KEY_PORT:
824 case SVCB_KEY_IPV4HINT:
825 case SVCB_KEY_IPV6HINT:
826 case SVCB_KEY_MANDATORY:
827 case SVCB_KEY_DOHPATH:
828 return 0;
829 default:
830 return 1;
831 }
832 }
833 switch (svcparamkey) {
834 case SVCB_KEY_PORT:
835 return rdata_svcparam_port_to_string(output, val_len, data+2);
836 case SVCB_KEY_IPV4HINT:
837 return rdata_svcparam_ipv4hint_to_string(output, val_len, data+2);
838 case SVCB_KEY_IPV6HINT:
839 return rdata_svcparam_ipv6hint_to_string(output, val_len, data+2);
840 case SVCB_KEY_MANDATORY:
841 return rdata_svcparam_mandatory_to_string(output, val_len, data+2);
842 case SVCB_KEY_NO_DEFAULT_ALPN:
843 return 0; /* wireformat error, should not have a value */
844 case SVCB_KEY_ALPN:
845 return rdata_svcparam_alpn_to_string(output, val_len, data+2);
846 case SVCB_KEY_ECH:
847 return rdata_svcparam_ech_to_string(output, val_len, data+2);
848 case SVCB_KEY_DOHPATH:
849 /* fallthrough */
850 default:
851 buffer_write(output, "=\"", 2);
852 dp = (void*) (data + 2);
853
854 for (i = 0; i < val_len; i++) {
855 if (dp[i] == '"' || dp[i] == '\\')
856 buffer_printf(output, "\\%c", dp[i]);
857
858 else if (!isprint(dp[i]))
859 buffer_printf(output, "\\%03u", (unsigned) dp[i]);
860
861 else
862 buffer_write_u8(output, dp[i]);
863 }
864 buffer_write_u8(output, '"');
865 break;
866 }
867 return 1;
868 }
869
870 static int
rdata_unknown_to_string(buffer_type * output,rdata_atom_type rdata,rr_type * ATTR_UNUSED (rr))871 rdata_unknown_to_string(buffer_type *output, rdata_atom_type rdata,
872 rr_type* ATTR_UNUSED(rr))
873 {
874 uint16_t size = rdata_atom_size(rdata);
875 buffer_printf(output, "\\# %lu ", (unsigned long) size);
876 hex_to_string(output, rdata_atom_data(rdata), size);
877 return 1;
878 }
879
880 static rdata_to_string_type rdata_to_string_table[RDATA_ZF_UNKNOWN + 1] = {
881 rdata_dname_to_string,
882 rdata_dns_name_to_string,
883 rdata_text_to_string,
884 rdata_texts_to_string,
885 rdata_byte_to_string,
886 rdata_short_to_string,
887 rdata_long_to_string,
888 rdata_a_to_string,
889 rdata_aaaa_to_string,
890 rdata_rrtype_to_string,
891 rdata_algorithm_to_string,
892 rdata_certificate_type_to_string,
893 rdata_period_to_string,
894 rdata_time_to_string,
895 rdata_base64_to_string,
896 rdata_base32_to_string,
897 rdata_hex_to_string,
898 rdata_hexlen_to_string,
899 rdata_nsap_to_string,
900 rdata_apl_to_string,
901 rdata_ipsecgateway_to_string,
902 rdata_services_to_string,
903 rdata_nxt_to_string,
904 rdata_nsec_to_string,
905 rdata_loc_to_string,
906 rdata_ilnp64_to_string,
907 rdata_eui48_to_string,
908 rdata_eui64_to_string,
909 rdata_long_text_to_string,
910 rdata_tag_to_string,
911 rdata_svcparam_to_string,
912 rdata_unknown_to_string
913 };
914
915 int
rdata_atom_to_string(buffer_type * output,rdata_zoneformat_type type,rdata_atom_type rdata,rr_type * record)916 rdata_atom_to_string(buffer_type *output, rdata_zoneformat_type type,
917 rdata_atom_type rdata, rr_type* record)
918 {
919 return rdata_to_string_table[type](output, rdata, record);
920 }
921
922 ssize_t
rdata_wireformat_to_rdata_atoms(region_type * region,domain_table_type * owners,uint16_t rrtype,uint16_t data_size,buffer_type * packet,rdata_atom_type ** rdatas)923 rdata_wireformat_to_rdata_atoms(region_type *region,
924 domain_table_type *owners,
925 uint16_t rrtype,
926 uint16_t data_size,
927 buffer_type *packet,
928 rdata_atom_type **rdatas)
929 {
930 size_t end = buffer_position(packet) + data_size;
931 size_t i;
932 rdata_atom_type temp_rdatas[MAXRDATALEN];
933 rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype);
934 region_type *temp_region;
935
936 assert(descriptor->maximum <= MAXRDATALEN);
937
938 if (!buffer_available(packet, data_size)) {
939 return -1;
940 }
941
942 temp_region = region_create(xalloc, free);
943
944 for (i = 0; i < descriptor->maximum; ++i) {
945 int is_domain = 0;
946 int is_normalized = 0;
947 int is_wirestore = 0;
948 size_t length = 0;
949 int required = i < descriptor->minimum;
950
951 switch (rdata_atom_wireformat_type(rrtype, i)) {
952 case RDATA_WF_COMPRESSED_DNAME:
953 case RDATA_WF_UNCOMPRESSED_DNAME:
954 is_domain = 1;
955 is_normalized = 1;
956 break;
957 case RDATA_WF_LITERAL_DNAME:
958 is_domain = 1;
959 is_wirestore = 1;
960 break;
961 case RDATA_WF_BYTE:
962 length = sizeof(uint8_t);
963 break;
964 case RDATA_WF_SHORT:
965 length = sizeof(uint16_t);
966 break;
967 case RDATA_WF_LONG:
968 length = sizeof(uint32_t);
969 break;
970 case RDATA_WF_TEXTS:
971 case RDATA_WF_LONG_TEXT:
972 length = end - buffer_position(packet);
973 break;
974 case RDATA_WF_TEXT:
975 case RDATA_WF_BINARYWITHLENGTH:
976 /* Length is stored in the first byte. */
977 length = 1;
978 if (buffer_position(packet) + length <= end) {
979 length += buffer_current(packet)[length - 1];
980 }
981 break;
982 case RDATA_WF_A:
983 length = sizeof(in_addr_t);
984 break;
985 case RDATA_WF_AAAA:
986 length = IP6ADDRLEN;
987 break;
988 case RDATA_WF_ILNP64:
989 length = IP6ADDRLEN/2;
990 break;
991 case RDATA_WF_EUI48:
992 length = EUI48ADDRLEN;
993 break;
994 case RDATA_WF_EUI64:
995 length = EUI64ADDRLEN;
996 break;
997 case RDATA_WF_BINARY:
998 /* Remaining RDATA is binary. */
999 length = end - buffer_position(packet);
1000 break;
1001 case RDATA_WF_APL:
1002 length = (sizeof(uint16_t) /* address family */
1003 + sizeof(uint8_t) /* prefix */
1004 + sizeof(uint8_t)); /* length */
1005 if (buffer_position(packet) + length <= end) {
1006 /* Mask out negation bit. */
1007 length += (buffer_current(packet)[length - 1]
1008 & APL_LENGTH_MASK);
1009 }
1010 break;
1011 case RDATA_WF_IPSECGATEWAY:
1012 assert(i>1); /* we are past the gateway type */
1013 switch(rdata_atom_data(temp_rdatas[1])[0]) /* gateway type */ {
1014 default:
1015 case IPSECKEY_NOGATEWAY:
1016 length = 0;
1017 break;
1018 case IPSECKEY_IP4:
1019 length = IP4ADDRLEN;
1020 break;
1021 case IPSECKEY_IP6:
1022 length = IP6ADDRLEN;
1023 break;
1024 case IPSECKEY_DNAME:
1025 is_domain = 1;
1026 is_normalized = 1;
1027 is_wirestore = 1;
1028 break;
1029 }
1030 break;
1031 case RDATA_WF_SVCPARAM:
1032 length = 4;
1033 if (buffer_position(packet) + 4 <= end) {
1034 length +=
1035 read_uint16(buffer_current(packet) + 2);
1036 }
1037 break;
1038 }
1039
1040 if (is_domain) {
1041 const dname_type *dname;
1042
1043 if (!required && buffer_position(packet) == end) {
1044 break;
1045 }
1046
1047 dname = dname_make_from_packet(
1048 temp_region, packet, 1, is_normalized);
1049 if (!dname || buffer_position(packet) > end) {
1050 /* Error in domain name. */
1051 region_destroy(temp_region);
1052 return -1;
1053 }
1054 if(is_wirestore) {
1055 temp_rdatas[i].data = (uint16_t *) region_alloc(
1056 region, sizeof(uint16_t) + ((size_t)dname->name_size));
1057 temp_rdatas[i].data[0] = dname->name_size;
1058 memcpy(temp_rdatas[i].data+1, dname_name(dname),
1059 dname->name_size);
1060 } else {
1061 temp_rdatas[i].domain
1062 = domain_table_insert(owners, dname);
1063 temp_rdatas[i].domain->usage ++;
1064 }
1065 } else {
1066 if (buffer_position(packet) + length > end) {
1067 if (required) {
1068 /* Truncated RDATA. */
1069 region_destroy(temp_region);
1070 return -1;
1071 } else {
1072 break;
1073 }
1074 }
1075 if (!required && buffer_position(packet) == end) {
1076 break;
1077 }
1078
1079 temp_rdatas[i].data = (uint16_t *) region_alloc(
1080 region, sizeof(uint16_t) + length);
1081 temp_rdatas[i].data[0] = length;
1082 buffer_read(packet, temp_rdatas[i].data + 1, length);
1083 }
1084 }
1085
1086 if (buffer_position(packet) < end) {
1087 /* Trailing garbage. */
1088 region_destroy(temp_region);
1089 return -1;
1090 }
1091
1092 *rdatas = (rdata_atom_type *) region_alloc_array_init(
1093 region, temp_rdatas, i, sizeof(rdata_atom_type));
1094 region_destroy(temp_region);
1095 return (ssize_t)i;
1096 }
1097
1098 size_t
rdata_maximum_wireformat_size(rrtype_descriptor_type * descriptor,size_t rdata_count,rdata_atom_type * rdatas)1099 rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor,
1100 size_t rdata_count,
1101 rdata_atom_type *rdatas)
1102 {
1103 size_t result = 0;
1104 size_t i;
1105 for (i = 0; i < rdata_count; ++i) {
1106 if (rdata_atom_is_domain(descriptor->type, i)) {
1107 result += domain_dname(rdata_atom_domain(rdatas[i]))->name_size;
1108 } else {
1109 result += rdata_atom_size(rdatas[i]);
1110 }
1111 }
1112 return result;
1113 }
1114
1115 int
rdata_atoms_to_unknown_string(buffer_type * output,rrtype_descriptor_type * descriptor,size_t rdata_count,rdata_atom_type * rdatas)1116 rdata_atoms_to_unknown_string(buffer_type *output,
1117 rrtype_descriptor_type *descriptor,
1118 size_t rdata_count,
1119 rdata_atom_type *rdatas)
1120 {
1121 size_t i;
1122 size_t size =
1123 rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas);
1124 buffer_printf(output, " \\# %lu ", (unsigned long) size);
1125 for (i = 0; i < rdata_count; ++i) {
1126 if (rdata_atom_is_domain(descriptor->type, i)) {
1127 const dname_type *dname =
1128 domain_dname(rdata_atom_domain(rdatas[i]));
1129 hex_to_string(
1130 output, dname_name(dname), dname->name_size);
1131 } else {
1132 hex_to_string(output, rdata_atom_data(rdatas[i]),
1133 rdata_atom_size(rdatas[i]));
1134 }
1135 }
1136 return 1;
1137 }
1138
1139 int
print_rdata(buffer_type * output,rrtype_descriptor_type * descriptor,rr_type * record)1140 print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor,
1141 rr_type *record)
1142 {
1143 size_t i;
1144 size_t saved_position = buffer_position(output);
1145
1146 for (i = 0; i < record->rdata_count; ++i) {
1147 if (i == 0) {
1148 buffer_printf(output, "\t");
1149 } else if (descriptor->type == TYPE_SOA && i == 2) {
1150 buffer_printf(output, " (\n\t\t");
1151 } else {
1152 buffer_printf(output, " ");
1153 }
1154 if (!rdata_atom_to_string(
1155 output,
1156 (rdata_zoneformat_type) descriptor->zoneformat[i],
1157 record->rdatas[i], record))
1158 {
1159 buffer_set_position(output, saved_position);
1160 return 0;
1161 }
1162 }
1163 if (descriptor->type == TYPE_SOA) {
1164 buffer_printf(output, " )");
1165 }
1166
1167 return 1;
1168 }
1169
1170