xref: /netbsd-src/external/mpl/bind/dist/lib/dns/rdata/generic/uri_256.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: uri_256.c,v 1.9 2025/01/26 16:25:34 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 #ifndef GENERIC_URI_256_C
17 #define GENERIC_URI_256_C 1
18 
19 #define RRTYPE_URI_ATTRIBUTES (0)
20 
21 static isc_result_t
22 fromtext_uri(ARGS_FROMTEXT) {
23 	isc_token_t token;
24 
25 	REQUIRE(type == dns_rdatatype_uri);
26 
27 	UNUSED(type);
28 	UNUSED(rdclass);
29 	UNUSED(origin);
30 	UNUSED(options);
31 	UNUSED(callbacks);
32 
33 	/*
34 	 * Priority
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 	/*
44 	 * Weight
45 	 */
46 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
47 				      false));
48 	if (token.value.as_ulong > 0xffffU) {
49 		RETTOK(ISC_R_RANGE);
50 	}
51 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
52 
53 	/*
54 	 * Target URI
55 	 */
56 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
57 				      false));
58 	if (token.type != isc_tokentype_qstring) {
59 		RETTOK(DNS_R_SYNTAX);
60 	}
61 	RETTOK(multitxt_fromtext(&token.value.as_textregion, target));
62 	return ISC_R_SUCCESS;
63 }
64 
65 static isc_result_t
66 totext_uri(ARGS_TOTEXT) {
67 	isc_region_t region;
68 	unsigned short priority, weight;
69 	char buf[sizeof("65000 ")];
70 
71 	UNUSED(tctx);
72 
73 	REQUIRE(rdata->type == dns_rdatatype_uri);
74 	REQUIRE(rdata->length != 0);
75 
76 	dns_rdata_toregion(rdata, &region);
77 
78 	/*
79 	 * Priority
80 	 */
81 	priority = uint16_fromregion(&region);
82 	isc_region_consume(&region, 2);
83 	snprintf(buf, sizeof(buf), "%u ", priority);
84 	RETERR(str_totext(buf, target));
85 
86 	/*
87 	 * Weight
88 	 */
89 	weight = uint16_fromregion(&region);
90 	isc_region_consume(&region, 2);
91 	snprintf(buf, sizeof(buf), "%u ", weight);
92 	RETERR(str_totext(buf, target));
93 
94 	/*
95 	 * Target URI
96 	 */
97 	RETERR(multitxt_totext(&region, target));
98 	return ISC_R_SUCCESS;
99 }
100 
101 static isc_result_t
102 fromwire_uri(ARGS_FROMWIRE) {
103 	isc_region_t region;
104 
105 	REQUIRE(type == dns_rdatatype_uri);
106 
107 	UNUSED(type);
108 	UNUSED(rdclass);
109 	UNUSED(dctx);
110 
111 	/*
112 	 * Priority, weight
113 	 */
114 	isc_buffer_activeregion(source, &region);
115 	if (region.length < 4) {
116 		return ISC_R_UNEXPECTEDEND;
117 	}
118 
119 	/*
120 	 * Priority, weight and target URI
121 	 */
122 	isc_buffer_forward(source, region.length);
123 	return mem_tobuffer(target, region.base, region.length);
124 }
125 
126 static isc_result_t
127 towire_uri(ARGS_TOWIRE) {
128 	isc_region_t region;
129 
130 	REQUIRE(rdata->type == dns_rdatatype_uri);
131 	REQUIRE(rdata->length != 0);
132 
133 	UNUSED(cctx);
134 
135 	dns_rdata_toregion(rdata, &region);
136 	return mem_tobuffer(target, region.base, region.length);
137 }
138 
139 static int
140 compare_uri(ARGS_COMPARE) {
141 	isc_region_t r1;
142 	isc_region_t r2;
143 	int order;
144 
145 	REQUIRE(rdata1->type == rdata2->type);
146 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
147 	REQUIRE(rdata1->type == dns_rdatatype_uri);
148 	REQUIRE(rdata1->length != 0);
149 	REQUIRE(rdata2->length != 0);
150 
151 	dns_rdata_toregion(rdata1, &r1);
152 	dns_rdata_toregion(rdata2, &r2);
153 
154 	/*
155 	 * Priority
156 	 */
157 	order = memcmp(r1.base, r2.base, 2);
158 	if (order != 0) {
159 		return order < 0 ? -1 : 1;
160 	}
161 	isc_region_consume(&r1, 2);
162 	isc_region_consume(&r2, 2);
163 
164 	/*
165 	 * Weight
166 	 */
167 	order = memcmp(r1.base, r2.base, 2);
168 	if (order != 0) {
169 		return order < 0 ? -1 : 1;
170 	}
171 	isc_region_consume(&r1, 2);
172 	isc_region_consume(&r2, 2);
173 
174 	return isc_region_compare(&r1, &r2);
175 }
176 
177 static isc_result_t
178 fromstruct_uri(ARGS_FROMSTRUCT) {
179 	dns_rdata_uri_t *uri = source;
180 
181 	REQUIRE(type == dns_rdatatype_uri);
182 	REQUIRE(uri != NULL);
183 	REQUIRE(uri->common.rdtype == type);
184 	REQUIRE(uri->common.rdclass == rdclass);
185 	REQUIRE(uri->target != NULL && uri->tgt_len != 0);
186 
187 	UNUSED(type);
188 	UNUSED(rdclass);
189 
190 	/*
191 	 * Priority
192 	 */
193 	RETERR(uint16_tobuffer(uri->priority, target));
194 
195 	/*
196 	 * Weight
197 	 */
198 	RETERR(uint16_tobuffer(uri->weight, target));
199 
200 	/*
201 	 * Target URI
202 	 */
203 	return mem_tobuffer(target, uri->target, uri->tgt_len);
204 }
205 
206 static isc_result_t
207 tostruct_uri(ARGS_TOSTRUCT) {
208 	dns_rdata_uri_t *uri = target;
209 	isc_region_t sr;
210 
211 	REQUIRE(rdata->type == dns_rdatatype_uri);
212 	REQUIRE(uri != NULL);
213 	REQUIRE(rdata->length >= 4);
214 
215 	uri->common.rdclass = rdata->rdclass;
216 	uri->common.rdtype = rdata->type;
217 	ISC_LINK_INIT(&uri->common, link);
218 
219 	dns_rdata_toregion(rdata, &sr);
220 
221 	/*
222 	 * Priority
223 	 */
224 	uri->priority = uint16_fromregion(&sr);
225 	isc_region_consume(&sr, 2);
226 
227 	/*
228 	 * Weight
229 	 */
230 	uri->weight = uint16_fromregion(&sr);
231 	isc_region_consume(&sr, 2);
232 
233 	/*
234 	 * Target URI
235 	 */
236 	uri->tgt_len = sr.length;
237 	uri->target = mem_maybedup(mctx, sr.base, sr.length);
238 	uri->mctx = mctx;
239 	return ISC_R_SUCCESS;
240 }
241 
242 static void
243 freestruct_uri(ARGS_FREESTRUCT) {
244 	dns_rdata_uri_t *uri = (dns_rdata_uri_t *)source;
245 
246 	REQUIRE(uri != NULL);
247 	REQUIRE(uri->common.rdtype == dns_rdatatype_uri);
248 
249 	if (uri->mctx == NULL) {
250 		return;
251 	}
252 
253 	if (uri->target != NULL) {
254 		isc_mem_free(uri->mctx, uri->target);
255 	}
256 	uri->mctx = NULL;
257 }
258 
259 static isc_result_t
260 additionaldata_uri(ARGS_ADDLDATA) {
261 	REQUIRE(rdata->type == dns_rdatatype_uri);
262 
263 	UNUSED(rdata);
264 	UNUSED(owner);
265 	UNUSED(add);
266 	UNUSED(arg);
267 
268 	return ISC_R_SUCCESS;
269 }
270 
271 static isc_result_t
272 digest_uri(ARGS_DIGEST) {
273 	isc_region_t r;
274 
275 	REQUIRE(rdata->type == dns_rdatatype_uri);
276 
277 	dns_rdata_toregion(rdata, &r);
278 
279 	return (digest)(arg, &r);
280 }
281 
282 static bool
283 checkowner_uri(ARGS_CHECKOWNER) {
284 	REQUIRE(type == dns_rdatatype_uri);
285 
286 	UNUSED(name);
287 	UNUSED(type);
288 	UNUSED(rdclass);
289 	UNUSED(wildcard);
290 
291 	return true;
292 }
293 
294 static bool
295 checknames_uri(ARGS_CHECKNAMES) {
296 	REQUIRE(rdata->type == dns_rdatatype_uri);
297 
298 	UNUSED(rdata);
299 	UNUSED(owner);
300 	UNUSED(bad);
301 
302 	return true;
303 }
304 
305 static int
306 casecompare_uri(ARGS_COMPARE) {
307 	return compare_uri(rdata1, rdata2);
308 }
309 
310 #endif /* GENERIC_URI_256_C */
311