00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef RDATA_GENERIC_NSEC_47_C
00025 #define RDATA_GENERIC_NSEC_47_C
00026
00027
00028
00029
00030
00031 #define RRTYPE_NSEC_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
00032
00033 static inline isc_result_t
00034 fromtext_nsec(ARGS_FROMTEXT) {
00035 isc_token_t token;
00036 dns_name_t name;
00037 isc_buffer_t buffer;
00038 unsigned char bm[8*1024];
00039 dns_rdatatype_t covered;
00040 int octet;
00041 int window;
00042
00043 REQUIRE(type == 47);
00044
00045 UNUSED(type);
00046 UNUSED(rdclass);
00047 UNUSED(callbacks);
00048
00049
00050
00051
00052 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00053 ISC_FALSE));
00054 dns_name_init(&name, NULL);
00055 buffer_fromregion(&buffer, &token.value.as_region);
00056 origin = (origin != NULL) ? origin : dns_rootname;
00057 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00058
00059 memset(bm, 0, sizeof(bm));
00060 do {
00061 RETERR(isc_lex_getmastertoken(lexer, &token,
00062 isc_tokentype_string, ISC_TRUE));
00063 if (token.type != isc_tokentype_string)
00064 break;
00065 RETTOK(dns_rdatatype_fromtext(&covered,
00066 &token.value.as_textregion));
00067 bm[covered/8] |= (0x80>>(covered%8));
00068 } while (1);
00069 isc_lex_ungettoken(lexer, &token);
00070 for (window = 0; window < 256 ; window++) {
00071
00072
00073
00074 for (octet = 31; octet >= 0; octet--)
00075 if (bm[window * 32 + octet] != 0)
00076 break;
00077 if (octet < 0)
00078 continue;
00079 RETERR(uint8_tobuffer(window, target));
00080 RETERR(uint8_tobuffer(octet + 1, target));
00081 RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1));
00082 }
00083 return (ISC_R_SUCCESS);
00084 }
00085
00086 static inline isc_result_t
00087 totext_nsec(ARGS_TOTEXT) {
00088 isc_region_t sr;
00089 unsigned int i, j, k;
00090 dns_name_t name;
00091 unsigned int window, len;
00092
00093 REQUIRE(rdata->type == 47);
00094 REQUIRE(rdata->length != 0);
00095
00096 UNUSED(tctx);
00097
00098 dns_name_init(&name, NULL);
00099 dns_rdata_toregion(rdata, &sr);
00100 dns_name_fromregion(&name, &sr);
00101 isc_region_consume(&sr, name_length(&name));
00102 RETERR(dns_name_totext(&name, ISC_FALSE, target));
00103
00104
00105 for (i = 0; i < sr.length; i += len) {
00106 INSIST(i + 2 <= sr.length);
00107 window = sr.base[i];
00108 len = sr.base[i + 1];
00109 INSIST(len > 0 && len <= 32);
00110 i += 2;
00111 INSIST(i + len <= sr.length);
00112 for (j = 0; j < len; j++) {
00113 dns_rdatatype_t t;
00114 if (sr.base[i + j] == 0)
00115 continue;
00116 for (k = 0; k < 8; k++) {
00117 if ((sr.base[i + j] & (0x80 >> k)) == 0)
00118 continue;
00119 t = window * 256 + j * 8 + k;
00120 RETERR(str_totext(" ", target));
00121 if (dns_rdatatype_isknown(t)) {
00122 RETERR(dns_rdatatype_totext(t, target));
00123 } else {
00124 char buf[sizeof("TYPE65535")];
00125 sprintf(buf, "TYPE%u", t);
00126 RETERR(str_totext(buf, target));
00127 }
00128 }
00129 }
00130 }
00131 return (ISC_R_SUCCESS);
00132 }
00133
00134 static isc_result_t
00135 fromwire_nsec(ARGS_FROMWIRE) {
00136 isc_region_t sr;
00137 dns_name_t name;
00138 unsigned int window, lastwindow = 0;
00139 unsigned int len;
00140 isc_boolean_t first = ISC_TRUE;
00141 unsigned int i;
00142
00143 REQUIRE(type == 47);
00144
00145 UNUSED(type);
00146 UNUSED(rdclass);
00147
00148 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00149
00150 dns_name_init(&name, NULL);
00151 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
00152
00153 isc_buffer_activeregion(source, &sr);
00154 for (i = 0; i < sr.length; i += len) {
00155
00156
00157
00158 if (i + 2 > sr.length)
00159 RETERR(DNS_R_FORMERR);
00160 window = sr.base[i];
00161 len = sr.base[i + 1];
00162 i += 2;
00163
00164
00165
00166 if (!first && window <= lastwindow)
00167 RETERR(DNS_R_FORMERR);
00168
00169
00170
00171 if (len < 1 || len > 32)
00172 RETERR(DNS_R_FORMERR);
00173
00174
00175
00176 if (i + len > sr.length)
00177 RETERR(DNS_R_FORMERR);
00178
00179
00180
00181 if (sr.base[i + len - 1] == 0)
00182 RETERR(DNS_R_FORMERR);
00183 lastwindow = window;
00184 first = ISC_FALSE;
00185 }
00186 if (i != sr.length)
00187 return (DNS_R_EXTRADATA);
00188 if (first)
00189 RETERR(DNS_R_FORMERR);
00190 RETERR(mem_tobuffer(target, sr.base, sr.length));
00191 isc_buffer_forward(source, sr.length);
00192 return (ISC_R_SUCCESS);
00193 }
00194
00195 static inline isc_result_t
00196 towire_nsec(ARGS_TOWIRE) {
00197 isc_region_t sr;
00198 dns_name_t name;
00199 dns_offsets_t offsets;
00200
00201 REQUIRE(rdata->type == 47);
00202 REQUIRE(rdata->length != 0);
00203
00204 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
00205 dns_name_init(&name, offsets);
00206 dns_rdata_toregion(rdata, &sr);
00207 dns_name_fromregion(&name, &sr);
00208 isc_region_consume(&sr, name_length(&name));
00209 RETERR(dns_name_towire(&name, cctx, target));
00210
00211 return (mem_tobuffer(target, sr.base, sr.length));
00212 }
00213
00214 static inline int
00215 compare_nsec(ARGS_COMPARE) {
00216 isc_region_t r1;
00217 isc_region_t r2;
00218
00219 REQUIRE(rdata1->type == rdata2->type);
00220 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00221 REQUIRE(rdata1->type == 47);
00222 REQUIRE(rdata1->length != 0);
00223 REQUIRE(rdata2->length != 0);
00224
00225 dns_rdata_toregion(rdata1, &r1);
00226 dns_rdata_toregion(rdata2, &r2);
00227 return (isc_region_compare(&r1, &r2));
00228 }
00229
00230 static inline isc_result_t
00231 fromstruct_nsec(ARGS_FROMSTRUCT) {
00232 dns_rdata_nsec_t *nsec = source;
00233 isc_region_t region;
00234 unsigned int i, len, window, lastwindow = 0;
00235 isc_boolean_t first = ISC_TRUE;
00236
00237 REQUIRE(type == 47);
00238 REQUIRE(source != NULL);
00239 REQUIRE(nsec->common.rdtype == type);
00240 REQUIRE(nsec->common.rdclass == rdclass);
00241 REQUIRE(nsec->typebits != NULL || nsec->len == 0);
00242
00243 UNUSED(type);
00244 UNUSED(rdclass);
00245
00246 dns_name_toregion(&nsec->next, ®ion);
00247 RETERR(isc_buffer_copyregion(target, ®ion));
00248
00249
00250
00251 for (i = 0; i < nsec->len ; i += len) {
00252 INSIST(i + 2 <= nsec->len);
00253 window = nsec->typebits[i];
00254 len = nsec->typebits[i+1];
00255 i += 2;
00256 INSIST(first || window > lastwindow);
00257 INSIST(len > 0 && len <= 32);
00258 INSIST(i + len <= nsec->len);
00259 INSIST(nsec->typebits[i + len - 1] != 0);
00260 lastwindow = window;
00261 first = ISC_FALSE;
00262 }
00263 INSIST(!first);
00264 return (mem_tobuffer(target, nsec->typebits, nsec->len));
00265 }
00266
00267 static inline isc_result_t
00268 tostruct_nsec(ARGS_TOSTRUCT) {
00269 isc_region_t region;
00270 dns_rdata_nsec_t *nsec = target;
00271 dns_name_t name;
00272
00273 REQUIRE(rdata->type == 47);
00274 REQUIRE(target != NULL);
00275 REQUIRE(rdata->length != 0);
00276
00277 nsec->common.rdclass = rdata->rdclass;
00278 nsec->common.rdtype = rdata->type;
00279 ISC_LINK_INIT(&nsec->common, link);
00280
00281 dns_name_init(&name, NULL);
00282 dns_rdata_toregion(rdata, ®ion);
00283 dns_name_fromregion(&name, ®ion);
00284 isc_region_consume(®ion, name_length(&name));
00285 dns_name_init(&nsec->next, NULL);
00286 RETERR(name_duporclone(&name, mctx, &nsec->next));
00287
00288 nsec->len = region.length;
00289 nsec->typebits = mem_maybedup(mctx, region.base, region.length);
00290 if (nsec->typebits == NULL)
00291 goto cleanup;
00292
00293 nsec->mctx = mctx;
00294 return (ISC_R_SUCCESS);
00295
00296 cleanup:
00297 if (mctx != NULL)
00298 dns_name_free(&nsec->next, mctx);
00299 return (ISC_R_NOMEMORY);
00300 }
00301
00302 static inline void
00303 freestruct_nsec(ARGS_FREESTRUCT) {
00304 dns_rdata_nsec_t *nsec = source;
00305
00306 REQUIRE(source != NULL);
00307 REQUIRE(nsec->common.rdtype == 47);
00308
00309 if (nsec->mctx == NULL)
00310 return;
00311
00312 dns_name_free(&nsec->next, nsec->mctx);
00313 if (nsec->typebits != NULL)
00314 isc_mem_free(nsec->mctx, nsec->typebits);
00315 nsec->mctx = NULL;
00316 }
00317
00318 static inline isc_result_t
00319 additionaldata_nsec(ARGS_ADDLDATA) {
00320 REQUIRE(rdata->type == 47);
00321
00322 UNUSED(rdata);
00323 UNUSED(add);
00324 UNUSED(arg);
00325
00326 return (ISC_R_SUCCESS);
00327 }
00328
00329 static inline isc_result_t
00330 digest_nsec(ARGS_DIGEST) {
00331 isc_region_t r;
00332
00333 REQUIRE(rdata->type == 47);
00334
00335 dns_rdata_toregion(rdata, &r);
00336 return ((digest)(arg, &r));
00337 }
00338
00339 static inline isc_boolean_t
00340 checkowner_nsec(ARGS_CHECKOWNER) {
00341
00342 REQUIRE(type == 47);
00343
00344 UNUSED(name);
00345 UNUSED(type);
00346 UNUSED(rdclass);
00347 UNUSED(wildcard);
00348
00349 return (ISC_TRUE);
00350 }
00351
00352 static inline isc_boolean_t
00353 checknames_nsec(ARGS_CHECKNAMES) {
00354
00355 REQUIRE(rdata->type == 47);
00356
00357 UNUSED(rdata);
00358 UNUSED(owner);
00359 UNUSED(bad);
00360
00361 return (ISC_TRUE);
00362 }
00363
00364 static inline int
00365 casecompare_nsec(ARGS_COMPARE) {
00366 isc_region_t region1;
00367 isc_region_t region2;
00368 dns_name_t name1;
00369 dns_name_t name2;
00370 int order;
00371
00372 REQUIRE(rdata1->type == rdata2->type);
00373 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00374 REQUIRE(rdata1->type == 47);
00375 REQUIRE(rdata1->length != 0);
00376 REQUIRE(rdata2->length != 0);
00377
00378 dns_name_init(&name1, NULL);
00379 dns_name_init(&name2, NULL);
00380
00381 dns_rdata_toregion(rdata1, ®ion1);
00382 dns_rdata_toregion(rdata2, ®ion2);
00383
00384 dns_name_fromregion(&name1, ®ion1);
00385 dns_name_fromregion(&name2, ®ion2);
00386
00387 order = dns_name_rdatacompare(&name1, &name2);
00388 if (order != 0)
00389 return (order);
00390
00391 isc_region_consume(®ion1, name_length(&name1));
00392 isc_region_consume(®ion2, name_length(&name2));
00393
00394 return (isc_region_compare(®ion1, ®ion2));
00395 }
00396 #endif