1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009, 2015  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001  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: rp_17.c,v 1.44 2009/12/04 22:06:37 tbox Exp $ */
19 
20 /* RFC1183 */
21 
22 #ifndef RDATA_GENERIC_RP_17_C
23 #define RDATA_GENERIC_RP_17_C
24 
25 #define RRTYPE_RP_ATTRIBUTES (0)
26 
27 static inline isc_result_t
fromtext_rp(ARGS_FROMTEXT)28 fromtext_rp(ARGS_FROMTEXT) {
29 	isc_token_t token;
30 	dns_name_t name;
31 	isc_buffer_t buffer;
32 	int i;
33 	isc_boolean_t ok;
34 
35 	REQUIRE(type == dns_rdatatype_rp);
36 
37 	UNUSED(type);
38 	UNUSED(rdclass);
39 	UNUSED(callbacks);
40 
41 	if (origin == NULL)
42 		origin = dns_rootname;
43 
44 	for (i = 0; i < 2; i++) {
45 		RETERR(isc_lex_getmastertoken(lexer, &token,
46 					      isc_tokentype_string,
47 					      ISC_FALSE));
48 		dns_name_init(&name, NULL);
49 		buffer_fromregion(&buffer, &token.value.as_region);
50 		RETTOK(dns_name_fromtext(&name, &buffer, origin,
51 					 options, target));
52 		ok = ISC_TRUE;
53 		if ((options & DNS_RDATA_CHECKNAMES) != 0 && i == 0)
54 			ok = dns_name_ismailbox(&name);
55 		if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
56 			RETTOK(DNS_R_BADNAME);
57 		if (!ok && callbacks != NULL)
58 			warn_badname(&name, lexer, callbacks);
59 	}
60 	return (ISC_R_SUCCESS);
61 }
62 
63 static inline isc_result_t
totext_rp(ARGS_TOTEXT)64 totext_rp(ARGS_TOTEXT) {
65 	isc_region_t region;
66 	dns_name_t rmail;
67 	dns_name_t email;
68 	dns_name_t prefix;
69 	isc_boolean_t sub;
70 
71 	REQUIRE(rdata->type == dns_rdatatype_rp);
72 	REQUIRE(rdata->length != 0);
73 
74 	dns_name_init(&rmail, NULL);
75 	dns_name_init(&email, NULL);
76 	dns_name_init(&prefix, NULL);
77 
78 	dns_rdata_toregion(rdata, &region);
79 
80 	dns_name_fromregion(&rmail, &region);
81 	isc_region_consume(&region, rmail.length);
82 
83 	dns_name_fromregion(&email, &region);
84 	isc_region_consume(&region, email.length);
85 
86 	sub = name_prefix(&rmail, tctx->origin, &prefix);
87 	RETERR(dns_name_totext(&prefix, sub, target));
88 
89 	RETERR(str_totext(" ", target));
90 
91 	sub = name_prefix(&email, tctx->origin, &prefix);
92 	return (dns_name_totext(&prefix, sub, target));
93 }
94 
95 static inline isc_result_t
fromwire_rp(ARGS_FROMWIRE)96 fromwire_rp(ARGS_FROMWIRE) {
97 	dns_name_t rmail;
98 	dns_name_t email;
99 
100 	REQUIRE(type == dns_rdatatype_rp);
101 
102 	UNUSED(type);
103 	UNUSED(rdclass);
104 
105 	dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
106 
107 	dns_name_init(&rmail, NULL);
108 	dns_name_init(&email, NULL);
109 
110 	RETERR(dns_name_fromwire(&rmail, source, dctx, options, target));
111 	return (dns_name_fromwire(&email, source, dctx, options, target));
112 }
113 
114 static inline isc_result_t
towire_rp(ARGS_TOWIRE)115 towire_rp(ARGS_TOWIRE) {
116 	isc_region_t region;
117 	dns_name_t rmail;
118 	dns_name_t email;
119 	dns_offsets_t roffsets;
120 	dns_offsets_t eoffsets;
121 
122 	REQUIRE(rdata->type == dns_rdatatype_rp);
123 	REQUIRE(rdata->length != 0);
124 
125 	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
126 	dns_name_init(&rmail, roffsets);
127 	dns_name_init(&email, eoffsets);
128 
129 	dns_rdata_toregion(rdata, &region);
130 
131 	dns_name_fromregion(&rmail, &region);
132 	isc_region_consume(&region, rmail.length);
133 
134 	RETERR(dns_name_towire(&rmail, cctx, target));
135 
136 	dns_name_fromregion(&rmail, &region);
137 	isc_region_consume(&region, rmail.length);
138 
139 	return (dns_name_towire(&rmail, cctx, target));
140 }
141 
142 static inline int
compare_rp(ARGS_COMPARE)143 compare_rp(ARGS_COMPARE) {
144 	isc_region_t region1;
145 	isc_region_t region2;
146 	dns_name_t name1;
147 	dns_name_t name2;
148 	int order;
149 
150 	REQUIRE(rdata1->type == rdata2->type);
151 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
152 	REQUIRE(rdata1->type == dns_rdatatype_rp);
153 	REQUIRE(rdata1->length != 0);
154 	REQUIRE(rdata2->length != 0);
155 
156 	dns_name_init(&name1, NULL);
157 	dns_name_init(&name2, NULL);
158 
159 	dns_rdata_toregion(rdata1, &region1);
160 	dns_rdata_toregion(rdata2, &region2);
161 
162 	dns_name_fromregion(&name1, &region1);
163 	dns_name_fromregion(&name2, &region2);
164 
165 	order = dns_name_rdatacompare(&name1, &name2);
166 	if (order != 0)
167 		return (order);
168 
169 	isc_region_consume(&region1, name_length(&name1));
170 	isc_region_consume(&region2, name_length(&name2));
171 
172 	dns_name_init(&name1, NULL);
173 	dns_name_init(&name2, NULL);
174 
175 	dns_name_fromregion(&name1, &region1);
176 	dns_name_fromregion(&name2, &region2);
177 
178 	return (dns_name_rdatacompare(&name1, &name2));
179 }
180 
181 static inline isc_result_t
fromstruct_rp(ARGS_FROMSTRUCT)182 fromstruct_rp(ARGS_FROMSTRUCT) {
183 	dns_rdata_rp_t *rp = source;
184 	isc_region_t region;
185 
186 	REQUIRE(type == dns_rdatatype_rp);
187 	REQUIRE(source != NULL);
188 	REQUIRE(rp->common.rdtype == type);
189 	REQUIRE(rp->common.rdclass == rdclass);
190 
191 	UNUSED(type);
192 	UNUSED(rdclass);
193 
194 	dns_name_toregion(&rp->mail, &region);
195 	RETERR(isc_buffer_copyregion(target, &region));
196 	dns_name_toregion(&rp->text, &region);
197 	return (isc_buffer_copyregion(target, &region));
198 }
199 
200 static inline isc_result_t
tostruct_rp(ARGS_TOSTRUCT)201 tostruct_rp(ARGS_TOSTRUCT) {
202 	isc_result_t result;
203 	isc_region_t region;
204 	dns_rdata_rp_t *rp = target;
205 	dns_name_t name;
206 
207 	REQUIRE(rdata->type == dns_rdatatype_rp);
208 	REQUIRE(target != NULL);
209 	REQUIRE(rdata->length != 0);
210 
211 	rp->common.rdclass = rdata->rdclass;
212 	rp->common.rdtype = rdata->type;
213 	ISC_LINK_INIT(&rp->common, link);
214 
215 	dns_name_init(&name, NULL);
216 	dns_rdata_toregion(rdata, &region);
217 	dns_name_fromregion(&name, &region);
218 	dns_name_init(&rp->mail, NULL);
219 	RETERR(name_duporclone(&name, mctx, &rp->mail));
220 	isc_region_consume(&region, name_length(&name));
221 	dns_name_fromregion(&name, &region);
222 	dns_name_init(&rp->text, NULL);
223 	result = name_duporclone(&name, mctx, &rp->text);
224 	if (result != ISC_R_SUCCESS)
225 		goto cleanup;
226 
227 	rp->mctx = mctx;
228 	return (ISC_R_SUCCESS);
229 
230  cleanup:
231 	if (mctx != NULL)
232 		dns_name_free(&rp->mail, mctx);
233 	return (ISC_R_NOMEMORY);
234 }
235 
236 static inline void
freestruct_rp(ARGS_FREESTRUCT)237 freestruct_rp(ARGS_FREESTRUCT) {
238 	dns_rdata_rp_t *rp = source;
239 
240 	REQUIRE(source != NULL);
241 	REQUIRE(rp->common.rdtype == dns_rdatatype_rp);
242 
243 	if (rp->mctx == NULL)
244 		return;
245 
246 	dns_name_free(&rp->mail, rp->mctx);
247 	dns_name_free(&rp->text, rp->mctx);
248 	rp->mctx = NULL;
249 }
250 
251 static inline isc_result_t
additionaldata_rp(ARGS_ADDLDATA)252 additionaldata_rp(ARGS_ADDLDATA) {
253 	REQUIRE(rdata->type == dns_rdatatype_rp);
254 
255 	UNUSED(rdata);
256 	UNUSED(add);
257 	UNUSED(arg);
258 
259 	return (ISC_R_SUCCESS);
260 }
261 
262 static inline isc_result_t
digest_rp(ARGS_DIGEST)263 digest_rp(ARGS_DIGEST) {
264 	isc_region_t r;
265 	dns_name_t name;
266 
267 	REQUIRE(rdata->type == dns_rdatatype_rp);
268 
269 	dns_rdata_toregion(rdata, &r);
270 	dns_name_init(&name, NULL);
271 
272 	dns_name_fromregion(&name, &r);
273 	RETERR(dns_name_digest(&name, digest, arg));
274 	isc_region_consume(&r, name_length(&name));
275 
276 	dns_name_init(&name, NULL);
277 	dns_name_fromregion(&name, &r);
278 
279 	return (dns_name_digest(&name, digest, arg));
280 }
281 
282 static inline isc_boolean_t
checkowner_rp(ARGS_CHECKOWNER)283 checkowner_rp(ARGS_CHECKOWNER) {
284 
285 	REQUIRE(type == dns_rdatatype_rp);
286 
287 	UNUSED(name);
288 	UNUSED(type);
289 	UNUSED(rdclass);
290 	UNUSED(wildcard);
291 
292 	return (ISC_TRUE);
293 }
294 
295 static inline isc_boolean_t
checknames_rp(ARGS_CHECKNAMES)296 checknames_rp(ARGS_CHECKNAMES) {
297 	isc_region_t region;
298 	dns_name_t name;
299 
300 	REQUIRE(rdata->type == dns_rdatatype_rp);
301 
302 	UNUSED(owner);
303 
304 	dns_rdata_toregion(rdata, &region);
305 	dns_name_init(&name, NULL);
306 	dns_name_fromregion(&name, &region);
307 	if (!dns_name_ismailbox(&name)) {
308 		if (bad != NULL)
309 				dns_name_clone(&name, bad);
310 		return (ISC_FALSE);
311 	}
312 	return (ISC_TRUE);
313 }
314 
315 static inline int
casecompare_rp(ARGS_COMPARE)316 casecompare_rp(ARGS_COMPARE) {
317 	return (compare_rp(rdata1, rdata2));
318 }
319 #endif	/* RDATA_GENERIC_RP_17_C */
320