ipseckey_45.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005, 2007, 2009, 2011, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
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          * Precedence.
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          * Gateway type.
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          * Algorithm.
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          * Gateway.
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, &region);
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, &region);
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          * Public key.
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          * Precedence.
00140          */
00141         dns_rdata_toregion(rdata, &region);
00142         num = uint8_fromregion(&region);
00143         isc_region_consume(&region, 1);
00144         sprintf(buf, "%u ", num);
00145         RETERR(str_totext(buf, target));
00146 
00147         /*
00148          * Gateway type.
00149          */
00150         gateway = uint8_fromregion(&region);
00151         isc_region_consume(&region, 1);
00152         sprintf(buf, "%u ", gateway);
00153         RETERR(str_totext(buf, target));
00154 
00155         /*
00156          * Algorithm.
00157          */
00158         num = uint8_fromregion(&region);
00159         isc_region_consume(&region, 1);
00160         sprintf(buf, "%u ", num);
00161         RETERR(str_totext(buf, target));
00162 
00163         /*
00164          * Gateway.
00165          */
00166         switch (gateway) {
00167         case 0:
00168                 RETERR(str_totext(".", target));
00169                 break;
00170 
00171         case 1:
00172                 RETERR(inet_totext(AF_INET, &region, target));
00173                 isc_region_consume(&region, 4);
00174                 break;
00175 
00176         case 2:
00177                 RETERR(inet_totext(AF_INET6, &region, target));
00178                 isc_region_consume(&region, 16);
00179                 break;
00180 
00181         case 3:
00182                 dns_name_fromregion(&name, &region);
00183                 RETERR(dns_name_totext(&name, ISC_FALSE, target));
00184                 isc_region_consume(&region, name_length(&name));
00185                 break;
00186         }
00187 
00188         /*
00189          * Key.
00190          */
00191         if (region.length > 0U) {
00192                 RETERR(str_totext(tctx->linebreak, target));
00193                 if (tctx->width == 0)   /* No splitting */
00194                         RETERR(isc_base64_totext(&region, 60, "", target));
00195                 else
00196                         RETERR(isc_base64_totext(&region, 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, &region);
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, &region);
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, &region);
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, &region1);
00278         dns_rdata_toregion(rdata2, &region2);
00279 
00280         return (isc_region_compare(&region1, &region2));
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, &region);
00319                 RETERR(isc_buffer_copyregion(target, &region));
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, &region);
00346 
00347         ipseckey->precedence = uint8_fromregion(&region);
00348         isc_region_consume(&region, 1);
00349 
00350         ipseckey->gateway_type = uint8_fromregion(&region);
00351         isc_region_consume(&region, 1);
00352 
00353         ipseckey->algorithm = uint8_fromregion(&region);
00354         isc_region_consume(&region, 1);
00355 
00356         switch (ipseckey->gateway_type) {
00357         case 0:
00358                 break;
00359 
00360         case 1:
00361                 n = uint32_fromregion(&region);
00362                 ipseckey->in_addr.s_addr = htonl(n);
00363                 isc_region_consume(&region, 4);
00364                 break;
00365 
00366         case 2:
00367                 memmove(ipseckey->in6_addr.s6_addr, region.base, 16);
00368                 isc_region_consume(&region, 16);
00369                 break;
00370 
00371         case 3:
00372                 dns_name_init(&ipseckey->gateway, NULL);
00373                 dns_name_fromregion(&name, &region);
00374                 RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
00375                 isc_region_consume(&region, 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, &region);
00434         return ((digest)(arg, &region));
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, &region1);
00477         dns_rdata_toregion(rdata2, &region2);
00478 
00479         if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3)
00480                 return (isc_region_compare(&region1, &region2));
00481 
00482         dns_name_init(&name1, NULL);
00483         dns_name_init(&name2, NULL);
00484 
00485         isc_region_consume(&region1, 3);
00486         isc_region_consume(&region2, 3);
00487 
00488         dns_name_fromregion(&name1, &region1);
00489         dns_name_fromregion(&name2, &region2);
00490 
00491         order = dns_name_rdatacompare(&name1, &name2);
00492         if (order != 0)
00493                 return (order);
00494 
00495         isc_region_consume(&region1, name_length(&name1));
00496         isc_region_consume(&region2, name_length(&name2));
00497 
00498         return (isc_region_compare(&region1, &region2));
00499 }
00500 
00501 #endif  /* RDATA_GENERIC_IPSECKEY_45_C */

Generated on Tue Apr 28 17:40:59 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha