1/* $NetBSD: rt_21.c,v 1.8 2024/02/21 22:52:14 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 23static isc_result_t 24fromtext_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 65static isc_result_t 66totext_rt(ARGS_TOTEXT) { 67 isc_region_t region; 68 dns_name_t name; 69 dns_name_t prefix; 70 bool sub; 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 sub = name_prefix(&name, tctx->origin, &prefix); 88 return (dns_name_totext(&prefix, sub, target)); 89} 90 91static isc_result_t 92fromwire_rt(ARGS_FROMWIRE) { 93 dns_name_t name; 94 isc_region_t sregion; 95 isc_region_t tregion; 96 97 REQUIRE(type == dns_rdatatype_rt); 98 99 UNUSED(type); 100 UNUSED(rdclass); 101 102 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 103 104 dns_name_init(&name, NULL); 105 106 isc_buffer_activeregion(source, &sregion); 107 isc_buffer_availableregion(target, &tregion); 108 if (tregion.length < 2) { 109 return (ISC_R_NOSPACE); 110 } 111 if (sregion.length < 2) { 112 return (ISC_R_UNEXPECTEDEND); 113 } 114 memmove(tregion.base, sregion.base, 2); 115 isc_buffer_forward(source, 2); 116 isc_buffer_add(target, 2); 117 return (dns_name_fromwire(&name, source, dctx, options, target)); 118} 119 120static isc_result_t 121towire_rt(ARGS_TOWIRE) { 122 dns_name_t name; 123 dns_offsets_t offsets; 124 isc_region_t region; 125 isc_region_t tr; 126 127 REQUIRE(rdata->type == dns_rdatatype_rt); 128 REQUIRE(rdata->length != 0); 129 130 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 131 isc_buffer_availableregion(target, &tr); 132 dns_rdata_toregion(rdata, ®ion); 133 if (tr.length < 2) { 134 return (ISC_R_NOSPACE); 135 } 136 memmove(tr.base, region.base, 2); 137 isc_region_consume(®ion, 2); 138 isc_buffer_add(target, 2); 139 140 dns_name_init(&name, offsets); 141 dns_name_fromregion(&name, ®ion); 142 143 return (dns_name_towire(&name, cctx, target)); 144} 145 146static int 147compare_rt(ARGS_COMPARE) { 148 dns_name_t name1; 149 dns_name_t name2; 150 isc_region_t region1; 151 isc_region_t region2; 152 int order; 153 154 REQUIRE(rdata1->type == rdata2->type); 155 REQUIRE(rdata1->rdclass == rdata2->rdclass); 156 REQUIRE(rdata1->type == dns_rdatatype_rt); 157 REQUIRE(rdata1->length != 0); 158 REQUIRE(rdata2->length != 0); 159 160 order = memcmp(rdata1->data, rdata2->data, 2); 161 if (order != 0) { 162 return (order < 0 ? -1 : 1); 163 } 164 165 dns_name_init(&name1, NULL); 166 dns_name_init(&name2, NULL); 167 168 dns_rdata_toregion(rdata1, ®ion1); 169 dns_rdata_toregion(rdata2, ®ion2); 170 171 isc_region_consume(®ion1, 2); 172 isc_region_consume(®ion2, 2); 173 174 dns_name_fromregion(&name1, ®ion1); 175 dns_name_fromregion(&name2, ®ion2); 176 177 return (dns_name_rdatacompare(&name1, &name2)); 178} 179 180static isc_result_t 181fromstruct_rt(ARGS_FROMSTRUCT) { 182 dns_rdata_rt_t *rt = source; 183 isc_region_t region; 184 185 REQUIRE(type == dns_rdatatype_rt); 186 REQUIRE(rt != NULL); 187 REQUIRE(rt->common.rdtype == type); 188 REQUIRE(rt->common.rdclass == rdclass); 189 190 UNUSED(type); 191 UNUSED(rdclass); 192 193 RETERR(uint16_tobuffer(rt->preference, target)); 194 dns_name_toregion(&rt->host, ®ion); 195 return (isc_buffer_copyregion(target, ®ion)); 196} 197 198static isc_result_t 199tostruct_rt(ARGS_TOSTRUCT) { 200 isc_region_t region; 201 dns_rdata_rt_t *rt = target; 202 dns_name_t name; 203 204 REQUIRE(rdata->type == dns_rdatatype_rt); 205 REQUIRE(rt != NULL); 206 REQUIRE(rdata->length != 0); 207 208 rt->common.rdclass = rdata->rdclass; 209 rt->common.rdtype = rdata->type; 210 ISC_LINK_INIT(&rt->common, link); 211 212 dns_name_init(&name, NULL); 213 dns_rdata_toregion(rdata, ®ion); 214 rt->preference = uint16_fromregion(®ion); 215 isc_region_consume(®ion, 2); 216 dns_name_fromregion(&name, ®ion); 217 dns_name_init(&rt->host, NULL); 218 name_duporclone(&name, mctx, &rt->host); 219 220 rt->mctx = mctx; 221 return (ISC_R_SUCCESS); 222} 223 224static void 225freestruct_rt(ARGS_FREESTRUCT) { 226 dns_rdata_rt_t *rt = source; 227 228 REQUIRE(rt != NULL); 229 REQUIRE(rt->common.rdtype == dns_rdatatype_rt); 230 231 if (rt->mctx == NULL) { 232 return; 233 } 234 235 dns_name_free(&rt->host, rt->mctx); 236 rt->mctx = NULL; 237} 238 239static isc_result_t 240additionaldata_rt(ARGS_ADDLDATA) { 241 dns_name_t name; 242 dns_offsets_t offsets; 243 isc_region_t region; 244 isc_result_t result; 245 246 REQUIRE(rdata->type == dns_rdatatype_rt); 247 248 UNUSED(owner); 249 250 dns_name_init(&name, offsets); 251 dns_rdata_toregion(rdata, ®ion); 252 isc_region_consume(®ion, 2); 253 dns_name_fromregion(&name, ®ion); 254 255 result = (add)(arg, &name, dns_rdatatype_x25, NULL); 256 if (result != ISC_R_SUCCESS) { 257 return (result); 258 } 259 result = (add)(arg, &name, dns_rdatatype_isdn, NULL); 260 if (result != ISC_R_SUCCESS) { 261 return (result); 262 } 263 return ((add)(arg, &name, dns_rdatatype_a, NULL)); 264} 265 266static isc_result_t 267digest_rt(ARGS_DIGEST) { 268 isc_region_t r1, r2; 269 isc_result_t result; 270 dns_name_t name; 271 272 REQUIRE(rdata->type == dns_rdatatype_rt); 273 274 dns_rdata_toregion(rdata, &r1); 275 r2 = r1; 276 isc_region_consume(&r2, 2); 277 r1.length = 2; 278 result = (digest)(arg, &r1); 279 if (result != ISC_R_SUCCESS) { 280 return (result); 281 } 282 dns_name_init(&name, NULL); 283 dns_name_fromregion(&name, &r2); 284 return (dns_name_digest(&name, digest, arg)); 285} 286 287static bool 288checkowner_rt(ARGS_CHECKOWNER) { 289 REQUIRE(type == dns_rdatatype_rt); 290 291 UNUSED(name); 292 UNUSED(type); 293 UNUSED(rdclass); 294 UNUSED(wildcard); 295 296 return (true); 297} 298 299static bool 300checknames_rt(ARGS_CHECKNAMES) { 301 isc_region_t region; 302 dns_name_t name; 303 304 REQUIRE(rdata->type == dns_rdatatype_rt); 305 306 UNUSED(owner); 307 308 dns_rdata_toregion(rdata, ®ion); 309 isc_region_consume(®ion, 2); 310 dns_name_init(&name, NULL); 311 dns_name_fromregion(&name, ®ion); 312 if (!dns_name_ishostname(&name, false)) { 313 if (bad != NULL) { 314 dns_name_clone(&name, bad); 315 } 316 return (false); 317 } 318 return (true); 319} 320 321static int 322casecompare_rt(ARGS_COMPARE) { 323 return (compare_rt(rdata1, rdata2)); 324} 325 326#endif /* RDATA_GENERIC_RT_21_C */ 327