1/* $NetBSD: ptr_12.c,v 1.8 2024/02/21 22:52:13 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 21static isc_result_t 22fromtext_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 58static isc_result_t 59totext_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, ®ion); 72 dns_name_fromregion(&name, ®ion); 73 74 sub = name_prefix(&name, tctx->origin, &prefix); 75 76 return (dns_name_totext(&prefix, sub, target)); 77} 78 79static isc_result_t 80fromwire_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 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 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(owner); 198 UNUSED(add); 199 UNUSED(arg); 200 201 return (ISC_R_SUCCESS); 202} 203 204static isc_result_t 205digest_ptr(ARGS_DIGEST) { 206 isc_region_t r; 207 dns_name_t name; 208 209 REQUIRE(rdata->type == dns_rdatatype_ptr); 210 211 dns_rdata_toregion(rdata, &r); 212 dns_name_init(&name, NULL); 213 dns_name_fromregion(&name, &r); 214 215 return (dns_name_digest(&name, digest, arg)); 216} 217 218static bool 219checkowner_ptr(ARGS_CHECKOWNER) { 220 REQUIRE(type == dns_rdatatype_ptr); 221 222 UNUSED(name); 223 UNUSED(type); 224 UNUSED(rdclass); 225 UNUSED(wildcard); 226 227 return (true); 228} 229 230static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; 231static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; 232static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data, 233 ip6_arpa_offsets); 234 235static unsigned char ip6_int_data[] = "\003IP6\003INT"; 236static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; 237static const dns_name_t ip6_int = DNS_NAME_INITABSOLUTE(ip6_int_data, 238 ip6_int_offsets); 239 240static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; 241static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; 242static const dns_name_t in_addr_arpa = 243 DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets); 244 245static bool 246checknames_ptr(ARGS_CHECKNAMES) { 247 isc_region_t region; 248 dns_name_t name; 249 250 REQUIRE(rdata->type == dns_rdatatype_ptr); 251 252 if (rdata->rdclass != dns_rdataclass_in) { 253 return (true); 254 } 255 256 if (dns_name_isdnssd(owner)) { 257 return (true); 258 } 259 260 if (dns_name_issubdomain(owner, &in_addr_arpa) || 261 dns_name_issubdomain(owner, &ip6_arpa) || 262 dns_name_issubdomain(owner, &ip6_int)) 263 { 264 dns_rdata_toregion(rdata, ®ion); 265 dns_name_init(&name, NULL); 266 dns_name_fromregion(&name, ®ion); 267 if (!dns_name_ishostname(&name, false)) { 268 if (bad != NULL) { 269 dns_name_clone(&name, bad); 270 } 271 return (false); 272 } 273 } 274 return (true); 275} 276 277static int 278casecompare_ptr(ARGS_COMPARE) { 279 return (compare_ptr(rdata1, rdata2)); 280} 281#endif /* RDATA_GENERIC_PTR_12_C */ 282