1 /*	$NetBSD: gpos_27.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 /* RFC1712 */
17 
18 #ifndef RDATA_GENERIC_GPOS_27_C
19 #define RDATA_GENERIC_GPOS_27_C
20 
21 #define RRTYPE_GPOS_ATTRIBUTES (0)
22 
23 static isc_result_t
fromtext_gpos(ARGS_FROMTEXT)24 fromtext_gpos(ARGS_FROMTEXT) {
25 	isc_token_t token;
26 	int i;
27 
28 	REQUIRE(type == dns_rdatatype_gpos);
29 
30 	UNUSED(type);
31 	UNUSED(rdclass);
32 	UNUSED(origin);
33 	UNUSED(options);
34 	UNUSED(callbacks);
35 
36 	for (i = 0; i < 3; i++) {
37 		RETERR(isc_lex_getmastertoken(lexer, &token,
38 					      isc_tokentype_qstring, false));
39 		RETTOK(txt_fromtext(&token.value.as_textregion, target));
40 	}
41 	return (ISC_R_SUCCESS);
42 }
43 
44 static isc_result_t
totext_gpos(ARGS_TOTEXT)45 totext_gpos(ARGS_TOTEXT) {
46 	isc_region_t region;
47 	int i;
48 
49 	REQUIRE(rdata->type == dns_rdatatype_gpos);
50 	REQUIRE(rdata->length != 0);
51 
52 	UNUSED(tctx);
53 
54 	dns_rdata_toregion(rdata, &region);
55 
56 	for (i = 0; i < 3; i++) {
57 		RETERR(txt_totext(&region, true, target));
58 		if (i != 2) {
59 			RETERR(str_totext(" ", target));
60 		}
61 	}
62 
63 	return (ISC_R_SUCCESS);
64 }
65 
66 static isc_result_t
fromwire_gpos(ARGS_FROMWIRE)67 fromwire_gpos(ARGS_FROMWIRE) {
68 	int i;
69 
70 	REQUIRE(type == dns_rdatatype_gpos);
71 
72 	UNUSED(type);
73 	UNUSED(dctx);
74 	UNUSED(rdclass);
75 	UNUSED(options);
76 
77 	for (i = 0; i < 3; i++) {
78 		RETERR(txt_fromwire(source, target));
79 	}
80 	return (ISC_R_SUCCESS);
81 }
82 
83 static isc_result_t
towire_gpos(ARGS_TOWIRE)84 towire_gpos(ARGS_TOWIRE) {
85 	REQUIRE(rdata->type == dns_rdatatype_gpos);
86 	REQUIRE(rdata->length != 0);
87 
88 	UNUSED(cctx);
89 
90 	return (mem_tobuffer(target, rdata->data, rdata->length));
91 }
92 
93 static int
compare_gpos(ARGS_COMPARE)94 compare_gpos(ARGS_COMPARE) {
95 	isc_region_t r1;
96 	isc_region_t r2;
97 
98 	REQUIRE(rdata1->type == rdata2->type);
99 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
100 	REQUIRE(rdata1->type == dns_rdatatype_gpos);
101 	REQUIRE(rdata1->length != 0);
102 	REQUIRE(rdata2->length != 0);
103 
104 	dns_rdata_toregion(rdata1, &r1);
105 	dns_rdata_toregion(rdata2, &r2);
106 	return (isc_region_compare(&r1, &r2));
107 }
108 
109 static isc_result_t
fromstruct_gpos(ARGS_FROMSTRUCT)110 fromstruct_gpos(ARGS_FROMSTRUCT) {
111 	dns_rdata_gpos_t *gpos = source;
112 
113 	REQUIRE(type == dns_rdatatype_gpos);
114 	REQUIRE(gpos != NULL);
115 	REQUIRE(gpos->common.rdtype == type);
116 	REQUIRE(gpos->common.rdclass == rdclass);
117 
118 	UNUSED(type);
119 	UNUSED(rdclass);
120 
121 	RETERR(uint8_tobuffer(gpos->long_len, target));
122 	RETERR(mem_tobuffer(target, gpos->longitude, gpos->long_len));
123 	RETERR(uint8_tobuffer(gpos->lat_len, target));
124 	RETERR(mem_tobuffer(target, gpos->latitude, gpos->lat_len));
125 	RETERR(uint8_tobuffer(gpos->alt_len, target));
126 	return (mem_tobuffer(target, gpos->altitude, gpos->alt_len));
127 }
128 
129 static isc_result_t
tostruct_gpos(ARGS_TOSTRUCT)130 tostruct_gpos(ARGS_TOSTRUCT) {
131 	dns_rdata_gpos_t *gpos = target;
132 	isc_region_t region;
133 
134 	REQUIRE(rdata->type == dns_rdatatype_gpos);
135 	REQUIRE(gpos != NULL);
136 	REQUIRE(rdata->length != 0);
137 
138 	gpos->common.rdclass = rdata->rdclass;
139 	gpos->common.rdtype = rdata->type;
140 	ISC_LINK_INIT(&gpos->common, link);
141 
142 	dns_rdata_toregion(rdata, &region);
143 	gpos->long_len = uint8_fromregion(&region);
144 	isc_region_consume(&region, 1);
145 	gpos->longitude = mem_maybedup(mctx, region.base, gpos->long_len);
146 	if (gpos->longitude == NULL) {
147 		return (ISC_R_NOMEMORY);
148 	}
149 	isc_region_consume(&region, gpos->long_len);
150 
151 	gpos->lat_len = uint8_fromregion(&region);
152 	isc_region_consume(&region, 1);
153 	gpos->latitude = mem_maybedup(mctx, region.base, gpos->lat_len);
154 	if (gpos->latitude == NULL) {
155 		goto cleanup_longitude;
156 	}
157 	isc_region_consume(&region, gpos->lat_len);
158 
159 	gpos->alt_len = uint8_fromregion(&region);
160 	isc_region_consume(&region, 1);
161 	if (gpos->lat_len > 0) {
162 		gpos->altitude = mem_maybedup(mctx, region.base, gpos->alt_len);
163 		if (gpos->altitude == NULL) {
164 			goto cleanup_latitude;
165 		}
166 	} else {
167 		gpos->altitude = NULL;
168 	}
169 
170 	gpos->mctx = mctx;
171 	return (ISC_R_SUCCESS);
172 
173 cleanup_latitude:
174 	if (mctx != NULL && gpos->longitude != NULL) {
175 		isc_mem_free(mctx, gpos->longitude);
176 	}
177 
178 cleanup_longitude:
179 	if (mctx != NULL && gpos->latitude != NULL) {
180 		isc_mem_free(mctx, gpos->latitude);
181 	}
182 	return (ISC_R_NOMEMORY);
183 }
184 
185 static void
freestruct_gpos(ARGS_FREESTRUCT)186 freestruct_gpos(ARGS_FREESTRUCT) {
187 	dns_rdata_gpos_t *gpos = source;
188 
189 	REQUIRE(gpos != NULL);
190 	REQUIRE(gpos->common.rdtype == dns_rdatatype_gpos);
191 
192 	if (gpos->mctx == NULL) {
193 		return;
194 	}
195 
196 	if (gpos->longitude != NULL) {
197 		isc_mem_free(gpos->mctx, gpos->longitude);
198 	}
199 	if (gpos->latitude != NULL) {
200 		isc_mem_free(gpos->mctx, gpos->latitude);
201 	}
202 	if (gpos->altitude != NULL) {
203 		isc_mem_free(gpos->mctx, gpos->altitude);
204 	}
205 	gpos->mctx = NULL;
206 }
207 
208 static isc_result_t
additionaldata_gpos(ARGS_ADDLDATA)209 additionaldata_gpos(ARGS_ADDLDATA) {
210 	REQUIRE(rdata->type == dns_rdatatype_gpos);
211 
212 	UNUSED(rdata);
213 	UNUSED(add);
214 	UNUSED(arg);
215 
216 	return (ISC_R_SUCCESS);
217 }
218 
219 static isc_result_t
digest_gpos(ARGS_DIGEST)220 digest_gpos(ARGS_DIGEST) {
221 	isc_region_t r;
222 
223 	REQUIRE(rdata->type == dns_rdatatype_gpos);
224 
225 	dns_rdata_toregion(rdata, &r);
226 
227 	return ((digest)(arg, &r));
228 }
229 
230 static bool
checkowner_gpos(ARGS_CHECKOWNER)231 checkowner_gpos(ARGS_CHECKOWNER) {
232 	REQUIRE(type == dns_rdatatype_gpos);
233 
234 	UNUSED(name);
235 	UNUSED(type);
236 	UNUSED(rdclass);
237 	UNUSED(wildcard);
238 
239 	return (true);
240 }
241 
242 static bool
checknames_gpos(ARGS_CHECKNAMES)243 checknames_gpos(ARGS_CHECKNAMES) {
244 	REQUIRE(rdata->type == dns_rdatatype_gpos);
245 
246 	UNUSED(rdata);
247 	UNUSED(owner);
248 	UNUSED(bad);
249 
250 	return (true);
251 }
252 
253 static int
casecompare_gpos(ARGS_COMPARE)254 casecompare_gpos(ARGS_COMPARE) {
255 	return (compare_gpos(rdata1, rdata2));
256 }
257 
258 #endif /* RDATA_GENERIC_GPOS_27_C */
259