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