Home | History | Annotate | Line # | Download | only in generic
      1 /*	$NetBSD: dsync_66.c,v 1.2 2026/01/29 18:37:52 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 RDATA_GENERIC_DSYNC_66_C
     17 #define RDATA_GENERIC_DSYNC_66_C
     18 
     19 #include <string.h>
     20 
     21 #include <isc/net.h>
     22 
     23 #include <dns/dsync.h>
     24 #include <dns/fixedname.h>
     25 
     26 #define RRTYPE_DSYNC_ATTRIBUTES (0)
     27 
     28 static isc_result_t
     29 fromtext_dsync(ARGS_FROMTEXT) {
     30 	isc_token_t token;
     31 	isc_result_t result;
     32 	dns_fixedname_t fn;
     33 	dns_name_t *name = dns_fixedname_initname(&fn);
     34 	isc_buffer_t buffer;
     35 	dns_rdatatype_t rrtype;
     36 	dns_dsyncscheme_t scheme;
     37 	bool ok = true;
     38 
     39 	REQUIRE(type == dns_rdatatype_dsync);
     40 
     41 	UNUSED(type);
     42 	UNUSED(rdclass);
     43 	UNUSED(callbacks);
     44 
     45 	/*
     46 	 * RRtype
     47 	 */
     48 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     49 				      false));
     50 	result = dns_rdatatype_fromtext(&rrtype, &token.value.as_textregion);
     51 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
     52 		char *e = NULL;
     53 		long i = strtol(DNS_AS_STR(token), &e, 10);
     54 		if (i < 0 || i > 65535) {
     55 			RETTOK(ISC_R_RANGE);
     56 		}
     57 		if (*e != 0) {
     58 			RETTOK(result);
     59 		}
     60 		rrtype = (dns_rdatatype_t)i;
     61 	}
     62 	RETERR(uint16_tobuffer(rrtype, target));
     63 
     64 	/*
     65 	 * Scheme
     66 	 */
     67 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     68 				      false));
     69 	RETERR(dns_dsyncscheme_fromtext(&scheme, &token.value.as_textregion));
     70 	RETERR(uint8_tobuffer(scheme, target));
     71 
     72 	/*
     73 	 * Port
     74 	 */
     75 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     76 				      false));
     77 	if (token.value.as_ulong > 0xffffU) {
     78 		RETTOK(ISC_R_RANGE);
     79 	}
     80 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
     81 
     82 	/*
     83 	 * Target
     84 	 */
     85 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     86 				      false));
     87 
     88 	buffer_fromregion(&buffer, &token.value.as_region);
     89 	if (origin == NULL) {
     90 		origin = dns_rootname;
     91 	}
     92 	RETTOK(dns_name_fromtext(name, &buffer, origin, options, target));
     93 	if ((options & DNS_RDATA_CHECKNAMES) != 0) {
     94 		ok = dns_name_ishostname(name, false);
     95 	}
     96 	if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
     97 		RETTOK(DNS_R_BADNAME);
     98 	}
     99 	if (!ok && callbacks != NULL) {
    100 		warn_badname(name, lexer, callbacks);
    101 	}
    102 	return ISC_R_SUCCESS;
    103 }
    104 
    105 static isc_result_t
    106 totext_dsync(ARGS_TOTEXT) {
    107 	isc_region_t region;
    108 	dns_name_t name;
    109 	dns_name_t prefix;
    110 	unsigned int opts;
    111 	char buf[sizeof("TYPE64000")];
    112 	unsigned short num;
    113 	dns_rdatatype_t type;
    114 	dns_dsyncscheme_t scheme;
    115 
    116 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    117 	REQUIRE(rdata->length != 0);
    118 
    119 	dns_name_init(&name, NULL);
    120 	dns_name_init(&prefix, NULL);
    121 
    122 	dns_rdata_toregion(rdata, &region);
    123 
    124 	/*
    125 	 * Type.
    126 	 */
    127 	type = uint16_fromregion(&region);
    128 	isc_region_consume(&region, 2);
    129 	/*
    130 	 * XXXAG We should have something like dns_rdatatype_isknown()
    131 	 * that does the right thing with type 0.
    132 	 */
    133 	if (dns_rdatatype_isknown(type) && type != 0) {
    134 		RETERR(dns_rdatatype_totext(type, target));
    135 	} else {
    136 		snprintf(buf, sizeof(buf), "TYPE%u", type);
    137 		RETERR(str_totext(buf, target));
    138 	}
    139 	RETERR(str_totext(" ", target));
    140 
    141 	/*
    142 	 * Scheme.
    143 	 */
    144 	scheme = uint8_fromregion(&region);
    145 	isc_region_consume(&region, 1);
    146 	RETERR(dns_dsyncscheme_totext(scheme, target));
    147 
    148 	RETERR(str_totext(" ", target));
    149 
    150 	/*
    151 	 * Port
    152 	 */
    153 	num = uint16_fromregion(&region);
    154 	isc_region_consume(&region, 2);
    155 	snprintf(buf, sizeof(buf), "%u", num);
    156 	RETERR(str_totext(buf, target));
    157 
    158 	RETERR(str_totext(" ", target));
    159 
    160 	/*
    161 	 * Target
    162 	 */
    163 	dns_name_fromregion(&name, &region);
    164 	opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
    165 							 : 0;
    166 	return dns_name_totext(&prefix, opts, target);
    167 }
    168 
    169 static isc_result_t
    170 fromwire_dsync(ARGS_FROMWIRE) {
    171 	dns_name_t name;
    172 	isc_region_t sregion;
    173 
    174 	REQUIRE(type == dns_rdatatype_dsync);
    175 
    176 	UNUSED(type);
    177 	UNUSED(rdclass);
    178 
    179 	dctx = dns_decompress_setpermitted(dctx, false);
    180 
    181 	dns_name_init(&name, NULL);
    182 
    183 	isc_buffer_activeregion(source, &sregion);
    184 	if (sregion.length < 5) {
    185 		return ISC_R_UNEXPECTEDEND;
    186 	}
    187 	RETERR(mem_tobuffer(target, sregion.base, 5));
    188 	isc_buffer_forward(source, 5);
    189 	return dns_name_fromwire(&name, source, dctx, target);
    190 }
    191 
    192 static isc_result_t
    193 towire_dsync(ARGS_TOWIRE) {
    194 	dns_name_t name;
    195 	isc_region_t region;
    196 
    197 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    198 	REQUIRE(rdata->length != 0);
    199 
    200 	dns_compress_setpermitted(cctx, false);
    201 
    202 	dns_rdata_toregion(rdata, &region);
    203 	RETERR(mem_tobuffer(target, region.base, 5));
    204 	isc_region_consume(&region, 5);
    205 
    206 	dns_name_init(&name, NULL);
    207 	dns_name_fromregion(&name, &region);
    208 
    209 	return dns_name_towire(&name, cctx, target, NULL);
    210 }
    211 
    212 static int
    213 compare_dsync(ARGS_COMPARE) {
    214 	isc_region_t region1;
    215 	isc_region_t region2;
    216 
    217 	REQUIRE(rdata1->type == rdata2->type);
    218 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
    219 	REQUIRE(rdata1->type == dns_rdatatype_dsync);
    220 	REQUIRE(rdata1->length != 0);
    221 	REQUIRE(rdata2->length != 0);
    222 
    223 	dns_rdata_toregion(rdata1, &region1);
    224 	dns_rdata_toregion(rdata2, &region2);
    225 	return isc_region_compare(&region1, &region2);
    226 }
    227 
    228 static isc_result_t
    229 fromstruct_dsync(ARGS_FROMSTRUCT) {
    230 	dns_rdata_dsync_t *dsync = source;
    231 	isc_region_t region;
    232 
    233 	REQUIRE(type == dns_rdatatype_dsync);
    234 	REQUIRE(dsync != NULL);
    235 	REQUIRE(dsync->common.rdtype == type);
    236 	REQUIRE(dsync->common.rdclass == rdclass);
    237 
    238 	UNUSED(type);
    239 	UNUSED(rdclass);
    240 
    241 	RETERR(uint16_tobuffer(dsync->type, target));
    242 	RETERR(uint16_tobuffer(dsync->scheme, target));
    243 	RETERR(uint16_tobuffer(dsync->port, target));
    244 	dns_name_toregion(&dsync->target, &region);
    245 	return isc_buffer_copyregion(target, &region);
    246 }
    247 
    248 static isc_result_t
    249 tostruct_dsync(ARGS_TOSTRUCT) {
    250 	isc_region_t region;
    251 	dns_rdata_dsync_t *dsync = target;
    252 	dns_name_t name;
    253 
    254 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    255 	REQUIRE(dsync != NULL);
    256 	REQUIRE(rdata->length != 0);
    257 
    258 	DNS_RDATACOMMON_INIT(dsync, rdata->type, rdata->rdclass);
    259 
    260 	dns_name_init(&name, NULL);
    261 	dns_rdata_toregion(rdata, &region);
    262 	dsync->type = uint16_fromregion(&region);
    263 	isc_region_consume(&region, 2);
    264 	dsync->scheme = uint8_fromregion(&region);
    265 	isc_region_consume(&region, 1);
    266 	dsync->port = uint16_fromregion(&region);
    267 	isc_region_consume(&region, 2);
    268 	dns_name_fromregion(&name, &region);
    269 	dns_name_init(&dsync->target, NULL);
    270 	name_duporclone(&name, mctx, &dsync->target);
    271 	dsync->mctx = mctx;
    272 	return ISC_R_SUCCESS;
    273 }
    274 
    275 static void
    276 freestruct_dsync(ARGS_FREESTRUCT) {
    277 	dns_rdata_dsync_t *dsync = source;
    278 
    279 	REQUIRE(dsync != NULL);
    280 	REQUIRE(dsync->common.rdtype == dns_rdatatype_dsync);
    281 
    282 	if (dsync->mctx == NULL) {
    283 		return;
    284 	}
    285 
    286 	dns_name_free(&dsync->target, dsync->mctx);
    287 	dsync->mctx = NULL;
    288 }
    289 
    290 static isc_result_t
    291 additionaldata_dsync(ARGS_ADDLDATA) {
    292 	dns_name_t name;
    293 	isc_region_t region;
    294 
    295 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    296 
    297 	UNUSED(owner);
    298 
    299 	dns_name_init(&name, NULL);
    300 	dns_rdata_toregion(rdata, &region);
    301 	isc_region_consume(&region, 5);
    302 	dns_name_fromregion(&name, &region);
    303 
    304 	if (dns_name_equal(&name, dns_rootname)) {
    305 		return ISC_R_SUCCESS;
    306 	}
    307 
    308 	return (add)(arg, &name, dns_rdatatype_a, NULL DNS__DB_FILELINE);
    309 }
    310 
    311 static isc_result_t
    312 digest_dsync(ARGS_DIGEST) {
    313 	isc_region_t r1;
    314 
    315 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    316 
    317 	dns_rdata_toregion(rdata, &r1);
    318 	return (digest)(arg, &r1);
    319 }
    320 
    321 static bool
    322 checkowner_dsync(ARGS_CHECKOWNER) {
    323 	REQUIRE(type == dns_rdatatype_dsync);
    324 
    325 	UNUSED(name);
    326 	UNUSED(rdclass);
    327 	UNUSED(type);
    328 	UNUSED(wildcard);
    329 
    330 	return true;
    331 }
    332 
    333 static bool
    334 checknames_dsync(ARGS_CHECKNAMES) {
    335 	isc_region_t region;
    336 	dns_name_t name;
    337 
    338 	REQUIRE(rdata->type == dns_rdatatype_dsync);
    339 	REQUIRE(rdata->length > 5);
    340 
    341 	UNUSED(owner);
    342 
    343 	dns_rdata_toregion(rdata, &region);
    344 	isc_region_consume(&region, 5);
    345 	dns_name_init(&name, NULL);
    346 	dns_name_fromregion(&name, &region);
    347 	if (!dns_name_ishostname(&name, false)) {
    348 		if (bad != NULL) {
    349 			dns_name_clone(&name, bad);
    350 		}
    351 		return false;
    352 	}
    353 	return true;
    354 }
    355 
    356 static int
    357 casecompare_dsync(ARGS_COMPARE) {
    358 	return compare_dsync(rdata1, rdata2);
    359 }
    360 
    361 #endif /* RDATA_GENERIC_DSYNC_66_C */
    362