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