00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef RDATA_IN_1_A6_28_C
00023 #define RDATA_IN_1_A6_28_C
00024
00025 #include <isc/net.h>
00026
00027 #define RRTYPE_A6_ATTRIBUTES (0)
00028
00029 static inline isc_result_t
00030 fromtext_in_a6(ARGS_FROMTEXT) {
00031 isc_token_t token;
00032 unsigned char addr[16];
00033 unsigned char prefixlen;
00034 unsigned char octets;
00035 unsigned char mask;
00036 dns_name_t name;
00037 isc_buffer_t buffer;
00038 isc_boolean_t ok;
00039
00040 REQUIRE(type == 38);
00041 REQUIRE(rdclass == 1);
00042
00043 UNUSED(type);
00044 UNUSED(rdclass);
00045 UNUSED(callbacks);
00046
00047
00048
00049
00050 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00051 ISC_FALSE));
00052 if (token.value.as_ulong > 128U)
00053 RETTOK(ISC_R_RANGE);
00054
00055 prefixlen = (unsigned char)token.value.as_ulong;
00056 RETERR(mem_tobuffer(target, &prefixlen, 1));
00057
00058
00059
00060
00061 if (prefixlen != 128) {
00062
00063
00064
00065 octets = prefixlen/8;
00066
00067
00068
00069 RETERR(isc_lex_getmastertoken(lexer, &token,
00070 isc_tokentype_string,
00071 ISC_FALSE));
00072 if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1)
00073 RETTOK(DNS_R_BADAAAA);
00074 mask = 0xff >> (prefixlen % 8);
00075 addr[octets] &= mask;
00076 RETERR(mem_tobuffer(target, &addr[octets], 16 - octets));
00077 }
00078
00079 if (prefixlen == 0)
00080 return (ISC_R_SUCCESS);
00081
00082 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00083 ISC_FALSE));
00084 dns_name_init(&name, NULL);
00085 buffer_fromregion(&buffer, &token.value.as_region);
00086 origin = (origin != NULL) ? origin : dns_rootname;
00087 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00088 ok = ISC_TRUE;
00089 if ((options & DNS_RDATA_CHECKNAMES) != 0)
00090 ok = dns_name_ishostname(&name, ISC_FALSE);
00091 if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
00092 RETTOK(DNS_R_BADNAME);
00093 if (!ok && callbacks != NULL)
00094 warn_badname(&name, lexer, callbacks);
00095 return (ISC_R_SUCCESS);
00096 }
00097
00098 static inline isc_result_t
00099 totext_in_a6(ARGS_TOTEXT) {
00100 isc_region_t sr, ar;
00101 unsigned char addr[16];
00102 unsigned char prefixlen;
00103 unsigned char octets;
00104 unsigned char mask;
00105 char buf[sizeof("128")];
00106 dns_name_t name;
00107 dns_name_t prefix;
00108 isc_boolean_t sub;
00109
00110 REQUIRE(rdata->type == 38);
00111 REQUIRE(rdata->rdclass == 1);
00112 REQUIRE(rdata->length != 0);
00113
00114 dns_rdata_toregion(rdata, &sr);
00115 prefixlen = sr.base[0];
00116 INSIST(prefixlen <= 128);
00117 isc_region_consume(&sr, 1);
00118 sprintf(buf, "%u", prefixlen);
00119 RETERR(str_totext(buf, target));
00120 RETERR(str_totext(" ", target));
00121
00122 if (prefixlen != 128) {
00123 octets = prefixlen/8;
00124 memset(addr, 0, sizeof(addr));
00125 memmove(&addr[octets], sr.base, 16 - octets);
00126 mask = 0xff >> (prefixlen % 8);
00127 addr[octets] &= mask;
00128 ar.base = addr;
00129 ar.length = sizeof(addr);
00130 RETERR(inet_totext(AF_INET6, &ar, target));
00131 isc_region_consume(&sr, 16 - octets);
00132 }
00133
00134 if (prefixlen == 0)
00135 return (ISC_R_SUCCESS);
00136
00137 RETERR(str_totext(" ", target));
00138 dns_name_init(&name, NULL);
00139 dns_name_init(&prefix, NULL);
00140 dns_name_fromregion(&name, &sr);
00141 sub = name_prefix(&name, tctx->origin, &prefix);
00142 return (dns_name_totext(&prefix, sub, target));
00143 }
00144
00145 static inline isc_result_t
00146 fromwire_in_a6(ARGS_FROMWIRE) {
00147 isc_region_t sr;
00148 unsigned char prefixlen;
00149 unsigned char octets;
00150 unsigned char mask;
00151 dns_name_t name;
00152
00153 REQUIRE(type == 38);
00154 REQUIRE(rdclass == 1);
00155
00156 UNUSED(type);
00157 UNUSED(rdclass);
00158
00159 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00160
00161 isc_buffer_activeregion(source, &sr);
00162
00163
00164
00165 if (sr.length < 1)
00166 return (ISC_R_UNEXPECTEDEND);
00167 prefixlen = sr.base[0];
00168 if (prefixlen > 128)
00169 return (ISC_R_RANGE);
00170 isc_region_consume(&sr, 1);
00171 RETERR(mem_tobuffer(target, &prefixlen, 1));
00172 isc_buffer_forward(source, 1);
00173
00174
00175
00176
00177 if (prefixlen != 128) {
00178 octets = 16 - prefixlen / 8;
00179 if (sr.length < octets)
00180 return (ISC_R_UNEXPECTEDEND);
00181 mask = 0xff >> (prefixlen % 8);
00182 sr.base[0] &= mask;
00183 RETERR(mem_tobuffer(target, sr.base, octets));
00184 isc_buffer_forward(source, octets);
00185 }
00186
00187 if (prefixlen == 0)
00188 return (ISC_R_SUCCESS);
00189
00190 dns_name_init(&name, NULL);
00191 return (dns_name_fromwire(&name, source, dctx, options, target));
00192 }
00193
00194 static inline isc_result_t
00195 towire_in_a6(ARGS_TOWIRE) {
00196 isc_region_t sr;
00197 dns_name_t name;
00198 dns_offsets_t offsets;
00199 unsigned char prefixlen;
00200 unsigned char octets;
00201
00202 REQUIRE(rdata->type == 38);
00203 REQUIRE(rdata->rdclass == 1);
00204 REQUIRE(rdata->length != 0);
00205
00206 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
00207 dns_rdata_toregion(rdata, &sr);
00208 prefixlen = sr.base[0];
00209 INSIST(prefixlen <= 128);
00210
00211 octets = 1 + 16 - prefixlen / 8;
00212 RETERR(mem_tobuffer(target, sr.base, octets));
00213 isc_region_consume(&sr, octets);
00214
00215 if (prefixlen == 0)
00216 return (ISC_R_SUCCESS);
00217
00218 dns_name_init(&name, offsets);
00219 dns_name_fromregion(&name, &sr);
00220 return (dns_name_towire(&name, cctx, target));
00221 }
00222
00223 static inline int
00224 compare_in_a6(ARGS_COMPARE) {
00225 int order;
00226 unsigned char prefixlen1, prefixlen2;
00227 unsigned char octets;
00228 dns_name_t name1;
00229 dns_name_t name2;
00230 isc_region_t region1;
00231 isc_region_t region2;
00232
00233 REQUIRE(rdata1->type == rdata2->type);
00234 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00235 REQUIRE(rdata1->type == 38);
00236 REQUIRE(rdata1->rdclass == 1);
00237 REQUIRE(rdata1->length != 0);
00238 REQUIRE(rdata2->length != 0);
00239
00240 dns_rdata_toregion(rdata1, ®ion1);
00241 dns_rdata_toregion(rdata2, ®ion2);
00242 prefixlen1 = region1.base[0];
00243 prefixlen2 = region2.base[0];
00244 isc_region_consume(®ion1, 1);
00245 isc_region_consume(®ion2, 1);
00246 if (prefixlen1 < prefixlen2)
00247 return (-1);
00248 else if (prefixlen1 > prefixlen2)
00249 return (1);
00250
00251
00252
00253 octets = 16 - prefixlen1 / 8;
00254
00255 if (octets > 0) {
00256 order = memcmp(region1.base, region2.base, octets);
00257 if (order < 0)
00258 return (-1);
00259 else if (order > 0)
00260 return (1);
00261
00262
00263
00264 if (prefixlen1 == 0)
00265 return (order);
00266 isc_region_consume(®ion1, octets);
00267 isc_region_consume(®ion2, octets);
00268 }
00269
00270 dns_name_init(&name1, NULL);
00271 dns_name_init(&name2, NULL);
00272 dns_name_fromregion(&name1, ®ion1);
00273 dns_name_fromregion(&name2, ®ion2);
00274 return (dns_name_rdatacompare(&name1, &name2));
00275 }
00276
00277 static inline isc_result_t
00278 fromstruct_in_a6(ARGS_FROMSTRUCT) {
00279 dns_rdata_in_a6_t *a6 = source;
00280 isc_region_t region;
00281 int octets;
00282 isc_uint8_t bits;
00283 isc_uint8_t first;
00284 isc_uint8_t mask;
00285
00286 REQUIRE(type == 38);
00287 REQUIRE(rdclass == 1);
00288 REQUIRE(source != NULL);
00289 REQUIRE(a6->common.rdtype == type);
00290 REQUIRE(a6->common.rdclass == rdclass);
00291
00292 UNUSED(type);
00293 UNUSED(rdclass);
00294
00295 if (a6->prefixlen > 128)
00296 return (ISC_R_RANGE);
00297
00298 RETERR(uint8_tobuffer(a6->prefixlen, target));
00299
00300
00301 if (a6->prefixlen != 128) {
00302 octets = 16 - a6->prefixlen / 8;
00303 bits = a6->prefixlen % 8;
00304 if (bits != 0) {
00305 mask = 0xffU >> bits;
00306 first = a6->in6_addr.s6_addr[16 - octets] & mask;
00307 RETERR(uint8_tobuffer(first, target));
00308 octets--;
00309 }
00310 if (octets > 0)
00311 RETERR(mem_tobuffer(target,
00312 a6->in6_addr.s6_addr + 16 - octets,
00313 octets));
00314 }
00315
00316 if (a6->prefixlen == 0)
00317 return (ISC_R_SUCCESS);
00318 dns_name_toregion(&a6->prefix, ®ion);
00319 return (isc_buffer_copyregion(target, ®ion));
00320 }
00321
00322 static inline isc_result_t
00323 tostruct_in_a6(ARGS_TOSTRUCT) {
00324 dns_rdata_in_a6_t *a6 = target;
00325 unsigned char octets;
00326 dns_name_t name;
00327 isc_region_t r;
00328
00329 REQUIRE(rdata->type == 38);
00330 REQUIRE(rdata->rdclass == 1);
00331 REQUIRE(target != NULL);
00332 REQUIRE(rdata->length != 0);
00333
00334 a6->common.rdclass = rdata->rdclass;
00335 a6->common.rdtype = rdata->type;
00336 ISC_LINK_INIT(&a6->common, link);
00337
00338 dns_rdata_toregion(rdata, &r);
00339
00340 a6->prefixlen = uint8_fromregion(&r);
00341 isc_region_consume(&r, 1);
00342 memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr));
00343
00344
00345
00346
00347 if (a6->prefixlen != 128) {
00348 octets = 16 - a6->prefixlen / 8;
00349 INSIST(r.length >= octets);
00350 memmove(a6->in6_addr.s6_addr + 16 - octets, r.base, octets);
00351 isc_region_consume(&r, octets);
00352 }
00353
00354
00355
00356
00357 dns_name_init(&a6->prefix, NULL);
00358 if (a6->prefixlen != 0) {
00359 dns_name_init(&name, NULL);
00360 dns_name_fromregion(&name, &r);
00361 RETERR(name_duporclone(&name, mctx, &a6->prefix));
00362 }
00363 a6->mctx = mctx;
00364 return (ISC_R_SUCCESS);
00365 }
00366
00367 static inline void
00368 freestruct_in_a6(ARGS_FREESTRUCT) {
00369 dns_rdata_in_a6_t *a6 = source;
00370
00371 REQUIRE(source != NULL);
00372 REQUIRE(a6->common.rdclass == 1);
00373 REQUIRE(a6->common.rdtype == 38);
00374
00375 if (a6->mctx == NULL)
00376 return;
00377
00378 if (dns_name_dynamic(&a6->prefix))
00379 dns_name_free(&a6->prefix, a6->mctx);
00380 a6->mctx = NULL;
00381 }
00382
00383 static inline isc_result_t
00384 additionaldata_in_a6(ARGS_ADDLDATA) {
00385 REQUIRE(rdata->type == 38);
00386 REQUIRE(rdata->rdclass == 1);
00387
00388 UNUSED(rdata);
00389 UNUSED(add);
00390 UNUSED(arg);
00391
00392 return (ISC_R_SUCCESS);
00393 }
00394
00395 static inline isc_result_t
00396 digest_in_a6(ARGS_DIGEST) {
00397 isc_region_t r1, r2;
00398 unsigned char prefixlen, octets;
00399 isc_result_t result;
00400 dns_name_t name;
00401
00402 REQUIRE(rdata->type == 38);
00403 REQUIRE(rdata->rdclass == 1);
00404
00405 dns_rdata_toregion(rdata, &r1);
00406 r2 = r1;
00407 prefixlen = r1.base[0];
00408 octets = 1 + 16 - prefixlen / 8;
00409
00410 r1.length = octets;
00411 result = (digest)(arg, &r1);
00412 if (result != ISC_R_SUCCESS)
00413 return (result);
00414 if (prefixlen == 0)
00415 return (ISC_R_SUCCESS);
00416
00417 isc_region_consume(&r2, octets);
00418 dns_name_init(&name, NULL);
00419 dns_name_fromregion(&name, &r2);
00420 return (dns_name_digest(&name, digest, arg));
00421 }
00422
00423 static inline isc_boolean_t
00424 checkowner_in_a6(ARGS_CHECKOWNER) {
00425
00426 REQUIRE(type == 38);
00427 REQUIRE(rdclass == 1);
00428
00429 UNUSED(type);
00430 UNUSED(rdclass);
00431
00432 return (dns_name_ishostname(name, wildcard));
00433 }
00434
00435 static inline isc_boolean_t
00436 checknames_in_a6(ARGS_CHECKNAMES) {
00437 isc_region_t region;
00438 dns_name_t name;
00439 unsigned int prefixlen;
00440
00441 REQUIRE(rdata->type == 38);
00442 REQUIRE(rdata->rdclass == 1);
00443
00444 UNUSED(owner);
00445
00446 dns_rdata_toregion(rdata, ®ion);
00447 prefixlen = uint8_fromregion(®ion);
00448 if (prefixlen == 0)
00449 return (ISC_TRUE);
00450 isc_region_consume(®ion, 1 + 16 - prefixlen / 8);
00451 dns_name_init(&name, NULL);
00452 dns_name_fromregion(&name, ®ion);
00453 if (!dns_name_ishostname(&name, ISC_FALSE)) {
00454 if (bad != NULL)
00455 dns_name_clone(&name, bad);
00456 return (ISC_FALSE);
00457 }
00458 return (ISC_TRUE);
00459 }
00460
00461 static inline int
00462 casecompare_in_a6(ARGS_COMPARE) {
00463 return (compare_in_a6(rdata1, rdata2));
00464 }
00465
00466 #endif