1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * SPDX-License-Identifier: MPL-2.0
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 /* RFC1183 */
15
16 #ifndef RDATA_GENERIC_AFSDB_18_C
17 #define RDATA_GENERIC_AFSDB_18_C
18
19 #define RRTYPE_AFSDB_ATTRIBUTES (0)
20
21 static inline isc_result_t
fromtext_afsdb(ARGS_FROMTEXT)22 fromtext_afsdb(ARGS_FROMTEXT) {
23 isc_token_t token;
24 isc_buffer_t buffer;
25 dns_name_t name;
26 bool ok;
27
28 REQUIRE(type == dns_rdatatype_afsdb);
29
30 UNUSED(type);
31 UNUSED(rdclass);
32 UNUSED(callbacks);
33
34 /*
35 * Subtype.
36 */
37 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
38 false));
39 if (token.value.as_ulong > 0xffffU) {
40 RETTOK(ISC_R_RANGE);
41 }
42 RETERR(uint16_tobuffer(token.value.as_ulong, target));
43
44 /*
45 * Hostname.
46 */
47 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
48 false));
49 dns_name_init(&name, NULL);
50 buffer_fromregion(&buffer, &token.value.as_region);
51 if (origin == NULL) {
52 origin = dns_rootname;
53 }
54 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
55 ok = true;
56 if ((options & DNS_RDATA_CHECKNAMES) != 0) {
57 ok = dns_name_ishostname(&name, false);
58 }
59 if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
60 RETTOK(DNS_R_BADNAME);
61 }
62 if (!ok && callbacks != NULL) {
63 warn_badname(&name, lexer, callbacks);
64 }
65 return (ISC_R_SUCCESS);
66 }
67
68 static inline isc_result_t
totext_afsdb(ARGS_TOTEXT)69 totext_afsdb(ARGS_TOTEXT) {
70 dns_name_t name;
71 dns_name_t prefix;
72 isc_region_t region;
73 char buf[sizeof("64000 ")];
74 bool sub;
75 unsigned int num;
76
77 REQUIRE(rdata->type == dns_rdatatype_afsdb);
78 REQUIRE(rdata->length != 0);
79
80 dns_name_init(&name, NULL);
81 dns_name_init(&prefix, NULL);
82
83 dns_rdata_toregion(rdata, ®ion);
84 num = uint16_fromregion(®ion);
85 isc_region_consume(®ion, 2);
86 snprintf(buf, sizeof(buf), "%u ", num);
87 RETERR(str_totext(buf, target));
88 dns_name_fromregion(&name, ®ion);
89 sub = name_prefix(&name, tctx->origin, &prefix);
90 return (dns_name_totext(&prefix, sub, target));
91 }
92
93 static inline isc_result_t
fromwire_afsdb(ARGS_FROMWIRE)94 fromwire_afsdb(ARGS_FROMWIRE) {
95 dns_name_t name;
96 isc_region_t sr;
97 isc_region_t tr;
98
99 REQUIRE(type == dns_rdatatype_afsdb);
100
101 UNUSED(type);
102 UNUSED(rdclass);
103
104 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
105
106 dns_name_init(&name, NULL);
107
108 isc_buffer_activeregion(source, &sr);
109 isc_buffer_availableregion(target, &tr);
110 if (tr.length < 2) {
111 return (ISC_R_NOSPACE);
112 }
113 if (sr.length < 2) {
114 return (ISC_R_UNEXPECTEDEND);
115 }
116 memmove(tr.base, sr.base, 2);
117 isc_buffer_forward(source, 2);
118 isc_buffer_add(target, 2);
119 return (dns_name_fromwire(&name, source, dctx, options, target));
120 }
121
122 static inline isc_result_t
towire_afsdb(ARGS_TOWIRE)123 towire_afsdb(ARGS_TOWIRE) {
124 isc_region_t tr;
125 isc_region_t sr;
126 dns_name_t name;
127 dns_offsets_t offsets;
128
129 REQUIRE(rdata->type == dns_rdatatype_afsdb);
130 REQUIRE(rdata->length != 0);
131
132 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
133 isc_buffer_availableregion(target, &tr);
134 dns_rdata_toregion(rdata, &sr);
135 if (tr.length < 2) {
136 return (ISC_R_NOSPACE);
137 }
138 memmove(tr.base, sr.base, 2);
139 isc_region_consume(&sr, 2);
140 isc_buffer_add(target, 2);
141
142 dns_name_init(&name, offsets);
143 dns_name_fromregion(&name, &sr);
144
145 return (dns_name_towire(&name, cctx, target));
146 }
147
148 static inline int
compare_afsdb(ARGS_COMPARE)149 compare_afsdb(ARGS_COMPARE) {
150 int result;
151 dns_name_t name1;
152 dns_name_t name2;
153 isc_region_t region1;
154 isc_region_t region2;
155
156 REQUIRE(rdata1->type == rdata2->type);
157 REQUIRE(rdata1->rdclass == rdata2->rdclass);
158 REQUIRE(rdata1->type == dns_rdatatype_afsdb);
159 REQUIRE(rdata1->length != 0);
160 REQUIRE(rdata2->length != 0);
161
162 result = memcmp(rdata1->data, rdata2->data, 2);
163 if (result != 0) {
164 return (result < 0 ? -1 : 1);
165 }
166
167 dns_name_init(&name1, NULL);
168 dns_name_init(&name2, NULL);
169
170 dns_rdata_toregion(rdata1, ®ion1);
171 dns_rdata_toregion(rdata2, ®ion2);
172
173 isc_region_consume(®ion1, 2);
174 isc_region_consume(®ion2, 2);
175
176 dns_name_fromregion(&name1, ®ion1);
177 dns_name_fromregion(&name2, ®ion2);
178
179 return (dns_name_rdatacompare(&name1, &name2));
180 }
181
182 static inline isc_result_t
fromstruct_afsdb(ARGS_FROMSTRUCT)183 fromstruct_afsdb(ARGS_FROMSTRUCT) {
184 dns_rdata_afsdb_t *afsdb = source;
185 isc_region_t region;
186
187 REQUIRE(type == dns_rdatatype_afsdb);
188 REQUIRE(afsdb != NULL);
189 REQUIRE(afsdb->common.rdclass == rdclass);
190 REQUIRE(afsdb->common.rdtype == type);
191
192 UNUSED(type);
193 UNUSED(rdclass);
194
195 RETERR(uint16_tobuffer(afsdb->subtype, target));
196 dns_name_toregion(&afsdb->server, ®ion);
197 return (isc_buffer_copyregion(target, ®ion));
198 }
199
200 static inline isc_result_t
tostruct_afsdb(ARGS_TOSTRUCT)201 tostruct_afsdb(ARGS_TOSTRUCT) {
202 isc_region_t region;
203 dns_rdata_afsdb_t *afsdb = target;
204 dns_name_t name;
205
206 REQUIRE(rdata->type == dns_rdatatype_afsdb);
207 REQUIRE(afsdb != NULL);
208 REQUIRE(rdata->length != 0);
209
210 afsdb->common.rdclass = rdata->rdclass;
211 afsdb->common.rdtype = rdata->type;
212 ISC_LINK_INIT(&afsdb->common, link);
213
214 dns_name_init(&afsdb->server, NULL);
215
216 dns_rdata_toregion(rdata, ®ion);
217
218 afsdb->subtype = uint16_fromregion(®ion);
219 isc_region_consume(®ion, 2);
220
221 dns_name_init(&name, NULL);
222 dns_name_fromregion(&name, ®ion);
223
224 RETERR(name_duporclone(&name, mctx, &afsdb->server));
225 afsdb->mctx = mctx;
226 return (ISC_R_SUCCESS);
227 }
228
229 static inline void
freestruct_afsdb(ARGS_FREESTRUCT)230 freestruct_afsdb(ARGS_FREESTRUCT) {
231 dns_rdata_afsdb_t *afsdb = source;
232
233 REQUIRE(afsdb != NULL);
234 REQUIRE(afsdb->common.rdtype == dns_rdatatype_afsdb);
235
236 if (afsdb->mctx == NULL) {
237 return;
238 }
239
240 dns_name_free(&afsdb->server, afsdb->mctx);
241 afsdb->mctx = NULL;
242 }
243
244 static inline isc_result_t
additionaldata_afsdb(ARGS_ADDLDATA)245 additionaldata_afsdb(ARGS_ADDLDATA) {
246 dns_name_t name;
247 dns_offsets_t offsets;
248 isc_region_t region;
249
250 REQUIRE(rdata->type == dns_rdatatype_afsdb);
251
252 dns_name_init(&name, offsets);
253 dns_rdata_toregion(rdata, ®ion);
254 isc_region_consume(®ion, 2);
255 dns_name_fromregion(&name, ®ion);
256
257 return ((add)(arg, &name, dns_rdatatype_a));
258 }
259
260 static inline isc_result_t
digest_afsdb(ARGS_DIGEST)261 digest_afsdb(ARGS_DIGEST) {
262 isc_region_t r1, r2;
263 dns_name_t name;
264
265 REQUIRE(rdata->type == dns_rdatatype_afsdb);
266
267 dns_rdata_toregion(rdata, &r1);
268 r2 = r1;
269 isc_region_consume(&r2, 2);
270 r1.length = 2;
271 RETERR((digest)(arg, &r1));
272 dns_name_init(&name, NULL);
273 dns_name_fromregion(&name, &r2);
274
275 return (dns_name_digest(&name, digest, arg));
276 }
277
278 static inline bool
checkowner_afsdb(ARGS_CHECKOWNER)279 checkowner_afsdb(ARGS_CHECKOWNER) {
280 REQUIRE(type == dns_rdatatype_afsdb);
281
282 UNUSED(name);
283 UNUSED(type);
284 UNUSED(rdclass);
285 UNUSED(wildcard);
286
287 return (true);
288 }
289
290 static inline bool
checknames_afsdb(ARGS_CHECKNAMES)291 checknames_afsdb(ARGS_CHECKNAMES) {
292 isc_region_t region;
293 dns_name_t name;
294
295 REQUIRE(rdata->type == dns_rdatatype_afsdb);
296
297 UNUSED(owner);
298
299 dns_rdata_toregion(rdata, ®ion);
300 isc_region_consume(®ion, 2);
301 dns_name_init(&name, NULL);
302 dns_name_fromregion(&name, ®ion);
303 if (!dns_name_ishostname(&name, false)) {
304 if (bad != NULL) {
305 dns_name_clone(&name, bad);
306 }
307 return (false);
308 }
309 return (true);
310 }
311
312 static inline int
casecompare_afsdb(ARGS_COMPARE)313 casecompare_afsdb(ARGS_COMPARE) {
314 return (compare_afsdb(rdata1, rdata2));
315 }
316 #endif /* RDATA_GENERIC_AFSDB_18_C */
317