1 /* $NetBSD: px_26.c,v 1.1 2024/02/18 20:57:46 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 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 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 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 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 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 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 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 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 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 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 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 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 377 casecompare_in_px(ARGS_COMPARE) { 378 return (compare_in_px(rdata1, rdata2)); 379 } 380 381 #endif /* RDATA_IN_1_PX_26_C */ 382