]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/rdata/generic/mx_15.c
Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / rdata / generic / mx_15.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009, 2012  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: mx_15.c,v 1.58 2009/12/04 22:06:37 tbox Exp $ */
19
20 /* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */
21
22 #ifndef RDATA_GENERIC_MX_15_C
23 #define RDATA_GENERIC_MX_15_C
24
25 #include <string.h>
26
27 #include <isc/net.h>
28
29 #define RRTYPE_MX_ATTRIBUTES (0)
30
31 static isc_boolean_t
32 check_mx(isc_token_t *token) {
33         char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")];
34         struct in_addr addr;
35         struct in6_addr addr6;
36
37         if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp))
38                 return (ISC_TRUE);
39
40         if (tmp[strlen(tmp) - 1] == '.')
41                 tmp[strlen(tmp) - 1] = '\0';
42         if (inet_aton(tmp, &addr) == 1 ||
43             inet_pton(AF_INET6, tmp, &addr6) == 1)
44                 return (ISC_FALSE);
45
46         return (ISC_TRUE);
47 }
48
49 static inline isc_result_t
50 fromtext_mx(ARGS_FROMTEXT) {
51         isc_token_t token;
52         dns_name_t name;
53         isc_buffer_t buffer;
54         isc_boolean_t ok;
55
56         REQUIRE(type == 15);
57
58         UNUSED(type);
59         UNUSED(rdclass);
60
61         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
62                                       ISC_FALSE));
63         if (token.value.as_ulong > 0xffffU)
64                 RETTOK(ISC_R_RANGE);
65         RETERR(uint16_tobuffer(token.value.as_ulong, target));
66
67         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
68                                       ISC_FALSE));
69
70         ok = ISC_TRUE;
71         if ((options & DNS_RDATA_CHECKMX) != 0)
72                 ok = check_mx(&token);
73         if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0)
74                 RETTOK(DNS_R_MXISADDRESS);
75         if (!ok && callbacks != NULL)
76                 warn_badmx(&token, lexer, callbacks);
77
78         dns_name_init(&name, NULL);
79         buffer_fromregion(&buffer, &token.value.as_region);
80         origin = (origin != NULL) ? origin : dns_rootname;
81         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
82         ok = ISC_TRUE;
83         if ((options & DNS_RDATA_CHECKNAMES) != 0)
84                 ok = dns_name_ishostname(&name, ISC_FALSE);
85         if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
86                 RETTOK(DNS_R_BADNAME);
87         if (!ok && callbacks != NULL)
88                 warn_badname(&name, lexer, callbacks);
89         return (ISC_R_SUCCESS);
90 }
91
92 static inline isc_result_t
93 totext_mx(ARGS_TOTEXT) {
94         isc_region_t region;
95         dns_name_t name;
96         dns_name_t prefix;
97         isc_boolean_t sub;
98         char buf[sizeof("64000")];
99         unsigned short num;
100
101         REQUIRE(rdata->type == 15);
102         REQUIRE(rdata->length != 0);
103
104         dns_name_init(&name, NULL);
105         dns_name_init(&prefix, NULL);
106
107         dns_rdata_toregion(rdata, &region);
108         num = uint16_fromregion(&region);
109         isc_region_consume(&region, 2);
110         sprintf(buf, "%u", num);
111         RETERR(str_totext(buf, target));
112
113         RETERR(str_totext(" ", target));
114
115         dns_name_fromregion(&name, &region);
116         sub = name_prefix(&name, tctx->origin, &prefix);
117         return (dns_name_totext(&prefix, sub, target));
118 }
119
120 static inline isc_result_t
121 fromwire_mx(ARGS_FROMWIRE) {
122         dns_name_t name;
123         isc_region_t sregion;
124
125         REQUIRE(type == 15);
126
127         UNUSED(type);
128         UNUSED(rdclass);
129
130         dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
131
132         dns_name_init(&name, NULL);
133
134         isc_buffer_activeregion(source, &sregion);
135         if (sregion.length < 2)
136                 return (ISC_R_UNEXPECTEDEND);
137         RETERR(mem_tobuffer(target, sregion.base, 2));
138         isc_buffer_forward(source, 2);
139         return (dns_name_fromwire(&name, source, dctx, options, target));
140 }
141
142 static inline isc_result_t
143 towire_mx(ARGS_TOWIRE) {
144         dns_name_t name;
145         dns_offsets_t offsets;
146         isc_region_t region;
147
148         REQUIRE(rdata->type == 15);
149         REQUIRE(rdata->length != 0);
150
151         dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
152
153         dns_rdata_toregion(rdata, &region);
154         RETERR(mem_tobuffer(target, region.base, 2));
155         isc_region_consume(&region, 2);
156
157         dns_name_init(&name, offsets);
158         dns_name_fromregion(&name, &region);
159
160         return (dns_name_towire(&name, cctx, target));
161 }
162
163 static inline int
164 compare_mx(ARGS_COMPARE) {
165         dns_name_t name1;
166         dns_name_t name2;
167         isc_region_t region1;
168         isc_region_t region2;
169         int order;
170
171         REQUIRE(rdata1->type == rdata2->type);
172         REQUIRE(rdata1->rdclass == rdata2->rdclass);
173         REQUIRE(rdata1->type == 15);
174         REQUIRE(rdata1->length != 0);
175         REQUIRE(rdata2->length != 0);
176
177         order = memcmp(rdata1->data, rdata2->data, 2);
178         if (order != 0)
179                 return (order < 0 ? -1 : 1);
180
181         dns_name_init(&name1, NULL);
182         dns_name_init(&name2, NULL);
183
184         dns_rdata_toregion(rdata1, &region1);
185         dns_rdata_toregion(rdata2, &region2);
186
187         isc_region_consume(&region1, 2);
188         isc_region_consume(&region2, 2);
189
190         dns_name_fromregion(&name1, &region1);
191         dns_name_fromregion(&name2, &region2);
192
193         return (dns_name_rdatacompare(&name1, &name2));
194 }
195
196 static inline isc_result_t
197 fromstruct_mx(ARGS_FROMSTRUCT) {
198         dns_rdata_mx_t *mx = source;
199         isc_region_t region;
200
201         REQUIRE(type == 15);
202         REQUIRE(source != NULL);
203         REQUIRE(mx->common.rdtype == type);
204         REQUIRE(mx->common.rdclass == rdclass);
205
206         UNUSED(type);
207         UNUSED(rdclass);
208
209         RETERR(uint16_tobuffer(mx->pref, target));
210         dns_name_toregion(&mx->mx, &region);
211         return (isc_buffer_copyregion(target, &region));
212 }
213
214 static inline isc_result_t
215 tostruct_mx(ARGS_TOSTRUCT) {
216         isc_region_t region;
217         dns_rdata_mx_t *mx = target;
218         dns_name_t name;
219
220         REQUIRE(rdata->type == 15);
221         REQUIRE(target != NULL);
222         REQUIRE(rdata->length != 0);
223
224         mx->common.rdclass = rdata->rdclass;
225         mx->common.rdtype = rdata->type;
226         ISC_LINK_INIT(&mx->common, link);
227
228         dns_name_init(&name, NULL);
229         dns_rdata_toregion(rdata, &region);
230         mx->pref = uint16_fromregion(&region);
231         isc_region_consume(&region, 2);
232         dns_name_fromregion(&name, &region);
233         dns_name_init(&mx->mx, NULL);
234         RETERR(name_duporclone(&name, mctx, &mx->mx));
235         mx->mctx = mctx;
236         return (ISC_R_SUCCESS);
237 }
238
239 static inline void
240 freestruct_mx(ARGS_FREESTRUCT) {
241         dns_rdata_mx_t *mx = source;
242
243         REQUIRE(source != NULL);
244         REQUIRE(mx->common.rdtype == 15);
245
246         if (mx->mctx == NULL)
247                 return;
248
249         dns_name_free(&mx->mx, mx->mctx);
250         mx->mctx = NULL;
251 }
252
253 static inline isc_result_t
254 additionaldata_mx(ARGS_ADDLDATA) {
255         dns_name_t name;
256         dns_offsets_t offsets;
257         isc_region_t region;
258
259         REQUIRE(rdata->type == 15);
260
261         dns_name_init(&name, offsets);
262         dns_rdata_toregion(rdata, &region);
263         isc_region_consume(&region, 2);
264         dns_name_fromregion(&name, &region);
265
266         return ((add)(arg, &name, dns_rdatatype_a));
267 }
268
269 static inline isc_result_t
270 digest_mx(ARGS_DIGEST) {
271         isc_region_t r1, r2;
272         dns_name_t name;
273
274         REQUIRE(rdata->type == 15);
275
276         dns_rdata_toregion(rdata, &r1);
277         r2 = r1;
278         isc_region_consume(&r2, 2);
279         r1.length = 2;
280         RETERR((digest)(arg, &r1));
281         dns_name_init(&name, NULL);
282         dns_name_fromregion(&name, &r2);
283         return (dns_name_digest(&name, digest, arg));
284 }
285
286 static inline isc_boolean_t
287 checkowner_mx(ARGS_CHECKOWNER) {
288
289         REQUIRE(type == 15);
290
291         UNUSED(type);
292         UNUSED(rdclass);
293
294         return (dns_name_ishostname(name, wildcard));
295 }
296
297 static inline isc_boolean_t
298 checknames_mx(ARGS_CHECKNAMES) {
299         isc_region_t region;
300         dns_name_t name;
301
302         REQUIRE(rdata->type == 15);
303
304         UNUSED(owner);
305
306         dns_rdata_toregion(rdata, &region);
307         isc_region_consume(&region, 2);
308         dns_name_init(&name, NULL);
309         dns_name_fromregion(&name, &region);
310         if (!dns_name_ishostname(&name, ISC_FALSE)) {
311                 if (bad != NULL)
312                         dns_name_clone(&name, bad);
313                 return (ISC_FALSE);
314         }
315         return (ISC_TRUE);
316 }
317
318 static inline int
319 casecompare_mx(ARGS_COMPARE) {
320         return (compare_mx(rdata1, rdata2));
321 }
322
323 #endif  /* RDATA_GENERIC_MX_15_C */