"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/dns/rdata/in_1/a6_38.c" (7 Sep 2020, 10948 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.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. For more information about "a6_38.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 9.11.22_vs_9.11.23.

    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, tctx->flags, &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         if ((sr.base[0] & ~mask) != 0) {
  177             return (DNS_R_FORMERR);
  178         }
  179         RETERR(mem_tobuffer(target, sr.base, octets));
  180         isc_buffer_forward(source, octets);
  181     }
  182 
  183     if (prefixlen == 0)
  184         return (ISC_R_SUCCESS);
  185 
  186     dns_name_init(&name, NULL);
  187     return (dns_name_fromwire(&name, source, dctx, options, target));
  188 }
  189 
  190 static inline isc_result_t
  191 towire_in_a6(ARGS_TOWIRE) {
  192     isc_region_t sr;
  193     dns_name_t name;
  194     dns_offsets_t offsets;
  195     unsigned char prefixlen;
  196     unsigned char octets;
  197 
  198     REQUIRE(rdata->type == dns_rdatatype_a6);
  199     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  200     REQUIRE(rdata->length != 0);
  201 
  202     dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
  203     dns_rdata_toregion(rdata, &sr);
  204     prefixlen = sr.base[0];
  205     INSIST(prefixlen <= 128);
  206 
  207     octets = 1 + 16 - prefixlen / 8;
  208     RETERR(mem_tobuffer(target, sr.base, octets));
  209     isc_region_consume(&sr, octets);
  210 
  211     if (prefixlen == 0)
  212         return (ISC_R_SUCCESS);
  213 
  214     dns_name_init(&name, offsets);
  215     dns_name_fromregion(&name, &sr);
  216     return (dns_name_towire(&name, cctx, target));
  217 }
  218 
  219 static inline int
  220 compare_in_a6(ARGS_COMPARE) {
  221     int order;
  222     unsigned char prefixlen1, prefixlen2;
  223     unsigned char octets;
  224     dns_name_t name1;
  225     dns_name_t name2;
  226     isc_region_t region1;
  227     isc_region_t region2;
  228 
  229     REQUIRE(rdata1->type == rdata2->type);
  230     REQUIRE(rdata1->rdclass == rdata2->rdclass);
  231     REQUIRE(rdata1->type == dns_rdatatype_a6);
  232     REQUIRE(rdata1->rdclass == dns_rdataclass_in);
  233     REQUIRE(rdata1->length != 0);
  234     REQUIRE(rdata2->length != 0);
  235 
  236     dns_rdata_toregion(rdata1, &region1);
  237     dns_rdata_toregion(rdata2, &region2);
  238     prefixlen1 = region1.base[0];
  239     prefixlen2 = region2.base[0];
  240     isc_region_consume(&region1, 1);
  241     isc_region_consume(&region2, 1);
  242     if (prefixlen1 < prefixlen2)
  243         return (-1);
  244     else if (prefixlen1 > prefixlen2)
  245         return (1);
  246     /*
  247      * Prefix lengths are equal.
  248      */
  249     octets = 16 - prefixlen1 / 8;
  250 
  251     if (octets > 0) {
  252         order = memcmp(region1.base, region2.base, octets);
  253         if (order < 0)
  254             return (-1);
  255         else if (order > 0)
  256             return (1);
  257         /*
  258          * Address suffixes are equal.
  259          */
  260         if (prefixlen1 == 0)
  261             return (order);
  262         isc_region_consume(&region1, octets);
  263         isc_region_consume(&region2, octets);
  264     }
  265 
  266     dns_name_init(&name1, NULL);
  267     dns_name_init(&name2, NULL);
  268     dns_name_fromregion(&name1, &region1);
  269     dns_name_fromregion(&name2, &region2);
  270     return (dns_name_rdatacompare(&name1, &name2));
  271 }
  272 
  273 static inline isc_result_t
  274 fromstruct_in_a6(ARGS_FROMSTRUCT) {
  275     dns_rdata_in_a6_t *a6;
  276     isc_region_t region;
  277     int octets;
  278     uint8_t bits;
  279     uint8_t first;
  280     uint8_t mask;
  281 
  282     REQUIRE(type == dns_rdatatype_a6);
  283     REQUIRE(rdclass == dns_rdataclass_in);
  284     REQUIRE(((dns_rdata_in_a6_t *)source) != NULL);
  285     REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdtype == type);
  286     REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdclass == rdclass);
  287 
  288     a6 = source;
  289 
  290     UNUSED(type);
  291     UNUSED(rdclass);
  292 
  293     if (a6->prefixlen > 128)
  294         return (ISC_R_RANGE);
  295 
  296     RETERR(uint8_tobuffer(a6->prefixlen, target));
  297 
  298     /* Suffix */
  299     if (a6->prefixlen != 128) {
  300         octets = 16 - a6->prefixlen / 8;
  301         bits = a6->prefixlen % 8;
  302         if (bits != 0) {
  303             mask = 0xffU >> bits;
  304             first = a6->in6_addr.s6_addr[16 - octets] & mask;
  305             RETERR(uint8_tobuffer(first, target));
  306             octets--;
  307         }
  308         if (octets > 0)
  309             RETERR(mem_tobuffer(target,
  310                         a6->in6_addr.s6_addr + 16 - octets,
  311                         octets));
  312     }
  313 
  314     if (a6->prefixlen == 0)
  315         return (ISC_R_SUCCESS);
  316     dns_name_toregion(&a6->prefix, &region);
  317     return (isc_buffer_copyregion(target, &region));
  318 }
  319 
  320 static inline isc_result_t
  321 tostruct_in_a6(ARGS_TOSTRUCT) {
  322     dns_rdata_in_a6_t *a6;
  323     unsigned char octets;
  324     dns_name_t name;
  325     isc_region_t r;
  326 
  327     REQUIRE(((dns_rdata_in_a6_t *)target) != NULL);
  328     REQUIRE(rdata->type == dns_rdatatype_a6);
  329     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  330     REQUIRE(rdata->length != 0);
  331 
  332     a6 = target;
  333 
  334     a6->common.rdclass = rdata->rdclass;
  335     a6->common.rdtype = rdata->type;
  336     ISC_LINK_INIT(&a6->common, link);
  337 
  338     dns_rdata_toregion(rdata, &r);
  339 
  340     a6->prefixlen = uint8_fromregion(&r);
  341     isc_region_consume(&r, 1);
  342     memset(a6->in6_addr.s6_addr, 0, sizeof(a6->in6_addr.s6_addr));
  343 
  344     /*
  345      * Suffix.
  346      */
  347     if (a6->prefixlen != 128) {
  348         octets = 16 - a6->prefixlen / 8;
  349         INSIST(r.length >= octets);
  350         memmove(a6->in6_addr.s6_addr + 16 - octets, r.base, octets);
  351         isc_region_consume(&r, octets);
  352     }
  353 
  354     /*
  355      * Prefix.
  356      */
  357     dns_name_init(&a6->prefix, NULL);
  358     if (a6->prefixlen != 0) {
  359         dns_name_init(&name, NULL);
  360         dns_name_fromregion(&name, &r);
  361         RETERR(name_duporclone(&name, mctx, &a6->prefix));
  362     }
  363     a6->mctx = mctx;
  364     return (ISC_R_SUCCESS);
  365 }
  366 
  367 static inline void
  368 freestruct_in_a6(ARGS_FREESTRUCT) {
  369     dns_rdata_in_a6_t *a6;
  370 
  371     REQUIRE(((dns_rdata_in_a6_t *)source) != NULL);
  372     REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdtype ==
  373         dns_rdatatype_a6);
  374     REQUIRE(((dns_rdata_in_a6_t *)source)->common.rdclass ==
  375         dns_rdataclass_in);
  376 
  377     a6 = source;
  378 
  379     if (a6->mctx == NULL)
  380         return;
  381 
  382     if (dns_name_dynamic(&a6->prefix))
  383         dns_name_free(&a6->prefix, a6->mctx);
  384     a6->mctx = NULL;
  385 }
  386 
  387 static inline isc_result_t
  388 additionaldata_in_a6(ARGS_ADDLDATA) {
  389     REQUIRE(rdata->type == dns_rdatatype_a6);
  390     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  391 
  392     UNUSED(rdata);
  393     UNUSED(add);
  394     UNUSED(arg);
  395 
  396     return (ISC_R_SUCCESS);
  397 }
  398 
  399 static inline isc_result_t
  400 digest_in_a6(ARGS_DIGEST) {
  401     isc_region_t r1, r2;
  402     unsigned char prefixlen, octets;
  403     isc_result_t result;
  404     dns_name_t name;
  405 
  406     REQUIRE(rdata->type == dns_rdatatype_a6);
  407     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  408 
  409     dns_rdata_toregion(rdata, &r1);
  410     r2 = r1;
  411     prefixlen = r1.base[0];
  412     octets = 1 + 16 - prefixlen / 8;
  413 
  414     r1.length = octets;
  415     result = (digest)(arg, &r1);
  416     if (result != ISC_R_SUCCESS)
  417         return (result);
  418     if (prefixlen == 0)
  419         return (ISC_R_SUCCESS);
  420 
  421     isc_region_consume(&r2, octets);
  422     dns_name_init(&name, NULL);
  423     dns_name_fromregion(&name, &r2);
  424     return (dns_name_digest(&name, digest, arg));
  425 }
  426 
  427 static inline bool
  428 checkowner_in_a6(ARGS_CHECKOWNER) {
  429 
  430     REQUIRE(type == dns_rdatatype_a6);
  431     REQUIRE(rdclass == dns_rdataclass_in);
  432 
  433     UNUSED(type);
  434     UNUSED(rdclass);
  435 
  436     return (dns_name_ishostname(name, wildcard));
  437 }
  438 
  439 static inline bool
  440 checknames_in_a6(ARGS_CHECKNAMES) {
  441     isc_region_t region;
  442     dns_name_t name;
  443     unsigned int prefixlen;
  444 
  445     REQUIRE(rdata->type == dns_rdatatype_a6);
  446     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  447 
  448     UNUSED(owner);
  449 
  450     dns_rdata_toregion(rdata, &region);
  451     prefixlen = uint8_fromregion(&region);
  452     if (prefixlen == 0)
  453         return (true);
  454     isc_region_consume(&region, 1 + 16 - prefixlen / 8);
  455     dns_name_init(&name, NULL);
  456     dns_name_fromregion(&name, &region);
  457     if (!dns_name_ishostname(&name, false)) {
  458         if (bad != NULL)
  459             dns_name_clone(&name, bad);
  460         return (false);
  461     }
  462     return (true);
  463 }
  464 
  465 static inline int
  466 casecompare_in_a6(ARGS_COMPARE) {
  467     return (compare_in_a6(rdata1, rdata2));
  468 }
  469 
  470 #endif  /* RDATA_IN_1_A6_38_C */