1 /* $NetBSD: dns_strrecord.c,v 1.3 2023/12/23 20:30:43 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* dns_strrecord 3
6 /* SUMMARY
7 /* name service resource record printable forms
8 /* SYNOPSIS
9 /* #include <dns.h>
10 /*
11 /* char *dns_strrecord(buf, record)
12 /* VSTRING *buf;
13 /* DNS_RR *record;
14 /* DESCRIPTION
15 /* dns_strrecord() formats a DNS resource record as "name ttl
16 /* class type preference value", where the class field is
17 /* always "IN", the preference field exists only for MX records,
18 /* and all names end in ".". The result value is the payload
19 /* of the buffer argument.
20 /* LICENSE
21 /* .ad
22 /* .fi
23 /* The Secure Mailer license must be distributed with this software.
24 /* AUTHOR(S)
25 /* Wietse Venema
26 /* IBM T.J. Watson Research
27 /* P.O. Box 704
28 /* Yorktown Heights, NY 10598, USA
29 /*
30 /* Wietse Venema
31 /* Google, Inc.
32 /* 111 8th Avenue
33 /* New York, NY 10011, USA
34 /*--*/
35
36 /* System library. */
37
38 #include <sys_defs.h>
39 #include <string.h> /* memcpy */
40
41 /* Utility library. */
42
43 #include <vstring.h>
44 #include <msg.h>
45
46 /* DNS library. */
47
48 #include <dns.h>
49
50 /* dns_strrecord - format resource record as generic string */
51
dns_strrecord(VSTRING * buf,DNS_RR * rr)52 char *dns_strrecord(VSTRING *buf, DNS_RR *rr)
53 {
54 const char myname[] = "dns_strrecord";
55 MAI_HOSTADDR_STR host;
56 UINT32_TYPE soa_buf[5];
57
58 vstring_sprintf(buf, "%s. %u IN %s ",
59 rr->rname, rr->ttl, dns_strtype(rr->type));
60 switch (rr->type) {
61 case T_A:
62 #ifdef T_AAAA
63 case T_AAAA:
64 #endif
65 if (dns_rr_to_pa(rr, &host) == 0)
66 msg_fatal("%s: conversion error for resource record type %s: %m",
67 myname, dns_strtype(rr->type));
68 vstring_sprintf_append(buf, "%s", host.buf);
69 break;
70 case T_CNAME:
71 case T_DNAME:
72 case T_MB:
73 case T_MG:
74 case T_MR:
75 case T_NS:
76 case T_PTR:
77 vstring_sprintf_append(buf, "%s.", rr->data);
78 break;
79 case T_TXT:
80 vstring_sprintf_append(buf, "%s", rr->data);
81 break;
82 case T_MX:
83 vstring_sprintf_append(buf, "%u %s.", rr->pref, rr->data);
84 break;
85 case T_SRV:
86 vstring_sprintf_append(buf, "%u %u %u %s.", rr->pref, rr->weight,
87 rr->port, rr->data);
88 break;
89 case T_TLSA:
90 if (rr->data_len >= 3) {
91 uint8_t *ip = (uint8_t *) rr->data;
92 uint8_t usage = *ip++;
93 uint8_t selector = *ip++;
94 uint8_t mtype = *ip++;
95 unsigned i;
96
97 /* /\.example\. \d+ IN TLSA \d+ \d+ \d+ [\da-f]*$/ IGNORE */
98 vstring_sprintf_append(buf, "%d %d %d ", usage, selector, mtype);
99 for (i = 3; i < rr->data_len; ++i)
100 vstring_sprintf_append(buf, "%02x", *ip++);
101 } else {
102 vstring_sprintf_append(buf, "[truncated record]");
103 }
104
105 /*
106 * We use the SOA record TTL to determine the negative reply TTL. We
107 * save the time fields in the SOA record for debugging, but for now
108 * we don't bother saving the source host and mailbox information, as
109 * that would require changes to the DNS_RR structure. See also code
110 * in dns_get_rr().
111 */
112 case T_SOA:
113 memcpy(soa_buf, rr->data, sizeof(soa_buf));
114 vstring_sprintf_append(buf, "- - %u %u %u %u %u",
115 soa_buf[0], soa_buf[1], soa_buf[2],
116 soa_buf[3], soa_buf[4]);
117 break;
118 default:
119 msg_fatal("%s: don't know how to print type %s",
120 myname, dns_strtype(rr->type));
121 }
122 return (vstring_str(buf));
123 }
124