]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/dns-type.c
Merge branch 'pr/980'
[thirdparty/systemd.git] / src / resolve / dns-type.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Zbigniew Jędrzejewski-Szmek
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sys/socket.h>
23
24 #include "dns-type.h"
25 #include "string-util.h"
26
27 typedef const struct {
28 uint16_t type;
29 const char *name;
30 } dns_type;
31
32 static const struct dns_type_name *
33 lookup_dns_type (register const char *str, register unsigned int len);
34
35 #include "dns_type-from-name.h"
36 #include "dns_type-to-name.h"
37
38 int dns_type_from_string(const char *s) {
39 const struct dns_type_name *sc;
40
41 assert(s);
42
43 sc = lookup_dns_type(s, strlen(s));
44 if (!sc)
45 return _DNS_TYPE_INVALID;
46
47 return sc->id;
48 }
49
50 bool dns_type_is_pseudo(uint16_t type) {
51
52 /* Checks whether the specified type is a "pseudo-type". What
53 * a "pseudo-type" precisely is, is defined only very weakly,
54 * but apparently entails all RR types that are not actually
55 * stored as RRs on the server and should hence also not be
56 * cached. We use this list primarily to validate NSEC type
57 * bitfields, and to verify what to cache. */
58
59 return IN_SET(type,
60 0, /* A Pseudo RR type, according to RFC 2931 */
61 DNS_TYPE_ANY,
62 DNS_TYPE_AXFR,
63 DNS_TYPE_IXFR,
64 DNS_TYPE_OPT,
65 DNS_TYPE_TSIG,
66 DNS_TYPE_TKEY
67 );
68 }
69
70 bool dns_class_is_pseudo(uint16_t class) {
71 return class == DNS_TYPE_ANY;
72 }
73
74 bool dns_type_is_valid_query(uint16_t type) {
75
76 /* The types valid as questions in packets */
77
78 return !IN_SET(type,
79 0,
80 DNS_TYPE_OPT,
81 DNS_TYPE_TSIG,
82 DNS_TYPE_TKEY,
83
84 /* RRSIG are technically valid as questions, but we refuse doing explicit queries for them, as
85 * they aren't really payload, but signatures for payload, and cannot be validated on their
86 * own. After all they are the signatures, and have no signatures of their own validating
87 * them. */
88 DNS_TYPE_RRSIG);
89 }
90
91 bool dns_type_is_valid_rr(uint16_t type) {
92
93 /* The types valid as RR in packets (but not necessarily
94 * stored on servers). */
95
96 return !IN_SET(type,
97 DNS_TYPE_ANY,
98 DNS_TYPE_AXFR,
99 DNS_TYPE_IXFR);
100 }
101
102 bool dns_class_is_valid_rr(uint16_t class) {
103 return class != DNS_CLASS_ANY;
104 }
105
106 bool dns_type_may_redirect(uint16_t type) {
107 /* The following record types should never be redirected using
108 * CNAME/DNAME RRs. See
109 * <https://tools.ietf.org/html/rfc4035#section-2.5>. */
110
111 if (dns_type_is_pseudo(type))
112 return false;
113
114 return !IN_SET(type,
115 DNS_TYPE_CNAME,
116 DNS_TYPE_DNAME,
117 DNS_TYPE_NSEC3,
118 DNS_TYPE_NSEC,
119 DNS_TYPE_RRSIG,
120 DNS_TYPE_NXT,
121 DNS_TYPE_SIG,
122 DNS_TYPE_KEY);
123 }
124
125 bool dns_type_may_wildcard(uint16_t type) {
126
127 /* The following records may not be expanded from wildcard RRsets */
128
129 if (dns_type_is_pseudo(type))
130 return false;
131
132 return !IN_SET(type,
133 DNS_TYPE_NSEC3,
134 DNS_TYPE_SOA,
135
136 /* Prohibited by https://tools.ietf.org/html/rfc4592#section-4.4 */
137 DNS_TYPE_DNAME);
138 }
139
140 bool dns_type_apex_only(uint16_t type) {
141
142 /* Returns true for all RR types that may only appear signed in a zone apex */
143
144 return IN_SET(type,
145 DNS_TYPE_SOA,
146 DNS_TYPE_NS, /* this one can appear elsewhere, too, but not signed */
147 DNS_TYPE_DNSKEY,
148 DNS_TYPE_NSEC3PARAM);
149 }
150
151 bool dns_type_is_dnssec(uint16_t type) {
152 return IN_SET(type,
153 DNS_TYPE_DS,
154 DNS_TYPE_DNSKEY,
155 DNS_TYPE_RRSIG,
156 DNS_TYPE_NSEC,
157 DNS_TYPE_NSEC3,
158 DNS_TYPE_NSEC3PARAM);
159 }
160
161 bool dns_type_is_obsolete(uint16_t type) {
162 return IN_SET(type,
163 /* Obsoleted by RFC 973 */
164 DNS_TYPE_MD,
165 DNS_TYPE_MF,
166 DNS_TYPE_MAILA,
167
168 /* Kinda obsoleted by RFC 2505 */
169 DNS_TYPE_MB,
170 DNS_TYPE_MG,
171 DNS_TYPE_MR,
172 DNS_TYPE_MINFO,
173 DNS_TYPE_MAILB,
174
175 /* RFC1127 kinda obsoleted this by recommending against its use */
176 DNS_TYPE_WKS,
177
178 /* Declared historical by RFC 6563 */
179 DNS_TYPE_A6,
180
181 /* Obsoleted by DNSSEC-bis */
182 DNS_TYPE_NXT,
183
184 /* RFC 1035 removed support for concepts that needed this from RFC 883 */
185 DNS_TYPE_NULL);
186 }
187
188 int dns_type_to_af(uint16_t t) {
189 switch (t) {
190
191 case DNS_TYPE_A:
192 return AF_INET;
193
194 case DNS_TYPE_AAAA:
195 return AF_INET6;
196
197 case DNS_TYPE_ANY:
198 return AF_UNSPEC;
199
200 default:
201 return -EINVAL;
202 }
203 }
204
205 const char *dns_class_to_string(uint16_t class) {
206
207 switch (class) {
208
209 case DNS_CLASS_IN:
210 return "IN";
211
212 case DNS_CLASS_ANY:
213 return "ANY";
214 }
215
216 return NULL;
217 }
218
219 int dns_class_from_string(const char *s) {
220
221 if (!s)
222 return _DNS_CLASS_INVALID;
223
224 if (strcaseeq(s, "IN"))
225 return DNS_CLASS_IN;
226 else if (strcaseeq(s, "ANY"))
227 return DNS_CLASS_ANY;
228
229 return _DNS_CLASS_INVALID;
230 }