1 /* $NetBSD: a_1.c,v 1.10 2025/01/26 16:25:34 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 #pragma once 17 18 #include <isc/net.h> 19 20 #define RRTYPE_A_ATTRIBUTES (0) 21 22 static isc_result_t 23 fromtext_hs_a(ARGS_FROMTEXT) { 24 isc_token_t token; 25 struct in_addr addr; 26 isc_region_t region; 27 28 REQUIRE(type == dns_rdatatype_a); 29 REQUIRE(rdclass == dns_rdataclass_hs); 30 31 UNUSED(type); 32 UNUSED(origin); 33 UNUSED(options); 34 UNUSED(rdclass); 35 UNUSED(callbacks); 36 37 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 38 false)); 39 40 if (inet_pton(AF_INET, DNS_AS_STR(token), &addr) != 1) { 41 RETTOK(DNS_R_BADDOTTEDQUAD); 42 } 43 isc_buffer_availableregion(target, ®ion); 44 if (region.length < 4) { 45 return ISC_R_NOSPACE; 46 } 47 memmove(region.base, &addr, 4); 48 isc_buffer_add(target, 4); 49 return ISC_R_SUCCESS; 50 } 51 52 static isc_result_t 53 totext_hs_a(ARGS_TOTEXT) { 54 isc_region_t region; 55 56 REQUIRE(rdata->type == dns_rdatatype_a); 57 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 58 REQUIRE(rdata->length == 4); 59 60 UNUSED(tctx); 61 62 dns_rdata_toregion(rdata, ®ion); 63 return inet_totext(AF_INET, tctx->flags, ®ion, target); 64 } 65 66 static isc_result_t 67 fromwire_hs_a(ARGS_FROMWIRE) { 68 isc_region_t sregion; 69 isc_region_t tregion; 70 71 REQUIRE(type == dns_rdatatype_a); 72 REQUIRE(rdclass == dns_rdataclass_hs); 73 74 UNUSED(type); 75 UNUSED(dctx); 76 UNUSED(rdclass); 77 78 isc_buffer_activeregion(source, &sregion); 79 isc_buffer_availableregion(target, &tregion); 80 if (sregion.length < 4) { 81 return ISC_R_UNEXPECTEDEND; 82 } 83 if (tregion.length < 4) { 84 return ISC_R_NOSPACE; 85 } 86 87 memmove(tregion.base, sregion.base, 4); 88 isc_buffer_forward(source, 4); 89 isc_buffer_add(target, 4); 90 return ISC_R_SUCCESS; 91 } 92 93 static isc_result_t 94 towire_hs_a(ARGS_TOWIRE) { 95 isc_region_t region; 96 97 REQUIRE(rdata->type == dns_rdatatype_a); 98 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 99 REQUIRE(rdata->length == 4); 100 101 UNUSED(cctx); 102 103 isc_buffer_availableregion(target, ®ion); 104 if (region.length < rdata->length) { 105 return ISC_R_NOSPACE; 106 } 107 memmove(region.base, rdata->data, rdata->length); 108 isc_buffer_add(target, 4); 109 return ISC_R_SUCCESS; 110 } 111 112 static int 113 compare_hs_a(ARGS_COMPARE) { 114 int order; 115 116 REQUIRE(rdata1->type == rdata2->type); 117 REQUIRE(rdata1->rdclass == rdata2->rdclass); 118 REQUIRE(rdata1->type == dns_rdatatype_a); 119 REQUIRE(rdata1->rdclass == dns_rdataclass_hs); 120 REQUIRE(rdata1->length == 4); 121 REQUIRE(rdata2->length == 4); 122 123 order = memcmp(rdata1->data, rdata2->data, 4); 124 if (order != 0) { 125 order = (order < 0) ? -1 : 1; 126 } 127 128 return order; 129 } 130 131 static isc_result_t 132 fromstruct_hs_a(ARGS_FROMSTRUCT) { 133 dns_rdata_hs_a_t *a = source; 134 uint32_t n; 135 136 REQUIRE(type == dns_rdatatype_a); 137 REQUIRE(rdclass == dns_rdataclass_hs); 138 REQUIRE(a != NULL); 139 REQUIRE(a->common.rdtype == type); 140 REQUIRE(a->common.rdclass == rdclass); 141 142 UNUSED(type); 143 UNUSED(rdclass); 144 145 n = ntohl(a->in_addr.s_addr); 146 147 return uint32_tobuffer(n, target); 148 } 149 150 static isc_result_t 151 tostruct_hs_a(ARGS_TOSTRUCT) { 152 dns_rdata_hs_a_t *a = target; 153 uint32_t n; 154 isc_region_t region; 155 156 REQUIRE(rdata->type == dns_rdatatype_a); 157 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 158 REQUIRE(rdata->length == 4); 159 REQUIRE(a != NULL); 160 161 UNUSED(mctx); 162 163 a->common.rdclass = rdata->rdclass; 164 a->common.rdtype = rdata->type; 165 ISC_LINK_INIT(&a->common, link); 166 167 dns_rdata_toregion(rdata, ®ion); 168 n = uint32_fromregion(®ion); 169 a->in_addr.s_addr = htonl(n); 170 171 return ISC_R_SUCCESS; 172 } 173 174 static void 175 freestruct_hs_a(ARGS_FREESTRUCT) { 176 UNUSED(source); 177 178 REQUIRE(source != NULL); 179 } 180 181 static isc_result_t 182 additionaldata_hs_a(ARGS_ADDLDATA) { 183 REQUIRE(rdata->type == dns_rdatatype_a); 184 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 185 186 UNUSED(rdata); 187 UNUSED(owner); 188 UNUSED(add); 189 UNUSED(arg); 190 191 return ISC_R_SUCCESS; 192 } 193 194 static isc_result_t 195 digest_hs_a(ARGS_DIGEST) { 196 isc_region_t r; 197 198 REQUIRE(rdata->type == dns_rdatatype_a); 199 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 200 201 dns_rdata_toregion(rdata, &r); 202 203 return (digest)(arg, &r); 204 } 205 206 static bool 207 checkowner_hs_a(ARGS_CHECKOWNER) { 208 REQUIRE(type == dns_rdatatype_a); 209 REQUIRE(rdclass == dns_rdataclass_hs); 210 211 UNUSED(name); 212 UNUSED(type); 213 UNUSED(rdclass); 214 UNUSED(wildcard); 215 216 return true; 217 } 218 219 static bool 220 checknames_hs_a(ARGS_CHECKNAMES) { 221 REQUIRE(rdata->type == dns_rdatatype_a); 222 REQUIRE(rdata->rdclass == dns_rdataclass_hs); 223 224 UNUSED(rdata); 225 UNUSED(owner); 226 UNUSED(bad); 227 228 return true; 229 } 230 231 static int 232 casecompare_hs_a(ARGS_COMPARE) { 233 return compare_hs_a(rdata1, rdata2); 234 } 235