Home | History | Annotate | Line # | Download | only in in_1
      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, &region);
     90 	num = uint16_fromregion(&region);
     91 	isc_region_consume(&region, 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, &region);
    100 	sub = name_prefix(&name, tctx->origin, &prefix);
    101 	isc_region_consume(&region, 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, &region);
    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, &region);
    164 	RETERR(mem_tobuffer(target, region.base, 2));
    165 	isc_region_consume(&region, 2);
    166 
    167 	/*
    168 	 * MAP822.
    169 	 */
    170 	dns_name_init(&name, offsets);
    171 	dns_name_fromregion(&name, &region);
    172 	RETERR(dns_name_towire(&name, cctx, target));
    173 	isc_region_consume(&region, name_length(&name));
    174 
    175 	/*
    176 	 * MAPX400.
    177 	 */
    178 	dns_name_init(&name, offsets);
    179 	dns_name_fromregion(&name, &region);
    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, &region1);
    207 	dns_rdata_toregion(rdata2, &region2);
    208 
    209 	isc_region_consume(&region1, 2);
    210 	isc_region_consume(&region2, 2);
    211 
    212 	dns_name_fromregion(&name1, &region1);
    213 	dns_name_fromregion(&name2, &region2);
    214 
    215 	order = dns_name_rdatacompare(&name1, &name2);
    216 	if (order != 0) {
    217 		return (order);
    218 	}
    219 
    220 	isc_region_consume(&region1, name_length(&name1));
    221 	isc_region_consume(&region2, name_length(&name2));
    222 
    223 	dns_name_fromregion(&name1, &region1);
    224 	dns_name_fromregion(&name2, &region2);
    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, &region);
    245 	RETERR(isc_buffer_copyregion(target, &region));
    246 	dns_name_toregion(&px->mapx400, &region);
    247 	return (isc_buffer_copyregion(target, &region));
    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, &region);
    268 
    269 	px->preference = uint16_fromregion(&region);
    270 	isc_region_consume(&region, 2);
    271 
    272 	dns_name_fromregion(&name, &region);
    273 
    274 	dns_name_init(&px->map822, NULL);
    275 	RETERR(name_duporclone(&name, mctx, &px->map822));
    276 	isc_region_consume(&region, 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