1 /* $NetBSD: uri_256.c,v 1.1 2024/02/18 20:57:45 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
fromtext_uri(ARGS_FROMTEXT)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
totext_uri(ARGS_TOTEXT)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, ®ion);
77
78 /*
79 * Priority
80 */
81 priority = uint16_fromregion(®ion);
82 isc_region_consume(®ion, 2);
83 snprintf(buf, sizeof(buf), "%u ", priority);
84 RETERR(str_totext(buf, target));
85
86 /*
87 * Weight
88 */
89 weight = uint16_fromregion(®ion);
90 isc_region_consume(®ion, 2);
91 snprintf(buf, sizeof(buf), "%u ", weight);
92 RETERR(str_totext(buf, target));
93
94 /*
95 * Target URI
96 */
97 RETERR(multitxt_totext(®ion, target));
98 return (ISC_R_SUCCESS);
99 }
100
101 static isc_result_t
fromwire_uri(ARGS_FROMWIRE)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 UNUSED(options);
111
112 /*
113 * Priority, weight
114 */
115 isc_buffer_activeregion(source, ®ion);
116 if (region.length < 4) {
117 return (ISC_R_UNEXPECTEDEND);
118 }
119
120 /*
121 * Priority, weight and target URI
122 */
123 isc_buffer_forward(source, region.length);
124 return (mem_tobuffer(target, region.base, region.length));
125 }
126
127 static isc_result_t
towire_uri(ARGS_TOWIRE)128 towire_uri(ARGS_TOWIRE) {
129 isc_region_t region;
130
131 REQUIRE(rdata->type == dns_rdatatype_uri);
132 REQUIRE(rdata->length != 0);
133
134 UNUSED(cctx);
135
136 dns_rdata_toregion(rdata, ®ion);
137 return (mem_tobuffer(target, region.base, region.length));
138 }
139
140 static int
compare_uri(ARGS_COMPARE)141 compare_uri(ARGS_COMPARE) {
142 isc_region_t r1;
143 isc_region_t r2;
144 int order;
145
146 REQUIRE(rdata1->type == rdata2->type);
147 REQUIRE(rdata1->rdclass == rdata2->rdclass);
148 REQUIRE(rdata1->type == dns_rdatatype_uri);
149 REQUIRE(rdata1->length != 0);
150 REQUIRE(rdata2->length != 0);
151
152 dns_rdata_toregion(rdata1, &r1);
153 dns_rdata_toregion(rdata2, &r2);
154
155 /*
156 * Priority
157 */
158 order = memcmp(r1.base, r2.base, 2);
159 if (order != 0) {
160 return (order < 0 ? -1 : 1);
161 }
162 isc_region_consume(&r1, 2);
163 isc_region_consume(&r2, 2);
164
165 /*
166 * Weight
167 */
168 order = memcmp(r1.base, r2.base, 2);
169 if (order != 0) {
170 return (order < 0 ? -1 : 1);
171 }
172 isc_region_consume(&r1, 2);
173 isc_region_consume(&r2, 2);
174
175 return (isc_region_compare(&r1, &r2));
176 }
177
178 static isc_result_t
fromstruct_uri(ARGS_FROMSTRUCT)179 fromstruct_uri(ARGS_FROMSTRUCT) {
180 dns_rdata_uri_t *uri = source;
181
182 REQUIRE(type == dns_rdatatype_uri);
183 REQUIRE(uri != NULL);
184 REQUIRE(uri->common.rdtype == type);
185 REQUIRE(uri->common.rdclass == rdclass);
186 REQUIRE(uri->target != NULL && uri->tgt_len != 0);
187
188 UNUSED(type);
189 UNUSED(rdclass);
190
191 /*
192 * Priority
193 */
194 RETERR(uint16_tobuffer(uri->priority, target));
195
196 /*
197 * Weight
198 */
199 RETERR(uint16_tobuffer(uri->weight, target));
200
201 /*
202 * Target URI
203 */
204 return (mem_tobuffer(target, uri->target, uri->tgt_len));
205 }
206
207 static isc_result_t
tostruct_uri(ARGS_TOSTRUCT)208 tostruct_uri(ARGS_TOSTRUCT) {
209 dns_rdata_uri_t *uri = target;
210 isc_region_t sr;
211
212 REQUIRE(rdata->type == dns_rdatatype_uri);
213 REQUIRE(uri != NULL);
214 REQUIRE(rdata->length != 0);
215
216 uri->common.rdclass = rdata->rdclass;
217 uri->common.rdtype = rdata->type;
218 ISC_LINK_INIT(&uri->common, link);
219
220 dns_rdata_toregion(rdata, &sr);
221
222 /*
223 * Priority
224 */
225 if (sr.length < 2) {
226 return (ISC_R_UNEXPECTEDEND);
227 }
228 uri->priority = uint16_fromregion(&sr);
229 isc_region_consume(&sr, 2);
230
231 /*
232 * Weight
233 */
234 if (sr.length < 2) {
235 return (ISC_R_UNEXPECTEDEND);
236 }
237 uri->weight = uint16_fromregion(&sr);
238 isc_region_consume(&sr, 2);
239
240 /*
241 * Target URI
242 */
243 uri->tgt_len = sr.length;
244 uri->target = mem_maybedup(mctx, sr.base, sr.length);
245 if (uri->target == NULL) {
246 return (ISC_R_NOMEMORY);
247 }
248
249 uri->mctx = mctx;
250 return (ISC_R_SUCCESS);
251 }
252
253 static void
freestruct_uri(ARGS_FREESTRUCT)254 freestruct_uri(ARGS_FREESTRUCT) {
255 dns_rdata_uri_t *uri = (dns_rdata_uri_t *)source;
256
257 REQUIRE(uri != NULL);
258 REQUIRE(uri->common.rdtype == dns_rdatatype_uri);
259
260 if (uri->mctx == NULL) {
261 return;
262 }
263
264 if (uri->target != NULL) {
265 isc_mem_free(uri->mctx, uri->target);
266 }
267 uri->mctx = NULL;
268 }
269
270 static isc_result_t
additionaldata_uri(ARGS_ADDLDATA)271 additionaldata_uri(ARGS_ADDLDATA) {
272 REQUIRE(rdata->type == dns_rdatatype_uri);
273
274 UNUSED(rdata);
275 UNUSED(add);
276 UNUSED(arg);
277
278 return (ISC_R_SUCCESS);
279 }
280
281 static isc_result_t
digest_uri(ARGS_DIGEST)282 digest_uri(ARGS_DIGEST) {
283 isc_region_t r;
284
285 REQUIRE(rdata->type == dns_rdatatype_uri);
286
287 dns_rdata_toregion(rdata, &r);
288
289 return ((digest)(arg, &r));
290 }
291
292 static bool
checkowner_uri(ARGS_CHECKOWNER)293 checkowner_uri(ARGS_CHECKOWNER) {
294 REQUIRE(type == dns_rdatatype_uri);
295
296 UNUSED(name);
297 UNUSED(type);
298 UNUSED(rdclass);
299 UNUSED(wildcard);
300
301 return (true);
302 }
303
304 static bool
checknames_uri(ARGS_CHECKNAMES)305 checknames_uri(ARGS_CHECKNAMES) {
306 REQUIRE(rdata->type == dns_rdatatype_uri);
307
308 UNUSED(rdata);
309 UNUSED(owner);
310 UNUSED(bad);
311
312 return (true);
313 }
314
315 static int
casecompare_uri(ARGS_COMPARE)316 casecompare_uri(ARGS_COMPARE) {
317 return (compare_uri(rdata1, rdata2));
318 }
319
320 #endif /* GENERIC_URI_256_C */
321