nxt_30.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: nxt_30.c,v 1.65 2009/12/04 22:06:37 tbox Exp $ */
00019 
00020 /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
00021 
00022 /* RFC2535 */
00023 
00024 #ifndef RDATA_GENERIC_NXT_30_C
00025 #define RDATA_GENERIC_NXT_30_C
00026 
00027 /*
00028  * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
00029  * because we must be able to handle a parent/child NXT pair.
00030  */
00031 #define RRTYPE_NXT_ATTRIBUTES (0)
00032 
00033 static inline isc_result_t
00034 fromtext_nxt(ARGS_FROMTEXT) {
00035         isc_token_t token;
00036         dns_name_t name;
00037         isc_buffer_t buffer;
00038         char *e;
00039         unsigned char bm[8*1024]; /* 64k bits */
00040         dns_rdatatype_t covered;
00041         dns_rdatatype_t maxcovered = 0;
00042         isc_boolean_t first = ISC_TRUE;
00043         long n;
00044 
00045         REQUIRE(type == 30);
00046 
00047         UNUSED(type);
00048         UNUSED(rdclass);
00049         UNUSED(callbacks);
00050 
00051         /*
00052          * Next domain.
00053          */
00054         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00055                                       ISC_FALSE));
00056         dns_name_init(&name, NULL);
00057         buffer_fromregion(&buffer, &token.value.as_region);
00058         origin = (origin != NULL) ? origin : dns_rootname;
00059         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00060 
00061         memset(bm, 0, sizeof(bm));
00062         do {
00063                 RETERR(isc_lex_getmastertoken(lexer, &token,
00064                                               isc_tokentype_string, ISC_TRUE));
00065                 if (token.type != isc_tokentype_string)
00066                         break;
00067                 n = strtol(DNS_AS_STR(token), &e, 10);
00068                 if (e != DNS_AS_STR(token) && *e == '\0') {
00069                         covered = (dns_rdatatype_t)n;
00070                 } else if (dns_rdatatype_fromtext(&covered,
00071                                 &token.value.as_textregion) == DNS_R_UNKNOWN)
00072                         RETTOK(DNS_R_UNKNOWN);
00073                 /*
00074                  * NXT is only specified for types 1..127.
00075                  */
00076                 if (covered < 1 || covered > 127)
00077                         return (ISC_R_RANGE);
00078                 if (first || covered > maxcovered)
00079                         maxcovered = covered;
00080                 first = ISC_FALSE;
00081                 bm[covered/8] |= (0x80>>(covered%8));
00082         } while (1);
00083         isc_lex_ungettoken(lexer, &token);
00084         if (first)
00085                 return (ISC_R_SUCCESS);
00086         n = (maxcovered + 8) / 8;
00087         return (mem_tobuffer(target, bm, n));
00088 }
00089 
00090 static inline isc_result_t
00091 totext_nxt(ARGS_TOTEXT) {
00092         isc_region_t sr;
00093         unsigned int i, j;
00094         dns_name_t name;
00095         dns_name_t prefix;
00096         isc_boolean_t sub;
00097 
00098         REQUIRE(rdata->type == 30);
00099         REQUIRE(rdata->length != 0);
00100 
00101         dns_name_init(&name, NULL);
00102         dns_name_init(&prefix, NULL);
00103         dns_rdata_toregion(rdata, &sr);
00104         dns_name_fromregion(&name, &sr);
00105         isc_region_consume(&sr, name_length(&name));
00106         sub = name_prefix(&name, tctx->origin, &prefix);
00107         RETERR(dns_name_totext(&prefix, sub, target));
00108 
00109         for (i = 0; i < sr.length; i++) {
00110                 if (sr.base[i] != 0)
00111                         for (j = 0; j < 8; j++)
00112                                 if ((sr.base[i] & (0x80 >> j)) != 0) {
00113                                         dns_rdatatype_t t = i * 8 + j;
00114                                         RETERR(str_totext(" ", target));
00115                                         if (dns_rdatatype_isknown(t)) {
00116                                                 RETERR(dns_rdatatype_totext(t,
00117                                                                       target));
00118                                         } else {
00119                                                 char buf[sizeof("65535")];
00120                                                 sprintf(buf, "%u", t);
00121                                                 RETERR(str_totext(buf,
00122                                                                   target));
00123                                         }
00124                                 }
00125         }
00126         return (ISC_R_SUCCESS);
00127 }
00128 
00129 static inline isc_result_t
00130 fromwire_nxt(ARGS_FROMWIRE) {
00131         isc_region_t sr;
00132         dns_name_t name;
00133 
00134         REQUIRE(type == 30);
00135 
00136         UNUSED(type);
00137         UNUSED(rdclass);
00138 
00139         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00140 
00141         dns_name_init(&name, NULL);
00142         RETERR(dns_name_fromwire(&name, source, dctx, options, target));
00143 
00144         isc_buffer_activeregion(source, &sr);
00145         if (sr.length > 0 && (sr.base[0] & 0x80) == 0 &&
00146             ((sr.length > 16) || sr.base[sr.length - 1] == 0))
00147                 return (DNS_R_BADBITMAP);
00148         RETERR(mem_tobuffer(target, sr.base, sr.length));
00149         isc_buffer_forward(source, sr.length);
00150         return (ISC_R_SUCCESS);
00151 }
00152 
00153 static inline isc_result_t
00154 towire_nxt(ARGS_TOWIRE) {
00155         isc_region_t sr;
00156         dns_name_t name;
00157         dns_offsets_t offsets;
00158 
00159         REQUIRE(rdata->type == 30);
00160         REQUIRE(rdata->length != 0);
00161 
00162         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
00163         dns_name_init(&name, offsets);
00164         dns_rdata_toregion(rdata, &sr);
00165         dns_name_fromregion(&name, &sr);
00166         isc_region_consume(&sr, name_length(&name));
00167         RETERR(dns_name_towire(&name, cctx, target));
00168 
00169         return (mem_tobuffer(target, sr.base, sr.length));
00170 }
00171 
00172 static inline int
00173 compare_nxt(ARGS_COMPARE) {
00174         isc_region_t r1;
00175         isc_region_t r2;
00176         dns_name_t name1;
00177         dns_name_t name2;
00178         int order;
00179 
00180         REQUIRE(rdata1->type == rdata2->type);
00181         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00182         REQUIRE(rdata1->type == 30);
00183         REQUIRE(rdata1->length != 0);
00184         REQUIRE(rdata2->length != 0);
00185 
00186         dns_name_init(&name1, NULL);
00187         dns_name_init(&name2, NULL);
00188         dns_rdata_toregion(rdata1, &r1);
00189         dns_rdata_toregion(rdata2, &r2);
00190         dns_name_fromregion(&name1, &r1);
00191         dns_name_fromregion(&name2, &r2);
00192         order = dns_name_rdatacompare(&name1, &name2);
00193         if (order != 0)
00194                 return (order);
00195 
00196         return (isc_region_compare(&r1, &r2));
00197 }
00198 
00199 static inline isc_result_t
00200 fromstruct_nxt(ARGS_FROMSTRUCT) {
00201         dns_rdata_nxt_t *nxt = source;
00202         isc_region_t region;
00203 
00204         REQUIRE(type == 30);
00205         REQUIRE(source != NULL);
00206         REQUIRE(nxt->common.rdtype == type);
00207         REQUIRE(nxt->common.rdclass == rdclass);
00208         REQUIRE(nxt->typebits != NULL || nxt->len == 0);
00209         if (nxt->typebits != NULL && (nxt->typebits[0] & 0x80) == 0) {
00210                 REQUIRE(nxt->len <= 16);
00211                 REQUIRE(nxt->typebits[nxt->len - 1] != 0);
00212         }
00213 
00214         UNUSED(type);
00215         UNUSED(rdclass);
00216 
00217         dns_name_toregion(&nxt->next, &region);
00218         RETERR(isc_buffer_copyregion(target, &region));
00219 
00220         return (mem_tobuffer(target, nxt->typebits, nxt->len));
00221 }
00222 
00223 static inline isc_result_t
00224 tostruct_nxt(ARGS_TOSTRUCT) {
00225         isc_region_t region;
00226         dns_rdata_nxt_t *nxt = target;
00227         dns_name_t name;
00228 
00229         REQUIRE(rdata->type == 30);
00230         REQUIRE(target != NULL);
00231         REQUIRE(rdata->length != 0);
00232 
00233         nxt->common.rdclass = rdata->rdclass;
00234         nxt->common.rdtype = rdata->type;
00235         ISC_LINK_INIT(&nxt->common, link);
00236 
00237         dns_name_init(&name, NULL);
00238         dns_rdata_toregion(rdata, &region);
00239         dns_name_fromregion(&name, &region);
00240         isc_region_consume(&region, name_length(&name));
00241         dns_name_init(&nxt->next, NULL);
00242         RETERR(name_duporclone(&name, mctx, &nxt->next));
00243 
00244         nxt->len = region.length;
00245         nxt->typebits = mem_maybedup(mctx, region.base, region.length);
00246         if (nxt->typebits == NULL)
00247                 goto cleanup;
00248 
00249         nxt->mctx = mctx;
00250         return (ISC_R_SUCCESS);
00251 
00252  cleanup:
00253         if (mctx != NULL)
00254                 dns_name_free(&nxt->next, mctx);
00255         return (ISC_R_NOMEMORY);
00256 }
00257 
00258 static inline void
00259 freestruct_nxt(ARGS_FREESTRUCT) {
00260         dns_rdata_nxt_t *nxt = source;
00261 
00262         REQUIRE(source != NULL);
00263         REQUIRE(nxt->common.rdtype == 30);
00264 
00265         if (nxt->mctx == NULL)
00266                 return;
00267 
00268         dns_name_free(&nxt->next, nxt->mctx);
00269         if (nxt->typebits != NULL)
00270                 isc_mem_free(nxt->mctx, nxt->typebits);
00271         nxt->mctx = NULL;
00272 }
00273 
00274 static inline isc_result_t
00275 additionaldata_nxt(ARGS_ADDLDATA) {
00276         REQUIRE(rdata->type == 30);
00277 
00278         UNUSED(rdata);
00279         UNUSED(add);
00280         UNUSED(arg);
00281 
00282         return (ISC_R_SUCCESS);
00283 }
00284 
00285 static inline isc_result_t
00286 digest_nxt(ARGS_DIGEST) {
00287         isc_region_t r;
00288         dns_name_t name;
00289         isc_result_t result;
00290 
00291         REQUIRE(rdata->type == 30);
00292 
00293         dns_rdata_toregion(rdata, &r);
00294         dns_name_init(&name, NULL);
00295         dns_name_fromregion(&name, &r);
00296         result = dns_name_digest(&name, digest, arg);
00297         if (result != ISC_R_SUCCESS)
00298                 return (result);
00299         isc_region_consume(&r, name_length(&name));
00300 
00301         return ((digest)(arg, &r));
00302 }
00303 
00304 static inline isc_boolean_t
00305 checkowner_nxt(ARGS_CHECKOWNER) {
00306 
00307         REQUIRE(type == 30);
00308 
00309         UNUSED(name);
00310         UNUSED(type);
00311         UNUSED(rdclass);
00312         UNUSED(wildcard);
00313 
00314         return (ISC_TRUE);
00315 }
00316 
00317 static inline isc_boolean_t
00318 checknames_nxt(ARGS_CHECKNAMES) {
00319 
00320         REQUIRE(rdata->type == 30);
00321 
00322         UNUSED(rdata);
00323         UNUSED(owner);
00324         UNUSED(bad);
00325 
00326         return (ISC_TRUE);
00327 }
00328 
00329 static inline int
00330 casecompare_nxt(ARGS_COMPARE) {
00331         return (compare_nxt(rdata1, rdata2));
00332 }
00333 #endif  /* RDATA_GENERIC_NXT_30_C */

Generated on Tue Apr 28 17:41:00 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha