xref: /netbsd-src/external/mpl/bind/dist/lib/dns/rdata/generic/rt_21.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: rt_21.c,v 1.9 2025/01/26 16:25:33 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
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
66 totext_rt(ARGS_TOTEXT) {
67 	isc_region_t region;
68 	dns_name_t name;
69 	dns_name_t prefix;
70 	unsigned int opts;
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 	opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
88 							 : 0;
89 	return dns_name_totext(&prefix, opts, target);
90 }
91 
92 static isc_result_t
93 fromwire_rt(ARGS_FROMWIRE) {
94 	dns_name_t name;
95 	isc_region_t sregion;
96 	isc_region_t tregion;
97 
98 	REQUIRE(type == dns_rdatatype_rt);
99 
100 	UNUSED(type);
101 	UNUSED(rdclass);
102 
103 	dctx = dns_decompress_setpermitted(dctx, false);
104 
105 	dns_name_init(&name, NULL);
106 
107 	isc_buffer_activeregion(source, &sregion);
108 	isc_buffer_availableregion(target, &tregion);
109 	if (tregion.length < 2) {
110 		return ISC_R_NOSPACE;
111 	}
112 	if (sregion.length < 2) {
113 		return ISC_R_UNEXPECTEDEND;
114 	}
115 	memmove(tregion.base, sregion.base, 2);
116 	isc_buffer_forward(source, 2);
117 	isc_buffer_add(target, 2);
118 	return dns_name_fromwire(&name, source, dctx, target);
119 }
120 
121 static isc_result_t
122 towire_rt(ARGS_TOWIRE) {
123 	dns_name_t name;
124 	dns_offsets_t offsets;
125 	isc_region_t region;
126 	isc_region_t tr;
127 
128 	REQUIRE(rdata->type == dns_rdatatype_rt);
129 	REQUIRE(rdata->length != 0);
130 
131 	dns_compress_setpermitted(cctx, false);
132 	isc_buffer_availableregion(target, &tr);
133 	dns_rdata_toregion(rdata, &region);
134 	if (tr.length < 2) {
135 		return ISC_R_NOSPACE;
136 	}
137 	memmove(tr.base, region.base, 2);
138 	isc_region_consume(&region, 2);
139 	isc_buffer_add(target, 2);
140 
141 	dns_name_init(&name, offsets);
142 	dns_name_fromregion(&name, &region);
143 
144 	return dns_name_towire(&name, cctx, target, NULL);
145 }
146 
147 static int
148 compare_rt(ARGS_COMPARE) {
149 	dns_name_t name1;
150 	dns_name_t name2;
151 	isc_region_t region1;
152 	isc_region_t region2;
153 	int order;
154 
155 	REQUIRE(rdata1->type == rdata2->type);
156 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
157 	REQUIRE(rdata1->type == dns_rdatatype_rt);
158 	REQUIRE(rdata1->length != 0);
159 	REQUIRE(rdata2->length != 0);
160 
161 	order = memcmp(rdata1->data, rdata2->data, 2);
162 	if (order != 0) {
163 		return order < 0 ? -1 : 1;
164 	}
165 
166 	dns_name_init(&name1, NULL);
167 	dns_name_init(&name2, NULL);
168 
169 	dns_rdata_toregion(rdata1, &region1);
170 	dns_rdata_toregion(rdata2, &region2);
171 
172 	isc_region_consume(&region1, 2);
173 	isc_region_consume(&region2, 2);
174 
175 	dns_name_fromregion(&name1, &region1);
176 	dns_name_fromregion(&name2, &region2);
177 
178 	return dns_name_rdatacompare(&name1, &name2);
179 }
180 
181 static isc_result_t
182 fromstruct_rt(ARGS_FROMSTRUCT) {
183 	dns_rdata_rt_t *rt = source;
184 	isc_region_t region;
185 
186 	REQUIRE(type == dns_rdatatype_rt);
187 	REQUIRE(rt != NULL);
188 	REQUIRE(rt->common.rdtype == type);
189 	REQUIRE(rt->common.rdclass == rdclass);
190 
191 	UNUSED(type);
192 	UNUSED(rdclass);
193 
194 	RETERR(uint16_tobuffer(rt->preference, target));
195 	dns_name_toregion(&rt->host, &region);
196 	return isc_buffer_copyregion(target, &region);
197 }
198 
199 static isc_result_t
200 tostruct_rt(ARGS_TOSTRUCT) {
201 	isc_region_t region;
202 	dns_rdata_rt_t *rt = target;
203 	dns_name_t name;
204 
205 	REQUIRE(rdata->type == dns_rdatatype_rt);
206 	REQUIRE(rt != NULL);
207 	REQUIRE(rdata->length != 0);
208 
209 	rt->common.rdclass = rdata->rdclass;
210 	rt->common.rdtype = rdata->type;
211 	ISC_LINK_INIT(&rt->common, link);
212 
213 	dns_name_init(&name, NULL);
214 	dns_rdata_toregion(rdata, &region);
215 	rt->preference = uint16_fromregion(&region);
216 	isc_region_consume(&region, 2);
217 	dns_name_fromregion(&name, &region);
218 	dns_name_init(&rt->host, NULL);
219 	name_duporclone(&name, mctx, &rt->host);
220 
221 	rt->mctx = mctx;
222 	return ISC_R_SUCCESS;
223 }
224 
225 static void
226 freestruct_rt(ARGS_FREESTRUCT) {
227 	dns_rdata_rt_t *rt = source;
228 
229 	REQUIRE(rt != NULL);
230 	REQUIRE(rt->common.rdtype == dns_rdatatype_rt);
231 
232 	if (rt->mctx == NULL) {
233 		return;
234 	}
235 
236 	dns_name_free(&rt->host, rt->mctx);
237 	rt->mctx = NULL;
238 }
239 
240 static isc_result_t
241 additionaldata_rt(ARGS_ADDLDATA) {
242 	dns_name_t name;
243 	dns_offsets_t offsets;
244 	isc_region_t region;
245 	isc_result_t result;
246 
247 	REQUIRE(rdata->type == dns_rdatatype_rt);
248 
249 	UNUSED(owner);
250 
251 	dns_name_init(&name, offsets);
252 	dns_rdata_toregion(rdata, &region);
253 	isc_region_consume(&region, 2);
254 	dns_name_fromregion(&name, &region);
255 
256 	result = (add)(arg, &name, dns_rdatatype_x25, NULL DNS__DB_FILELINE);
257 	if (result != ISC_R_SUCCESS) {
258 		return result;
259 	}
260 	result = (add)(arg, &name, dns_rdatatype_isdn, NULL DNS__DB_FILELINE);
261 	if (result != ISC_R_SUCCESS) {
262 		return result;
263 	}
264 	return (add)(arg, &name, dns_rdatatype_a, NULL DNS__DB_FILELINE);
265 }
266 
267 static isc_result_t
268 digest_rt(ARGS_DIGEST) {
269 	isc_region_t r1, r2;
270 	isc_result_t result;
271 	dns_name_t name;
272 
273 	REQUIRE(rdata->type == dns_rdatatype_rt);
274 
275 	dns_rdata_toregion(rdata, &r1);
276 	r2 = r1;
277 	isc_region_consume(&r2, 2);
278 	r1.length = 2;
279 	result = (digest)(arg, &r1);
280 	if (result != ISC_R_SUCCESS) {
281 		return result;
282 	}
283 	dns_name_init(&name, NULL);
284 	dns_name_fromregion(&name, &r2);
285 	return dns_name_digest(&name, digest, arg);
286 }
287 
288 static bool
289 checkowner_rt(ARGS_CHECKOWNER) {
290 	REQUIRE(type == dns_rdatatype_rt);
291 
292 	UNUSED(name);
293 	UNUSED(type);
294 	UNUSED(rdclass);
295 	UNUSED(wildcard);
296 
297 	return true;
298 }
299 
300 static bool
301 checknames_rt(ARGS_CHECKNAMES) {
302 	isc_region_t region;
303 	dns_name_t name;
304 
305 	REQUIRE(rdata->type == dns_rdatatype_rt);
306 
307 	UNUSED(owner);
308 
309 	dns_rdata_toregion(rdata, &region);
310 	isc_region_consume(&region, 2);
311 	dns_name_init(&name, NULL);
312 	dns_name_fromregion(&name, &region);
313 	if (!dns_name_ishostname(&name, false)) {
314 		if (bad != NULL) {
315 			dns_name_clone(&name, bad);
316 		}
317 		return false;
318 	}
319 	return true;
320 }
321 
322 static int
323 casecompare_rt(ARGS_COMPARE) {
324 	return compare_rt(rdata1, rdata2);
325 }
326 
327 #endif /* RDATA_GENERIC_RT_21_C */
328