1189251Ssam/* $NetBSD: ptr_12.c,v 1.1 2024/02/18 20:57:44 christos Exp $ */ 2189251Ssam 3189251Ssam/* 4189251Ssam * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5252726Srpaulo * 6252726Srpaulo * SPDX-License-Identifier: MPL-2.0 7189251Ssam * 8189251Ssam * This Source Code Form is subject to the terms of the Mozilla Public 9189251Ssam * License, v. 2.0. If a copy of the MPL was not distributed with this 10189251Ssam * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11189251Ssam * 12189251Ssam * See the COPYRIGHT file distributed with this work for additional 13189251Ssam * information regarding copyright ownership. 14189251Ssam */ 15189251Ssam 16189251Ssam#ifndef RDATA_GENERIC_PTR_12_C 17189251Ssam#define RDATA_GENERIC_PTR_12_C 18189251Ssam 19189251Ssam#define RRTYPE_PTR_ATTRIBUTES (0) 20189251Ssam 21189251Ssamstatic isc_result_t 22189251Ssamfromtext_ptr(ARGS_FROMTEXT) { 23189251Ssam isc_token_t token; 24189251Ssam dns_name_t name; 25189251Ssam isc_buffer_t buffer; 26189251Ssam 27189251Ssam REQUIRE(type == dns_rdatatype_ptr); 28189251Ssam 29189251Ssam UNUSED(type); 30189251Ssam UNUSED(rdclass); 31189251Ssam UNUSED(callbacks); 32189251Ssam 33189251Ssam RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 34189251Ssam false)); 35189251Ssam 36189251Ssam dns_name_init(&name, NULL); 37189251Ssam buffer_fromregion(&buffer, &token.value.as_region); 38189251Ssam if (origin == NULL) { 39189251Ssam origin = dns_rootname; 40189251Ssam } 41189251Ssam RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 42189251Ssam if (rdclass == dns_rdataclass_in && 43189251Ssam (options & DNS_RDATA_CHECKNAMES) != 0 && 44189251Ssam (options & DNS_RDATA_CHECKREVERSE) != 0) 45189251Ssam { 46189251Ssam bool ok; 47189251Ssam ok = dns_name_ishostname(&name, false); 48189251Ssam if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) { 49189251Ssam RETTOK(DNS_R_BADNAME); 50189251Ssam } 51189251Ssam if (!ok && callbacks != NULL) { 52189251Ssam warn_badname(&name, lexer, callbacks); 53189251Ssam } 54189251Ssam } 55189251Ssam return (ISC_R_SUCCESS); 56189251Ssam} 57189251Ssam 58189251Ssamstatic isc_result_t 59189251Ssamtotext_ptr(ARGS_TOTEXT) { 60189251Ssam isc_region_t region; 61189251Ssam dns_name_t name; 62189251Ssam dns_name_t prefix; 63252726Srpaulo bool sub; 64209158Srpaulo 65252726Srpaulo REQUIRE(rdata->type == dns_rdatatype_ptr); 66189251Ssam REQUIRE(rdata->length != 0); 67189251Ssam 68189251Ssam dns_name_init(&name, NULL); 69189251Ssam dns_name_init(&prefix, NULL); 70189251Ssam 71189251Ssam dns_rdata_toregion(rdata, ®ion); 72189251Ssam dns_name_fromregion(&name, ®ion); 73189251Ssam 74252726Srpaulo sub = name_prefix(&name, tctx->origin, &prefix); 75252726Srpaulo 76189251Ssam return (dns_name_totext(&prefix, sub, target)); 77189251Ssam} 78252726Srpaulo 79252726Srpaulostatic isc_result_t 80252726Srpaulofromwire_ptr(ARGS_FROMWIRE) { 81189251Ssam dns_name_t name; 82189251Ssam 83189251Ssam REQUIRE(type == dns_rdatatype_ptr); 84189251Ssam 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 94static isc_result_t 95towire_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, ®ion); 107 dns_name_fromregion(&name, ®ion); 108 109 return (dns_name_towire(&name, cctx, target)); 110} 111 112static int 113compare_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, ®ion1); 129 dns_rdata_toregion(rdata2, ®ion2); 130 131 dns_name_fromregion(&name1, ®ion1); 132 dns_name_fromregion(&name2, ®ion2); 133 134 return (dns_name_rdatacompare(&name1, &name2)); 135} 136 137static isc_result_t 138fromstruct_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, ®ion); 151 return (isc_buffer_copyregion(target, ®ion)); 152} 153 154static isc_result_t 155tostruct_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, ®ion); 170 dns_name_fromregion(&name, ®ion); 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 177static void 178freestruct_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 192static isc_result_t 193additionaldata_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 203static isc_result_t 204digest_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 217static bool 218checkowner_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 229static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; 230static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; 231static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data, 232 ip6_arpa_offsets); 233 234static unsigned char ip6_int_data[] = "\003IP6\003INT"; 235static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; 236static const dns_name_t ip6_int = DNS_NAME_INITABSOLUTE(ip6_int_data, 237 ip6_int_offsets); 238 239static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; 240static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; 241static const dns_name_t in_addr_arpa = 242 DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets); 243 244static bool 245checknames_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, ®ion); 264 dns_name_init(&name, NULL); 265 dns_name_fromregion(&name, ®ion); 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 276static int 277casecompare_ptr(ARGS_COMPARE) { 278 return (compare_ptr(rdata1, rdata2)); 279} 280#endif /* RDATA_GENERIC_PTR_12_C */ 281