mx_15.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2009, 2012  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: mx_15.c,v 1.58 2009/12/04 22:06:37 tbox Exp $ */
00019 
00020 /* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */
00021 
00022 #ifndef RDATA_GENERIC_MX_15_C
00023 #define RDATA_GENERIC_MX_15_C
00024 
00025 #include <string.h>
00026 
00027 #include <isc/net.h>
00028 
00029 #define RRTYPE_MX_ATTRIBUTES (0)
00030 
00031 static isc_boolean_t
00032 check_mx(isc_token_t *token) {
00033         char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")];
00034         struct in_addr addr;
00035         struct in6_addr addr6;
00036 
00037         if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp))
00038                 return (ISC_TRUE);
00039 
00040         if (tmp[strlen(tmp) - 1] == '.')
00041                 tmp[strlen(tmp) - 1] = '\0';
00042         if (inet_aton(tmp, &addr) == 1 ||
00043             inet_pton(AF_INET6, tmp, &addr6) == 1)
00044                 return (ISC_FALSE);
00045 
00046         return (ISC_TRUE);
00047 }
00048 
00049 static inline isc_result_t
00050 fromtext_mx(ARGS_FROMTEXT) {
00051         isc_token_t token;
00052         dns_name_t name;
00053         isc_buffer_t buffer;
00054         isc_boolean_t ok;
00055 
00056         REQUIRE(type == 15);
00057 
00058         UNUSED(type);
00059         UNUSED(rdclass);
00060 
00061         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00062                                       ISC_FALSE));
00063         if (token.value.as_ulong > 0xffffU)
00064                 RETTOK(ISC_R_RANGE);
00065         RETERR(uint16_tobuffer(token.value.as_ulong, target));
00066 
00067         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00068                                       ISC_FALSE));
00069 
00070         ok = ISC_TRUE;
00071         if ((options & DNS_RDATA_CHECKMX) != 0)
00072                 ok = check_mx(&token);
00073         if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0)
00074                 RETTOK(DNS_R_MXISADDRESS);
00075         if (!ok && callbacks != NULL)
00076                 warn_badmx(&token, lexer, callbacks);
00077 
00078         dns_name_init(&name, NULL);
00079         buffer_fromregion(&buffer, &token.value.as_region);
00080         origin = (origin != NULL) ? origin : dns_rootname;
00081         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
00082         ok = ISC_TRUE;
00083         if ((options & DNS_RDATA_CHECKNAMES) != 0)
00084                 ok = dns_name_ishostname(&name, ISC_FALSE);
00085         if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
00086                 RETTOK(DNS_R_BADNAME);
00087         if (!ok && callbacks != NULL)
00088                 warn_badname(&name, lexer, callbacks);
00089         return (ISC_R_SUCCESS);
00090 }
00091 
00092 static inline isc_result_t
00093 totext_mx(ARGS_TOTEXT) {
00094         isc_region_t region;
00095         dns_name_t name;
00096         dns_name_t prefix;
00097         isc_boolean_t sub;
00098         char buf[sizeof("64000")];
00099         unsigned short num;
00100 
00101         REQUIRE(rdata->type == 15);
00102         REQUIRE(rdata->length != 0);
00103 
00104         dns_name_init(&name, NULL);
00105         dns_name_init(&prefix, NULL);
00106 
00107         dns_rdata_toregion(rdata, &region);
00108         num = uint16_fromregion(&region);
00109         isc_region_consume(&region, 2);
00110         sprintf(buf, "%u", num);
00111         RETERR(str_totext(buf, target));
00112 
00113         RETERR(str_totext(" ", target));
00114 
00115         dns_name_fromregion(&name, &region);
00116         sub = name_prefix(&name, tctx->origin, &prefix);
00117         return (dns_name_totext(&prefix, sub, target));
00118 }
00119 
00120 static inline isc_result_t
00121 fromwire_mx(ARGS_FROMWIRE) {
00122         dns_name_t name;
00123         isc_region_t sregion;
00124 
00125         REQUIRE(type == 15);
00126 
00127         UNUSED(type);
00128         UNUSED(rdclass);
00129 
00130         dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
00131 
00132         dns_name_init(&name, NULL);
00133 
00134         isc_buffer_activeregion(source, &sregion);
00135         if (sregion.length < 2)
00136                 return (ISC_R_UNEXPECTEDEND);
00137         RETERR(mem_tobuffer(target, sregion.base, 2));
00138         isc_buffer_forward(source, 2);
00139         return (dns_name_fromwire(&name, source, dctx, options, target));
00140 }
00141 
00142 static inline isc_result_t
00143 towire_mx(ARGS_TOWIRE) {
00144         dns_name_t name;
00145         dns_offsets_t offsets;
00146         isc_region_t region;
00147 
00148         REQUIRE(rdata->type == 15);
00149         REQUIRE(rdata->length != 0);
00150 
00151         dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
00152 
00153         dns_rdata_toregion(rdata, &region);
00154         RETERR(mem_tobuffer(target, region.base, 2));
00155         isc_region_consume(&region, 2);
00156 
00157         dns_name_init(&name, offsets);
00158         dns_name_fromregion(&name, &region);
00159 
00160         return (dns_name_towire(&name, cctx, target));
00161 }
00162 
00163 static inline int
00164 compare_mx(ARGS_COMPARE) {
00165         dns_name_t name1;
00166         dns_name_t name2;
00167         isc_region_t region1;
00168         isc_region_t region2;
00169         int order;
00170 
00171         REQUIRE(rdata1->type == rdata2->type);
00172         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00173         REQUIRE(rdata1->type == 15);
00174         REQUIRE(rdata1->length != 0);
00175         REQUIRE(rdata2->length != 0);
00176 
00177         order = memcmp(rdata1->data, rdata2->data, 2);
00178         if (order != 0)
00179                 return (order < 0 ? -1 : 1);
00180 
00181         dns_name_init(&name1, NULL);
00182         dns_name_init(&name2, NULL);
00183 
00184         dns_rdata_toregion(rdata1, &region1);
00185         dns_rdata_toregion(rdata2, &region2);
00186 
00187         isc_region_consume(&region1, 2);
00188         isc_region_consume(&region2, 2);
00189 
00190         dns_name_fromregion(&name1, &region1);
00191         dns_name_fromregion(&name2, &region2);
00192 
00193         return (dns_name_rdatacompare(&name1, &name2));
00194 }
00195 
00196 static inline isc_result_t
00197 fromstruct_mx(ARGS_FROMSTRUCT) {
00198         dns_rdata_mx_t *mx = source;
00199         isc_region_t region;
00200 
00201         REQUIRE(type == 15);
00202         REQUIRE(source != NULL);
00203         REQUIRE(mx->common.rdtype == type);
00204         REQUIRE(mx->common.rdclass == rdclass);
00205 
00206         UNUSED(type);
00207         UNUSED(rdclass);
00208 
00209         RETERR(uint16_tobuffer(mx->pref, target));
00210         dns_name_toregion(&mx->mx, &region);
00211         return (isc_buffer_copyregion(target, &region));
00212 }
00213 
00214 static inline isc_result_t
00215 tostruct_mx(ARGS_TOSTRUCT) {
00216         isc_region_t region;
00217         dns_rdata_mx_t *mx = target;
00218         dns_name_t name;
00219 
00220         REQUIRE(rdata->type == 15);
00221         REQUIRE(target != NULL);
00222         REQUIRE(rdata->length != 0);
00223 
00224         mx->common.rdclass = rdata->rdclass;
00225         mx->common.rdtype = rdata->type;
00226         ISC_LINK_INIT(&mx->common, link);
00227 
00228         dns_name_init(&name, NULL);
00229         dns_rdata_toregion(rdata, &region);
00230         mx->pref = uint16_fromregion(&region);
00231         isc_region_consume(&region, 2);
00232         dns_name_fromregion(&name, &region);
00233         dns_name_init(&mx->mx, NULL);
00234         RETERR(name_duporclone(&name, mctx, &mx->mx));
00235         mx->mctx = mctx;
00236         return (ISC_R_SUCCESS);
00237 }
00238 
00239 static inline void
00240 freestruct_mx(ARGS_FREESTRUCT) {
00241         dns_rdata_mx_t *mx = source;
00242 
00243         REQUIRE(source != NULL);
00244         REQUIRE(mx->common.rdtype == 15);
00245 
00246         if (mx->mctx == NULL)
00247                 return;
00248 
00249         dns_name_free(&mx->mx, mx->mctx);
00250         mx->mctx = NULL;
00251 }
00252 
00253 static inline isc_result_t
00254 additionaldata_mx(ARGS_ADDLDATA) {
00255         dns_name_t name;
00256         dns_offsets_t offsets;
00257         isc_region_t region;
00258 
00259         REQUIRE(rdata->type == 15);
00260 
00261         dns_name_init(&name, offsets);
00262         dns_rdata_toregion(rdata, &region);
00263         isc_region_consume(&region, 2);
00264         dns_name_fromregion(&name, &region);
00265 
00266         return ((add)(arg, &name, dns_rdatatype_a));
00267 }
00268 
00269 static inline isc_result_t
00270 digest_mx(ARGS_DIGEST) {
00271         isc_region_t r1, r2;
00272         dns_name_t name;
00273 
00274         REQUIRE(rdata->type == 15);
00275 
00276         dns_rdata_toregion(rdata, &r1);
00277         r2 = r1;
00278         isc_region_consume(&r2, 2);
00279         r1.length = 2;
00280         RETERR((digest)(arg, &r1));
00281         dns_name_init(&name, NULL);
00282         dns_name_fromregion(&name, &r2);
00283         return (dns_name_digest(&name, digest, arg));
00284 }
00285 
00286 static inline isc_boolean_t
00287 checkowner_mx(ARGS_CHECKOWNER) {
00288 
00289         REQUIRE(type == 15);
00290 
00291         UNUSED(type);
00292         UNUSED(rdclass);
00293 
00294         return (dns_name_ishostname(name, wildcard));
00295 }
00296 
00297 static inline isc_boolean_t
00298 checknames_mx(ARGS_CHECKNAMES) {
00299         isc_region_t region;
00300         dns_name_t name;
00301 
00302         REQUIRE(rdata->type == 15);
00303 
00304         UNUSED(owner);
00305 
00306         dns_rdata_toregion(rdata, &region);
00307         isc_region_consume(&region, 2);
00308         dns_name_init(&name, NULL);
00309         dns_name_fromregion(&name, &region);
00310         if (!dns_name_ishostname(&name, ISC_FALSE)) {
00311                 if (bad != NULL)
00312                         dns_name_clone(&name, bad);
00313                 return (ISC_FALSE);
00314         }
00315         return (ISC_TRUE);
00316 }
00317 
00318 static inline int
00319 casecompare_mx(ARGS_COMPARE) {
00320         return (compare_mx(rdata1, rdata2));
00321 }
00322 
00323 #endif  /* RDATA_GENERIC_MX_15_C */

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