nxt_30.c revision 1.4
1/* $NetBSD: nxt_30.c,v 1.4 2019/11/27 05:48:42 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14/* RFC2535 */ 15 16#ifndef RDATA_GENERIC_NXT_30_C 17#define RDATA_GENERIC_NXT_30_C 18 19/* 20 * The attributes do not include DNS_RDATATYPEATTR_SINGLETON 21 * because we must be able to handle a parent/child NXT pair. 22 */ 23#define RRTYPE_NXT_ATTRIBUTES (0) 24 25static inline isc_result_t 26fromtext_nxt(ARGS_FROMTEXT) { 27 isc_token_t token; 28 dns_name_t name; 29 isc_buffer_t buffer; 30 char *e; 31 unsigned char bm[8*1024]; /* 64k bits */ 32 dns_rdatatype_t covered; 33 dns_rdatatype_t maxcovered = 0; 34 bool first = true; 35 long n; 36 37 REQUIRE(type == dns_rdatatype_nxt); 38 39 UNUSED(type); 40 UNUSED(rdclass); 41 UNUSED(callbacks); 42 43 /* 44 * Next domain. 45 */ 46 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 47 false)); 48 dns_name_init(&name, NULL); 49 buffer_fromregion(&buffer, &token.value.as_region); 50 if (origin == NULL) 51 origin = dns_rootname; 52 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 53 54 memset(bm, 0, sizeof(bm)); 55 do { 56 RETERR(isc_lex_getmastertoken(lexer, &token, 57 isc_tokentype_string, true)); 58 if (token.type != isc_tokentype_string) 59 break; 60 n = strtol(DNS_AS_STR(token), &e, 10); 61 if (e != DNS_AS_STR(token) && *e == '\0') { 62 covered = (dns_rdatatype_t)n; 63 } else if (dns_rdatatype_fromtext(&covered, 64 &token.value.as_textregion) == DNS_R_UNKNOWN) 65 RETTOK(DNS_R_UNKNOWN); 66 /* 67 * NXT is only specified for types 1..127. 68 */ 69 if (covered < 1 || covered > 127) 70 return (ISC_R_RANGE); 71 if (first || covered > maxcovered) 72 maxcovered = covered; 73 first = false; 74 bm[covered/8] |= (0x80>>(covered%8)); 75 } while (1); 76 isc_lex_ungettoken(lexer, &token); 77 if (first) 78 return (ISC_R_SUCCESS); 79 n = (maxcovered + 8) / 8; 80 return (mem_tobuffer(target, bm, n)); 81} 82 83static inline isc_result_t 84totext_nxt(ARGS_TOTEXT) { 85 isc_region_t sr; 86 unsigned int i, j; 87 dns_name_t name; 88 dns_name_t prefix; 89 bool sub; 90 91 REQUIRE(rdata->type == dns_rdatatype_nxt); 92 REQUIRE(rdata->length != 0); 93 94 dns_name_init(&name, NULL); 95 dns_name_init(&prefix, NULL); 96 dns_rdata_toregion(rdata, &sr); 97 dns_name_fromregion(&name, &sr); 98 isc_region_consume(&sr, name_length(&name)); 99 sub = name_prefix(&name, tctx->origin, &prefix); 100 RETERR(dns_name_totext(&prefix, sub, target)); 101 102 for (i = 0; i < sr.length; i++) { 103 if (sr.base[i] != 0) 104 for (j = 0; j < 8; j++) 105 if ((sr.base[i] & (0x80 >> j)) != 0) { 106 dns_rdatatype_t t = i * 8 + j; 107 RETERR(str_totext(" ", target)); 108 if (dns_rdatatype_isknown(t)) { 109 RETERR(dns_rdatatype_totext(t, 110 target)); 111 } else { 112 char buf[sizeof("65535")]; 113 snprintf(buf, sizeof(buf), 114 "%u", t); 115 RETERR(str_totext(buf, 116 target)); 117 } 118 } 119 } 120 return (ISC_R_SUCCESS); 121} 122 123static inline isc_result_t 124fromwire_nxt(ARGS_FROMWIRE) { 125 isc_region_t sr; 126 dns_name_t name; 127 128 REQUIRE(type == dns_rdatatype_nxt); 129 130 UNUSED(type); 131 UNUSED(rdclass); 132 133 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 134 135 dns_name_init(&name, NULL); 136 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 137 138 isc_buffer_activeregion(source, &sr); 139 if (sr.length > 0 && (sr.base[0] & 0x80) == 0 && 140 ((sr.length > 16) || sr.base[sr.length - 1] == 0)) 141 return (DNS_R_BADBITMAP); 142 RETERR(mem_tobuffer(target, sr.base, sr.length)); 143 isc_buffer_forward(source, sr.length); 144 return (ISC_R_SUCCESS); 145} 146 147static inline isc_result_t 148towire_nxt(ARGS_TOWIRE) { 149 isc_region_t sr; 150 dns_name_t name; 151 dns_offsets_t offsets; 152 153 REQUIRE(rdata->type == dns_rdatatype_nxt); 154 REQUIRE(rdata->length != 0); 155 156 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 157 dns_name_init(&name, offsets); 158 dns_rdata_toregion(rdata, &sr); 159 dns_name_fromregion(&name, &sr); 160 isc_region_consume(&sr, name_length(&name)); 161 RETERR(dns_name_towire(&name, cctx, target)); 162 163 return (mem_tobuffer(target, sr.base, sr.length)); 164} 165 166static inline int 167compare_nxt(ARGS_COMPARE) { 168 isc_region_t r1; 169 isc_region_t r2; 170 dns_name_t name1; 171 dns_name_t name2; 172 int order; 173 174 REQUIRE(rdata1->type == rdata2->type); 175 REQUIRE(rdata1->rdclass == rdata2->rdclass); 176 REQUIRE(rdata1->type == dns_rdatatype_nxt); 177 REQUIRE(rdata1->length != 0); 178 REQUIRE(rdata2->length != 0); 179 180 dns_name_init(&name1, NULL); 181 dns_name_init(&name2, NULL); 182 dns_rdata_toregion(rdata1, &r1); 183 dns_rdata_toregion(rdata2, &r2); 184 dns_name_fromregion(&name1, &r1); 185 dns_name_fromregion(&name2, &r2); 186 order = dns_name_rdatacompare(&name1, &name2); 187 if (order != 0) 188 return (order); 189 190 isc_region_consume(&r1, name_length(&name1)); 191 isc_region_consume(&r2, name_length(&name2)); 192 193 return (isc_region_compare(&r1, &r2)); 194} 195 196static inline isc_result_t 197fromstruct_nxt(ARGS_FROMSTRUCT) { 198 dns_rdata_nxt_t *nxt = source; 199 isc_region_t region; 200 201 REQUIRE(type == dns_rdatatype_nxt); 202 REQUIRE(nxt != NULL); 203 REQUIRE(nxt->common.rdtype == type); 204 REQUIRE(nxt->common.rdclass == rdclass); 205 REQUIRE(nxt->typebits != NULL || nxt->len == 0); 206 if (nxt->typebits != NULL && (nxt->typebits[0] & 0x80) == 0) { 207 REQUIRE(nxt->len <= 16); 208 REQUIRE(nxt->typebits[nxt->len - 1] != 0); 209 } 210 211 UNUSED(type); 212 UNUSED(rdclass); 213 214 dns_name_toregion(&nxt->next, ®ion); 215 RETERR(isc_buffer_copyregion(target, ®ion)); 216 217 return (mem_tobuffer(target, nxt->typebits, nxt->len)); 218} 219 220static inline isc_result_t 221tostruct_nxt(ARGS_TOSTRUCT) { 222 isc_region_t region; 223 dns_rdata_nxt_t *nxt = target; 224 dns_name_t name; 225 226 REQUIRE(rdata->type == dns_rdatatype_nxt); 227 REQUIRE(nxt != NULL); 228 REQUIRE(rdata->length != 0); 229 230 nxt->common.rdclass = rdata->rdclass; 231 nxt->common.rdtype = rdata->type; 232 ISC_LINK_INIT(&nxt->common, link); 233 234 dns_name_init(&name, NULL); 235 dns_rdata_toregion(rdata, ®ion); 236 dns_name_fromregion(&name, ®ion); 237 isc_region_consume(®ion, name_length(&name)); 238 dns_name_init(&nxt->next, NULL); 239 RETERR(name_duporclone(&name, mctx, &nxt->next)); 240 241 nxt->len = region.length; 242 nxt->typebits = mem_maybedup(mctx, region.base, region.length); 243 if (nxt->typebits == NULL) 244 goto cleanup; 245 246 nxt->mctx = mctx; 247 return (ISC_R_SUCCESS); 248 249 cleanup: 250 if (mctx != NULL) 251 dns_name_free(&nxt->next, mctx); 252 return (ISC_R_NOMEMORY); 253} 254 255static inline void 256freestruct_nxt(ARGS_FREESTRUCT) { 257 dns_rdata_nxt_t *nxt = source; 258 259 REQUIRE(nxt != NULL); 260 REQUIRE(nxt->common.rdtype == dns_rdatatype_nxt); 261 262 if (nxt->mctx == NULL) 263 return; 264 265 dns_name_free(&nxt->next, nxt->mctx); 266 if (nxt->typebits != NULL) 267 isc_mem_free(nxt->mctx, nxt->typebits); 268 nxt->mctx = NULL; 269} 270 271static inline isc_result_t 272additionaldata_nxt(ARGS_ADDLDATA) { 273 REQUIRE(rdata->type == dns_rdatatype_nxt); 274 275 UNUSED(rdata); 276 UNUSED(add); 277 UNUSED(arg); 278 279 return (ISC_R_SUCCESS); 280} 281 282static inline isc_result_t 283digest_nxt(ARGS_DIGEST) { 284 isc_region_t r; 285 dns_name_t name; 286 isc_result_t result; 287 288 REQUIRE(rdata->type == dns_rdatatype_nxt); 289 290 dns_rdata_toregion(rdata, &r); 291 dns_name_init(&name, NULL); 292 dns_name_fromregion(&name, &r); 293 result = dns_name_digest(&name, digest, arg); 294 if (result != ISC_R_SUCCESS) 295 return (result); 296 isc_region_consume(&r, name_length(&name)); 297 298 return ((digest)(arg, &r)); 299} 300 301static inline bool 302checkowner_nxt(ARGS_CHECKOWNER) { 303 304 REQUIRE(type == dns_rdatatype_nxt); 305 306 UNUSED(name); 307 UNUSED(type); 308 UNUSED(rdclass); 309 UNUSED(wildcard); 310 311 return (true); 312} 313 314static inline bool 315checknames_nxt(ARGS_CHECKNAMES) { 316 317 REQUIRE(rdata->type == dns_rdatatype_nxt); 318 319 UNUSED(rdata); 320 UNUSED(owner); 321 UNUSED(bad); 322 323 return (true); 324} 325 326static inline int 327casecompare_nxt(ARGS_COMPARE) { 328 return (compare_nxt(rdata1, rdata2)); 329} 330#endif /* RDATA_GENERIC_NXT_30_C */ 331