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_NAPTR_35_C
00025 #define RDATA_GENERIC_NAPTR_35_C
00026
00027 #define RRTYPE_NAPTR_ATTRIBUTES (0)
00028
00029 #include <isc/regex.h>
00030
00031
00032
00033
00034
00035 static inline isc_result_t
00036 txt_valid_regex(const unsigned char *txt) {
00037 unsigned int nsub = 0;
00038 char regex[256];
00039 char *cp;
00040 isc_boolean_t flags = ISC_FALSE;
00041 isc_boolean_t replace = ISC_FALSE;
00042 unsigned char c;
00043 unsigned char delim;
00044 unsigned int len;
00045 int n;
00046
00047 len = *txt++;
00048 if (len == 0U)
00049 return (ISC_R_SUCCESS);
00050
00051 delim = *txt++;
00052 len--;
00053
00054
00055
00056
00057 switch (delim) {
00058 case '0': case '1': case '2': case '3': case '4':
00059 case '5': case '6': case '7': case '8': case '9':
00060 case '\\': case 'i': case 0:
00061 return (DNS_R_SYNTAX);
00062 }
00063
00064 cp = regex;
00065 while (len-- > 0) {
00066 c = *txt++;
00067 if (c == 0)
00068 return (DNS_R_SYNTAX);
00069 if (c == delim && !replace) {
00070 replace = ISC_TRUE;
00071 continue;
00072 } else if (c == delim && !flags) {
00073 flags = ISC_TRUE;
00074 continue;
00075 } else if (c == delim)
00076 return (DNS_R_SYNTAX);
00077
00078
00079
00080 if (flags) {
00081 switch (c) {
00082 case 'i':
00083 continue;
00084 default:
00085 return (DNS_R_SYNTAX);
00086 }
00087 }
00088 if (!replace)
00089 *cp++ = c;
00090 if (c == '\\') {
00091 if (len == 0)
00092 return (DNS_R_SYNTAX);
00093 c = *txt++;
00094 if (c == 0)
00095 return (DNS_R_SYNTAX);
00096 len--;
00097 if (replace)
00098 switch (c) {
00099 case '0': return (DNS_R_SYNTAX);
00100 case '1': if (nsub < 1) nsub = 1; break;
00101 case '2': if (nsub < 2) nsub = 2; break;
00102 case '3': if (nsub < 3) nsub = 3; break;
00103 case '4': if (nsub < 4) nsub = 4; break;
00104 case '5': if (nsub < 5) nsub = 5; break;
00105 case '6': if (nsub < 6) nsub = 6; break;
00106 case '7': if (nsub < 7) nsub = 7; break;
00107 case '8': if (nsub < 8) nsub = 8; break;
00108 case '9': if (nsub < 9) nsub = 9; break;
00109 }
00110 if (!replace)
00111 *cp++ = c;
00112 }
00113 }
00114 if (!flags)
00115 return (DNS_R_SYNTAX);
00116 *cp = '\0';
00117 n = isc_regex_validate(regex);
00118 if (n < 0 || nsub > (unsigned int)n)
00119 return (DNS_R_SYNTAX);
00120 return (ISC_R_SUCCESS);
00121 }
00122
00123 static inline isc_result_t
00124 fromtext_naptr(ARGS_FROMTEXT) {
00125 isc_token_t token;
00126 dns_name_t name;
00127 isc_buffer_t buffer;
00128 unsigned char *regex;
00129
00130 REQUIRE(type == 35);
00131
00132 UNUSED(type);
00133 UNUSED(rdclass);
00134 UNUSED(callbacks);
00135
00136
00137
00138
00139 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00140 ISC_FALSE));
00141 if (token.value.as_ulong > 0xffffU)
00142 RETTOK(ISC_R_RANGE);
00143 RETERR(uint16_tobuffer(token.value.as_ulong, target));
00144
00145
00146
00147
00148 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00149 ISC_FALSE));
00150 if (token.value.as_ulong > 0xffffU)
00151 RETTOK(ISC_R_RANGE);
00152 RETERR(uint16_tobuffer(token.value.as_ulong, target));
00153
00154
00155
00156
00157 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
00158 ISC_FALSE));
00159 RETTOK(txt_fromtext(&token.value.as_textregion, target));
00160
00161
00162
00163
00164 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
00165 ISC_FALSE));
00166 RETTOK(txt_fromtext(&token.value.as_textregion, target));
00167
00168
00169
00170
00171 regex = isc_buffer_used(target);
00172 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
00173 ISC_FALSE));
00174 RETTOK(txt_fromtext(&token.value.as_textregion, target));
00175 RETTOK(txt_valid_regex(regex));
00176
00177
00178
00179
00180 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00181 ISC_FALSE));
00182 dns_name_init(&name, NULL);
00183 buffer_fromregion(&buffer, &token.value.as_region);
00184 origin = (origin != NULL) ? origin : dns_rootname;
00185 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00186 return (ISC_R_SUCCESS);
00187 }
00188
00189 static inline isc_result_t
00190 totext_naptr(ARGS_TOTEXT) {
00191 isc_region_t region;
00192 dns_name_t name;
00193 dns_name_t prefix;
00194 isc_boolean_t sub;
00195 char buf[sizeof("64000")];
00196 unsigned short num;
00197
00198 REQUIRE(rdata->type == 35);
00199 REQUIRE(rdata->length != 0);
00200
00201 dns_name_init(&name, NULL);
00202 dns_name_init(&prefix, NULL);
00203
00204 dns_rdata_toregion(rdata, ®ion);
00205
00206
00207
00208
00209 num = uint16_fromregion(®ion);
00210 isc_region_consume(®ion, 2);
00211 sprintf(buf, "%u", num);
00212 RETERR(str_totext(buf, target));
00213 RETERR(str_totext(" ", target));
00214
00215
00216
00217
00218 num = uint16_fromregion(®ion);
00219 isc_region_consume(®ion, 2);
00220 sprintf(buf, "%u", num);
00221 RETERR(str_totext(buf, target));
00222 RETERR(str_totext(" ", target));
00223
00224
00225
00226
00227 RETERR(txt_totext(®ion, ISC_TRUE, target));
00228 RETERR(str_totext(" ", target));
00229
00230
00231
00232
00233 RETERR(txt_totext(®ion, ISC_TRUE, target));
00234 RETERR(str_totext(" ", target));
00235
00236
00237
00238
00239 RETERR(txt_totext(®ion, ISC_TRUE, target));
00240 RETERR(str_totext(" ", target));
00241
00242
00243
00244
00245 dns_name_fromregion(&name, ®ion);
00246 sub = name_prefix(&name, tctx->origin, &prefix);
00247 return (dns_name_totext(&prefix, sub, target));
00248 }
00249
00250 static inline isc_result_t
00251 fromwire_naptr(ARGS_FROMWIRE) {
00252 dns_name_t name;
00253 isc_region_t sr;
00254 unsigned char *regex;
00255
00256 REQUIRE(type == 35);
00257
00258 UNUSED(type);
00259 UNUSED(rdclass);
00260
00261 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00262
00263 dns_name_init(&name, NULL);
00264
00265
00266
00267
00268 isc_buffer_activeregion(source, &sr);
00269 if (sr.length < 4)
00270 return (ISC_R_UNEXPECTEDEND);
00271 RETERR(mem_tobuffer(target, sr.base, 4));
00272 isc_buffer_forward(source, 4);
00273
00274
00275
00276
00277 RETERR(txt_fromwire(source, target));
00278
00279
00280
00281
00282 RETERR(txt_fromwire(source, target));
00283
00284
00285
00286
00287 regex = isc_buffer_used(target);
00288 RETERR(txt_fromwire(source, target));
00289 RETERR(txt_valid_regex(regex));
00290
00291
00292
00293
00294 return (dns_name_fromwire(&name, source, dctx, options, target));
00295 }
00296
00297 static inline isc_result_t
00298 towire_naptr(ARGS_TOWIRE) {
00299 dns_name_t name;
00300 dns_offsets_t offsets;
00301 isc_region_t sr;
00302
00303 REQUIRE(rdata->type == 35);
00304 REQUIRE(rdata->length != 0);
00305
00306 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
00307
00308
00309
00310 dns_rdata_toregion(rdata, &sr);
00311 RETERR(mem_tobuffer(target, sr.base, 4));
00312 isc_region_consume(&sr, 4);
00313
00314
00315
00316
00317 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
00318 isc_region_consume(&sr, sr.base[0] + 1);
00319
00320
00321
00322
00323 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
00324 isc_region_consume(&sr, sr.base[0] + 1);
00325
00326
00327
00328
00329 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
00330 isc_region_consume(&sr, sr.base[0] + 1);
00331
00332
00333
00334
00335 dns_name_init(&name, offsets);
00336 dns_name_fromregion(&name, &sr);
00337 return (dns_name_towire(&name, cctx, target));
00338 }
00339
00340 static inline int
00341 compare_naptr(ARGS_COMPARE) {
00342 dns_name_t name1;
00343 dns_name_t name2;
00344 isc_region_t region1;
00345 isc_region_t region2;
00346 int order, len;
00347
00348 REQUIRE(rdata1->type == rdata2->type);
00349 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00350 REQUIRE(rdata1->type == 35);
00351 REQUIRE(rdata1->length != 0);
00352 REQUIRE(rdata2->length != 0);
00353
00354 dns_rdata_toregion(rdata1, ®ion1);
00355 dns_rdata_toregion(rdata2, ®ion2);
00356
00357
00358
00359
00360 order = memcmp(region1.base, region2.base, 4);
00361 if (order != 0)
00362 return (order < 0 ? -1 : 1);
00363 isc_region_consume(®ion1, 4);
00364 isc_region_consume(®ion2, 4);
00365
00366
00367
00368
00369 len = ISC_MIN(region1.base[0], region2.base[0]);
00370 order = memcmp(region1.base, region2.base, len + 1);
00371 if (order != 0)
00372 return (order < 0 ? -1 : 1);
00373 isc_region_consume(®ion1, region1.base[0] + 1);
00374 isc_region_consume(®ion2, region2.base[0] + 1);
00375
00376
00377
00378
00379 len = ISC_MIN(region1.base[0], region2.base[0]);
00380 order = memcmp(region1.base, region2.base, len + 1);
00381 if (order != 0)
00382 return (order < 0 ? -1 : 1);
00383 isc_region_consume(®ion1, region1.base[0] + 1);
00384 isc_region_consume(®ion2, region2.base[0] + 1);
00385
00386
00387
00388
00389 len = ISC_MIN(region1.base[0], region2.base[0]);
00390 order = memcmp(region1.base, region2.base, len + 1);
00391 if (order != 0)
00392 return (order < 0 ? -1 : 1);
00393 isc_region_consume(®ion1, region1.base[0] + 1);
00394 isc_region_consume(®ion2, region2.base[0] + 1);
00395
00396
00397
00398
00399 dns_name_init(&name1, NULL);
00400 dns_name_init(&name2, NULL);
00401
00402 dns_name_fromregion(&name1, ®ion1);
00403 dns_name_fromregion(&name2, ®ion2);
00404
00405 return (dns_name_rdatacompare(&name1, &name2));
00406 }
00407
00408 static inline isc_result_t
00409 fromstruct_naptr(ARGS_FROMSTRUCT) {
00410 dns_rdata_naptr_t *naptr = source;
00411 isc_region_t region;
00412
00413 REQUIRE(type == 35);
00414 REQUIRE(source != NULL);
00415 REQUIRE(naptr->common.rdtype == type);
00416 REQUIRE(naptr->common.rdclass == rdclass);
00417 REQUIRE(naptr->flags != NULL || naptr->flags_len == 0);
00418 REQUIRE(naptr->service != NULL || naptr->service_len == 0);
00419 REQUIRE(naptr->regexp != NULL || naptr->regexp_len == 0);
00420
00421 UNUSED(type);
00422 UNUSED(rdclass);
00423
00424 RETERR(uint16_tobuffer(naptr->order, target));
00425 RETERR(uint16_tobuffer(naptr->preference, target));
00426 RETERR(uint8_tobuffer(naptr->flags_len, target));
00427 RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len));
00428 RETERR(uint8_tobuffer(naptr->service_len, target));
00429 RETERR(mem_tobuffer(target, naptr->service, naptr->service_len));
00430 RETERR(uint8_tobuffer(naptr->regexp_len, target));
00431 RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len));
00432 dns_name_toregion(&naptr->replacement, ®ion);
00433 return (isc_buffer_copyregion(target, ®ion));
00434 }
00435
00436 static inline isc_result_t
00437 tostruct_naptr(ARGS_TOSTRUCT) {
00438 dns_rdata_naptr_t *naptr = target;
00439 isc_region_t r;
00440 isc_result_t result;
00441 dns_name_t name;
00442
00443 REQUIRE(rdata->type == 35);
00444 REQUIRE(target != NULL);
00445 REQUIRE(rdata->length != 0);
00446
00447 naptr->common.rdclass = rdata->rdclass;
00448 naptr->common.rdtype = rdata->type;
00449 ISC_LINK_INIT(&naptr->common, link);
00450
00451 naptr->flags = NULL;
00452 naptr->service = NULL;
00453 naptr->regexp = NULL;
00454
00455 dns_rdata_toregion(rdata, &r);
00456
00457 naptr->order = uint16_fromregion(&r);
00458 isc_region_consume(&r, 2);
00459
00460 naptr->preference = uint16_fromregion(&r);
00461 isc_region_consume(&r, 2);
00462
00463 naptr->flags_len = uint8_fromregion(&r);
00464 isc_region_consume(&r, 1);
00465 INSIST(naptr->flags_len <= r.length);
00466 naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len);
00467 if (naptr->flags == NULL)
00468 goto cleanup;
00469 isc_region_consume(&r, naptr->flags_len);
00470
00471 naptr->service_len = uint8_fromregion(&r);
00472 isc_region_consume(&r, 1);
00473 INSIST(naptr->service_len <= r.length);
00474 naptr->service = mem_maybedup(mctx, r.base, naptr->service_len);
00475 if (naptr->service == NULL)
00476 goto cleanup;
00477 isc_region_consume(&r, naptr->service_len);
00478
00479 naptr->regexp_len = uint8_fromregion(&r);
00480 isc_region_consume(&r, 1);
00481 INSIST(naptr->regexp_len <= r.length);
00482 naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len);
00483 if (naptr->regexp == NULL)
00484 goto cleanup;
00485 isc_region_consume(&r, naptr->regexp_len);
00486
00487 dns_name_init(&name, NULL);
00488 dns_name_fromregion(&name, &r);
00489 dns_name_init(&naptr->replacement, NULL);
00490 result = name_duporclone(&name, mctx, &naptr->replacement);
00491 if (result != ISC_R_SUCCESS)
00492 goto cleanup;
00493 naptr->mctx = mctx;
00494 return (ISC_R_SUCCESS);
00495
00496 cleanup:
00497 if (mctx != NULL && naptr->flags != NULL)
00498 isc_mem_free(mctx, naptr->flags);
00499 if (mctx != NULL && naptr->service != NULL)
00500 isc_mem_free(mctx, naptr->service);
00501 if (mctx != NULL && naptr->regexp != NULL)
00502 isc_mem_free(mctx, naptr->regexp);
00503 return (ISC_R_NOMEMORY);
00504 }
00505
00506 static inline void
00507 freestruct_naptr(ARGS_FREESTRUCT) {
00508 dns_rdata_naptr_t *naptr = source;
00509
00510 REQUIRE(source != NULL);
00511 REQUIRE(naptr->common.rdtype == 35);
00512
00513 if (naptr->mctx == NULL)
00514 return;
00515
00516 if (naptr->flags != NULL)
00517 isc_mem_free(naptr->mctx, naptr->flags);
00518 if (naptr->service != NULL)
00519 isc_mem_free(naptr->mctx, naptr->service);
00520 if (naptr->regexp != NULL)
00521 isc_mem_free(naptr->mctx, naptr->regexp);
00522 dns_name_free(&naptr->replacement, naptr->mctx);
00523 naptr->mctx = NULL;
00524 }
00525
00526 static inline isc_result_t
00527 additionaldata_naptr(ARGS_ADDLDATA) {
00528 dns_name_t name;
00529 dns_offsets_t offsets;
00530 isc_region_t sr;
00531 dns_rdatatype_t atype;
00532 unsigned int i, flagslen;
00533 char *cp;
00534
00535 REQUIRE(rdata->type == 35);
00536
00537
00538
00539
00540 dns_rdata_toregion(rdata, &sr);
00541 isc_region_consume(&sr, 4);
00542
00543
00544
00545
00546 atype = 0;
00547 flagslen = sr.base[0];
00548 cp = (char *)&sr.base[1];
00549 for (i = 0; i < flagslen; i++, cp++) {
00550 if (*cp == 'S' || *cp == 's') {
00551 atype = dns_rdatatype_srv;
00552 break;
00553 }
00554 if (*cp == 'A' || *cp == 'a') {
00555 atype = dns_rdatatype_a;
00556 break;
00557 }
00558 }
00559 isc_region_consume(&sr, flagslen + 1);
00560
00561
00562
00563
00564 isc_region_consume(&sr, sr.base[0] + 1);
00565
00566
00567
00568
00569 isc_region_consume(&sr, sr.base[0] + 1);
00570
00571
00572
00573
00574 dns_name_init(&name, offsets);
00575 dns_name_fromregion(&name, &sr);
00576
00577 if (atype != 0)
00578 return ((add)(arg, &name, atype));
00579
00580 return (ISC_R_SUCCESS);
00581 }
00582
00583 static inline isc_result_t
00584 digest_naptr(ARGS_DIGEST) {
00585 isc_region_t r1, r2;
00586 unsigned int length, n;
00587 isc_result_t result;
00588 dns_name_t name;
00589
00590 REQUIRE(rdata->type == 35);
00591
00592 dns_rdata_toregion(rdata, &r1);
00593 r2 = r1;
00594 length = 0;
00595
00596
00597
00598
00599 length += 4;
00600 isc_region_consume(&r2, 4);
00601
00602
00603
00604
00605 n = r2.base[0] + 1;
00606 length += n;
00607 isc_region_consume(&r2, n);
00608
00609
00610
00611
00612 n = r2.base[0] + 1;
00613 length += n;
00614 isc_region_consume(&r2, n);
00615
00616
00617
00618
00619 n = r2.base[0] + 1;
00620 length += n;
00621 isc_region_consume(&r2, n);
00622
00623
00624
00625
00626 r1.length = length;
00627 result = (digest)(arg, &r1);
00628 if (result != ISC_R_SUCCESS)
00629 return (result);
00630
00631
00632
00633
00634
00635 dns_name_init(&name, NULL);
00636 dns_name_fromregion(&name, &r2);
00637
00638 return (dns_name_digest(&name, digest, arg));
00639 }
00640
00641 static inline isc_boolean_t
00642 checkowner_naptr(ARGS_CHECKOWNER) {
00643
00644 REQUIRE(type == 35);
00645
00646 UNUSED(name);
00647 UNUSED(type);
00648 UNUSED(rdclass);
00649 UNUSED(wildcard);
00650
00651 return (ISC_TRUE);
00652 }
00653
00654 static inline isc_boolean_t
00655 checknames_naptr(ARGS_CHECKNAMES) {
00656
00657 REQUIRE(rdata->type == 35);
00658
00659 UNUSED(rdata);
00660 UNUSED(owner);
00661 UNUSED(bad);
00662
00663 return (ISC_TRUE);
00664 }
00665
00666 static inline int
00667 casecompare_naptr(ARGS_COMPARE) {
00668 return (compare_naptr(rdata1, rdata2));
00669 }
00670
00671 #endif