00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef RDATA_IN_1_APL_42_C
00023 #define RDATA_IN_1_APL_42_C
00024
00025 #define RRTYPE_APL_ATTRIBUTES (0)
00026
00027 static inline isc_result_t
00028 fromtext_in_apl(ARGS_FROMTEXT) {
00029 isc_token_t token;
00030 unsigned char addr[16];
00031 unsigned long afi;
00032 isc_uint8_t prefix;
00033 isc_uint8_t len;
00034 isc_boolean_t neg;
00035 char *cp, *ap, *slash;
00036 int n;
00037
00038 REQUIRE(type == 42);
00039 REQUIRE(rdclass == 1);
00040
00041 UNUSED(type);
00042 UNUSED(rdclass);
00043 UNUSED(origin);
00044 UNUSED(options);
00045 UNUSED(callbacks);
00046
00047 do {
00048 RETERR(isc_lex_getmastertoken(lexer, &token,
00049 isc_tokentype_string, ISC_TRUE));
00050 if (token.type != isc_tokentype_string)
00051 break;
00052
00053 cp = DNS_AS_STR(token);
00054 neg = ISC_TF(*cp == '!');
00055 if (neg)
00056 cp++;
00057 afi = strtoul(cp, &ap, 10);
00058 if (*ap++ != ':' || cp == ap)
00059 RETTOK(DNS_R_SYNTAX);
00060 if (afi > 0xffffU)
00061 RETTOK(ISC_R_RANGE);
00062 slash = strchr(ap, '/');
00063 if (slash == NULL || slash == ap)
00064 RETTOK(DNS_R_SYNTAX);
00065 RETTOK(isc_parse_uint8(&prefix, slash + 1, 10));
00066 switch (afi) {
00067 case 1:
00068 *slash = '\0';
00069 n = inet_pton(AF_INET, ap, addr);
00070 *slash = '/';
00071 if (n != 1)
00072 RETTOK(DNS_R_BADDOTTEDQUAD);
00073 if (prefix > 32)
00074 RETTOK(ISC_R_RANGE);
00075 for (len = 4; len > 0; len--)
00076 if (addr[len - 1] != 0)
00077 break;
00078 break;
00079
00080 case 2:
00081 *slash = '\0';
00082 n = inet_pton(AF_INET6, ap, addr);
00083 *slash = '/';
00084 if (n != 1)
00085 RETTOK(DNS_R_BADAAAA);
00086 if (prefix > 128)
00087 RETTOK(ISC_R_RANGE);
00088 for (len = 16; len > 0; len--)
00089 if (addr[len - 1] != 0)
00090 break;
00091 break;
00092
00093 default:
00094 RETTOK(ISC_R_NOTIMPLEMENTED);
00095 }
00096 RETERR(uint16_tobuffer(afi, target));
00097 RETERR(uint8_tobuffer(prefix, target));
00098 RETERR(uint8_tobuffer(len | ((neg) ? 0x80 : 0), target));
00099 RETERR(mem_tobuffer(target, addr, len));
00100 } while (1);
00101
00102
00103
00104
00105 isc_lex_ungettoken(lexer, &token);
00106
00107 return (ISC_R_SUCCESS);
00108 }
00109
00110 static inline isc_result_t
00111 totext_in_apl(ARGS_TOTEXT) {
00112 isc_region_t sr;
00113 isc_region_t ir;
00114 isc_uint16_t afi;
00115 isc_uint8_t prefix;
00116 isc_uint8_t len;
00117 isc_boolean_t neg;
00118 unsigned char buf[16];
00119 char txt[sizeof(" !64000")];
00120 const char *sep = "";
00121 int n;
00122
00123 REQUIRE(rdata->type == 42);
00124 REQUIRE(rdata->rdclass == 1);
00125
00126 UNUSED(tctx);
00127
00128 dns_rdata_toregion(rdata, &sr);
00129 ir.base = buf;
00130 ir.length = sizeof(buf);
00131
00132 while (sr.length > 0) {
00133 INSIST(sr.length >= 4);
00134 afi = uint16_fromregion(&sr);
00135 isc_region_consume(&sr, 2);
00136 prefix = *sr.base;
00137 isc_region_consume(&sr, 1);
00138 len = (*sr.base & 0x7f);
00139 neg = ISC_TF((*sr.base & 0x80) != 0);
00140 isc_region_consume(&sr, 1);
00141 INSIST(len <= sr.length);
00142 n = snprintf(txt, sizeof(txt), "%s%s%u:", sep,
00143 neg ? "!": "", afi);
00144 INSIST(n < (int)sizeof(txt));
00145 RETERR(str_totext(txt, target));
00146 switch (afi) {
00147 case 1:
00148 INSIST(len <= 4);
00149 INSIST(prefix <= 32);
00150 memset(buf, 0, sizeof(buf));
00151 memmove(buf, sr.base, len);
00152 RETERR(inet_totext(AF_INET, &ir, target));
00153 break;
00154
00155 case 2:
00156 INSIST(len <= 16);
00157 INSIST(prefix <= 128);
00158 memset(buf, 0, sizeof(buf));
00159 memmove(buf, sr.base, len);
00160 RETERR(inet_totext(AF_INET6, &ir, target));
00161 break;
00162
00163 default:
00164 return (ISC_R_NOTIMPLEMENTED);
00165 }
00166 n = snprintf(txt, sizeof(txt), "/%u", prefix);
00167 INSIST(n < (int)sizeof(txt));
00168 RETERR(str_totext(txt, target));
00169 isc_region_consume(&sr, len);
00170 sep = " ";
00171 }
00172 return (ISC_R_SUCCESS);
00173 }
00174
00175 static inline isc_result_t
00176 fromwire_in_apl(ARGS_FROMWIRE) {
00177 isc_region_t sr, sr2;
00178 isc_region_t tr;
00179 isc_uint16_t afi;
00180 isc_uint8_t prefix;
00181 isc_uint8_t len;
00182
00183 REQUIRE(type == 42);
00184 REQUIRE(rdclass == 1);
00185
00186 UNUSED(type);
00187 UNUSED(dctx);
00188 UNUSED(rdclass);
00189 UNUSED(options);
00190
00191 isc_buffer_activeregion(source, &sr);
00192 isc_buffer_availableregion(target, &tr);
00193 if (sr.length > tr.length)
00194 return (ISC_R_NOSPACE);
00195 sr2 = sr;
00196
00197
00198 while (sr.length > 0) {
00199 if (sr.length < 4)
00200 return (ISC_R_UNEXPECTEDEND);
00201 afi = uint16_fromregion(&sr);
00202 isc_region_consume(&sr, 2);
00203 prefix = *sr.base;
00204 isc_region_consume(&sr, 1);
00205 len = (*sr.base & 0x7f);
00206 isc_region_consume(&sr, 1);
00207 if (len > sr.length)
00208 return (ISC_R_UNEXPECTEDEND);
00209 switch (afi) {
00210 case 1:
00211 if (prefix > 32 || len > 4)
00212 return (ISC_R_RANGE);
00213 break;
00214 case 2:
00215 if (prefix > 128 || len > 16)
00216 return (ISC_R_RANGE);
00217 }
00218 if (len > 0 && sr.base[len - 1] == 0)
00219 return (DNS_R_FORMERR);
00220 isc_region_consume(&sr, len);
00221 }
00222 isc_buffer_forward(source, sr2.length);
00223 return (mem_tobuffer(target, sr2.base, sr2.length));
00224 }
00225
00226 static inline isc_result_t
00227 towire_in_apl(ARGS_TOWIRE) {
00228 UNUSED(cctx);
00229
00230 REQUIRE(rdata->type == 42);
00231 REQUIRE(rdata->rdclass == 1);
00232
00233 return (mem_tobuffer(target, rdata->data, rdata->length));
00234 }
00235
00236 static inline int
00237 compare_in_apl(ARGS_COMPARE) {
00238 isc_region_t r1;
00239 isc_region_t r2;
00240
00241 REQUIRE(rdata1->type == rdata2->type);
00242 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00243 REQUIRE(rdata1->type == 42);
00244 REQUIRE(rdata1->rdclass == 1);
00245
00246 dns_rdata_toregion(rdata1, &r1);
00247 dns_rdata_toregion(rdata2, &r2);
00248 return (isc_region_compare(&r1, &r2));
00249 }
00250
00251 static inline isc_result_t
00252 fromstruct_in_apl(ARGS_FROMSTRUCT) {
00253 dns_rdata_in_apl_t *apl = source;
00254 isc_buffer_t b;
00255
00256 REQUIRE(type == 42);
00257 REQUIRE(rdclass == 1);
00258 REQUIRE(source != NULL);
00259 REQUIRE(apl->common.rdtype == type);
00260 REQUIRE(apl->common.rdclass == rdclass);
00261 REQUIRE(apl->apl != NULL || apl->apl_len == 0);
00262
00263 isc_buffer_init(&b, apl->apl, apl->apl_len);
00264 isc_buffer_add(&b, apl->apl_len);
00265 isc_buffer_setactive(&b, apl->apl_len);
00266 return(fromwire_in_apl(rdclass, type, &b, NULL, ISC_FALSE, target));
00267 }
00268
00269 static inline isc_result_t
00270 tostruct_in_apl(ARGS_TOSTRUCT) {
00271 dns_rdata_in_apl_t *apl = target;
00272 isc_region_t r;
00273
00274 REQUIRE(rdata->type == 42);
00275 REQUIRE(rdata->rdclass == 1);
00276
00277 apl->common.rdclass = rdata->rdclass;
00278 apl->common.rdtype = rdata->type;
00279 ISC_LINK_INIT(&apl->common, link);
00280
00281 dns_rdata_toregion(rdata, &r);
00282 apl->apl_len = r.length;
00283 apl->apl = mem_maybedup(mctx, r.base, r.length);
00284 if (apl->apl == NULL)
00285 return (ISC_R_NOMEMORY);
00286
00287 apl->offset = 0;
00288 apl->mctx = mctx;
00289 return (ISC_R_SUCCESS);
00290 }
00291
00292 static inline void
00293 freestruct_in_apl(ARGS_FREESTRUCT) {
00294 dns_rdata_in_apl_t *apl = source;
00295
00296 REQUIRE(source != NULL);
00297 REQUIRE(apl->common.rdtype == 42);
00298 REQUIRE(apl->common.rdclass == 1);
00299
00300 if (apl->mctx == NULL)
00301 return;
00302 if (apl->apl != NULL)
00303 isc_mem_free(apl->mctx, apl->apl);
00304 apl->mctx = NULL;
00305 }
00306
00307 isc_result_t
00308 dns_rdata_apl_first(dns_rdata_in_apl_t *apl) {
00309 isc_uint32_t length;
00310
00311 REQUIRE(apl != NULL);
00312 REQUIRE(apl->common.rdtype == 42);
00313 REQUIRE(apl->common.rdclass == 1);
00314 REQUIRE(apl->apl != NULL || apl->apl_len == 0);
00315
00316
00317
00318
00319 if (apl->apl == NULL)
00320 return (ISC_R_NOMORE);
00321
00322
00323
00324
00325 INSIST(apl->apl_len > 3U);
00326 length = apl->apl[apl->offset + 3] & 0x7f;
00327 INSIST(length <= apl->apl_len);
00328
00329 apl->offset = 0;
00330 return (ISC_R_SUCCESS);
00331 }
00332
00333 isc_result_t
00334 dns_rdata_apl_next(dns_rdata_in_apl_t *apl) {
00335 isc_uint32_t length;
00336
00337 REQUIRE(apl != NULL);
00338 REQUIRE(apl->common.rdtype == 42);
00339 REQUIRE(apl->common.rdclass == 1);
00340 REQUIRE(apl->apl != NULL || apl->apl_len == 0);
00341
00342
00343
00344
00345 if (apl->apl == NULL || apl->offset == apl->apl_len)
00346 return (ISC_R_NOMORE);
00347
00348
00349
00350
00351 INSIST(apl->offset < apl->apl_len);
00352 INSIST(apl->apl_len > 3U);
00353 INSIST(apl->offset <= apl->apl_len - 4U);
00354 length = apl->apl[apl->offset + 3] & 0x7f;
00355
00356
00357
00358
00359 INSIST(length + apl->offset <= apl->apl_len);
00360
00361 apl->offset += apl->apl[apl->offset + 3] & 0x7f;
00362 return ((apl->offset >= apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
00363 }
00364
00365 isc_result_t
00366 dns_rdata_apl_current(dns_rdata_in_apl_t *apl, dns_rdata_apl_ent_t *ent) {
00367 isc_uint32_t length;
00368
00369 REQUIRE(apl != NULL);
00370 REQUIRE(apl->common.rdtype == 42);
00371 REQUIRE(apl->common.rdclass == 1);
00372 REQUIRE(ent != NULL);
00373 REQUIRE(apl->apl != NULL || apl->apl_len == 0);
00374 REQUIRE(apl->offset <= apl->apl_len);
00375
00376 if (apl->offset == apl->apl_len)
00377 return (ISC_R_NOMORE);
00378
00379
00380
00381
00382 INSIST(apl->apl_len > 3U);
00383 INSIST(apl->offset <= apl->apl_len - 4U);
00384 length = apl->apl[apl->offset + 3] & 0x7f;
00385
00386
00387
00388
00389 INSIST(length + apl->offset <= apl->apl_len);
00390
00391 ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1];
00392 ent->prefix = apl->apl[apl->offset + 2];
00393 ent->length = apl->apl[apl->offset + 3] & 0x7f;
00394 ent->negative = ISC_TF((apl->apl[apl->offset + 3] & 0x80) != 0);
00395 if (ent->length != 0)
00396 ent->data = &apl->apl[apl->offset + 4];
00397 else
00398 ent->data = NULL;
00399 return (ISC_R_SUCCESS);
00400 }
00401
00402 static inline isc_result_t
00403 additionaldata_in_apl(ARGS_ADDLDATA) {
00404 REQUIRE(rdata->type == 42);
00405 REQUIRE(rdata->rdclass == 1);
00406
00407 (void)add;
00408 (void)arg;
00409
00410 return (ISC_R_SUCCESS);
00411 }
00412
00413 static inline isc_result_t
00414 digest_in_apl(ARGS_DIGEST) {
00415 isc_region_t r;
00416
00417 REQUIRE(rdata->type == 42);
00418 REQUIRE(rdata->rdclass == 1);
00419
00420 dns_rdata_toregion(rdata, &r);
00421
00422 return ((digest)(arg, &r));
00423 }
00424
00425 static inline isc_boolean_t
00426 checkowner_in_apl(ARGS_CHECKOWNER) {
00427
00428 REQUIRE(type == 42);
00429 REQUIRE(rdclass == 1);
00430
00431 UNUSED(name);
00432 UNUSED(type);
00433 UNUSED(rdclass);
00434 UNUSED(wildcard);
00435
00436 return (ISC_TRUE);
00437 }
00438
00439
00440 static inline isc_boolean_t
00441 checknames_in_apl(ARGS_CHECKNAMES) {
00442
00443 REQUIRE(rdata->type == 42);
00444 REQUIRE(rdata->rdclass == 1);
00445
00446 UNUSED(rdata);
00447 UNUSED(owner);
00448 UNUSED(bad);
00449
00450 return (ISC_TRUE);
00451 }
00452
00453 static inline int
00454 casecompare_in_apl(ARGS_COMPARE) {
00455 return (compare_in_apl(rdata1, rdata2));
00456 }
00457
00458 #endif