1 /*
2  * Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* RFC 7477 */
18 
19 #ifndef RDATA_GENERIC_CSYNC_62_C
20 #define RDATA_GENERIC_CSYNC_62_C
21 
22 #define RRTYPE_CSYNC_ATTRIBUTES 0
23 
24 static inline isc_result_t
fromtext_csync(ARGS_FROMTEXT)25 fromtext_csync(ARGS_FROMTEXT) {
26 	isc_token_t token;
27 
28 	REQUIRE(type == dns_rdatatype_csync);
29 
30 	UNUSED(type);
31 	UNUSED(rdclass);
32 	UNUSED(origin);
33 	UNUSED(options);
34 	UNUSED(callbacks);
35 
36 	/* Serial. */
37 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
38 				      ISC_FALSE));
39 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
40 
41 	/* Flags. */
42 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
43 				      ISC_FALSE));
44 	if (token.value.as_ulong > 0xffffU)
45 		RETTOK(ISC_R_RANGE);
46 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
47 
48 	/* Type Map */
49 	return (typemap_fromtext(lexer, target, ISC_TRUE));
50 }
51 
52 static inline isc_result_t
totext_csync(ARGS_TOTEXT)53 totext_csync(ARGS_TOTEXT) {
54 	unsigned long num;
55 	char buf[sizeof("0123456789")];	/* Also TYPE65535 */
56 	isc_region_t sr;
57 
58 	REQUIRE(rdata->type == dns_rdatatype_csync);
59 	REQUIRE(rdata->length >= 6);
60 
61 	UNUSED(tctx);
62 
63 	dns_rdata_toregion(rdata, &sr);
64 
65 	num = uint32_fromregion(&sr);
66 	isc_region_consume(&sr, 4);
67 	sprintf(buf, "%lu", num);
68 	RETERR(str_totext(buf, target));
69 
70 	RETERR(str_totext(" ", target));
71 
72 	num = uint16_fromregion(&sr);
73 	isc_region_consume(&sr, 2);
74 	sprintf(buf, "%lu", num);
75 	RETERR(str_totext(buf, target));
76 
77 	return (typemap_totext(&sr, NULL, target));
78 }
79 
80 static /* inline */ isc_result_t
fromwire_csync(ARGS_FROMWIRE)81 fromwire_csync(ARGS_FROMWIRE) {
82 	isc_region_t sr;
83 
84 	REQUIRE(type == dns_rdatatype_csync);
85 
86 	UNUSED(type);
87 	UNUSED(rdclass);
88 	UNUSED(options);
89 	UNUSED(dctx);
90 
91 	/*
92 	 * Serial + Flags
93 	 */
94 	isc_buffer_activeregion(source, &sr);
95 	if (sr.length < 6)
96 		return (ISC_R_UNEXPECTEDEND);
97 
98 	RETERR(mem_tobuffer(target, sr.base, 6));
99 	isc_buffer_forward(source, 6);
100 	isc_region_consume(&sr, 6);
101 
102 	RETERR(typemap_test(&sr, ISC_TRUE));
103 
104 	RETERR(mem_tobuffer(target, sr.base, sr.length));
105 	isc_buffer_forward(source, sr.length);
106 	return (ISC_R_SUCCESS);
107 }
108 
109 static inline isc_result_t
towire_csync(ARGS_TOWIRE)110 towire_csync(ARGS_TOWIRE) {
111 
112 	REQUIRE(rdata->type == dns_rdatatype_csync);
113 	REQUIRE(rdata->length >= 6);
114 
115 	UNUSED(cctx);
116 
117 	return (mem_tobuffer(target, rdata->data, rdata->length));
118 }
119 
120 static inline int
compare_csync(ARGS_COMPARE)121 compare_csync(ARGS_COMPARE) {
122 	isc_region_t r1;
123 	isc_region_t r2;
124 
125 	REQUIRE(rdata1->type == rdata2->type);
126 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
127 	REQUIRE(rdata1->type == dns_rdatatype_csync);
128 	REQUIRE(rdata1->length >= 6);
129 	REQUIRE(rdata2->length >= 6);
130 
131 	dns_rdata_toregion(rdata1, &r1);
132 	dns_rdata_toregion(rdata2, &r2);
133 	return (isc_region_compare(&r1, &r2));
134 }
135 
136 static inline isc_result_t
fromstruct_csync(ARGS_FROMSTRUCT)137 fromstruct_csync(ARGS_FROMSTRUCT) {
138 	dns_rdata_csync_t *csync = source;
139 	isc_region_t region;
140 
141 	REQUIRE(type == dns_rdatatype_csync);
142 	REQUIRE(source != NULL);
143 	REQUIRE(csync->common.rdtype == type);
144 	REQUIRE(csync->common.rdclass == rdclass);
145 	REQUIRE(csync->typebits != NULL || csync->len == 0);
146 
147 	UNUSED(type);
148 	UNUSED(rdclass);
149 
150 	RETERR(uint32_tobuffer(csync->serial, target));
151 	RETERR(uint16_tobuffer(csync->flags, target));
152 
153 	region.base = csync->typebits;
154 	region.length = csync->len;
155 	RETERR(typemap_test(&region, ISC_TRUE));
156 	return (mem_tobuffer(target, csync->typebits, csync->len));
157 }
158 
159 static inline isc_result_t
tostruct_csync(ARGS_TOSTRUCT)160 tostruct_csync(ARGS_TOSTRUCT) {
161 	isc_region_t region;
162 	dns_rdata_csync_t *csync = target;
163 
164 	REQUIRE(rdata->type == dns_rdatatype_csync);
165 	REQUIRE(target != NULL);
166 	REQUIRE(rdata->length != 0);
167 
168 	csync->common.rdclass = rdata->rdclass;
169 	csync->common.rdtype = rdata->type;
170 	ISC_LINK_INIT(&csync->common, link);
171 
172 	dns_rdata_toregion(rdata, &region);
173 
174 	csync->serial = uint32_fromregion(&region);
175 	isc_region_consume(&region, 4);
176 
177 	csync->flags = uint16_fromregion(&region);
178 	isc_region_consume(&region, 2);
179 
180 	csync->len = region.length;
181 	csync->typebits = mem_maybedup(mctx, region.base, region.length);
182 	if (csync->typebits == NULL)
183 		goto cleanup;
184 
185 	csync->mctx = mctx;
186 	return (ISC_R_SUCCESS);
187 
188  cleanup:
189 	return (ISC_R_NOMEMORY);
190 }
191 
192 static inline void
freestruct_csync(ARGS_FREESTRUCT)193 freestruct_csync(ARGS_FREESTRUCT) {
194 	dns_rdata_csync_t *csync = source;
195 
196 	REQUIRE(source != NULL);
197 	REQUIRE(csync->common.rdtype == dns_rdatatype_csync);
198 
199 	if (csync->mctx == NULL)
200 		return;
201 
202 	if (csync->typebits != NULL)
203 		isc_mem_free(csync->mctx, csync->typebits);
204 	csync->mctx = NULL;
205 }
206 
207 static inline isc_result_t
additionaldata_csync(ARGS_ADDLDATA)208 additionaldata_csync(ARGS_ADDLDATA) {
209 	REQUIRE(rdata->type == dns_rdatatype_csync);
210 
211 	UNUSED(rdata);
212 	UNUSED(add);
213 	UNUSED(arg);
214 
215 	return (ISC_R_SUCCESS);
216 }
217 
218 static inline isc_result_t
digest_csync(ARGS_DIGEST)219 digest_csync(ARGS_DIGEST) {
220 	isc_region_t r;
221 
222 	REQUIRE(rdata->type == dns_rdatatype_csync);
223 
224 	dns_rdata_toregion(rdata, &r);
225 	return ((digest)(arg, &r));
226 }
227 
228 static inline isc_boolean_t
checkowner_csync(ARGS_CHECKOWNER)229 checkowner_csync(ARGS_CHECKOWNER) {
230 
231        REQUIRE(type == dns_rdatatype_csync);
232 
233        UNUSED(name);
234        UNUSED(type);
235        UNUSED(rdclass);
236        UNUSED(wildcard);
237 
238        return (ISC_TRUE);
239 }
240 
241 static inline isc_boolean_t
checknames_csync(ARGS_CHECKNAMES)242 checknames_csync(ARGS_CHECKNAMES) {
243 
244 	REQUIRE(rdata->type == dns_rdatatype_csync);
245 
246 	UNUSED(rdata);
247 	UNUSED(owner);
248 	UNUSED(bad);
249 
250 	return (ISC_TRUE);
251 }
252 
253 static inline int
casecompare_csync(ARGS_COMPARE)254 casecompare_csync(ARGS_COMPARE) {
255 	isc_region_t region1;
256 	isc_region_t region2;
257 
258 	REQUIRE(rdata1->type == rdata2->type);
259 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
260 	REQUIRE(rdata1->type == dns_rdatatype_csync);
261 	REQUIRE(rdata1->length >= 6);
262 	REQUIRE(rdata2->length >= 6);
263 
264 	dns_rdata_toregion(rdata1, &region1);
265 	dns_rdata_toregion(rdata2, &region2);
266 	return (isc_region_compare(&region1, &region2));
267 }
268 #endif	/* RDATA_GENERIC_CSYNC_62_C */
269