"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/dns/rdata/in_1/apl_42.c" (4 Sep 2020, 10557 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


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 "apl_42.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.2_vs_9.17.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 /* RFC3123 */
   13 
   14 #ifndef RDATA_IN_1_APL_42_C
   15 #define RDATA_IN_1_APL_42_C
   16 
   17 #define RRTYPE_APL_ATTRIBUTES (0)
   18 
   19 static inline isc_result_t
   20 fromtext_in_apl(ARGS_FROMTEXT) {
   21     isc_token_t token;
   22     unsigned char addr[16];
   23     unsigned long afi;
   24     uint8_t prefix;
   25     uint8_t len;
   26     bool neg;
   27     char *cp, *ap, *slash;
   28     int n;
   29 
   30     REQUIRE(type == dns_rdatatype_apl);
   31     REQUIRE(rdclass == dns_rdataclass_in);
   32 
   33     UNUSED(type);
   34     UNUSED(rdclass);
   35     UNUSED(origin);
   36     UNUSED(options);
   37     UNUSED(callbacks);
   38 
   39     do {
   40         RETERR(isc_lex_getmastertoken(lexer, &token,
   41                           isc_tokentype_string, true));
   42         if (token.type != isc_tokentype_string) {
   43             break;
   44         }
   45 
   46         cp = DNS_AS_STR(token);
   47         neg = (*cp == '!');
   48         if (neg) {
   49             cp++;
   50         }
   51         afi = strtoul(cp, &ap, 10);
   52         if (*ap++ != ':' || cp == ap) {
   53             RETTOK(DNS_R_SYNTAX);
   54         }
   55         if (afi > 0xffffU) {
   56             RETTOK(ISC_R_RANGE);
   57         }
   58         slash = strchr(ap, '/');
   59         if (slash == NULL || slash == ap) {
   60             RETTOK(DNS_R_SYNTAX);
   61         }
   62         RETTOK(isc_parse_uint8(&prefix, slash + 1, 10));
   63         switch (afi) {
   64         case 1:
   65             *slash = '\0';
   66             n = inet_pton(AF_INET, ap, addr);
   67             *slash = '/';
   68             if (n != 1) {
   69                 RETTOK(DNS_R_BADDOTTEDQUAD);
   70             }
   71             if (prefix > 32) {
   72                 RETTOK(ISC_R_RANGE);
   73             }
   74             for (len = 4; len > 0; len--) {
   75                 if (addr[len - 1] != 0) {
   76                     break;
   77                 }
   78             }
   79             break;
   80 
   81         case 2:
   82             *slash = '\0';
   83             n = inet_pton(AF_INET6, ap, addr);
   84             *slash = '/';
   85             if (n != 1) {
   86                 RETTOK(DNS_R_BADAAAA);
   87             }
   88             if (prefix > 128) {
   89                 RETTOK(ISC_R_RANGE);
   90             }
   91             for (len = 16; len > 0; len--) {
   92                 if (addr[len - 1] != 0) {
   93                     break;
   94                 }
   95             }
   96             break;
   97 
   98         default:
   99             RETTOK(ISC_R_NOTIMPLEMENTED);
  100         }
  101         RETERR(uint16_tobuffer(afi, target));
  102         RETERR(uint8_tobuffer(prefix, target));
  103         RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target));
  104         RETERR(mem_tobuffer(target, addr, len));
  105     } while (1);
  106 
  107     /*
  108      * Let upper layer handle eol/eof.
  109      */
  110     isc_lex_ungettoken(lexer, &token);
  111 
  112     return (ISC_R_SUCCESS);
  113 }
  114 
  115 static inline isc_result_t
  116 totext_in_apl(ARGS_TOTEXT) {
  117     isc_region_t sr;
  118     isc_region_t ir;
  119     uint16_t afi;
  120     uint8_t prefix;
  121     uint8_t len;
  122     bool neg;
  123     unsigned char buf[16];
  124     char txt[sizeof(" !64000:")];
  125     const char *sep = "";
  126     int n;
  127 
  128     REQUIRE(rdata->type == dns_rdatatype_apl);
  129     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  130 
  131     UNUSED(tctx);
  132 
  133     dns_rdata_toregion(rdata, &sr);
  134     ir.base = buf;
  135     ir.length = sizeof(buf);
  136 
  137     while (sr.length > 0) {
  138         INSIST(sr.length >= 4);
  139         afi = uint16_fromregion(&sr);
  140         isc_region_consume(&sr, 2);
  141         prefix = *sr.base;
  142         isc_region_consume(&sr, 1);
  143         len = (*sr.base & 0x7f);
  144         neg = (*sr.base & 0x80);
  145         isc_region_consume(&sr, 1);
  146         INSIST(len <= sr.length);
  147         n = snprintf(txt, sizeof(txt), "%s%s%u:", sep, neg ? "!" : "",
  148                  afi);
  149         INSIST(n < (int)sizeof(txt));
  150         RETERR(str_totext(txt, target));
  151         switch (afi) {
  152         case 1:
  153             INSIST(len <= 4);
  154             INSIST(prefix <= 32);
  155             memset(buf, 0, sizeof(buf));
  156             memmove(buf, sr.base, len);
  157             RETERR(inet_totext(AF_INET, tctx->flags, &ir, target));
  158             break;
  159 
  160         case 2:
  161             INSIST(len <= 16);
  162             INSIST(prefix <= 128);
  163             memset(buf, 0, sizeof(buf));
  164             memmove(buf, sr.base, len);
  165             RETERR(inet_totext(AF_INET6, tctx->flags, &ir, target));
  166             break;
  167 
  168         default:
  169             return (ISC_R_NOTIMPLEMENTED);
  170         }
  171         n = snprintf(txt, sizeof(txt), "/%u", prefix);
  172         INSIST(n < (int)sizeof(txt));
  173         RETERR(str_totext(txt, target));
  174         isc_region_consume(&sr, len);
  175         sep = " ";
  176     }
  177     return (ISC_R_SUCCESS);
  178 }
  179 
  180 static inline isc_result_t
  181 fromwire_in_apl(ARGS_FROMWIRE) {
  182     isc_region_t sr, sr2;
  183     isc_region_t tr;
  184     uint16_t afi;
  185     uint8_t prefix;
  186     uint8_t len;
  187 
  188     REQUIRE(type == dns_rdatatype_apl);
  189     REQUIRE(rdclass == dns_rdataclass_in);
  190 
  191     UNUSED(type);
  192     UNUSED(dctx);
  193     UNUSED(rdclass);
  194     UNUSED(options);
  195 
  196     isc_buffer_activeregion(source, &sr);
  197     isc_buffer_availableregion(target, &tr);
  198     if (sr.length > tr.length) {
  199         return (ISC_R_NOSPACE);
  200     }
  201     sr2 = sr;
  202 
  203     /* Zero or more items */
  204     while (sr.length > 0) {
  205         if (sr.length < 4) {
  206             return (ISC_R_UNEXPECTEDEND);
  207         }
  208         afi = uint16_fromregion(&sr);
  209         isc_region_consume(&sr, 2);
  210         prefix = *sr.base;
  211         isc_region_consume(&sr, 1);
  212         len = (*sr.base & 0x7f);
  213         isc_region_consume(&sr, 1);
  214         if (len > sr.length) {
  215             return (ISC_R_UNEXPECTEDEND);
  216         }
  217         switch (afi) {
  218         case 1:
  219             if (prefix > 32 || len > 4) {
  220                 return (ISC_R_RANGE);
  221             }
  222             break;
  223         case 2:
  224             if (prefix > 128 || len > 16) {
  225                 return (ISC_R_RANGE);
  226             }
  227         }
  228         if (len > 0 && sr.base[len - 1] == 0) {
  229             return (DNS_R_FORMERR);
  230         }
  231         isc_region_consume(&sr, len);
  232     }
  233     isc_buffer_forward(source, sr2.length);
  234     return (mem_tobuffer(target, sr2.base, sr2.length));
  235 }
  236 
  237 static inline isc_result_t
  238 towire_in_apl(ARGS_TOWIRE) {
  239     UNUSED(cctx);
  240 
  241     REQUIRE(rdata->type == dns_rdatatype_apl);
  242     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  243 
  244     return (mem_tobuffer(target, rdata->data, rdata->length));
  245 }
  246 
  247 static inline int
  248 compare_in_apl(ARGS_COMPARE) {
  249     isc_region_t r1;
  250     isc_region_t r2;
  251 
  252     REQUIRE(rdata1->type == rdata2->type);
  253     REQUIRE(rdata1->rdclass == rdata2->rdclass);
  254     REQUIRE(rdata1->type == dns_rdatatype_apl);
  255     REQUIRE(rdata1->rdclass == dns_rdataclass_in);
  256 
  257     dns_rdata_toregion(rdata1, &r1);
  258     dns_rdata_toregion(rdata2, &r2);
  259     return (isc_region_compare(&r1, &r2));
  260 }
  261 
  262 static inline isc_result_t
  263 fromstruct_in_apl(ARGS_FROMSTRUCT) {
  264     dns_rdata_in_apl_t *apl = source;
  265     isc_buffer_t b;
  266 
  267     REQUIRE(type == dns_rdatatype_apl);
  268     REQUIRE(rdclass == dns_rdataclass_in);
  269     REQUIRE(apl != NULL);
  270     REQUIRE(apl->common.rdtype == type);
  271     REQUIRE(apl->common.rdclass == rdclass);
  272     REQUIRE(apl->apl != NULL || apl->apl_len == 0);
  273 
  274     isc_buffer_init(&b, apl->apl, apl->apl_len);
  275     isc_buffer_add(&b, apl->apl_len);
  276     isc_buffer_setactive(&b, apl->apl_len);
  277     return (fromwire_in_apl(rdclass, type, &b, NULL, false, target));
  278 }
  279 
  280 static inline isc_result_t
  281 tostruct_in_apl(ARGS_TOSTRUCT) {
  282     dns_rdata_in_apl_t *apl = target;
  283     isc_region_t r;
  284 
  285     REQUIRE(apl != NULL);
  286     REQUIRE(rdata->type == dns_rdatatype_apl);
  287     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  288 
  289     apl->common.rdclass = rdata->rdclass;
  290     apl->common.rdtype = rdata->type;
  291     ISC_LINK_INIT(&apl->common, link);
  292 
  293     dns_rdata_toregion(rdata, &r);
  294     apl->apl_len = r.length;
  295     apl->apl = mem_maybedup(mctx, r.base, r.length);
  296     if (apl->apl == NULL) {
  297         return (ISC_R_NOMEMORY);
  298     }
  299 
  300     apl->offset = 0;
  301     apl->mctx = mctx;
  302     return (ISC_R_SUCCESS);
  303 }
  304 
  305 static inline void
  306 freestruct_in_apl(ARGS_FREESTRUCT) {
  307     dns_rdata_in_apl_t *apl = source;
  308 
  309     REQUIRE(apl != NULL);
  310     REQUIRE(apl->common.rdtype == dns_rdatatype_apl);
  311     REQUIRE(apl->common.rdclass == dns_rdataclass_in);
  312 
  313     if (apl->mctx == NULL) {
  314         return;
  315     }
  316     if (apl->apl != NULL) {
  317         isc_mem_free(apl->mctx, apl->apl);
  318     }
  319     apl->mctx = NULL;
  320 }
  321 
  322 isc_result_t
  323 dns_rdata_apl_first(dns_rdata_in_apl_t *apl) {
  324     uint32_t length;
  325 
  326     REQUIRE(apl != NULL);
  327     REQUIRE(apl->common.rdtype == dns_rdatatype_apl);
  328     REQUIRE(apl->common.rdclass == dns_rdataclass_in);
  329     REQUIRE(apl->apl != NULL || apl->apl_len == 0);
  330 
  331     /*
  332      * If no APL return ISC_R_NOMORE.
  333      */
  334     if (apl->apl == NULL) {
  335         return (ISC_R_NOMORE);
  336     }
  337 
  338     /*
  339      * Sanity check data.
  340      */
  341     INSIST(apl->apl_len > 3U);
  342     length = apl->apl[apl->offset + 3] & 0x7f;
  343     INSIST(4 + length <= apl->apl_len);
  344 
  345     apl->offset = 0;
  346     return (ISC_R_SUCCESS);
  347 }
  348 
  349 isc_result_t
  350 dns_rdata_apl_next(dns_rdata_in_apl_t *apl) {
  351     uint32_t length;
  352 
  353     REQUIRE(apl != NULL);
  354     REQUIRE(apl->common.rdtype == dns_rdatatype_apl);
  355     REQUIRE(apl->common.rdclass == dns_rdataclass_in);
  356     REQUIRE(apl->apl != NULL || apl->apl_len == 0);
  357 
  358     /*
  359      * No APL or have already reached the end return ISC_R_NOMORE.
  360      */
  361     if (apl->apl == NULL || apl->offset == apl->apl_len) {
  362         return (ISC_R_NOMORE);
  363     }
  364 
  365     /*
  366      * Sanity check data.
  367      */
  368     INSIST(apl->offset < apl->apl_len);
  369     INSIST(apl->apl_len > 3U);
  370     INSIST(apl->offset <= apl->apl_len - 4U);
  371     length = apl->apl[apl->offset + 3] & 0x7f;
  372     /*
  373      * 16 to 32 bits promotion as 'length' is 32 bits so there is
  374      * no overflow problems.
  375      */
  376     INSIST(4 + length + apl->offset <= apl->apl_len);
  377 
  378     apl->offset += 4 + length;
  379     return ((apl->offset < apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
  380 }
  381 
  382 isc_result_t
  383 dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) {
  384     uint32_t length;
  385 
  386     REQUIRE(apl != NULL);
  387     REQUIRE(apl->common.rdtype == dns_rdatatype_apl);
  388     REQUIRE(apl->common.rdclass == dns_rdataclass_in);
  389     REQUIRE(ent != NULL);
  390     REQUIRE(apl->apl != NULL || apl->apl_len == 0);
  391     REQUIRE(apl->offset <= apl->apl_len);
  392 
  393     if (apl->offset == apl->apl_len) {
  394         return (ISC_R_NOMORE);
  395     }
  396 
  397     /*
  398      * Sanity check data.
  399      */
  400     INSIST(apl->apl_len > 3U);
  401     INSIST(apl->offset <= apl->apl_len - 4U);
  402     length = (apl->apl[apl->offset + 3] & 0x7f);
  403     /*
  404      * 16 to 32 bits promotion as 'length' is 32 bits so there is
  405      * no overflow problems.
  406      */
  407     INSIST(4 + length + apl->offset <= apl->apl_len);
  408 
  409     ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1];
  410     ent->prefix = apl->apl[apl->offset + 2];
  411     ent->length = length;
  412     ent->negative = (apl->apl[apl->offset + 3] & 0x80);
  413     if (ent->length != 0) {
  414         ent->data = &apl->apl[apl->offset + 4];
  415     } else {
  416         ent->data = NULL;
  417     }
  418     return (ISC_R_SUCCESS);
  419 }
  420 
  421 unsigned int
  422 dns_rdata_apl_count(const dns_rdata_in_apl_t *apl) {
  423     return (apl->apl_len);
  424 }
  425 
  426 static inline isc_result_t
  427 additionaldata_in_apl(ARGS_ADDLDATA) {
  428     REQUIRE(rdata->type == dns_rdatatype_apl);
  429     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  430 
  431     (void)add;
  432     (void)arg;
  433 
  434     return (ISC_R_SUCCESS);
  435 }
  436 
  437 static inline isc_result_t
  438 digest_in_apl(ARGS_DIGEST) {
  439     isc_region_t r;
  440 
  441     REQUIRE(rdata->type == dns_rdatatype_apl);
  442     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  443 
  444     dns_rdata_toregion(rdata, &r);
  445 
  446     return ((digest)(arg, &r));
  447 }
  448 
  449 static inline bool
  450 checkowner_in_apl(ARGS_CHECKOWNER) {
  451     REQUIRE(type == dns_rdatatype_apl);
  452     REQUIRE(rdclass == dns_rdataclass_in);
  453 
  454     UNUSED(name);
  455     UNUSED(type);
  456     UNUSED(rdclass);
  457     UNUSED(wildcard);
  458 
  459     return (true);
  460 }
  461 
  462 static inline bool
  463 checknames_in_apl(ARGS_CHECKNAMES) {
  464     REQUIRE(rdata->type == dns_rdatatype_apl);
  465     REQUIRE(rdata->rdclass == dns_rdataclass_in);
  466 
  467     UNUSED(rdata);
  468     UNUSED(owner);
  469     UNUSED(bad);
  470 
  471     return (true);
  472 }
  473 
  474 static inline int
  475 casecompare_in_apl(ARGS_COMPARE) {
  476     return (compare_in_apl(rdata1, rdata2));
  477 }
  478 
  479 #endif /* RDATA_IN_1_APL_42_C */