1/* $NetBSD: afsdb_18.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/* RFC1183 */ 17 18#ifndef RDATA_GENERIC_AFSDB_18_C 19#define RDATA_GENERIC_AFSDB_18_C 20 21#define RRTYPE_AFSDB_ATTRIBUTES (0) 22 23static isc_result_t 24fromtext_afsdb(ARGS_FROMTEXT) { 25 isc_token_t token; 26 isc_buffer_t buffer; 27 dns_name_t name; 28 bool ok; 29 30 REQUIRE(type == dns_rdatatype_afsdb); 31 32 UNUSED(type); 33 UNUSED(rdclass); 34 UNUSED(callbacks); 35 36 /* 37 * Subtype. 38 */ 39 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 40 false)); 41 if (token.value.as_ulong > 0xffffU) { 42 RETTOK(ISC_R_RANGE); 43 } 44 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 45 46 /* 47 * Hostname. 48 */ 49 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 50 false)); 51 dns_name_init(&name, NULL); 52 buffer_fromregion(&buffer, &token.value.as_region); 53 if (origin == NULL) { 54 origin = dns_rootname; 55 } 56 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 57 ok = true; 58 if ((options & DNS_RDATA_CHECKNAMES) != 0) { 59 ok = dns_name_ishostname(&name, false); 60 } 61 if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) { 62 RETTOK(DNS_R_BADNAME); 63 } 64 if (!ok && callbacks != NULL) { 65 warn_badname(&name, lexer, callbacks); 66 } 67 return (ISC_R_SUCCESS); 68} 69 70static isc_result_t 71totext_afsdb(ARGS_TOTEXT) { 72 dns_name_t name; 73 dns_name_t prefix; 74 isc_region_t region; 75 char buf[sizeof("64000 ")]; 76 bool sub; 77 unsigned int num; 78 79 REQUIRE(rdata->type == dns_rdatatype_afsdb); 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 num = uint16_fromregion(®ion); 87 isc_region_consume(®ion, 2); 88 snprintf(buf, sizeof(buf), "%u ", num); 89 RETERR(str_totext(buf, target)); 90 dns_name_fromregion(&name, ®ion); 91 sub = name_prefix(&name, tctx->origin, &prefix); 92 return (dns_name_totext(&prefix, sub, target)); 93} 94 95static isc_result_t 96fromwire_afsdb(ARGS_FROMWIRE) { 97 dns_name_t name; 98 isc_region_t sr; 99 isc_region_t tr; 100 101 REQUIRE(type == dns_rdatatype_afsdb); 102 103 UNUSED(type); 104 UNUSED(rdclass); 105 106 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 107 108 dns_name_init(&name, NULL); 109 110 isc_buffer_activeregion(source, &sr); 111 isc_buffer_availableregion(target, &tr); 112 if (tr.length < 2) { 113 return (ISC_R_NOSPACE); 114 } 115 if (sr.length < 2) { 116 return (ISC_R_UNEXPECTEDEND); 117 } 118 memmove(tr.base, sr.base, 2); 119 isc_buffer_forward(source, 2); 120 isc_buffer_add(target, 2); 121 return (dns_name_fromwire(&name, source, dctx, options, target)); 122} 123 124static isc_result_t 125towire_afsdb(ARGS_TOWIRE) { 126 isc_region_t tr; 127 isc_region_t sr; 128 dns_name_t name; 129 dns_offsets_t offsets; 130 131 REQUIRE(rdata->type == dns_rdatatype_afsdb); 132 REQUIRE(rdata->length != 0); 133 134 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 135 isc_buffer_availableregion(target, &tr); 136 dns_rdata_toregion(rdata, &sr); 137 if (tr.length < 2) { 138 return (ISC_R_NOSPACE); 139 } 140 memmove(tr.base, sr.base, 2); 141 isc_region_consume(&sr, 2); 142 isc_buffer_add(target, 2); 143 144 dns_name_init(&name, offsets); 145 dns_name_fromregion(&name, &sr); 146 147 return (dns_name_towire(&name, cctx, target)); 148} 149 150static int 151compare_afsdb(ARGS_COMPARE) { 152 int result; 153 dns_name_t name1; 154 dns_name_t name2; 155 isc_region_t region1; 156 isc_region_t region2; 157 158 REQUIRE(rdata1->type == rdata2->type); 159 REQUIRE(rdata1->rdclass == rdata2->rdclass); 160 REQUIRE(rdata1->type == dns_rdatatype_afsdb); 161 REQUIRE(rdata1->length != 0); 162 REQUIRE(rdata2->length != 0); 163 164 result = memcmp(rdata1->data, rdata2->data, 2); 165 if (result != 0) { 166 return (result < 0 ? -1 : 1); 167 } 168 169 dns_name_init(&name1, NULL); 170 dns_name_init(&name2, NULL); 171 172 dns_rdata_toregion(rdata1, ®ion1); 173 dns_rdata_toregion(rdata2, ®ion2); 174 175 isc_region_consume(®ion1, 2); 176 isc_region_consume(®ion2, 2); 177 178 dns_name_fromregion(&name1, ®ion1); 179 dns_name_fromregion(&name2, ®ion2); 180 181 return (dns_name_rdatacompare(&name1, &name2)); 182} 183 184static isc_result_t 185fromstruct_afsdb(ARGS_FROMSTRUCT) { 186 dns_rdata_afsdb_t *afsdb = source; 187 isc_region_t region; 188 189 REQUIRE(type == dns_rdatatype_afsdb); 190 REQUIRE(afsdb != NULL); 191 REQUIRE(afsdb->common.rdclass == rdclass); 192 REQUIRE(afsdb->common.rdtype == type); 193 194 UNUSED(type); 195 UNUSED(rdclass); 196 197 RETERR(uint16_tobuffer(afsdb->subtype, target)); 198 dns_name_toregion(&afsdb->server, ®ion); 199 return (isc_buffer_copyregion(target, ®ion)); 200} 201 202static isc_result_t 203tostruct_afsdb(ARGS_TOSTRUCT) { 204 isc_region_t region; 205 dns_rdata_afsdb_t *afsdb = target; 206 dns_name_t name; 207 208 REQUIRE(rdata->type == dns_rdatatype_afsdb); 209 REQUIRE(afsdb != NULL); 210 REQUIRE(rdata->length != 0); 211 212 afsdb->common.rdclass = rdata->rdclass; 213 afsdb->common.rdtype = rdata->type; 214 ISC_LINK_INIT(&afsdb->common, link); 215 216 dns_name_init(&afsdb->server, NULL); 217 218 dns_rdata_toregion(rdata, ®ion); 219 220 afsdb->subtype = uint16_fromregion(®ion); 221 isc_region_consume(®ion, 2); 222 223 dns_name_init(&name, NULL); 224 dns_name_fromregion(&name, ®ion); 225 226 RETERR(name_duporclone(&name, mctx, &afsdb->server)); 227 afsdb->mctx = mctx; 228 return (ISC_R_SUCCESS); 229} 230 231static void 232freestruct_afsdb(ARGS_FREESTRUCT) { 233 dns_rdata_afsdb_t *afsdb = source; 234 235 REQUIRE(afsdb != NULL); 236 REQUIRE(afsdb->common.rdtype == dns_rdatatype_afsdb); 237 238 if (afsdb->mctx == NULL) { 239 return; 240 } 241 242 dns_name_free(&afsdb->server, afsdb->mctx); 243 afsdb->mctx = NULL; 244} 245 246static isc_result_t 247additionaldata_afsdb(ARGS_ADDLDATA) { 248 dns_name_t name; 249 dns_offsets_t offsets; 250 isc_region_t region; 251 252 REQUIRE(rdata->type == dns_rdatatype_afsdb); 253 254 dns_name_init(&name, offsets); 255 dns_rdata_toregion(rdata, ®ion); 256 isc_region_consume(®ion, 2); 257 dns_name_fromregion(&name, ®ion); 258 259 return ((add)(arg, &name, dns_rdatatype_a)); 260} 261 262static isc_result_t 263digest_afsdb(ARGS_DIGEST) { 264 isc_region_t r1, r2; 265 dns_name_t name; 266 267 REQUIRE(rdata->type == dns_rdatatype_afsdb); 268 269 dns_rdata_toregion(rdata, &r1); 270 r2 = r1; 271 isc_region_consume(&r2, 2); 272 r1.length = 2; 273 RETERR((digest)(arg, &r1)); 274 dns_name_init(&name, NULL); 275 dns_name_fromregion(&name, &r2); 276 277 return (dns_name_digest(&name, digest, arg)); 278} 279 280static bool 281checkowner_afsdb(ARGS_CHECKOWNER) { 282 REQUIRE(type == dns_rdatatype_afsdb); 283 284 UNUSED(name); 285 UNUSED(type); 286 UNUSED(rdclass); 287 UNUSED(wildcard); 288 289 return (true); 290} 291 292static bool 293checknames_afsdb(ARGS_CHECKNAMES) { 294 isc_region_t region; 295 dns_name_t name; 296 297 REQUIRE(rdata->type == dns_rdatatype_afsdb); 298 299 UNUSED(owner); 300 301 dns_rdata_toregion(rdata, ®ion); 302 isc_region_consume(®ion, 2); 303 dns_name_init(&name, NULL); 304 dns_name_fromregion(&name, ®ion); 305 if (!dns_name_ishostname(&name, false)) { 306 if (bad != NULL) { 307 dns_name_clone(&name, bad); 308 } 309 return (false); 310 } 311 return (true); 312} 313 314static int 315casecompare_afsdb(ARGS_COMPARE) { 316 return (compare_afsdb(rdata1, rdata2)); 317} 318#endif /* RDATA_GENERIC_AFSDB_18_C */ 319