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(®ion, 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, ®ion);
173
174 csync->serial = uint32_fromregion(®ion);
175 isc_region_consume(®ion, 4);
176
177 csync->flags = uint16_fromregion(®ion);
178 isc_region_consume(®ion, 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, ®ion1);
265 dns_rdata_toregion(rdata2, ®ion2);
266 return (isc_region_compare(®ion1, ®ion2));
267 }
268 #endif /* RDATA_GENERIC_CSYNC_62_C */
269