Home | History | Annotate | Line # | Download | only in ch_3
      1 /*	$NetBSD: a_1.c,v 1.1 2024/02/18 20:57:40 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 /* by Bjorn.Victor (at) it.uu.se, 2005-05-07 */
     17 /* Based on generic/soa_6.c and generic/mx_15.c */
     18 
     19 #ifndef RDATA_CH_3_A_1_C
     20 #define RDATA_CH_3_A_1_C
     21 
     22 #include <isc/net.h>
     23 
     24 #define RRTYPE_A_ATTRIBUTES (0)
     25 
     26 static isc_result_t
     27 fromtext_ch_a(ARGS_FROMTEXT) {
     28 	isc_token_t token;
     29 	dns_name_t name;
     30 	isc_buffer_t buffer;
     31 
     32 	REQUIRE(type == dns_rdatatype_a);
     33 	REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */
     34 
     35 	UNUSED(type);
     36 	UNUSED(callbacks);
     37 
     38 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     39 				      false));
     40 
     41 	/* get domain name */
     42 	dns_name_init(&name, NULL);
     43 	buffer_fromregion(&buffer, &token.value.as_region);
     44 	if (origin == NULL) {
     45 		origin = dns_rootname;
     46 	}
     47 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
     48 	if ((options & DNS_RDATA_CHECKNAMES) != 0 &&
     49 	    (options & DNS_RDATA_CHECKREVERSE) != 0)
     50 	{
     51 		bool ok;
     52 		ok = dns_name_ishostname(&name, false);
     53 		if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
     54 			RETTOK(DNS_R_BADNAME);
     55 		}
     56 		if (!ok && callbacks != NULL) {
     57 			warn_badname(&name, lexer, callbacks);
     58 		}
     59 	}
     60 
     61 	/* 16-bit octal address */
     62 	RETERR(isc_lex_getoctaltoken(lexer, &token, false));
     63 	if (token.value.as_ulong > 0xffffU) {
     64 		RETTOK(ISC_R_RANGE);
     65 	}
     66 	return (uint16_tobuffer(token.value.as_ulong, target));
     67 }
     68 
     69 static isc_result_t
     70 totext_ch_a(ARGS_TOTEXT) {
     71 	isc_region_t region;
     72 	dns_name_t name;
     73 	dns_name_t prefix;
     74 	bool sub;
     75 	char buf[sizeof("0177777")];
     76 	uint16_t addr;
     77 
     78 	REQUIRE(rdata->type == dns_rdatatype_a);
     79 	REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */
     80 	REQUIRE(rdata->length != 0);
     81 
     82 	dns_name_init(&name, NULL);
     83 	dns_name_init(&prefix, NULL);
     84 
     85 	dns_rdata_toregion(rdata, &region);
     86 	dns_name_fromregion(&name, &region);
     87 	isc_region_consume(&region, name_length(&name));
     88 	addr = uint16_fromregion(&region);
     89 
     90 	sub = name_prefix(&name, tctx->origin, &prefix);
     91 	RETERR(dns_name_totext(&prefix, sub, target));
     92 
     93 	snprintf(buf, sizeof(buf), "%o", addr); /* note octal */
     94 	RETERR(str_totext(" ", target));
     95 	return (str_totext(buf, target));
     96 }
     97 
     98 static isc_result_t
     99 fromwire_ch_a(ARGS_FROMWIRE) {
    100 	isc_region_t sregion;
    101 	isc_region_t tregion;
    102 	dns_name_t name;
    103 
    104 	REQUIRE(type == dns_rdatatype_a);
    105 	REQUIRE(rdclass == dns_rdataclass_ch);
    106 
    107 	UNUSED(type);
    108 	UNUSED(rdclass);
    109 
    110 	dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
    111 
    112 	dns_name_init(&name, NULL);
    113 
    114 	RETERR(dns_name_fromwire(&name, source, dctx, options, target));
    115 
    116 	isc_buffer_activeregion(source, &sregion);
    117 	isc_buffer_availableregion(target, &tregion);
    118 	if (sregion.length < 2) {
    119 		return (ISC_R_UNEXPECTEDEND);
    120 	}
    121 	if (tregion.length < 2) {
    122 		return (ISC_R_NOSPACE);
    123 	}
    124 
    125 	memmove(tregion.base, sregion.base, 2);
    126 	isc_buffer_forward(source, 2);
    127 	isc_buffer_add(target, 2);
    128 
    129 	return (ISC_R_SUCCESS);
    130 }
    131 
    132 static isc_result_t
    133 towire_ch_a(ARGS_TOWIRE) {
    134 	dns_name_t name;
    135 	dns_offsets_t offsets;
    136 	isc_region_t sregion;
    137 	isc_region_t tregion;
    138 
    139 	REQUIRE(rdata->type == dns_rdatatype_a);
    140 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
    141 	REQUIRE(rdata->length != 0);
    142 
    143 	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
    144 
    145 	dns_name_init(&name, offsets);
    146 
    147 	dns_rdata_toregion(rdata, &sregion);
    148 
    149 	dns_name_fromregion(&name, &sregion);
    150 	isc_region_consume(&sregion, name_length(&name));
    151 	RETERR(dns_name_towire(&name, cctx, target));
    152 
    153 	isc_buffer_availableregion(target, &tregion);
    154 	if (tregion.length < 2) {
    155 		return (ISC_R_NOSPACE);
    156 	}
    157 
    158 	memmove(tregion.base, sregion.base, 2);
    159 	isc_buffer_add(target, 2);
    160 	return (ISC_R_SUCCESS);
    161 }
    162 
    163 static int
    164 compare_ch_a(ARGS_COMPARE) {
    165 	dns_name_t name1;
    166 	dns_name_t name2;
    167 	isc_region_t region1;
    168 	isc_region_t region2;
    169 	int order;
    170 
    171 	REQUIRE(rdata1->type == rdata2->type);
    172 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
    173 	REQUIRE(rdata1->type == dns_rdatatype_a);
    174 	REQUIRE(rdata1->rdclass == dns_rdataclass_ch);
    175 	REQUIRE(rdata1->length != 0);
    176 	REQUIRE(rdata2->length != 0);
    177 
    178 	dns_name_init(&name1, NULL);
    179 	dns_name_init(&name2, NULL);
    180 
    181 	dns_rdata_toregion(rdata1, &region1);
    182 	dns_rdata_toregion(rdata2, &region2);
    183 
    184 	dns_name_fromregion(&name1, &region1);
    185 	dns_name_fromregion(&name2, &region2);
    186 	isc_region_consume(&region1, name_length(&name1));
    187 	isc_region_consume(&region2, name_length(&name2));
    188 
    189 	order = dns_name_rdatacompare(&name1, &name2);
    190 	if (order != 0) {
    191 		return (order);
    192 	}
    193 
    194 	order = memcmp(region1.base, region2.base, 2);
    195 	if (order != 0) {
    196 		order = (order < 0) ? -1 : 1;
    197 	}
    198 	return (order);
    199 }
    200 
    201 static isc_result_t
    202 fromstruct_ch_a(ARGS_FROMSTRUCT) {
    203 	dns_rdata_ch_a_t *a = source;
    204 	isc_region_t region;
    205 
    206 	REQUIRE(type == dns_rdatatype_a);
    207 	REQUIRE(a != NULL);
    208 	REQUIRE(a->common.rdtype == type);
    209 	REQUIRE(a->common.rdclass == rdclass);
    210 
    211 	UNUSED(type);
    212 	UNUSED(rdclass);
    213 
    214 	dns_name_toregion(&a->ch_addr_dom, &region);
    215 	RETERR(isc_buffer_copyregion(target, &region));
    216 
    217 	return (uint16_tobuffer(ntohs(a->ch_addr), target));
    218 }
    219 
    220 static isc_result_t
    221 tostruct_ch_a(ARGS_TOSTRUCT) {
    222 	dns_rdata_ch_a_t *a = target;
    223 	isc_region_t region;
    224 	dns_name_t name;
    225 
    226 	REQUIRE(rdata->type == dns_rdatatype_a);
    227 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
    228 	REQUIRE(rdata->length != 0);
    229 
    230 	a->common.rdclass = rdata->rdclass;
    231 	a->common.rdtype = rdata->type;
    232 	ISC_LINK_INIT(&a->common, link);
    233 
    234 	dns_rdata_toregion(rdata, &region);
    235 
    236 	dns_name_init(&name, NULL);
    237 	dns_name_fromregion(&name, &region);
    238 	isc_region_consume(&region, name_length(&name));
    239 
    240 	dns_name_init(&a->ch_addr_dom, NULL);
    241 	RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom));
    242 	a->ch_addr = htons(uint16_fromregion(&region));
    243 	a->mctx = mctx;
    244 	return (ISC_R_SUCCESS);
    245 }
    246 
    247 static void
    248 freestruct_ch_a(ARGS_FREESTRUCT) {
    249 	dns_rdata_ch_a_t *a = source;
    250 
    251 	REQUIRE(a != NULL);
    252 	REQUIRE(a->common.rdtype == dns_rdatatype_a);
    253 
    254 	if (a->mctx == NULL) {
    255 		return;
    256 	}
    257 
    258 	dns_name_free(&a->ch_addr_dom, a->mctx);
    259 	a->mctx = NULL;
    260 }
    261 
    262 static isc_result_t
    263 additionaldata_ch_a(ARGS_ADDLDATA) {
    264 	REQUIRE(rdata->type == dns_rdatatype_a);
    265 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
    266 
    267 	UNUSED(rdata);
    268 	UNUSED(add);
    269 	UNUSED(arg);
    270 
    271 	return (ISC_R_SUCCESS);
    272 }
    273 
    274 static isc_result_t
    275 digest_ch_a(ARGS_DIGEST) {
    276 	isc_region_t r;
    277 	dns_name_t name;
    278 
    279 	REQUIRE(rdata->type == dns_rdatatype_a);
    280 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
    281 
    282 	dns_rdata_toregion(rdata, &r);
    283 	dns_name_init(&name, NULL);
    284 	dns_name_fromregion(&name, &r);
    285 	isc_region_consume(&r, name_length(&name));
    286 	RETERR(dns_name_digest(&name, digest, arg));
    287 	return ((digest)(arg, &r));
    288 }
    289 
    290 static bool
    291 checkowner_ch_a(ARGS_CHECKOWNER) {
    292 	REQUIRE(type == dns_rdatatype_a);
    293 	REQUIRE(rdclass == dns_rdataclass_ch);
    294 
    295 	UNUSED(type);
    296 
    297 	return (dns_name_ishostname(name, wildcard));
    298 }
    299 
    300 static bool
    301 checknames_ch_a(ARGS_CHECKNAMES) {
    302 	isc_region_t region;
    303 	dns_name_t name;
    304 
    305 	REQUIRE(rdata->type == dns_rdatatype_a);
    306 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
    307 
    308 	UNUSED(owner);
    309 
    310 	dns_rdata_toregion(rdata, &region);
    311 	dns_name_init(&name, NULL);
    312 	dns_name_fromregion(&name, &region);
    313 	if (!dns_name_ishostname(&name, false)) {
    314 		if (bad != NULL) {
    315 			dns_name_clone(&name, bad);
    316 		}
    317 		return (false);
    318 	}
    319 
    320 	return (true);
    321 }
    322 
    323 static int
    324 casecompare_ch_a(ARGS_COMPARE) {
    325 	return (compare_ch_a(rdata1, rdata2));
    326 }
    327 #endif /* RDATA_CH_3_A_1_C */
    328