1/* $NetBSD: csync_62.c,v 1.8 2024/02/21 22:52:12 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 23static isc_result_t 24fromtext_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 52static isc_result_t 53totext_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 86static isc_result_t 87fromwire_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 116static isc_result_t 117towire_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 126static int 127compare_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 142static isc_result_t 143fromstruct_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 165static isc_result_t 166tostruct_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 195cleanup: 196 return (ISC_R_NOMEMORY); 197} 198 199static void 200freestruct_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 216static isc_result_t 217additionaldata_csync(ARGS_ADDLDATA) { 218 REQUIRE(rdata->type == dns_rdatatype_csync); 219 220 UNUSED(rdata); 221 UNUSED(owner); 222 UNUSED(add); 223 UNUSED(arg); 224 225 return (ISC_R_SUCCESS); 226} 227 228static isc_result_t 229digest_csync(ARGS_DIGEST) { 230 isc_region_t r; 231 232 REQUIRE(rdata->type == dns_rdatatype_csync); 233 234 dns_rdata_toregion(rdata, &r); 235 return ((digest)(arg, &r)); 236} 237 238static bool 239checkowner_csync(ARGS_CHECKOWNER) { 240 REQUIRE(type == dns_rdatatype_csync); 241 242 UNUSED(name); 243 UNUSED(type); 244 UNUSED(rdclass); 245 UNUSED(wildcard); 246 247 return (true); 248} 249 250static bool 251checknames_csync(ARGS_CHECKNAMES) { 252 REQUIRE(rdata->type == dns_rdatatype_csync); 253 254 UNUSED(rdata); 255 UNUSED(owner); 256 UNUSED(bad); 257 258 return (true); 259} 260 261static int 262casecompare_csync(ARGS_COMPARE) { 263 isc_region_t region1; 264 isc_region_t region2; 265 266 REQUIRE(rdata1->type == rdata2->type); 267 REQUIRE(rdata1->rdclass == rdata2->rdclass); 268 REQUIRE(rdata1->type == dns_rdatatype_csync); 269 REQUIRE(rdata1->length >= 6); 270 REQUIRE(rdata2->length >= 6); 271 272 dns_rdata_toregion(rdata1, ®ion1); 273 dns_rdata_toregion(rdata2, ®ion2); 274 return (isc_region_compare(®ion1, ®ion2)); 275} 276#endif /* RDATA_GENERIC_CSYNC_62_C */ 277