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, ®ion); 86 dns_name_fromregion(&name, ®ion); 87 isc_region_consume(®ion, name_length(&name)); 88 addr = uint16_fromregion(®ion); 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, ®ion1); 182 dns_rdata_toregion(rdata2, ®ion2); 183 184 dns_name_fromregion(&name1, ®ion1); 185 dns_name_fromregion(&name2, ®ion2); 186 isc_region_consume(®ion1, name_length(&name1)); 187 isc_region_consume(®ion2, 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, ®ion); 215 RETERR(isc_buffer_copyregion(target, ®ion)); 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, ®ion); 235 236 dns_name_init(&name, NULL); 237 dns_name_fromregion(&name, ®ion); 238 isc_region_consume(®ion, 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(®ion)); 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, ®ion); 311 dns_name_init(&name, NULL); 312 dns_name_fromregion(&name, ®ion); 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