1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 /* RFC 7477 */
13
14 #ifndef RDATA_GENERIC_CSYNC_62_C
15 #define RDATA_GENERIC_CSYNC_62_C
16
17 #define RRTYPE_CSYNC_ATTRIBUTES 0
18
19 static inline isc_result_t
fromtext_csync(ARGS_FROMTEXT)20 fromtext_csync(ARGS_FROMTEXT) {
21 isc_token_t token;
22
23 REQUIRE(type == dns_rdatatype_csync);
24
25 UNUSED(type);
26 UNUSED(rdclass);
27 UNUSED(origin);
28 UNUSED(options);
29 UNUSED(callbacks);
30
31 /* Serial. */
32 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
33 false));
34 RETERR(uint32_tobuffer(token.value.as_ulong, target));
35
36 /* Flags. */
37 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
38 false));
39 if (token.value.as_ulong > 0xffffU) {
40 RETTOK(ISC_R_RANGE);
41 }
42 RETERR(uint16_tobuffer(token.value.as_ulong, target));
43
44 /* Type Map */
45 return (typemap_fromtext(lexer, target, true));
46 }
47
48 static inline isc_result_t
totext_csync(ARGS_TOTEXT)49 totext_csync(ARGS_TOTEXT) {
50 unsigned long num;
51 char buf[sizeof("0123456789")]; /* Also TYPE65535 */
52 isc_region_t sr;
53
54 REQUIRE(rdata->type == dns_rdatatype_csync);
55 REQUIRE(rdata->length >= 6);
56
57 UNUSED(tctx);
58
59 dns_rdata_toregion(rdata, &sr);
60
61 num = uint32_fromregion(&sr);
62 isc_region_consume(&sr, 4);
63 snprintf(buf, sizeof(buf), "%lu", num);
64 RETERR(str_totext(buf, target));
65
66 RETERR(str_totext(" ", target));
67
68 num = uint16_fromregion(&sr);
69 isc_region_consume(&sr, 2);
70 snprintf(buf, sizeof(buf), "%lu", num);
71 RETERR(str_totext(buf, target));
72
73 /*
74 * Don't leave a trailing space when there's no typemap present.
75 */
76 if (sr.length > 0) {
77 RETERR(str_totext(" ", target));
78 }
79 return (typemap_totext(&sr, NULL, target));
80 }
81
82 static /* inline */ isc_result_t
fromwire_csync(ARGS_FROMWIRE)83 fromwire_csync(ARGS_FROMWIRE) {
84 isc_region_t sr;
85
86 REQUIRE(type == dns_rdatatype_csync);
87
88 UNUSED(type);
89 UNUSED(rdclass);
90 UNUSED(options);
91 UNUSED(dctx);
92
93 /*
94 * Serial + Flags
95 */
96 isc_buffer_activeregion(source, &sr);
97 if (sr.length < 6) {
98 return (ISC_R_UNEXPECTEDEND);
99 }
100
101 RETERR(mem_tobuffer(target, sr.base, 6));
102 isc_buffer_forward(source, 6);
103 isc_region_consume(&sr, 6);
104
105 RETERR(typemap_test(&sr, true));
106
107 RETERR(mem_tobuffer(target, sr.base, sr.length));
108 isc_buffer_forward(source, sr.length);
109 return (ISC_R_SUCCESS);
110 }
111
112 static inline isc_result_t
towire_csync(ARGS_TOWIRE)113 towire_csync(ARGS_TOWIRE) {
114 REQUIRE(rdata->type == dns_rdatatype_csync);
115 REQUIRE(rdata->length >= 6);
116
117 UNUSED(cctx);
118
119 return (mem_tobuffer(target, rdata->data, rdata->length));
120 }
121
122 static inline int
compare_csync(ARGS_COMPARE)123 compare_csync(ARGS_COMPARE) {
124 isc_region_t r1;
125 isc_region_t r2;
126
127 REQUIRE(rdata1->type == rdata2->type);
128 REQUIRE(rdata1->rdclass == rdata2->rdclass);
129 REQUIRE(rdata1->type == dns_rdatatype_csync);
130 REQUIRE(rdata1->length >= 6);
131 REQUIRE(rdata2->length >= 6);
132
133 dns_rdata_toregion(rdata1, &r1);
134 dns_rdata_toregion(rdata2, &r2);
135 return (isc_region_compare(&r1, &r2));
136 }
137
138 static inline isc_result_t
fromstruct_csync(ARGS_FROMSTRUCT)139 fromstruct_csync(ARGS_FROMSTRUCT) {
140 dns_rdata_csync_t *csync = source;
141 isc_region_t region;
142
143 REQUIRE(type == dns_rdatatype_csync);
144 REQUIRE(csync != NULL);
145 REQUIRE(csync->common.rdtype == type);
146 REQUIRE(csync->common.rdclass == rdclass);
147 REQUIRE(csync->typebits != NULL || csync->len == 0);
148
149 UNUSED(type);
150 UNUSED(rdclass);
151
152 RETERR(uint32_tobuffer(csync->serial, target));
153 RETERR(uint16_tobuffer(csync->flags, target));
154
155 region.base = csync->typebits;
156 region.length = csync->len;
157 RETERR(typemap_test(®ion, true));
158 return (mem_tobuffer(target, csync->typebits, csync->len));
159 }
160
161 static inline isc_result_t
tostruct_csync(ARGS_TOSTRUCT)162 tostruct_csync(ARGS_TOSTRUCT) {
163 isc_region_t region;
164 dns_rdata_csync_t *csync = target;
165
166 REQUIRE(rdata->type == dns_rdatatype_csync);
167 REQUIRE(csync != NULL);
168 REQUIRE(rdata->length != 0);
169
170 csync->common.rdclass = rdata->rdclass;
171 csync->common.rdtype = rdata->type;
172 ISC_LINK_INIT(&csync->common, link);
173
174 dns_rdata_toregion(rdata, ®ion);
175
176 csync->serial = uint32_fromregion(®ion);
177 isc_region_consume(®ion, 4);
178
179 csync->flags = uint16_fromregion(®ion);
180 isc_region_consume(®ion, 2);
181
182 csync->len = region.length;
183 csync->typebits = mem_maybedup(mctx, region.base, region.length);
184 if (csync->typebits == NULL) {
185 goto cleanup;
186 }
187
188 csync->mctx = mctx;
189 return (ISC_R_SUCCESS);
190
191 cleanup:
192 return (ISC_R_NOMEMORY);
193 }
194
195 static inline void
freestruct_csync(ARGS_FREESTRUCT)196 freestruct_csync(ARGS_FREESTRUCT) {
197 dns_rdata_csync_t *csync = source;
198
199 REQUIRE(csync != NULL);
200 REQUIRE(csync->common.rdtype == dns_rdatatype_csync);
201
202 if (csync->mctx == NULL) {
203 return;
204 }
205
206 if (csync->typebits != NULL) {
207 isc_mem_free(csync->mctx, csync->typebits);
208 }
209 csync->mctx = NULL;
210 }
211
212 static inline isc_result_t
additionaldata_csync(ARGS_ADDLDATA)213 additionaldata_csync(ARGS_ADDLDATA) {
214 REQUIRE(rdata->type == dns_rdatatype_csync);
215
216 UNUSED(rdata);
217 UNUSED(owner);
218 UNUSED(add);
219 UNUSED(arg);
220
221 return (ISC_R_SUCCESS);
222 }
223
224 static inline isc_result_t
digest_csync(ARGS_DIGEST)225 digest_csync(ARGS_DIGEST) {
226 isc_region_t r;
227
228 REQUIRE(rdata->type == dns_rdatatype_csync);
229
230 dns_rdata_toregion(rdata, &r);
231 return ((digest)(arg, &r));
232 }
233
234 static inline bool
checkowner_csync(ARGS_CHECKOWNER)235 checkowner_csync(ARGS_CHECKOWNER) {
236 REQUIRE(type == dns_rdatatype_csync);
237
238 UNUSED(name);
239 UNUSED(type);
240 UNUSED(rdclass);
241 UNUSED(wildcard);
242
243 return (true);
244 }
245
246 static inline bool
checknames_csync(ARGS_CHECKNAMES)247 checknames_csync(ARGS_CHECKNAMES) {
248 REQUIRE(rdata->type == dns_rdatatype_csync);
249
250 UNUSED(rdata);
251 UNUSED(owner);
252 UNUSED(bad);
253
254 return (true);
255 }
256
257 static inline int
casecompare_csync(ARGS_COMPARE)258 casecompare_csync(ARGS_COMPARE) {
259 isc_region_t region1;
260 isc_region_t region2;
261
262 REQUIRE(rdata1->type == rdata2->type);
263 REQUIRE(rdata1->rdclass == rdata2->rdclass);
264 REQUIRE(rdata1->type == dns_rdatatype_csync);
265 REQUIRE(rdata1->length >= 6);
266 REQUIRE(rdata2->length >= 6);
267
268 dns_rdata_toregion(rdata1, ®ion1);
269 dns_rdata_toregion(rdata2, ®ion2);
270 return (isc_region_compare(®ion1, ®ion2));
271 }
272 #endif /* RDATA_GENERIC_CSYNC_62_C */
273