xref: /netbsd-src/external/ibm-public/postfix/dist/src/dns/dns_strrecord.c (revision c48c605c14fd8622b523d1d6a3f0c0bad133ea89)
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