1 /* $NetBSD: px_26.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 /* RFC2163 */
17
18 #ifndef RDATA_IN_1_PX_26_C
19 #define RDATA_IN_1_PX_26_C
20
21 #define RRTYPE_PX_ATTRIBUTES (0)
22
23 static isc_result_t
fromtext_in_px(ARGS_FROMTEXT)24 fromtext_in_px(ARGS_FROMTEXT) {
25 isc_token_t token;
26 dns_name_t name;
27 isc_buffer_t buffer;
28
29 REQUIRE(type == dns_rdatatype_px);
30 REQUIRE(rdclass == dns_rdataclass_in);
31
32 UNUSED(type);
33 UNUSED(rdclass);
34 UNUSED(callbacks);
35
36 if (origin == NULL) {
37 origin = dns_rootname;
38 }
39
40 /*
41 * Preference.
42 */
43 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
44 false));
45 if (token.value.as_ulong > 0xffffU) {
46 RETTOK(ISC_R_RANGE);
47 }
48 RETERR(uint16_tobuffer(token.value.as_ulong, target));
49
50 /*
51 * MAP822.
52 */
53 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
54 false));
55 dns_name_init(&name, NULL);
56 buffer_fromregion(&buffer, &token.value.as_region);
57 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
58
59 /*
60 * MAPX400.
61 */
62 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
63 false));
64 dns_name_init(&name, NULL);
65 buffer_fromregion(&buffer, &token.value.as_region);
66 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
67 return (ISC_R_SUCCESS);
68 }
69
70 static isc_result_t
totext_in_px(ARGS_TOTEXT)71 totext_in_px(ARGS_TOTEXT) {
72 isc_region_t region;
73 dns_name_t name;
74 dns_name_t prefix;
75 bool sub;
76 char buf[sizeof("64000")];
77 unsigned short num;
78
79 REQUIRE(rdata->type == dns_rdatatype_px);
80 REQUIRE(rdata->rdclass == dns_rdataclass_in);
81 REQUIRE(rdata->length != 0);
82
83 dns_name_init(&name, NULL);
84 dns_name_init(&prefix, NULL);
85
86 /*
87 * Preference.
88 */
89 dns_rdata_toregion(rdata, ®ion);
90 num = uint16_fromregion(®ion);
91 isc_region_consume(®ion, 2);
92 snprintf(buf, sizeof(buf), "%u", num);
93 RETERR(str_totext(buf, target));
94 RETERR(str_totext(" ", target));
95
96 /*
97 * MAP822.
98 */
99 dns_name_fromregion(&name, ®ion);
100 sub = name_prefix(&name, tctx->origin, &prefix);
101 isc_region_consume(®ion, name_length(&name));
102 RETERR(dns_name_totext(&prefix, sub, target));
103 RETERR(str_totext(" ", target));
104
105 /*
106 * MAPX400.
107 */
108 dns_name_fromregion(&name, ®ion);
109 sub = name_prefix(&name, tctx->origin, &prefix);
110 return (dns_name_totext(&prefix, sub, target));
111 }
112
113 static isc_result_t
fromwire_in_px(ARGS_FROMWIRE)114 fromwire_in_px(ARGS_FROMWIRE) {
115 dns_name_t name;
116 isc_region_t sregion;
117
118 REQUIRE(type == dns_rdatatype_px);
119 REQUIRE(rdclass == dns_rdataclass_in);
120
121 UNUSED(type);
122 UNUSED(rdclass);
123
124 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
125
126 dns_name_init(&name, NULL);
127
128 /*
129 * Preference.
130 */
131 isc_buffer_activeregion(source, &sregion);
132 if (sregion.length < 2) {
133 return (ISC_R_UNEXPECTEDEND);
134 }
135 RETERR(mem_tobuffer(target, sregion.base, 2));
136 isc_buffer_forward(source, 2);
137
138 /*
139 * MAP822.
140 */
141 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
142
143 /*
144 * MAPX400.
145 */
146 return (dns_name_fromwire(&name, source, dctx, options, target));
147 }
148
149 static isc_result_t
towire_in_px(ARGS_TOWIRE)150 towire_in_px(ARGS_TOWIRE) {
151 dns_name_t name;
152 dns_offsets_t offsets;
153 isc_region_t region;
154
155 REQUIRE(rdata->type == dns_rdatatype_px);
156 REQUIRE(rdata->rdclass == dns_rdataclass_in);
157 REQUIRE(rdata->length != 0);
158
159 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
160 /*
161 * Preference.
162 */
163 dns_rdata_toregion(rdata, ®ion);
164 RETERR(mem_tobuffer(target, region.base, 2));
165 isc_region_consume(®ion, 2);
166
167 /*
168 * MAP822.
169 */
170 dns_name_init(&name, offsets);
171 dns_name_fromregion(&name, ®ion);
172 RETERR(dns_name_towire(&name, cctx, target));
173 isc_region_consume(®ion, name_length(&name));
174
175 /*
176 * MAPX400.
177 */
178 dns_name_init(&name, offsets);
179 dns_name_fromregion(&name, ®ion);
180 return (dns_name_towire(&name, cctx, target));
181 }
182
183 static int
compare_in_px(ARGS_COMPARE)184 compare_in_px(ARGS_COMPARE) {
185 dns_name_t name1;
186 dns_name_t name2;
187 isc_region_t region1;
188 isc_region_t region2;
189 int order;
190
191 REQUIRE(rdata1->type == rdata2->type);
192 REQUIRE(rdata1->rdclass == rdata2->rdclass);
193 REQUIRE(rdata1->type == dns_rdatatype_px);
194 REQUIRE(rdata1->rdclass == dns_rdataclass_in);
195 REQUIRE(rdata1->length != 0);
196 REQUIRE(rdata2->length != 0);
197
198 order = memcmp(rdata1->data, rdata2->data, 2);
199 if (order != 0) {
200 return (order < 0 ? -1 : 1);
201 }
202
203 dns_name_init(&name1, NULL);
204 dns_name_init(&name2, NULL);
205
206 dns_rdata_toregion(rdata1, ®ion1);
207 dns_rdata_toregion(rdata2, ®ion2);
208
209 isc_region_consume(®ion1, 2);
210 isc_region_consume(®ion2, 2);
211
212 dns_name_fromregion(&name1, ®ion1);
213 dns_name_fromregion(&name2, ®ion2);
214
215 order = dns_name_rdatacompare(&name1, &name2);
216 if (order != 0) {
217 return (order);
218 }
219
220 isc_region_consume(®ion1, name_length(&name1));
221 isc_region_consume(®ion2, name_length(&name2));
222
223 dns_name_fromregion(&name1, ®ion1);
224 dns_name_fromregion(&name2, ®ion2);
225
226 return (dns_name_rdatacompare(&name1, &name2));
227 }
228
229 static isc_result_t
fromstruct_in_px(ARGS_FROMSTRUCT)230 fromstruct_in_px(ARGS_FROMSTRUCT) {
231 dns_rdata_in_px_t *px = source;
232 isc_region_t region;
233
234 REQUIRE(type == dns_rdatatype_px);
235 REQUIRE(rdclass == dns_rdataclass_in);
236 REQUIRE(px != NULL);
237 REQUIRE(px->common.rdtype == type);
238 REQUIRE(px->common.rdclass == rdclass);
239
240 UNUSED(type);
241 UNUSED(rdclass);
242
243 RETERR(uint16_tobuffer(px->preference, target));
244 dns_name_toregion(&px->map822, ®ion);
245 RETERR(isc_buffer_copyregion(target, ®ion));
246 dns_name_toregion(&px->mapx400, ®ion);
247 return (isc_buffer_copyregion(target, ®ion));
248 }
249
250 static isc_result_t
tostruct_in_px(ARGS_TOSTRUCT)251 tostruct_in_px(ARGS_TOSTRUCT) {
252 dns_rdata_in_px_t *px = target;
253 dns_name_t name;
254 isc_region_t region;
255 isc_result_t result;
256
257 REQUIRE(rdata->type == dns_rdatatype_px);
258 REQUIRE(rdata->rdclass == dns_rdataclass_in);
259 REQUIRE(px != NULL);
260 REQUIRE(rdata->length != 0);
261
262 px->common.rdclass = rdata->rdclass;
263 px->common.rdtype = rdata->type;
264 ISC_LINK_INIT(&px->common, link);
265
266 dns_name_init(&name, NULL);
267 dns_rdata_toregion(rdata, ®ion);
268
269 px->preference = uint16_fromregion(®ion);
270 isc_region_consume(®ion, 2);
271
272 dns_name_fromregion(&name, ®ion);
273
274 dns_name_init(&px->map822, NULL);
275 RETERR(name_duporclone(&name, mctx, &px->map822));
276 isc_region_consume(®ion, name_length(&px->map822));
277
278 dns_name_init(&px->mapx400, NULL);
279 result = name_duporclone(&name, mctx, &px->mapx400);
280 if (result != ISC_R_SUCCESS) {
281 goto cleanup;
282 }
283
284 px->mctx = mctx;
285 return (result);
286
287 cleanup:
288 dns_name_free(&px->map822, mctx);
289 return (ISC_R_NOMEMORY);
290 }
291
292 static void
freestruct_in_px(ARGS_FREESTRUCT)293 freestruct_in_px(ARGS_FREESTRUCT) {
294 dns_rdata_in_px_t *px = source;
295
296 REQUIRE(px != NULL);
297 REQUIRE(px->common.rdclass == dns_rdataclass_in);
298 REQUIRE(px->common.rdtype == dns_rdatatype_px);
299
300 if (px->mctx == NULL) {
301 return;
302 }
303
304 dns_name_free(&px->map822, px->mctx);
305 dns_name_free(&px->mapx400, px->mctx);
306 px->mctx = NULL;
307 }
308
309 static isc_result_t
additionaldata_in_px(ARGS_ADDLDATA)310 additionaldata_in_px(ARGS_ADDLDATA) {
311 REQUIRE(rdata->type == dns_rdatatype_px);
312 REQUIRE(rdata->rdclass == dns_rdataclass_in);
313
314 UNUSED(rdata);
315 UNUSED(add);
316 UNUSED(arg);
317
318 return (ISC_R_SUCCESS);
319 }
320
321 static isc_result_t
digest_in_px(ARGS_DIGEST)322 digest_in_px(ARGS_DIGEST) {
323 isc_region_t r1, r2;
324 dns_name_t name;
325 isc_result_t result;
326
327 REQUIRE(rdata->type == dns_rdatatype_px);
328 REQUIRE(rdata->rdclass == dns_rdataclass_in);
329
330 dns_rdata_toregion(rdata, &r1);
331 r2 = r1;
332 isc_region_consume(&r2, 2);
333 r1.length = 2;
334 result = (digest)(arg, &r1);
335 if (result != ISC_R_SUCCESS) {
336 return (result);
337 }
338 dns_name_init(&name, NULL);
339 dns_name_fromregion(&name, &r2);
340 result = dns_name_digest(&name, digest, arg);
341 if (result != ISC_R_SUCCESS) {
342 return (result);
343 }
344 isc_region_consume(&r2, name_length(&name));
345 dns_name_init(&name, NULL);
346 dns_name_fromregion(&name, &r2);
347
348 return (dns_name_digest(&name, digest, arg));
349 }
350
351 static bool
checkowner_in_px(ARGS_CHECKOWNER)352 checkowner_in_px(ARGS_CHECKOWNER) {
353 REQUIRE(type == dns_rdatatype_px);
354 REQUIRE(rdclass == dns_rdataclass_in);
355
356 UNUSED(name);
357 UNUSED(type);
358 UNUSED(rdclass);
359 UNUSED(wildcard);
360
361 return (true);
362 }
363
364 static bool
checknames_in_px(ARGS_CHECKNAMES)365 checknames_in_px(ARGS_CHECKNAMES) {
366 REQUIRE(rdata->type == dns_rdatatype_px);
367 REQUIRE(rdata->rdclass == dns_rdataclass_in);
368
369 UNUSED(rdata);
370 UNUSED(owner);
371 UNUSED(bad);
372
373 return (true);
374 }
375
376 static int
casecompare_in_px(ARGS_COMPARE)377 casecompare_in_px(ARGS_COMPARE) {
378 return (compare_in_px(rdata1, rdata2));
379 }
380
381 #endif /* RDATA_IN_1_PX_26_C */
382