xref: /netbsd/external/mpl/bind/dist/lib/dns/rdata/ch_3/a_1.c (revision c0b5d9fb)
1 /*	$NetBSD: a_1.c,v 1.7 2022/09/23 12:15:31 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 /* by Bjorn.Victor@it.uu.se, 2005-05-07 */
17 /* Based on generic/soa_6.c and generic/mx_15.c */
18 
19 #ifndef RDATA_CH_3_A_1_C
20 #define RDATA_CH_3_A_1_C
21 
22 #include <isc/net.h>
23 
24 #define RRTYPE_A_ATTRIBUTES (0)
25 
26 static isc_result_t
fromtext_ch_a(ARGS_FROMTEXT)27 fromtext_ch_a(ARGS_FROMTEXT) {
28 	isc_token_t token;
29 	dns_name_t name;
30 	isc_buffer_t buffer;
31 
32 	REQUIRE(type == dns_rdatatype_a);
33 	REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */
34 
35 	UNUSED(type);
36 	UNUSED(callbacks);
37 
38 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
39 				      false));
40 
41 	/* get domain name */
42 	dns_name_init(&name, NULL);
43 	buffer_fromregion(&buffer, &token.value.as_region);
44 	if (origin == NULL) {
45 		origin = dns_rootname;
46 	}
47 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
48 	if ((options & DNS_RDATA_CHECKNAMES) != 0 &&
49 	    (options & DNS_RDATA_CHECKREVERSE) != 0)
50 	{
51 		bool ok;
52 		ok = dns_name_ishostname(&name, false);
53 		if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) {
54 			RETTOK(DNS_R_BADNAME);
55 		}
56 		if (!ok && callbacks != NULL) {
57 			warn_badname(&name, lexer, callbacks);
58 		}
59 	}
60 
61 	/* 16-bit octal address */
62 	RETERR(isc_lex_getoctaltoken(lexer, &token, false));
63 	if (token.value.as_ulong > 0xffffU) {
64 		RETTOK(ISC_R_RANGE);
65 	}
66 	return (uint16_tobuffer(token.value.as_ulong, target));
67 }
68 
69 static isc_result_t
totext_ch_a(ARGS_TOTEXT)70 totext_ch_a(ARGS_TOTEXT) {
71 	isc_region_t region;
72 	dns_name_t name;
73 	dns_name_t prefix;
74 	bool sub;
75 	char buf[sizeof("0177777")];
76 	uint16_t addr;
77 
78 	REQUIRE(rdata->type == dns_rdatatype_a);
79 	REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */
80 	REQUIRE(rdata->length != 0);
81 
82 	dns_name_init(&name, NULL);
83 	dns_name_init(&prefix, NULL);
84 
85 	dns_rdata_toregion(rdata, &region);
86 	dns_name_fromregion(&name, &region);
87 	isc_region_consume(&region, name_length(&name));
88 	addr = uint16_fromregion(&region);
89 
90 	sub = name_prefix(&name, tctx->origin, &prefix);
91 	RETERR(dns_name_totext(&prefix, sub, target));
92 
93 	snprintf(buf, sizeof(buf), "%o", addr); /* note octal */
94 	RETERR(str_totext(" ", target));
95 	return (str_totext(buf, target));
96 }
97 
98 static isc_result_t
fromwire_ch_a(ARGS_FROMWIRE)99 fromwire_ch_a(ARGS_FROMWIRE) {
100 	isc_region_t sregion;
101 	isc_region_t tregion;
102 	dns_name_t name;
103 
104 	REQUIRE(type == dns_rdatatype_a);
105 	REQUIRE(rdclass == dns_rdataclass_ch);
106 
107 	UNUSED(type);
108 	UNUSED(rdclass);
109 
110 	dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
111 
112 	dns_name_init(&name, NULL);
113 
114 	RETERR(dns_name_fromwire(&name, source, dctx, options, target));
115 
116 	isc_buffer_activeregion(source, &sregion);
117 	isc_buffer_availableregion(target, &tregion);
118 	if (sregion.length < 2) {
119 		return (ISC_R_UNEXPECTEDEND);
120 	}
121 	if (tregion.length < 2) {
122 		return (ISC_R_NOSPACE);
123 	}
124 
125 	memmove(tregion.base, sregion.base, 2);
126 	isc_buffer_forward(source, 2);
127 	isc_buffer_add(target, 2);
128 
129 	return (ISC_R_SUCCESS);
130 }
131 
132 static isc_result_t
towire_ch_a(ARGS_TOWIRE)133 towire_ch_a(ARGS_TOWIRE) {
134 	dns_name_t name;
135 	dns_offsets_t offsets;
136 	isc_region_t sregion;
137 	isc_region_t tregion;
138 
139 	REQUIRE(rdata->type == dns_rdatatype_a);
140 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
141 	REQUIRE(rdata->length != 0);
142 
143 	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
144 
145 	dns_name_init(&name, offsets);
146 
147 	dns_rdata_toregion(rdata, &sregion);
148 
149 	dns_name_fromregion(&name, &sregion);
150 	isc_region_consume(&sregion, name_length(&name));
151 	RETERR(dns_name_towire(&name, cctx, target));
152 
153 	isc_buffer_availableregion(target, &tregion);
154 	if (tregion.length < 2) {
155 		return (ISC_R_NOSPACE);
156 	}
157 
158 	memmove(tregion.base, sregion.base, 2);
159 	isc_buffer_add(target, 2);
160 	return (ISC_R_SUCCESS);
161 }
162 
163 static int
compare_ch_a(ARGS_COMPARE)164 compare_ch_a(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 == dns_rdatatype_a);
174 	REQUIRE(rdata1->rdclass == dns_rdataclass_ch);
175 	REQUIRE(rdata1->length != 0);
176 	REQUIRE(rdata2->length != 0);
177 
178 	dns_name_init(&name1, NULL);
179 	dns_name_init(&name2, NULL);
180 
181 	dns_rdata_toregion(rdata1, &region1);
182 	dns_rdata_toregion(rdata2, &region2);
183 
184 	dns_name_fromregion(&name1, &region1);
185 	dns_name_fromregion(&name2, &region2);
186 	isc_region_consume(&region1, name_length(&name1));
187 	isc_region_consume(&region2, name_length(&name2));
188 
189 	order = dns_name_rdatacompare(&name1, &name2);
190 	if (order != 0) {
191 		return (order);
192 	}
193 
194 	order = memcmp(region1.base, region2.base, 2);
195 	if (order != 0) {
196 		order = (order < 0) ? -1 : 1;
197 	}
198 	return (order);
199 }
200 
201 static isc_result_t
fromstruct_ch_a(ARGS_FROMSTRUCT)202 fromstruct_ch_a(ARGS_FROMSTRUCT) {
203 	dns_rdata_ch_a_t *a = source;
204 	isc_region_t region;
205 
206 	REQUIRE(type == dns_rdatatype_a);
207 	REQUIRE(a != NULL);
208 	REQUIRE(a->common.rdtype == type);
209 	REQUIRE(a->common.rdclass == rdclass);
210 
211 	UNUSED(type);
212 	UNUSED(rdclass);
213 
214 	dns_name_toregion(&a->ch_addr_dom, &region);
215 	RETERR(isc_buffer_copyregion(target, &region));
216 
217 	return (uint16_tobuffer(ntohs(a->ch_addr), target));
218 }
219 
220 static isc_result_t
tostruct_ch_a(ARGS_TOSTRUCT)221 tostruct_ch_a(ARGS_TOSTRUCT) {
222 	dns_rdata_ch_a_t *a = target;
223 	isc_region_t region;
224 	dns_name_t name;
225 
226 	REQUIRE(rdata->type == dns_rdatatype_a);
227 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
228 	REQUIRE(rdata->length != 0);
229 
230 	a->common.rdclass = rdata->rdclass;
231 	a->common.rdtype = rdata->type;
232 	ISC_LINK_INIT(&a->common, link);
233 
234 	dns_rdata_toregion(rdata, &region);
235 
236 	dns_name_init(&name, NULL);
237 	dns_name_fromregion(&name, &region);
238 	isc_region_consume(&region, name_length(&name));
239 
240 	dns_name_init(&a->ch_addr_dom, NULL);
241 	RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom));
242 	a->ch_addr = htons(uint16_fromregion(&region));
243 	a->mctx = mctx;
244 	return (ISC_R_SUCCESS);
245 }
246 
247 static void
freestruct_ch_a(ARGS_FREESTRUCT)248 freestruct_ch_a(ARGS_FREESTRUCT) {
249 	dns_rdata_ch_a_t *a = source;
250 
251 	REQUIRE(a != NULL);
252 	REQUIRE(a->common.rdtype == dns_rdatatype_a);
253 
254 	if (a->mctx == NULL) {
255 		return;
256 	}
257 
258 	dns_name_free(&a->ch_addr_dom, a->mctx);
259 	a->mctx = NULL;
260 }
261 
262 static isc_result_t
additionaldata_ch_a(ARGS_ADDLDATA)263 additionaldata_ch_a(ARGS_ADDLDATA) {
264 	REQUIRE(rdata->type == dns_rdatatype_a);
265 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
266 
267 	UNUSED(rdata);
268 	UNUSED(add);
269 	UNUSED(arg);
270 
271 	return (ISC_R_SUCCESS);
272 }
273 
274 static isc_result_t
digest_ch_a(ARGS_DIGEST)275 digest_ch_a(ARGS_DIGEST) {
276 	isc_region_t r;
277 	dns_name_t name;
278 
279 	REQUIRE(rdata->type == dns_rdatatype_a);
280 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
281 
282 	dns_rdata_toregion(rdata, &r);
283 	dns_name_init(&name, NULL);
284 	dns_name_fromregion(&name, &r);
285 	isc_region_consume(&r, name_length(&name));
286 	RETERR(dns_name_digest(&name, digest, arg));
287 	return ((digest)(arg, &r));
288 }
289 
290 static bool
checkowner_ch_a(ARGS_CHECKOWNER)291 checkowner_ch_a(ARGS_CHECKOWNER) {
292 	REQUIRE(type == dns_rdatatype_a);
293 	REQUIRE(rdclass == dns_rdataclass_ch);
294 
295 	UNUSED(type);
296 
297 	return (dns_name_ishostname(name, wildcard));
298 }
299 
300 static bool
checknames_ch_a(ARGS_CHECKNAMES)301 checknames_ch_a(ARGS_CHECKNAMES) {
302 	isc_region_t region;
303 	dns_name_t name;
304 
305 	REQUIRE(rdata->type == dns_rdatatype_a);
306 	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
307 
308 	UNUSED(owner);
309 
310 	dns_rdata_toregion(rdata, &region);
311 	dns_name_init(&name, NULL);
312 	dns_name_fromregion(&name, &region);
313 	if (!dns_name_ishostname(&name, false)) {
314 		if (bad != NULL) {
315 			dns_name_clone(&name, bad);
316 		}
317 		return (false);
318 	}
319 
320 	return (true);
321 }
322 
323 static int
casecompare_ch_a(ARGS_COMPARE)324 casecompare_ch_a(ARGS_COMPARE) {
325 	return (compare_ch_a(rdata1, rdata2));
326 }
327 #endif /* RDATA_CH_3_A_1_C */
328