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