00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef RDATA_GENERIC_IPSECKEY_45_C
00020 #define RDATA_GENERIC_IPSECKEY_45_C
00021
00022 #include <string.h>
00023
00024 #include <isc/net.h>
00025
00026 #define RRTYPE_IPSECKEY_ATTRIBUTES (0)
00027
00028 static inline isc_result_t
00029 fromtext_ipseckey(ARGS_FROMTEXT) {
00030 isc_token_t token;
00031 dns_name_t name;
00032 isc_buffer_t buffer;
00033 unsigned int gateway;
00034 struct in_addr addr;
00035 unsigned char addr6[16];
00036 isc_region_t region;
00037
00038 REQUIRE(type == 45);
00039
00040 UNUSED(type);
00041 UNUSED(rdclass);
00042 UNUSED(callbacks);
00043
00044
00045
00046
00047 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00048 ISC_FALSE));
00049 if (token.value.as_ulong > 0xffU)
00050 RETTOK(ISC_R_RANGE);
00051 RETERR(uint8_tobuffer(token.value.as_ulong, target));
00052
00053
00054
00055
00056 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00057 ISC_FALSE));
00058 if (token.value.as_ulong > 0x3U)
00059 RETTOK(ISC_R_RANGE);
00060 RETERR(uint8_tobuffer(token.value.as_ulong, target));
00061 gateway = token.value.as_ulong;
00062
00063
00064
00065
00066 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00067 ISC_FALSE));
00068 if (token.value.as_ulong > 0xffU)
00069 RETTOK(ISC_R_RANGE);
00070 RETERR(uint8_tobuffer(token.value.as_ulong, target));
00071
00072
00073
00074
00075 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00076 ISC_FALSE));
00077
00078 switch (gateway) {
00079 case 0:
00080 if (strcmp(DNS_AS_STR(token), ".") != 0)
00081 RETTOK(DNS_R_SYNTAX);
00082 break;
00083
00084 case 1:
00085 if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
00086 RETTOK(DNS_R_BADDOTTEDQUAD);
00087 isc_buffer_availableregion(target, ®ion);
00088 if (region.length < 4)
00089 return (ISC_R_NOSPACE);
00090 memmove(region.base, &addr, 4);
00091 isc_buffer_add(target, 4);
00092 break;
00093
00094 case 2:
00095 if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1)
00096 RETTOK(DNS_R_BADAAAA);
00097 isc_buffer_availableregion(target, ®ion);
00098 if (region.length < 16)
00099 return (ISC_R_NOSPACE);
00100 memmove(region.base, addr6, 16);
00101 isc_buffer_add(target, 16);
00102 break;
00103
00104 case 3:
00105 dns_name_init(&name, NULL);
00106 buffer_fromregion(&buffer, &token.value.as_region);
00107 origin = (origin != NULL) ? origin : dns_rootname;
00108 RETTOK(dns_name_fromtext(&name, &buffer, origin,
00109 options, target));
00110 break;
00111 }
00112
00113
00114
00115
00116 return (isc_base64_tobuffer(lexer, target, -1));
00117 }
00118
00119 static inline isc_result_t
00120 totext_ipseckey(ARGS_TOTEXT) {
00121 isc_region_t region;
00122 dns_name_t name;
00123 char buf[sizeof("255 ")];
00124 unsigned short num;
00125 unsigned short gateway;
00126
00127 REQUIRE(rdata->type == 45);
00128 REQUIRE(rdata->length >= 3);
00129
00130 dns_name_init(&name, NULL);
00131
00132 if (rdata->data[1] > 3U)
00133 return (ISC_R_NOTIMPLEMENTED);
00134
00135 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00136 RETERR(str_totext("( ", target));
00137
00138
00139
00140
00141 dns_rdata_toregion(rdata, ®ion);
00142 num = uint8_fromregion(®ion);
00143 isc_region_consume(®ion, 1);
00144 sprintf(buf, "%u ", num);
00145 RETERR(str_totext(buf, target));
00146
00147
00148
00149
00150 gateway = uint8_fromregion(®ion);
00151 isc_region_consume(®ion, 1);
00152 sprintf(buf, "%u ", gateway);
00153 RETERR(str_totext(buf, target));
00154
00155
00156
00157
00158 num = uint8_fromregion(®ion);
00159 isc_region_consume(®ion, 1);
00160 sprintf(buf, "%u ", num);
00161 RETERR(str_totext(buf, target));
00162
00163
00164
00165
00166 switch (gateway) {
00167 case 0:
00168 RETERR(str_totext(".", target));
00169 break;
00170
00171 case 1:
00172 RETERR(inet_totext(AF_INET, ®ion, target));
00173 isc_region_consume(®ion, 4);
00174 break;
00175
00176 case 2:
00177 RETERR(inet_totext(AF_INET6, ®ion, target));
00178 isc_region_consume(®ion, 16);
00179 break;
00180
00181 case 3:
00182 dns_name_fromregion(&name, ®ion);
00183 RETERR(dns_name_totext(&name, ISC_FALSE, target));
00184 isc_region_consume(®ion, name_length(&name));
00185 break;
00186 }
00187
00188
00189
00190
00191 if (region.length > 0U) {
00192 RETERR(str_totext(tctx->linebreak, target));
00193 if (tctx->width == 0)
00194 RETERR(isc_base64_totext(®ion, 60, "", target));
00195 else
00196 RETERR(isc_base64_totext(®ion, tctx->width - 2,
00197 tctx->linebreak, target));
00198 }
00199
00200 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00201 RETERR(str_totext(" )", target));
00202 return (ISC_R_SUCCESS);
00203 }
00204
00205 static inline isc_result_t
00206 fromwire_ipseckey(ARGS_FROMWIRE) {
00207 dns_name_t name;
00208 isc_region_t region;
00209
00210 REQUIRE(type == 45);
00211
00212 UNUSED(type);
00213 UNUSED(rdclass);
00214
00215 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
00216
00217 dns_name_init(&name, NULL);
00218
00219 isc_buffer_activeregion(source, ®ion);
00220 if (region.length < 3)
00221 return (ISC_R_UNEXPECTEDEND);
00222
00223 switch (region.base[1]) {
00224 case 0:
00225 isc_buffer_forward(source, region.length);
00226 return (mem_tobuffer(target, region.base, region.length));
00227
00228 case 1:
00229 if (region.length < 7)
00230 return (ISC_R_UNEXPECTEDEND);
00231 isc_buffer_forward(source, region.length);
00232 return (mem_tobuffer(target, region.base, region.length));
00233
00234 case 2:
00235 if (region.length < 19)
00236 return (ISC_R_UNEXPECTEDEND);
00237 isc_buffer_forward(source, region.length);
00238 return (mem_tobuffer(target, region.base, region.length));
00239
00240 case 3:
00241 RETERR(mem_tobuffer(target, region.base, 3));
00242 isc_buffer_forward(source, 3);
00243 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
00244 isc_buffer_activeregion(source, ®ion);
00245 isc_buffer_forward(source, region.length);
00246 return(mem_tobuffer(target, region.base, region.length));
00247
00248 default:
00249 return (ISC_R_NOTIMPLEMENTED);
00250 }
00251 }
00252
00253 static inline isc_result_t
00254 towire_ipseckey(ARGS_TOWIRE) {
00255 isc_region_t region;
00256
00257 REQUIRE(rdata->type == 45);
00258 REQUIRE(rdata->length != 0);
00259
00260 UNUSED(cctx);
00261
00262 dns_rdata_toregion(rdata, ®ion);
00263 return (mem_tobuffer(target, region.base, region.length));
00264 }
00265
00266 static inline int
00267 compare_ipseckey(ARGS_COMPARE) {
00268 isc_region_t region1;
00269 isc_region_t region2;
00270
00271 REQUIRE(rdata1->type == rdata2->type);
00272 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00273 REQUIRE(rdata1->type == 45);
00274 REQUIRE(rdata1->length >= 3);
00275 REQUIRE(rdata2->length >= 3);
00276
00277 dns_rdata_toregion(rdata1, ®ion1);
00278 dns_rdata_toregion(rdata2, ®ion2);
00279
00280 return (isc_region_compare(®ion1, ®ion2));
00281 }
00282
00283 static inline isc_result_t
00284 fromstruct_ipseckey(ARGS_FROMSTRUCT) {
00285 dns_rdata_ipseckey_t *ipseckey = source;
00286 isc_region_t region;
00287 isc_uint32_t n;
00288
00289 REQUIRE(type == 45);
00290 REQUIRE(source != NULL);
00291 REQUIRE(ipseckey->common.rdtype == type);
00292 REQUIRE(ipseckey->common.rdclass == rdclass);
00293
00294 UNUSED(type);
00295 UNUSED(rdclass);
00296
00297 if (ipseckey->gateway_type > 3U)
00298 return (ISC_R_NOTIMPLEMENTED);
00299
00300 RETERR(uint8_tobuffer(ipseckey->precedence, target));
00301 RETERR(uint8_tobuffer(ipseckey->gateway_type, target));
00302 RETERR(uint8_tobuffer(ipseckey->algorithm, target));
00303
00304 switch (ipseckey->gateway_type) {
00305 case 0:
00306 break;
00307
00308 case 1:
00309 n = ntohl(ipseckey->in_addr.s_addr);
00310 RETERR(uint32_tobuffer(n, target));
00311 break;
00312
00313 case 2:
00314 RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16));
00315 break;
00316
00317 case 3:
00318 dns_name_toregion(&ipseckey->gateway, ®ion);
00319 RETERR(isc_buffer_copyregion(target, ®ion));
00320 break;
00321 }
00322
00323 return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength));
00324 }
00325
00326 static inline isc_result_t
00327 tostruct_ipseckey(ARGS_TOSTRUCT) {
00328 isc_region_t region;
00329 dns_rdata_ipseckey_t *ipseckey = target;
00330 dns_name_t name;
00331 isc_uint32_t n;
00332
00333 REQUIRE(rdata->type == 45);
00334 REQUIRE(target != NULL);
00335 REQUIRE(rdata->length >= 3);
00336
00337 if (rdata->data[1] > 3U)
00338 return (ISC_R_NOTIMPLEMENTED);
00339
00340 ipseckey->common.rdclass = rdata->rdclass;
00341 ipseckey->common.rdtype = rdata->type;
00342 ISC_LINK_INIT(&ipseckey->common, link);
00343
00344 dns_name_init(&name, NULL);
00345 dns_rdata_toregion(rdata, ®ion);
00346
00347 ipseckey->precedence = uint8_fromregion(®ion);
00348 isc_region_consume(®ion, 1);
00349
00350 ipseckey->gateway_type = uint8_fromregion(®ion);
00351 isc_region_consume(®ion, 1);
00352
00353 ipseckey->algorithm = uint8_fromregion(®ion);
00354 isc_region_consume(®ion, 1);
00355
00356 switch (ipseckey->gateway_type) {
00357 case 0:
00358 break;
00359
00360 case 1:
00361 n = uint32_fromregion(®ion);
00362 ipseckey->in_addr.s_addr = htonl(n);
00363 isc_region_consume(®ion, 4);
00364 break;
00365
00366 case 2:
00367 memmove(ipseckey->in6_addr.s6_addr, region.base, 16);
00368 isc_region_consume(®ion, 16);
00369 break;
00370
00371 case 3:
00372 dns_name_init(&ipseckey->gateway, NULL);
00373 dns_name_fromregion(&name, ®ion);
00374 RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
00375 isc_region_consume(®ion, name_length(&name));
00376 break;
00377 }
00378
00379 ipseckey->keylength = region.length;
00380 if (ipseckey->keylength != 0U) {
00381 ipseckey->key = mem_maybedup(mctx, region.base,
00382 ipseckey->keylength);
00383 if (ipseckey->key == NULL) {
00384 if (ipseckey->gateway_type == 3)
00385 dns_name_free(&ipseckey->gateway,
00386 ipseckey->mctx);
00387 return (ISC_R_NOMEMORY);
00388 }
00389 } else
00390 ipseckey->key = NULL;
00391
00392 ipseckey->mctx = mctx;
00393 return (ISC_R_SUCCESS);
00394 }
00395
00396 static inline void
00397 freestruct_ipseckey(ARGS_FREESTRUCT) {
00398 dns_rdata_ipseckey_t *ipseckey = source;
00399
00400 REQUIRE(source != NULL);
00401 REQUIRE(ipseckey->common.rdtype == 45);
00402
00403 if (ipseckey->mctx == NULL)
00404 return;
00405
00406 if (ipseckey->gateway_type == 3)
00407 dns_name_free(&ipseckey->gateway, ipseckey->mctx);
00408
00409 if (ipseckey->key != NULL)
00410 isc_mem_free(ipseckey->mctx, ipseckey->key);
00411
00412 ipseckey->mctx = NULL;
00413 }
00414
00415 static inline isc_result_t
00416 additionaldata_ipseckey(ARGS_ADDLDATA) {
00417
00418 REQUIRE(rdata->type == 45);
00419
00420 UNUSED(rdata);
00421 UNUSED(add);
00422 UNUSED(arg);
00423
00424 return (ISC_R_SUCCESS);
00425 }
00426
00427 static inline isc_result_t
00428 digest_ipseckey(ARGS_DIGEST) {
00429 isc_region_t region;
00430
00431 REQUIRE(rdata->type == 45);
00432
00433 dns_rdata_toregion(rdata, ®ion);
00434 return ((digest)(arg, ®ion));
00435 }
00436
00437 static inline isc_boolean_t
00438 checkowner_ipseckey(ARGS_CHECKOWNER) {
00439
00440 REQUIRE(type == 45);
00441
00442 UNUSED(name);
00443 UNUSED(type);
00444 UNUSED(rdclass);
00445 UNUSED(wildcard);
00446
00447 return (ISC_TRUE);
00448 }
00449
00450 static inline isc_boolean_t
00451 checknames_ipseckey(ARGS_CHECKNAMES) {
00452
00453 REQUIRE(rdata->type == 45);
00454
00455 UNUSED(rdata);
00456 UNUSED(owner);
00457 UNUSED(bad);
00458
00459 return (ISC_TRUE);
00460 }
00461
00462 static inline int
00463 casecompare_ipseckey(ARGS_COMPARE) {
00464 isc_region_t region1;
00465 isc_region_t region2;
00466 dns_name_t name1;
00467 dns_name_t name2;
00468 int order;
00469
00470 REQUIRE(rdata1->type == rdata2->type);
00471 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00472 REQUIRE(rdata1->type == 45);
00473 REQUIRE(rdata1->length >= 3);
00474 REQUIRE(rdata2->length >= 3);
00475
00476 dns_rdata_toregion(rdata1, ®ion1);
00477 dns_rdata_toregion(rdata2, ®ion2);
00478
00479 if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3)
00480 return (isc_region_compare(®ion1, ®ion2));
00481
00482 dns_name_init(&name1, NULL);
00483 dns_name_init(&name2, NULL);
00484
00485 isc_region_consume(®ion1, 3);
00486 isc_region_consume(®ion2, 3);
00487
00488 dns_name_fromregion(&name1, ®ion1);
00489 dns_name_fromregion(&name2, ®ion2);
00490
00491 order = dns_name_rdatacompare(&name1, &name2);
00492 if (order != 0)
00493 return (order);
00494
00495 isc_region_consume(®ion1, name_length(&name1));
00496 isc_region_consume(®ion2, name_length(&name2));
00497
00498 return (isc_region_compare(®ion1, ®ion2));
00499 }
00500
00501 #endif