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