Home | History | Annotate | Line # | Download | only in generic
      1 /*	$NetBSD: ptr_12.c,v 1.1 2024/02/18 20:57:44 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_PTR_12_C
     17 #define RDATA_GENERIC_PTR_12_C
     18 
     19 #define RRTYPE_PTR_ATTRIBUTES (0)
     20 
     21 static isc_result_t
     22 fromtext_ptr(ARGS_FROMTEXT) {
     23 	isc_token_t token;
     24 	dns_name_t name;
     25 	isc_buffer_t buffer;
     26 
     27 	REQUIRE(type == dns_rdatatype_ptr);
     28 
     29 	UNUSED(type);
     30 	UNUSED(rdclass);
     31 	UNUSED(callbacks);
     32 
     33 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
     34 				      false));
     35 
     36 	dns_name_init(&name, NULL);
     37 	buffer_fromregion(&buffer, &token.value.as_region);
     38 	if (origin == NULL) {
     39 		origin = dns_rootname;
     40 	}
     41 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
     42 	if (rdclass == dns_rdataclass_in &&
     43 	    (options & DNS_RDATA_CHECKNAMES) != 0 &&
     44 	    (options & DNS_RDATA_CHECKREVERSE) != 0)
     45 	{
     46 		bool ok;
     47 		ok = dns_name_ishostname(&name, false);
     48 		if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
     49 			RETTOK(DNS_R_BADNAME);
     50 		}
     51 		if (!ok && callbacks != NULL) {
     52 			warn_badname(&name, lexer, callbacks);
     53 		}
     54 	}
     55 	return (ISC_R_SUCCESS);
     56 }
     57 
     58 static isc_result_t
     59 totext_ptr(ARGS_TOTEXT) {
     60 	isc_region_t region;
     61 	dns_name_t name;
     62 	dns_name_t prefix;
     63 	bool sub;
     64 
     65 	REQUIRE(rdata->type == dns_rdatatype_ptr);
     66 	REQUIRE(rdata->length != 0);
     67 
     68 	dns_name_init(&name, NULL);
     69 	dns_name_init(&prefix, NULL);
     70 
     71 	dns_rdata_toregion(rdata, &region);
     72 	dns_name_fromregion(&name, &region);
     73 
     74 	sub = name_prefix(&name, tctx->origin, &prefix);
     75 
     76 	return (dns_name_totext(&prefix, sub, target));
     77 }
     78 
     79 static isc_result_t
     80 fromwire_ptr(ARGS_FROMWIRE) {
     81 	dns_name_t name;
     82 
     83 	REQUIRE(type == dns_rdatatype_ptr);
     84 
     85 	UNUSED(type);
     86 	UNUSED(rdclass);
     87 
     88 	dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
     89 
     90 	dns_name_init(&name, NULL);
     91 	return (dns_name_fromwire(&name, source, dctx, options, target));
     92 }
     93 
     94 static isc_result_t
     95 towire_ptr(ARGS_TOWIRE) {
     96 	dns_name_t name;
     97 	dns_offsets_t offsets;
     98 	isc_region_t region;
     99 
    100 	REQUIRE(rdata->type == dns_rdatatype_ptr);
    101 	REQUIRE(rdata->length != 0);
    102 
    103 	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
    104 
    105 	dns_name_init(&name, offsets);
    106 	dns_rdata_toregion(rdata, &region);
    107 	dns_name_fromregion(&name, &region);
    108 
    109 	return (dns_name_towire(&name, cctx, target));
    110 }
    111 
    112 static int
    113 compare_ptr(ARGS_COMPARE) {
    114 	dns_name_t name1;
    115 	dns_name_t name2;
    116 	isc_region_t region1;
    117 	isc_region_t region2;
    118 
    119 	REQUIRE(rdata1->type == rdata2->type);
    120 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
    121 	REQUIRE(rdata1->type == dns_rdatatype_ptr);
    122 	REQUIRE(rdata1->length != 0);
    123 	REQUIRE(rdata2->length != 0);
    124 
    125 	dns_name_init(&name1, NULL);
    126 	dns_name_init(&name2, NULL);
    127 
    128 	dns_rdata_toregion(rdata1, &region1);
    129 	dns_rdata_toregion(rdata2, &region2);
    130 
    131 	dns_name_fromregion(&name1, &region1);
    132 	dns_name_fromregion(&name2, &region2);
    133 
    134 	return (dns_name_rdatacompare(&name1, &name2));
    135 }
    136 
    137 static isc_result_t
    138 fromstruct_ptr(ARGS_FROMSTRUCT) {
    139 	dns_rdata_ptr_t *ptr = source;
    140 	isc_region_t region;
    141 
    142 	REQUIRE(type == dns_rdatatype_ptr);
    143 	REQUIRE(ptr != NULL);
    144 	REQUIRE(ptr->common.rdtype == type);
    145 	REQUIRE(ptr->common.rdclass == rdclass);
    146 
    147 	UNUSED(type);
    148 	UNUSED(rdclass);
    149 
    150 	dns_name_toregion(&ptr->ptr, &region);
    151 	return (isc_buffer_copyregion(target, &region));
    152 }
    153 
    154 static isc_result_t
    155 tostruct_ptr(ARGS_TOSTRUCT) {
    156 	isc_region_t region;
    157 	dns_rdata_ptr_t *ptr = target;
    158 	dns_name_t name;
    159 
    160 	REQUIRE(rdata->type == dns_rdatatype_ptr);
    161 	REQUIRE(ptr != NULL);
    162 	REQUIRE(rdata->length != 0);
    163 
    164 	ptr->common.rdclass = rdata->rdclass;
    165 	ptr->common.rdtype = rdata->type;
    166 	ISC_LINK_INIT(&ptr->common, link);
    167 
    168 	dns_name_init(&name, NULL);
    169 	dns_rdata_toregion(rdata, &region);
    170 	dns_name_fromregion(&name, &region);
    171 	dns_name_init(&ptr->ptr, NULL);
    172 	RETERR(name_duporclone(&name, mctx, &ptr->ptr));
    173 	ptr->mctx = mctx;
    174 	return (ISC_R_SUCCESS);
    175 }
    176 
    177 static void
    178 freestruct_ptr(ARGS_FREESTRUCT) {
    179 	dns_rdata_ptr_t *ptr = source;
    180 
    181 	REQUIRE(ptr != NULL);
    182 	REQUIRE(ptr->common.rdtype == dns_rdatatype_ptr);
    183 
    184 	if (ptr->mctx == NULL) {
    185 		return;
    186 	}
    187 
    188 	dns_name_free(&ptr->ptr, ptr->mctx);
    189 	ptr->mctx = NULL;
    190 }
    191 
    192 static isc_result_t
    193 additionaldata_ptr(ARGS_ADDLDATA) {
    194 	REQUIRE(rdata->type == dns_rdatatype_ptr);
    195 
    196 	UNUSED(rdata);
    197 	UNUSED(add);
    198 	UNUSED(arg);
    199 
    200 	return (ISC_R_SUCCESS);
    201 }
    202 
    203 static isc_result_t
    204 digest_ptr(ARGS_DIGEST) {
    205 	isc_region_t r;
    206 	dns_name_t name;
    207 
    208 	REQUIRE(rdata->type == dns_rdatatype_ptr);
    209 
    210 	dns_rdata_toregion(rdata, &r);
    211 	dns_name_init(&name, NULL);
    212 	dns_name_fromregion(&name, &r);
    213 
    214 	return (dns_name_digest(&name, digest, arg));
    215 }
    216 
    217 static bool
    218 checkowner_ptr(ARGS_CHECKOWNER) {
    219 	REQUIRE(type == dns_rdatatype_ptr);
    220 
    221 	UNUSED(name);
    222 	UNUSED(type);
    223 	UNUSED(rdclass);
    224 	UNUSED(wildcard);
    225 
    226 	return (true);
    227 }
    228 
    229 static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
    230 static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
    231 static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data,
    232 							 ip6_arpa_offsets);
    233 
    234 static unsigned char ip6_int_data[] = "\003IP6\003INT";
    235 static unsigned char ip6_int_offsets[] = { 0, 4, 8 };
    236 static const dns_name_t ip6_int = DNS_NAME_INITABSOLUTE(ip6_int_data,
    237 							ip6_int_offsets);
    238 
    239 static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
    240 static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 };
    241 static const dns_name_t in_addr_arpa =
    242 	DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets);
    243 
    244 static bool
    245 checknames_ptr(ARGS_CHECKNAMES) {
    246 	isc_region_t region;
    247 	dns_name_t name;
    248 
    249 	REQUIRE(rdata->type == dns_rdatatype_ptr);
    250 
    251 	if (rdata->rdclass != dns_rdataclass_in) {
    252 		return (true);
    253 	}
    254 
    255 	if (dns_name_isdnssd(owner)) {
    256 		return (true);
    257 	}
    258 
    259 	if (dns_name_issubdomain(owner, &in_addr_arpa) ||
    260 	    dns_name_issubdomain(owner, &ip6_arpa) ||
    261 	    dns_name_issubdomain(owner, &ip6_int))
    262 	{
    263 		dns_rdata_toregion(rdata, &region);
    264 		dns_name_init(&name, NULL);
    265 		dns_name_fromregion(&name, &region);
    266 		if (!dns_name_ishostname(&name, false)) {
    267 			if (bad != NULL) {
    268 				dns_name_clone(&name, bad);
    269 			}
    270 			return (false);
    271 		}
    272 	}
    273 	return (true);
    274 }
    275 
    276 static int
    277 casecompare_ptr(ARGS_COMPARE) {
    278 	return (compare_ptr(rdata1, rdata2));
    279 }
    280 #endif /* RDATA_GENERIC_PTR_12_C */
    281