1 /* $NetBSD: csync_62.c,v 1.1 2024/02/18 20:57:41 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 /* RFC 7477 */
17
18 #ifndef RDATA_GENERIC_CSYNC_62_C
19 #define RDATA_GENERIC_CSYNC_62_C
20
21 #define RRTYPE_CSYNC_ATTRIBUTES 0
22
23 static isc_result_t
fromtext_csync(ARGS_FROMTEXT)24 fromtext_csync(ARGS_FROMTEXT) {
25 isc_token_t token;
26
27 REQUIRE(type == dns_rdatatype_csync);
28
29 UNUSED(type);
30 UNUSED(rdclass);
31 UNUSED(origin);
32 UNUSED(options);
33 UNUSED(callbacks);
34
35 /* Serial. */
36 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
37 false));
38 RETERR(uint32_tobuffer(token.value.as_ulong, target));
39
40 /* Flags. */
41 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
42 false));
43 if (token.value.as_ulong > 0xffffU) {
44 RETTOK(ISC_R_RANGE);
45 }
46 RETERR(uint16_tobuffer(token.value.as_ulong, target));
47
48 /* Type Map */
49 return (typemap_fromtext(lexer, target, true));
50 }
51
52 static 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 snprintf(buf, sizeof(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 snprintf(buf, sizeof(buf), "%lu", num);
75 RETERR(str_totext(buf, target));
76
77 /*
78 * Don't leave a trailing space when there's no typemap present.
79 */
80 if (sr.length > 0) {
81 RETERR(str_totext(" ", target));
82 }
83 return (typemap_totext(&sr, NULL, target));
84 }
85
86 static isc_result_t
fromwire_csync(ARGS_FROMWIRE)87 fromwire_csync(ARGS_FROMWIRE) {
88 isc_region_t sr;
89
90 REQUIRE(type == dns_rdatatype_csync);
91
92 UNUSED(type);
93 UNUSED(rdclass);
94 UNUSED(options);
95 UNUSED(dctx);
96
97 /*
98 * Serial + Flags
99 */
100 isc_buffer_activeregion(source, &sr);
101 if (sr.length < 6) {
102 return (ISC_R_UNEXPECTEDEND);
103 }
104
105 RETERR(mem_tobuffer(target, sr.base, 6));
106 isc_buffer_forward(source, 6);
107 isc_region_consume(&sr, 6);
108
109 RETERR(typemap_test(&sr, true));
110
111 RETERR(mem_tobuffer(target, sr.base, sr.length));
112 isc_buffer_forward(source, sr.length);
113 return (ISC_R_SUCCESS);
114 }
115
116 static isc_result_t
towire_csync(ARGS_TOWIRE)117 towire_csync(ARGS_TOWIRE) {
118 REQUIRE(rdata->type == dns_rdatatype_csync);
119 REQUIRE(rdata->length >= 6);
120
121 UNUSED(cctx);
122
123 return (mem_tobuffer(target, rdata->data, rdata->length));
124 }
125
126 static int
compare_csync(ARGS_COMPARE)127 compare_csync(ARGS_COMPARE) {
128 isc_region_t r1;
129 isc_region_t r2;
130
131 REQUIRE(rdata1->type == rdata2->type);
132 REQUIRE(rdata1->rdclass == rdata2->rdclass);
133 REQUIRE(rdata1->type == dns_rdatatype_csync);
134 REQUIRE(rdata1->length >= 6);
135 REQUIRE(rdata2->length >= 6);
136
137 dns_rdata_toregion(rdata1, &r1);
138 dns_rdata_toregion(rdata2, &r2);
139 return (isc_region_compare(&r1, &r2));
140 }
141
142 static isc_result_t
fromstruct_csync(ARGS_FROMSTRUCT)143 fromstruct_csync(ARGS_FROMSTRUCT) {
144 dns_rdata_csync_t *csync = source;
145 isc_region_t region;
146
147 REQUIRE(type == dns_rdatatype_csync);
148 REQUIRE(csync != NULL);
149 REQUIRE(csync->common.rdtype == type);
150 REQUIRE(csync->common.rdclass == rdclass);
151 REQUIRE(csync->typebits != NULL || csync->len == 0);
152
153 UNUSED(type);
154 UNUSED(rdclass);
155
156 RETERR(uint32_tobuffer(csync->serial, target));
157 RETERR(uint16_tobuffer(csync->flags, target));
158
159 region.base = csync->typebits;
160 region.length = csync->len;
161 RETERR(typemap_test(®ion, true));
162 return (mem_tobuffer(target, csync->typebits, csync->len));
163 }
164
165 static isc_result_t
tostruct_csync(ARGS_TOSTRUCT)166 tostruct_csync(ARGS_TOSTRUCT) {
167 isc_region_t region;
168 dns_rdata_csync_t *csync = target;
169
170 REQUIRE(rdata->type == dns_rdatatype_csync);
171 REQUIRE(csync != NULL);
172 REQUIRE(rdata->length != 0);
173
174 csync->common.rdclass = rdata->rdclass;
175 csync->common.rdtype = rdata->type;
176 ISC_LINK_INIT(&csync->common, link);
177
178 dns_rdata_toregion(rdata, ®ion);
179
180 csync->serial = uint32_fromregion(®ion);
181 isc_region_consume(®ion, 4);
182
183 csync->flags = uint16_fromregion(®ion);
184 isc_region_consume(®ion, 2);
185
186 csync->len = region.length;
187 csync->typebits = mem_maybedup(mctx, region.base, region.length);
188 if (csync->typebits == NULL) {
189 goto cleanup;
190 }
191
192 csync->mctx = mctx;
193 return (ISC_R_SUCCESS);
194
195 cleanup:
196 return (ISC_R_NOMEMORY);
197 }
198
199 static void
freestruct_csync(ARGS_FREESTRUCT)200 freestruct_csync(ARGS_FREESTRUCT) {
201 dns_rdata_csync_t *csync = source;
202
203 REQUIRE(csync != NULL);
204 REQUIRE(csync->common.rdtype == dns_rdatatype_csync);
205
206 if (csync->mctx == NULL) {
207 return;
208 }
209
210 if (csync->typebits != NULL) {
211 isc_mem_free(csync->mctx, csync->typebits);
212 }
213 csync->mctx = NULL;
214 }
215
216 static isc_result_t
additionaldata_csync(ARGS_ADDLDATA)217 additionaldata_csync(ARGS_ADDLDATA) {
218 REQUIRE(rdata->type == dns_rdatatype_csync);
219
220 UNUSED(rdata);
221 UNUSED(add);
222 UNUSED(arg);
223
224 return (ISC_R_SUCCESS);
225 }
226
227 static isc_result_t
digest_csync(ARGS_DIGEST)228 digest_csync(ARGS_DIGEST) {
229 isc_region_t r;
230
231 REQUIRE(rdata->type == dns_rdatatype_csync);
232
233 dns_rdata_toregion(rdata, &r);
234 return ((digest)(arg, &r));
235 }
236
237 static bool
checkowner_csync(ARGS_CHECKOWNER)238 checkowner_csync(ARGS_CHECKOWNER) {
239 REQUIRE(type == dns_rdatatype_csync);
240
241 UNUSED(name);
242 UNUSED(type);
243 UNUSED(rdclass);
244 UNUSED(wildcard);
245
246 return (true);
247 }
248
249 static bool
checknames_csync(ARGS_CHECKNAMES)250 checknames_csync(ARGS_CHECKNAMES) {
251 REQUIRE(rdata->type == dns_rdatatype_csync);
252
253 UNUSED(rdata);
254 UNUSED(owner);
255 UNUSED(bad);
256
257 return (true);
258 }
259
260 static int
casecompare_csync(ARGS_COMPARE)261 casecompare_csync(ARGS_COMPARE) {
262 isc_region_t region1;
263 isc_region_t region2;
264
265 REQUIRE(rdata1->type == rdata2->type);
266 REQUIRE(rdata1->rdclass == rdata2->rdclass);
267 REQUIRE(rdata1->type == dns_rdatatype_csync);
268 REQUIRE(rdata1->length >= 6);
269 REQUIRE(rdata2->length >= 6);
270
271 dns_rdata_toregion(rdata1, ®ion1);
272 dns_rdata_toregion(rdata2, ®ion2);
273 return (isc_region_compare(®ion1, ®ion2));
274 }
275 #endif /* RDATA_GENERIC_CSYNC_62_C */
276