"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.12.3-P1/lib/dns/rdata/in_1/a6_38.c" (7 Dec 2018, 10724 Bytes) of package /linux/misc/dns/bind9/9.12.3-P1/bind-9.12.3-P1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "a6_38.c": 9.12.2-P2_vs_9.12.3.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 /* RFC2874 */
   14 
   15 #ifndef RDATA_IN_1_A6_28_C
   16 #define RDATA_IN_1_A6_28_C
   17 
   18 #include <isc/net.h>
   19 
   20 #define RRTYPE_A6_ATTRIBUTES (0)
   21 
   22 static inline isc_result_t
   23 fromtext_in_a6(ARGS_FROMTEXT) {
   24     isc_token_t token;
   25     unsigned char addr[16];
   26     unsigned char prefixlen;
   27     unsigned char octets;
   28     unsigned char mask;
   29     dns_name_t name;
   30     isc_buffer_t buffer;
   31     bool ok;
   32 
   33     REQUIRE(type == dns_rdatatype_a6);
   34     REQUIRE(rdclass == dns_rdataclass_in);
   35 
   36     UNUSED(type);
   37     UNUSED(rdclass);
   38     UNUSED(callbacks);
   39 
   40     /*
   41      * Prefix length.
   42      */
   43     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
   44                       false));
   45     if (token.value.as_ulong > 128U)
   46         RETTOK(ISC_R_RANGE);
   47 
   48     prefixlen = (unsigned char)token.value.as_ulong;
   49     RETERR(mem_tobuffer(target, &prefixlen, 1));
   50 
   51     /*
   52      * Suffix.
   53      */
   54     if (prefixlen != 128) {
   55         /*
   56          * Prefix 0..127.
   57          */
   58         octets = prefixlen/8;
   59         /*
   60          * Octets 0..15.
   61          */
   62         RETERR(isc_lex_getmastertoken(lexer, &token,
   63                           isc_tokentype_string,
   64                           false));
   65         if (inet_pton(AF_INET6, DNS_AS_STR(token), addr) != 1)
   66             RETTOK(DNS_R_BADAAAA);
   67         mask = 0xff >> (prefixlen % 8);
   68         addr[octets] &= mask;
   69         RETERR(mem_tobuffer(target, &addr[octets], 16 - octets));
   70     }
   71 
   72     if (prefixlen == 0)
   73         return (ISC_R_SUCCESS);
   74 
   75     RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
   76                       false));
   77     dns_name_init(&name, NULL);
   78     buffer_fromregion(&buffer, &token.value.as_region);
   79     if (origin == NULL)
   80         origin = dns_rootname;
   81     RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
   82     ok = true;
   83     if ((options & DNS_RDATA_CHECKNAMES) != 0)
   84         ok = dns_name_ishostname(&name, false);
   85     if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
   86         RETTOK(DNS_R_BADNAME);
   87     if (!ok && callbacks != NULL)
   88         warn_badname(&name, lexer, callbacks);
   89     return (ISC_R_SUCCESS);
   90 }
   91 
   92 static inline isc_result_t
   93 totext_in_a6(ARGS_TOTEXT) {
   94     isc_region_t sr, ar;
   95     unsigned char addr[16];
   96     unsigned char prefixlen;
   97     unsigned char octets;
   98     unsigned char mask;
   99     char buf[sizeof("128")];
  100     dns_name_t name;
  101     dns_name_t prefix;
  102     bool sub;
  103 
  104     REQUIRE(rdata->type == dns_rdatatype_a6);
  105     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  106     REQUIRE(rdata->length != 0);
  107 
  108     dns_rdata_toregion(rdata, &sr);
  109     prefixlen = sr.base[0];
  110     INSIST(prefixlen <= 128);
  111     isc_region_consume(&sr, 1);
  112     snprintf(buf, sizeof(buf), "%u", prefixlen);
  113     RETERR(str_totext(buf, target));
  114     RETERR(str_totext(" ", target));
  115 
  116     if (prefixlen != 128) {
  117         octets = prefixlen/8;
  118         memset(addr, 0, sizeof(addr));
  119         memmove(&addr[octets], sr.base, 16 - octets);
  120         mask = 0xff >> (prefixlen % 8);
  121         addr[octets] &= mask;
  122         ar.base = addr;
  123         ar.length = sizeof(addr);
  124         RETERR(inet_totext(AF_INET6, &ar, target));
  125         isc_region_consume(&sr, 16 - octets);
  126     }
  127 
  128     if (prefixlen == 0)
  129         return (ISC_R_SUCCESS);
  130 
  131     RETERR(str_totext(" ", target));
  132     dns_name_init(&name, NULL);
  133     dns_name_init(&prefix, NULL);
  134     dns_name_fromregion(&name, &sr);
  135     sub = name_prefix(&name, tctx->origin, &prefix);
  136     return (dns_name_totext(&prefix, sub, target));
  137 }
  138 
  139 static inline isc_result_t
  140 fromwire_in_a6(ARGS_FROMWIRE) {
  141     isc_region_t sr;
  142     unsigned char prefixlen;
  143     unsigned char octets;
  144     unsigned char mask;
  145     dns_name_t name;
  146 
  147     REQUIRE(type == dns_rdatatype_a6);
  148     REQUIRE(rdclass == dns_rdataclass_in);
  149 
  150     UNUSED(type);
  151     UNUSED(rdclass);
  152 
  153     dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
  154 
  155     isc_buffer_activeregion(source, &sr);
  156     /*
  157      * Prefix length.
  158      */
  159     if (sr.length < 1)
  160         return (ISC_R_UNEXPECTEDEND);
  161     prefixlen = sr.base[0];
  162     if (prefixlen > 128)
  163         return (ISC_R_RANGE);
  164     isc_region_consume(&sr, 1);
  165     RETERR(mem_tobuffer(target, &prefixlen, 1));
  166     isc_buffer_forward(source, 1);
  167 
  168     /*
  169      * Suffix.
  170      */
  171     if (prefixlen != 128) {
  172         octets = 16 - prefixlen / 8;
  173         if (sr.length < octets)
  174             return (ISC_R_UNEXPECTEDEND);
  175         mask = 0xff >> (prefixlen % 8);
  176         sr.base[0] &= mask; /* Ensure pad bits are zero. */
  177         RETERR(mem_tobuffer(target, sr.base, octets));
  178         isc_buffer_forward(source, octets);
  179     }
  180 
  181     if (prefixlen == 0)
  182         return (ISC_R_SUCCESS);
  183 
  184     dns_name_init(&name, NULL);
  185     return (dns_name_fromwire(&name, source, dctx, options, target));
  186 }
  187 
  188 static inline isc_result_t
  189 towire_in_a6(ARGS_TOWIRE) {
  190     isc_region_t sr;
  191     dns_name_t name;
  192     dns_offsets_t offsets;
  193     unsigned char prefixlen;
  194     unsigned char octets;
  195 
  196     REQUIRE(rdata->type == dns_rdatatype_a6);
  197     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  198     REQUIRE(rdata->length != 0);
  199 
  200     dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
  201     dns_rdata_toregion(rdata, &sr);
  202     prefixlen = sr.base[0];
  203     INSIST(prefixlen <= 128);
  204 
  205     octets = 1 + 16 - prefixlen / 8;
  206     RETERR(mem_tobuffer(target, sr.base, octets));
  207     isc_region_consume(&sr, octets);
  208 
  209     if (prefixlen == 0)
  210         return (ISC_R_SUCCESS);
  211 
  212     dns_name_init(&name, offsets);
  213     dns_name_fromregion(&name, &sr);
  214     return (dns_name_towire(&name, cctx, target));
  215 }
  216 
  217 static inline int
  218 compare_in_a6(ARGS_COMPARE) {
  219     int order;
  220     unsigned char prefixlen1, prefixlen2;
  221     unsigned char octets;
  222     dns_name_t name1;
  223     dns_name_t name2;
  224     isc_region_t region1;
  225     isc_region_t region2;
  226 
  227     REQUIRE(rdata1->type == rdata2->type);
  228     REQUIRE(rdata1->rdclass == rdata2->rdclass);
  229     REQUIRE(rdata1->type == dns_rdatatype_a6);
  230     REQUIRE(rdata1->rdclass == dns_rdataclass_in);
  231     REQUIRE(rdata1->length != 0);
  232     REQUIRE(rdata2->length != 0);
  233 
  234     dns_rdata_toregion(rdata1, &region1);
  235     dns_rdata_toregion(rdata2, &region2);
  236     prefixlen1 = region1.base[0];
  237     prefixlen2 = region2.base[0];
  238     isc_region_consume(&region1, 1);
  239     isc_region_consume(&region2, 1);
  240     if (prefixlen1 < prefixlen2)
  241         return (-1);
  242     else if (prefixlen1 > prefixlen2)
  243         return (1);
  244     /*
  245      * Prefix lengths are equal.
  246      */
  247     octets = 16 - prefixlen1 / 8;
  248 
  249     if (octets > 0) {
  250         order = memcmp(region1.base, region2.base, octets);
  251         if (order < 0)
  252             return (-1);
  253         else if (order > 0)
  254             return (1);
  255         /*
  256          * Address suffixes are equal.
  257          */
  258         if (prefixlen1 == 0)
  259             return (order);
  260         isc_region_consume(&region1, octets);
  261         isc_region_consume(&region2, octets);
  262     }
  263 
  264     dns_name_init(&name1, NULL);
  265     dns_name_init(&name2, NULL);
  266     dns_name_fromregion(&name1, &region1);
  267     dns_name_fromregion(&name2, &region2);
  268     return (dns_name_rdatacompare(&name1, &name2));
  269 }
  270 
  271 static inline isc_result_t
  272 fromstruct_in_a6(ARGS_FROMSTRUCT) {
  273     dns_rdata_in_a6_t *a6 = source;
  274     isc_region_t region;
  275     int octets;
  276     uint8_t bits;
  277     uint8_t first;
  278     uint8_t mask;
  279 
  280     REQUIRE(type == dns_rdatatype_a6);
  281     REQUIRE(rdclass == dns_rdataclass_in);
  282     REQUIRE(source != NULL);
  283     REQUIRE(a6->common.rdtype == type);
  284     REQUIRE(a6->common.rdclass == rdclass);
  285 
  286     UNUSED(type);
  287     UNUSED(rdclass);
  288 
  289     if (a6->prefixlen > 128)
  290         return (ISC_R_RANGE);
  291 
  292     RETERR(uint8_tobuffer(a6->prefixlen, target));
  293 
  294     /* Suffix */
  295     if (a6->prefixlen != 128) {
  296         octets = 16 - a6->prefixlen / 8;
  297         bits = a6->prefixlen % 8;
  298         if (bits != 0) {
  299             mask = 0xffU >> bits;
  300             first = a6->in6_addr.s6_addr[16 - octets] & mask;
  301             RETERR(uint8_tobuffer(first, target));
  302             octets--;
  303         }
  304         if (octets > 0)
  305             RETERR(mem_tobuffer(target,
  306                         a6->in6_addr.s6_addr + 16 - octets,
  307                         octets));
  308     }
  309 
  310     if (a6->prefixlen == 0)
  311         return (ISC_R_SUCCESS);
  312     dns_name_toregion(&a6->prefix, &region);
  313     return (isc_buffer_copyregion(target, &region));
  314 }
  315 
  316 static inline isc_result_t
  317 tostruct_in_a6(ARGS_TOSTRUCT) {
  318     dns_rdata_in_a6_t *a6 = target;
  319     unsigned char octets;
  320     dns_name_t name;
  321     isc_region_t r;
  322 
  323     REQUIRE(rdata->type == dns_rdatatype_a6);
  324     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  325     REQUIRE(target != NULL);
  326     REQUIRE(rdata->length != 0);
  327 
  328     a6->common.rdclass = rdata->rdclass;
  329     a6->common.rdtype = rdata->type;
  330     ISC_LINK_INIT(&a6->common, link);
  331 
  332     dns_rdata_toregion(rdata, &r);
  333 
  334     a6->prefixlen = uint8_fromregion(&r);
  335     isc_region_consume(&r, 1);
  336     memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr));
  337 
  338     /*
  339      * Suffix.
  340      */
  341     if (a6->prefixlen != 128) {
  342         octets = 16 - a6->prefixlen / 8;
  343         INSIST(r.length >= octets);
  344         memmove(a6->in6_addr.s6_addr + 16 - octets, r.base, octets);
  345         isc_region_consume(&r, octets);
  346     }
  347 
  348     /*
  349      * Prefix.
  350      */
  351     dns_name_init(&a6->prefix, NULL);
  352     if (a6->prefixlen != 0) {
  353         dns_name_init(&name, NULL);
  354         dns_name_fromregion(&name, &r);
  355         RETERR(name_duporclone(&name, mctx, &a6->prefix));
  356     }
  357     a6->mctx = mctx;
  358     return (ISC_R_SUCCESS);
  359 }
  360 
  361 static inline void
  362 freestruct_in_a6(ARGS_FREESTRUCT) {
  363     dns_rdata_in_a6_t *a6 = source;
  364 
  365     REQUIRE(source != NULL);
  366     REQUIRE(a6->common.rdclass == dns_rdataclass_in);
  367     REQUIRE(a6->common.rdtype == dns_rdatatype_a6);
  368 
  369     if (a6->mctx == NULL)
  370         return;
  371 
  372     if (dns_name_dynamic(&a6->prefix))
  373         dns_name_free(&a6->prefix, a6->mctx);
  374     a6->mctx = NULL;
  375 }
  376 
  377 static inline isc_result_t
  378 additionaldata_in_a6(ARGS_ADDLDATA) {
  379     REQUIRE(rdata->type == dns_rdatatype_a6);
  380     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  381 
  382     UNUSED(rdata);
  383     UNUSED(add);
  384     UNUSED(arg);
  385 
  386     return (ISC_R_SUCCESS);
  387 }
  388 
  389 static inline isc_result_t
  390 digest_in_a6(ARGS_DIGEST) {
  391     isc_region_t r1, r2;
  392     unsigned char prefixlen, octets;
  393     isc_result_t result;
  394     dns_name_t name;
  395 
  396     REQUIRE(rdata->type == dns_rdatatype_a6);
  397     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  398 
  399     dns_rdata_toregion(rdata, &r1);
  400     r2 = r1;
  401     prefixlen = r1.base[0];
  402     octets = 1 + 16 - prefixlen / 8;
  403 
  404     r1.length = octets;
  405     result = (digest)(arg, &r1);
  406     if (result != ISC_R_SUCCESS)
  407         return (result);
  408     if (prefixlen == 0)
  409         return (ISC_R_SUCCESS);
  410 
  411     isc_region_consume(&r2, octets);
  412     dns_name_init(&name, NULL);
  413     dns_name_fromregion(&name, &r2);
  414     return (dns_name_digest(&name, digest, arg));
  415 }
  416 
  417 static inline bool
  418 checkowner_in_a6(ARGS_CHECKOWNER) {
  419 
  420     REQUIRE(type == dns_rdatatype_a6);
  421     REQUIRE(rdclass == dns_rdataclass_in);
  422 
  423     UNUSED(type);
  424     UNUSED(rdclass);
  425 
  426     return (dns_name_ishostname(name, wildcard));
  427 }
  428 
  429 static inline bool
  430 checknames_in_a6(ARGS_CHECKNAMES) {
  431     isc_region_t region;
  432     dns_name_t name;
  433     unsigned int prefixlen;
  434 
  435     REQUIRE(rdata->type == dns_rdatatype_a6);
  436     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  437 
  438     UNUSED(owner);
  439 
  440     dns_rdata_toregion(rdata, &region);
  441     prefixlen = uint8_fromregion(&region);
  442     if (prefixlen == 0)
  443         return (true);
  444     isc_region_consume(&region, 1 + 16 - prefixlen / 8);
  445     dns_name_init(&name, NULL);
  446     dns_name_fromregion(&name, &region);
  447     if (!dns_name_ishostname(&name, false)) {
  448         if (bad != NULL)
  449             dns_name_clone(&name, bad);
  450         return (false);
  451     }
  452     return (true);
  453 }
  454 
  455 static inline int
  456 casecompare_in_a6(ARGS_COMPARE) {
  457     return (compare_in_a6(rdata1, rdata2));
  458 }
  459 
  460 #endif  /* RDATA_IN_1_A6_38_C */