1/*	$NetBSD: a_1.c,v 1.9 2024/02/21 22:52:14 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
22static isc_result_t
23fromtext_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, &region);
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
52static isc_result_t
53totext_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, &region);
63	return (inet_totext(AF_INET, tctx->flags, &region, target));
64}
65
66static isc_result_t
67fromwire_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(options);
77	UNUSED(rdclass);
78
79	isc_buffer_activeregion(source, &sregion);
80	isc_buffer_availableregion(target, &tregion);
81	if (sregion.length < 4) {
82		return (ISC_R_UNEXPECTEDEND);
83	}
84	if (tregion.length < 4) {
85		return (ISC_R_NOSPACE);
86	}
87
88	memmove(tregion.base, sregion.base, 4);
89	isc_buffer_forward(source, 4);
90	isc_buffer_add(target, 4);
91	return (ISC_R_SUCCESS);
92}
93
94static isc_result_t
95towire_hs_a(ARGS_TOWIRE) {
96	isc_region_t region;
97
98	REQUIRE(rdata->type == dns_rdatatype_a);
99	REQUIRE(rdata->rdclass == dns_rdataclass_hs);
100	REQUIRE(rdata->length == 4);
101
102	UNUSED(cctx);
103
104	isc_buffer_availableregion(target, &region);
105	if (region.length < rdata->length) {
106		return (ISC_R_NOSPACE);
107	}
108	memmove(region.base, rdata->data, rdata->length);
109	isc_buffer_add(target, 4);
110	return (ISC_R_SUCCESS);
111}
112
113static int
114compare_hs_a(ARGS_COMPARE) {
115	int order;
116
117	REQUIRE(rdata1->type == rdata2->type);
118	REQUIRE(rdata1->rdclass == rdata2->rdclass);
119	REQUIRE(rdata1->type == dns_rdatatype_a);
120	REQUIRE(rdata1->rdclass == dns_rdataclass_hs);
121	REQUIRE(rdata1->length == 4);
122	REQUIRE(rdata2->length == 4);
123
124	order = memcmp(rdata1->data, rdata2->data, 4);
125	if (order != 0) {
126		order = (order < 0) ? -1 : 1;
127	}
128
129	return (order);
130}
131
132static isc_result_t
133fromstruct_hs_a(ARGS_FROMSTRUCT) {
134	dns_rdata_hs_a_t *a = source;
135	uint32_t n;
136
137	REQUIRE(type == dns_rdatatype_a);
138	REQUIRE(rdclass == dns_rdataclass_hs);
139	REQUIRE(a != NULL);
140	REQUIRE(a->common.rdtype == type);
141	REQUIRE(a->common.rdclass == rdclass);
142
143	UNUSED(type);
144	UNUSED(rdclass);
145
146	n = ntohl(a->in_addr.s_addr);
147
148	return (uint32_tobuffer(n, target));
149}
150
151static isc_result_t
152tostruct_hs_a(ARGS_TOSTRUCT) {
153	dns_rdata_hs_a_t *a = target;
154	uint32_t n;
155	isc_region_t region;
156
157	REQUIRE(rdata->type == dns_rdatatype_a);
158	REQUIRE(rdata->rdclass == dns_rdataclass_hs);
159	REQUIRE(rdata->length == 4);
160	REQUIRE(a != NULL);
161
162	UNUSED(mctx);
163
164	a->common.rdclass = rdata->rdclass;
165	a->common.rdtype = rdata->type;
166	ISC_LINK_INIT(&a->common, link);
167
168	dns_rdata_toregion(rdata, &region);
169	n = uint32_fromregion(&region);
170	a->in_addr.s_addr = htonl(n);
171
172	return (ISC_R_SUCCESS);
173}
174
175static void
176freestruct_hs_a(ARGS_FREESTRUCT) {
177	UNUSED(source);
178
179	REQUIRE(source != NULL);
180}
181
182static isc_result_t
183additionaldata_hs_a(ARGS_ADDLDATA) {
184	REQUIRE(rdata->type == dns_rdatatype_a);
185	REQUIRE(rdata->rdclass == dns_rdataclass_hs);
186
187	UNUSED(rdata);
188	UNUSED(owner);
189	UNUSED(add);
190	UNUSED(arg);
191
192	return (ISC_R_SUCCESS);
193}
194
195static isc_result_t
196digest_hs_a(ARGS_DIGEST) {
197	isc_region_t r;
198
199	REQUIRE(rdata->type == dns_rdatatype_a);
200	REQUIRE(rdata->rdclass == dns_rdataclass_hs);
201
202	dns_rdata_toregion(rdata, &r);
203
204	return ((digest)(arg, &r));
205}
206
207static bool
208checkowner_hs_a(ARGS_CHECKOWNER) {
209	REQUIRE(type == dns_rdatatype_a);
210	REQUIRE(rdclass == dns_rdataclass_hs);
211
212	UNUSED(name);
213	UNUSED(type);
214	UNUSED(rdclass);
215	UNUSED(wildcard);
216
217	return (true);
218}
219
220static bool
221checknames_hs_a(ARGS_CHECKNAMES) {
222	REQUIRE(rdata->type == dns_rdatatype_a);
223	REQUIRE(rdata->rdclass == dns_rdataclass_hs);
224
225	UNUSED(rdata);
226	UNUSED(owner);
227	UNUSED(bad);
228
229	return (true);
230}
231
232static int
233casecompare_hs_a(ARGS_COMPARE) {
234	return (compare_hs_a(rdata1, rdata2));
235}
236