xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/dns/rdata/generic/rt_21.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: rt_21.c,v 1.1 2024/02/18 20:57:44 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_RT_21_C
19 #define RDATA_GENERIC_RT_21_C
20 
21 #define RRTYPE_RT_ATTRIBUTES (0)
22 
23 static isc_result_t
fromtext_rt(ARGS_FROMTEXT)24 fromtext_rt(ARGS_FROMTEXT) {
25 	isc_token_t token;
26 	dns_name_t name;
27 	isc_buffer_t buffer;
28 	bool ok;
29 
30 	REQUIRE(type == dns_rdatatype_rt);
31 
32 	UNUSED(type);
33 	UNUSED(rdclass);
34 	UNUSED(callbacks);
35 
36 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
37 				      false));
38 	if (token.value.as_ulong > 0xffffU) {
39 		RETTOK(ISC_R_RANGE);
40 	}
41 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
42 
43 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
44 				      false));
45 
46 	dns_name_init(&name, NULL);
47 	buffer_fromregion(&buffer, &token.value.as_region);
48 	if (origin == NULL) {
49 		origin = dns_rootname;
50 	}
51 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
52 	ok = true;
53 	if ((options & DNS_RDATA_CHECKNAMES) != 0) {
54 		ok = dns_name_ishostname(&name, false);
55 	}
56 	if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
57 		RETTOK(DNS_R_BADNAME);
58 	}
59 	if (!ok && callbacks != NULL) {
60 		warn_badname(&name, lexer, callbacks);
61 	}
62 	return (ISC_R_SUCCESS);
63 }
64 
65 static isc_result_t
totext_rt(ARGS_TOTEXT)66 totext_rt(ARGS_TOTEXT) {
67 	isc_region_t region;
68 	dns_name_t name;
69 	dns_name_t prefix;
70 	bool sub;
71 	char buf[sizeof("64000")];
72 	unsigned short num;
73 
74 	REQUIRE(rdata->type == dns_rdatatype_rt);
75 	REQUIRE(rdata->length != 0);
76 
77 	dns_name_init(&name, NULL);
78 	dns_name_init(&prefix, NULL);
79 
80 	dns_rdata_toregion(rdata, &region);
81 	num = uint16_fromregion(&region);
82 	isc_region_consume(&region, 2);
83 	snprintf(buf, sizeof(buf), "%u", num);
84 	RETERR(str_totext(buf, target));
85 	RETERR(str_totext(" ", target));
86 	dns_name_fromregion(&name, &region);
87 	sub = name_prefix(&name, tctx->origin, &prefix);
88 	return (dns_name_totext(&prefix, sub, target));
89 }
90 
91 static isc_result_t
fromwire_rt(ARGS_FROMWIRE)92 fromwire_rt(ARGS_FROMWIRE) {
93 	dns_name_t name;
94 	isc_region_t sregion;
95 	isc_region_t tregion;
96 
97 	REQUIRE(type == dns_rdatatype_rt);
98 
99 	UNUSED(type);
100 	UNUSED(rdclass);
101 
102 	dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
103 
104 	dns_name_init(&name, NULL);
105 
106 	isc_buffer_activeregion(source, &sregion);
107 	isc_buffer_availableregion(target, &tregion);
108 	if (tregion.length < 2) {
109 		return (ISC_R_NOSPACE);
110 	}
111 	if (sregion.length < 2) {
112 		return (ISC_R_UNEXPECTEDEND);
113 	}
114 	memmove(tregion.base, sregion.base, 2);
115 	isc_buffer_forward(source, 2);
116 	isc_buffer_add(target, 2);
117 	return (dns_name_fromwire(&name, source, dctx, options, target));
118 }
119 
120 static isc_result_t
towire_rt(ARGS_TOWIRE)121 towire_rt(ARGS_TOWIRE) {
122 	dns_name_t name;
123 	dns_offsets_t offsets;
124 	isc_region_t region;
125 	isc_region_t tr;
126 
127 	REQUIRE(rdata->type == dns_rdatatype_rt);
128 	REQUIRE(rdata->length != 0);
129 
130 	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
131 	isc_buffer_availableregion(target, &tr);
132 	dns_rdata_toregion(rdata, &region);
133 	if (tr.length < 2) {
134 		return (ISC_R_NOSPACE);
135 	}
136 	memmove(tr.base, region.base, 2);
137 	isc_region_consume(&region, 2);
138 	isc_buffer_add(target, 2);
139 
140 	dns_name_init(&name, offsets);
141 	dns_name_fromregion(&name, &region);
142 
143 	return (dns_name_towire(&name, cctx, target));
144 }
145 
146 static int
compare_rt(ARGS_COMPARE)147 compare_rt(ARGS_COMPARE) {
148 	dns_name_t name1;
149 	dns_name_t name2;
150 	isc_region_t region1;
151 	isc_region_t region2;
152 	int order;
153 
154 	REQUIRE(rdata1->type == rdata2->type);
155 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
156 	REQUIRE(rdata1->type == dns_rdatatype_rt);
157 	REQUIRE(rdata1->length != 0);
158 	REQUIRE(rdata2->length != 0);
159 
160 	order = memcmp(rdata1->data, rdata2->data, 2);
161 	if (order != 0) {
162 		return (order < 0 ? -1 : 1);
163 	}
164 
165 	dns_name_init(&name1, NULL);
166 	dns_name_init(&name2, NULL);
167 
168 	dns_rdata_toregion(rdata1, &region1);
169 	dns_rdata_toregion(rdata2, &region2);
170 
171 	isc_region_consume(&region1, 2);
172 	isc_region_consume(&region2, 2);
173 
174 	dns_name_fromregion(&name1, &region1);
175 	dns_name_fromregion(&name2, &region2);
176 
177 	return (dns_name_rdatacompare(&name1, &name2));
178 }
179 
180 static isc_result_t
fromstruct_rt(ARGS_FROMSTRUCT)181 fromstruct_rt(ARGS_FROMSTRUCT) {
182 	dns_rdata_rt_t *rt = source;
183 	isc_region_t region;
184 
185 	REQUIRE(type == dns_rdatatype_rt);
186 	REQUIRE(rt != NULL);
187 	REQUIRE(rt->common.rdtype == type);
188 	REQUIRE(rt->common.rdclass == rdclass);
189 
190 	UNUSED(type);
191 	UNUSED(rdclass);
192 
193 	RETERR(uint16_tobuffer(rt->preference, target));
194 	dns_name_toregion(&rt->host, &region);
195 	return (isc_buffer_copyregion(target, &region));
196 }
197 
198 static isc_result_t
tostruct_rt(ARGS_TOSTRUCT)199 tostruct_rt(ARGS_TOSTRUCT) {
200 	isc_region_t region;
201 	dns_rdata_rt_t *rt = target;
202 	dns_name_t name;
203 
204 	REQUIRE(rdata->type == dns_rdatatype_rt);
205 	REQUIRE(rt != NULL);
206 	REQUIRE(rdata->length != 0);
207 
208 	rt->common.rdclass = rdata->rdclass;
209 	rt->common.rdtype = rdata->type;
210 	ISC_LINK_INIT(&rt->common, link);
211 
212 	dns_name_init(&name, NULL);
213 	dns_rdata_toregion(rdata, &region);
214 	rt->preference = uint16_fromregion(&region);
215 	isc_region_consume(&region, 2);
216 	dns_name_fromregion(&name, &region);
217 	dns_name_init(&rt->host, NULL);
218 	RETERR(name_duporclone(&name, mctx, &rt->host));
219 
220 	rt->mctx = mctx;
221 	return (ISC_R_SUCCESS);
222 }
223 
224 static void
freestruct_rt(ARGS_FREESTRUCT)225 freestruct_rt(ARGS_FREESTRUCT) {
226 	dns_rdata_rt_t *rt = source;
227 
228 	REQUIRE(rt != NULL);
229 	REQUIRE(rt->common.rdtype == dns_rdatatype_rt);
230 
231 	if (rt->mctx == NULL) {
232 		return;
233 	}
234 
235 	dns_name_free(&rt->host, rt->mctx);
236 	rt->mctx = NULL;
237 }
238 
239 static isc_result_t
additionaldata_rt(ARGS_ADDLDATA)240 additionaldata_rt(ARGS_ADDLDATA) {
241 	dns_name_t name;
242 	dns_offsets_t offsets;
243 	isc_region_t region;
244 	isc_result_t result;
245 
246 	REQUIRE(rdata->type == dns_rdatatype_rt);
247 
248 	dns_name_init(&name, offsets);
249 	dns_rdata_toregion(rdata, &region);
250 	isc_region_consume(&region, 2);
251 	dns_name_fromregion(&name, &region);
252 
253 	result = (add)(arg, &name, dns_rdatatype_x25);
254 	if (result != ISC_R_SUCCESS) {
255 		return (result);
256 	}
257 	result = (add)(arg, &name, dns_rdatatype_isdn);
258 	if (result != ISC_R_SUCCESS) {
259 		return (result);
260 	}
261 	return ((add)(arg, &name, dns_rdatatype_a));
262 }
263 
264 static isc_result_t
digest_rt(ARGS_DIGEST)265 digest_rt(ARGS_DIGEST) {
266 	isc_region_t r1, r2;
267 	isc_result_t result;
268 	dns_name_t name;
269 
270 	REQUIRE(rdata->type == dns_rdatatype_rt);
271 
272 	dns_rdata_toregion(rdata, &r1);
273 	r2 = r1;
274 	isc_region_consume(&r2, 2);
275 	r1.length = 2;
276 	result = (digest)(arg, &r1);
277 	if (result != ISC_R_SUCCESS) {
278 		return (result);
279 	}
280 	dns_name_init(&name, NULL);
281 	dns_name_fromregion(&name, &r2);
282 	return (dns_name_digest(&name, digest, arg));
283 }
284 
285 static bool
checkowner_rt(ARGS_CHECKOWNER)286 checkowner_rt(ARGS_CHECKOWNER) {
287 	REQUIRE(type == dns_rdatatype_rt);
288 
289 	UNUSED(name);
290 	UNUSED(type);
291 	UNUSED(rdclass);
292 	UNUSED(wildcard);
293 
294 	return (true);
295 }
296 
297 static bool
checknames_rt(ARGS_CHECKNAMES)298 checknames_rt(ARGS_CHECKNAMES) {
299 	isc_region_t region;
300 	dns_name_t name;
301 
302 	REQUIRE(rdata->type == dns_rdatatype_rt);
303 
304 	UNUSED(owner);
305 
306 	dns_rdata_toregion(rdata, &region);
307 	isc_region_consume(&region, 2);
308 	dns_name_init(&name, NULL);
309 	dns_name_fromregion(&name, &region);
310 	if (!dns_name_ishostname(&name, false)) {
311 		if (bad != NULL) {
312 			dns_name_clone(&name, bad);
313 		}
314 		return (false);
315 	}
316 	return (true);
317 }
318 
319 static int
casecompare_rt(ARGS_COMPARE)320 casecompare_rt(ARGS_COMPARE) {
321 	return (compare_rt(rdata1, rdata2));
322 }
323 
324 #endif /* RDATA_GENERIC_RT_21_C */
325