]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1220. [func] Support for APL rdata type.
authorMark Andrews <marka@isc.org>
Wed, 6 Mar 2002 07:41:25 +0000 (07:41 +0000)
committerMark Andrews <marka@isc.org>
Wed, 6 Mar 2002 07:41:25 +0000 (07:41 +0000)
CHANGES
bin/tests/rdata_test.c
lib/dns/rdata/in_1/apl_42.c [new file with mode: 0644]
lib/dns/rdata/in_1/apl_42.h [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 470367fced9c8a957ccec18bfc397f1adbac2411..2cdcf3544a96475df49f79315759ea297c0709e0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+1220.  [func]          Support for APL rdata type.
+
 1219.  [func]          Named now reports the TSIG extended error code when
                        signature verification fails. [RT #1651]
 
index 1416d5bd870f4ce865611dd539b775df18795f6a..22568f2bdf542cf9e0aae0695c2b33fd0d2074b5 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rdata_test.c,v 1.37 2001/11/27 01:55:21 gson Exp $ */
+/* $Id: rdata_test.c,v 1.38 2002/03/06 07:41:25 marka Exp $ */
 
 #include <config.h>
 
@@ -91,6 +91,19 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx,
                result = ISC_R_NOTIMPLEMENTED;
                break;
        }
+       case dns_rdatatype_apl: {
+               switch (rdata->rdclass) {
+               case dns_rdataclass_in: {
+                       dns_rdata_in_apl_t in_apl;
+                       result = dns_rdata_tostruct(rdata, sp = &in_apl, NULL);
+                       break;
+               }
+               default:
+                       result = ISC_R_NOTIMPLEMENTED;
+                       break;
+               }
+               break;
+       }
        case dns_rdatatype_cert: {
                dns_rdata_cert_t cert;
                result = dns_rdata_tostruct(rdata, sp = &cert, NULL);
@@ -320,6 +333,19 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx,
                result = ISC_R_NOTIMPLEMENTED;
                break;
        }
+       case dns_rdatatype_apl: {
+               switch (rdata->rdclass) {
+               case dns_rdataclass_in: {
+                       dns_rdata_in_apl_t in_apl;
+                       result = dns_rdata_tostruct(rdata, sp = &in_apl, mctx);
+                       break;
+               }
+               default:
+                       result = ISC_R_NOTIMPLEMENTED;
+                       break;
+               }
+               break;
+       }
        case dns_rdatatype_cert: {
                dns_rdata_cert_t cert;
                result = dns_rdata_tostruct(rdata, sp = &cert, mctx);
@@ -578,6 +604,19 @@ viastruct(dns_rdata_t *rdata, isc_mem_t *mctx,
                result = ISC_R_NOTIMPLEMENTED;
                break;
        }
+       case dns_rdatatype_apl: {
+               switch (rdata->rdclass) {
+               case dns_rdataclass_in: {
+                       dns_rdata_in_apl_t in_apl;
+                       result = dns_rdata_fromstruct(rdata, rdc, rdt, &in_apl,                                                       b);
+                       break;
+               }
+               default:
+                       result = ISC_R_NOTIMPLEMENTED;
+                       break;
+               }
+               break;
+       }
        case dns_rdatatype_cert: {
                dns_rdata_cert_t cert;
                result = dns_rdata_fromstruct(rdata2, rdc, rdt, &cert, b);
diff --git a/lib/dns/rdata/in_1/apl_42.c b/lib/dns/rdata/in_1/apl_42.c
new file mode 100644 (file)
index 0000000..4fc079e
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2002  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: apl_42.c,v 1.1 2002/03/06 07:41:25 marka Exp $ */
+
+/* RFC 3123 */
+
+#ifndef RDATA_IN_1_ALP_42_C
+#define RDATA_IN_1_ALP_42_C
+
+#define RRTYPE_APL_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_in_apl(ARGS_FROMTEXT) {
+       isc_token_t token;
+       unsigned char addr[16];
+       isc_uint16_t afi;
+       isc_uint8_t prefix;
+       isc_uint8_t len;
+       isc_boolean_t neg;
+       char *cp, *ap, *slash;
+
+       REQUIRE(type == 42);
+       REQUIRE(rdclass == 1);
+
+       UNUSED(type);
+       UNUSED(rdclass);
+       UNUSED(origin);
+       UNUSED(downcase);
+       UNUSED(callbacks);
+
+       do {
+               RETERR(isc_lex_getmastertoken(lexer, &token,
+                                             isc_tokentype_string, ISC_TRUE));
+               if (token.type != isc_tokentype_string)
+                       break;
+       
+               cp = DNS_AS_STR(token);
+               neg = ISC_TF(*cp == '!');
+               if (neg)
+                       cp++;
+               afi = strtoul(cp, &ap, 10);
+               if (*ap++ != ':' || cp == ap)
+                       RETTOK(DNS_R_SYNTAX);
+               if (afi > 0xffff)
+                       RETTOK(ISC_R_RANGE);
+               slash = strchr(ap, '/');
+               if (slash == NULL || slash == ap)
+                       RETTOK(DNS_R_SYNTAX);
+               *slash++ = '\0';
+               prefix = strtoul(slash, &cp, 10);
+               if (*cp != '\0' || slash == cp)
+                       RETTOK(DNS_R_SYNTAX);
+               switch (afi) {
+               case 1:
+                       if (inet_pton(AF_INET, ap, addr) != 1)
+                               RETTOK(DNS_R_BADDOTTEDQUAD);
+                       if (prefix > 32)
+                               RETTOK(ISC_R_RANGE);
+                       for (len = 4; len > 0; len--)
+                               if (addr[len - 1] != 0)
+                                       break;
+                       break;
+
+               case 2:
+                       if (inet_pton(AF_INET6, ap, addr) != 1)
+                               RETTOK(DNS_R_BADAAAA);
+                       if (prefix > 128)
+                               RETTOK(ISC_R_RANGE);
+                       for (len = 16; len > 0; len--)
+                               if (addr[len - 1] != 0)
+                                       break;
+                       break;
+
+               default:
+                       RETTOK(ISC_R_NOTIMPLEMENTED);
+               }
+               RETERR(uint16_tobuffer(afi, target));
+               RETERR(uint8_tobuffer(prefix, target));
+               RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target));
+               RETERR(mem_tobuffer(target, addr, len));
+       } while (1);
+
+       /*
+        * Let upper layer handle eol/eof.
+        */
+       isc_lex_ungettoken(lexer, &token);
+
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+totext_in_apl(ARGS_TOTEXT) {
+       isc_region_t sr;
+       isc_region_t ir;
+       isc_uint16_t afi;
+       isc_uint8_t prefix;
+       isc_uint8_t len;
+       isc_boolean_t neg;
+       char buf[16];
+       const char *sep = "";
+       int n;
+
+       REQUIRE(rdata->type == 42);
+       REQUIRE(rdata->rdclass == 1);
+
+       UNUSED(tctx);
+
+       dns_rdata_toregion(rdata, &sr);
+       ir.base = buf;
+       ir.length = sizeof(buf);
+
+       while (sr.length > 0) {
+               INSIST(sr.length >= 4);
+               afi = uint16_fromregion(&sr);
+               isc_region_consume(&sr, 2);
+               prefix = *sr.base;
+               isc_region_consume(&sr, 1);
+               len = (*sr.base & 0x7f);
+               neg = ISC_TF((*sr.base & 0x80) != 0);
+               isc_region_consume(&sr, 1);
+               INSIST(len <= sr.length);
+               n = snprintf(buf, sizeof(buf), "%s%s%u:", sep,
+                            neg ? "!": "", afi);
+               INSIST(n < (int)sizeof(buf));
+               RETERR(str_totext(buf, target));
+               switch (afi) {
+               case 1:
+                       INSIST(len <= 4);
+                       INSIST(prefix <= 32);
+                       memset(buf, 0, sizeof(buf));
+                       memcpy(buf, sr.base, len);
+                       RETERR(inet_totext(AF_INET, &ir, target));
+                       break;
+
+               case 2:
+                       INSIST(len <= 16);
+                       INSIST(prefix <= 128);
+                       memset(buf, 0, sizeof(buf));
+                       memcpy(buf, sr.base, len);
+                       RETERR(inet_totext(AF_INET6, &ir, target));
+                       break;
+
+               default:
+                       return (ISC_R_NOTIMPLEMENTED);
+               }
+               n = snprintf(buf, sizeof(buf), "/%u", prefix);
+               INSIST(n < (int)sizeof(buf));
+               RETERR(str_totext(buf, target));
+               isc_region_consume(&sr, len);
+               sep = " ";
+       }
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_in_apl(ARGS_FROMWIRE) {
+       isc_region_t sr, sr2;
+       isc_region_t tr;
+       isc_uint16_t afi;
+       isc_uint8_t prefix;
+       isc_uint8_t len;
+
+       REQUIRE(type == 42);
+       REQUIRE(rdclass == 1);
+
+       UNUSED(type);
+       UNUSED(dctx);
+       UNUSED(rdclass);
+       UNUSED(downcase);
+
+       isc_buffer_activeregion(source, &sr);
+       isc_buffer_availableregion(target, &tr);
+       if (sr.length > tr.length)
+               return (ISC_R_NOSPACE);
+       sr2 = sr;
+
+       /* Zero or more items */
+       while (sr.length > 0) {
+               if (sr.length < 4)
+                       return (ISC_R_UNEXPECTEDEND);
+               afi = uint16_fromregion(&sr);
+               isc_region_consume(&sr, 2);
+               prefix = *sr.base;
+               isc_region_consume(&sr, 1);
+               len = (*sr.base & 0x7f);
+               isc_region_consume(&sr, 1);
+               if (len > sr.length)
+                       return (ISC_R_UNEXPECTEDEND);
+               switch (afi) {
+               case 1:
+                       if (prefix > 32 || len > 4)
+                               return (ISC_R_RANGE);
+                       break;
+               case 2:
+                       if (prefix > 128 || len > 16)
+                               return (ISC_R_RANGE);
+               }
+               if (len > 0 && sr.base[len - 1] == 0)
+                       return (DNS_R_FORMERR);
+               isc_region_consume(&sr, len);
+       }
+       isc_buffer_forward(source, sr2.length);
+       return (mem_tobuffer(target, sr2.base, sr2.length));
+}
+
+static inline isc_result_t
+towire_in_apl(ARGS_TOWIRE) {
+       UNUSED(cctx);
+
+       REQUIRE(rdata->type == 42);
+       REQUIRE(rdata->rdclass == 1);
+
+       return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_in_apl(ARGS_COMPARE) {
+       isc_region_t r1;
+       isc_region_t r2;
+
+       REQUIRE(rdata1->type == rdata2->type);
+       REQUIRE(rdata1->rdclass == rdata2->rdclass);
+       REQUIRE(rdata1->type == 42);
+       REQUIRE(rdata1->rdclass == 1);
+
+       dns_rdata_toregion(rdata1, &r1);
+       dns_rdata_toregion(rdata2, &r2);
+       return (isc_region_compare(&r1, &r2));
+}
+
+static inline isc_result_t
+fromstruct_in_apl(ARGS_FROMSTRUCT) {
+       dns_rdata_in_apl_t *apl = source;
+       isc_buffer_t b;
+
+       REQUIRE(type == 42);
+       REQUIRE(rdclass == 1);
+       REQUIRE(source != NULL);
+       REQUIRE(apl->common.rdtype == type);
+       REQUIRE(apl->common.rdclass == rdclass);
+       REQUIRE(apl->apl != NULL || apl->apl_len == 0);
+       
+       isc_buffer_init(&b, apl->apl, apl->apl_len);
+       isc_buffer_add(&b, apl->apl_len);
+       isc_buffer_setactive(&b, apl->apl_len);
+       return(fromwire_in_apl(rdclass, type, &b, NULL, ISC_FALSE, target));
+}
+
+static inline isc_result_t
+tostruct_in_apl(ARGS_TOSTRUCT) {
+       dns_rdata_in_apl_t *apl = target;
+       isc_region_t r;
+
+       REQUIRE(rdata->type == 42);
+       REQUIRE(rdata->rdclass == 1);
+
+       apl->common.rdclass = rdata->rdclass;
+       apl->common.rdtype = rdata->type;
+       ISC_LINK_INIT(&apl->common, link);
+
+       dns_rdata_toregion(rdata, &r);
+       apl->apl_len = r.length;
+       apl->apl = mem_maybedup(mctx, r.base, r.length);
+       if (apl->apl == NULL)
+               return (ISC_R_NOMEMORY);
+
+       apl->offset = 0;
+       apl->mctx = mctx;
+       return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_in_apl(ARGS_FREESTRUCT) {
+       dns_rdata_in_apl_t *apl = source;
+
+       REQUIRE(source != NULL);
+       REQUIRE(apl->common.rdtype == 42);
+       REQUIRE(apl->common.rdclass == 1);
+
+       if (apl->mctx == NULL)
+               return;
+       if (apl->apl != NULL)
+               isc_mem_free(apl->mctx, apl->apl);
+       apl->mctx = NULL;
+}
+
+isc_result_t
+dns_rdata_apl_first(dns_rdata_in_apl_t *apl) {
+       REQUIRE(apl->common.rdtype == 42);
+       REQUIRE(apl->common.rdclass == 1);
+       REQUIRE(apl->apl != NULL || apl->apl_len == 0);
+
+       apl->offset = 0;
+       return ((apl->apl_len != 0) ? ISC_R_SUCCESS : ISC_R_NOMORE);
+}
+
+isc_result_t
+dns_rdata_apl_next(dns_rdata_in_apl_t *apl) {
+       REQUIRE(apl->common.rdtype == 42);
+       REQUIRE(apl->common.rdclass == 1);
+       REQUIRE(apl->apl != NULL || apl->apl_len == 0);
+
+       if (apl->offset + 3 < apl->apl_len)
+               return (ISC_R_NOMORE);
+       apl->offset += apl->apl[apl->offset + 3] & 0x7f;
+       return ((apl->offset >= apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
+}
+
+isc_result_t
+dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) {
+
+       REQUIRE(apl->common.rdtype == 42);
+       REQUIRE(apl->common.rdclass == 1);
+       REQUIRE(ent != NULL);
+       REQUIRE(apl->apl != NULL || apl->apl_len == 0);
+
+       if (apl->offset >= apl->apl_len)
+               return (ISC_R_NOMORE);
+
+       ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1];
+       ent->prefix = apl->apl[apl->offset + 2];
+       ent->length = apl->apl[apl->offset + 3] & 0x7f;
+       ent->negative = ISC_TF((apl->apl[apl->offset + 3] & 0x80) != 0);
+       if (ent->length != 0)
+               ent->data = &apl->apl[apl->offset + 4];
+       else
+               ent->data = NULL;
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+additionaldata_in_apl(ARGS_ADDLDATA) {
+       REQUIRE(rdata->type == 42);
+       REQUIRE(rdata->rdclass == 1);
+
+       (void)add;
+       (void)arg;
+
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_in_apl(ARGS_DIGEST) {
+       isc_region_t r;
+
+       REQUIRE(rdata->type == 42);
+       REQUIRE(rdata->rdclass == 1);
+
+       dns_rdata_toregion(rdata, &r);
+
+       return ((digest)(arg, &r));
+}
+
+#endif /* RDATA_IN_1_ALP_42_C */
diff --git a/lib/dns/rdata/in_1/apl_42.h b/lib/dns/rdata/in_1/apl_42.h
new file mode 100644 (file)
index 0000000..ea8ed8b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 1998-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef IN_1_APL_42_H
+#define IN_1_APL_42_H 1
+
+/* $Id: apl_42.h,v 1.1 2002/03/06 07:41:25 marka Exp $ */
+
+typedef struct dns_rdata_apl_ent {
+       isc_boolean_t   negative;
+       isc_uint16_t    family;
+       isc_uint8_t     prefix;
+       isc_uint8_t     length;
+       unsigned char   *data;
+} dns_rdata_apl_ent_t;
+
+typedef struct dns_rdata_in_apl {
+       dns_rdatacommon_t       common;
+       isc_mem_t               *mctx;
+       /* type & class specific elements */
+       unsigned char           *apl;
+        isc_uint16_t            apl_len;
+        /* private */
+        isc_uint16_t            offset;
+} dns_rdata_in_apl_t;
+
+/*
+ * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
+ * via rdatastructpre.h and rdatastructsuf.h.
+ */
+
+isc_result_t
+dns_rdata_apl_first(dns_rdata_in_apl_t *);
+
+isc_result_t
+dns_rdata_apl_next(dns_rdata_in_apl_t *);
+
+isc_result_t
+dns_rdata_apl_current(dns_rdata_in_apl_t *, dns_rdata_apl_ent_t *);
+
+#endif /* IN_1_APL_42_H */