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 #ifndef RDATA_IN_1_A_1_C
13 #define RDATA_IN_1_A_1_C
14
15 #include <string.h>
16
17 #include <isc/net.h>
18
19 #define RRTYPE_A_ATTRIBUTES (0)
20
21 static inline isc_result_t
fromtext_in_a(ARGS_FROMTEXT)22 fromtext_in_a(ARGS_FROMTEXT) {
23 isc_token_t token;
24 struct in_addr addr;
25 isc_region_t region;
26
27 REQUIRE(type == dns_rdatatype_a);
28 REQUIRE(rdclass == dns_rdataclass_in);
29
30 UNUSED(type);
31 UNUSED(origin);
32 UNUSED(options);
33 UNUSED(rdclass);
34
35 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
36 false));
37
38 if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
39 RETTOK(DNS_R_BADDOTTEDQUAD);
40 isc_buffer_availableregion(target, ®ion);
41 if (region.length < 4)
42 return (ISC_R_NOSPACE);
43 memmove(region.base, &addr, 4);
44 isc_buffer_add(target, 4);
45 return (ISC_R_SUCCESS);
46 }
47
48 static inline isc_result_t
totext_in_a(ARGS_TOTEXT)49 totext_in_a(ARGS_TOTEXT) {
50 isc_region_t region;
51
52 REQUIRE(rdata->type == dns_rdatatype_a);
53 REQUIRE(rdata->rdclass == dns_rdataclass_in);
54 REQUIRE(rdata->length == 4);
55
56 UNUSED(tctx);
57
58 dns_rdata_toregion(rdata, ®ion);
59 return (inet_totext(AF_INET, tctx->flags, ®ion, target));
60 }
61
62 static inline isc_result_t
fromwire_in_a(ARGS_FROMWIRE)63 fromwire_in_a(ARGS_FROMWIRE) {
64 isc_region_t sregion;
65 isc_region_t tregion;
66
67 REQUIRE(type == dns_rdatatype_a);
68 REQUIRE(rdclass == dns_rdataclass_in);
69
70 UNUSED(type);
71 UNUSED(dctx);
72 UNUSED(options);
73 UNUSED(rdclass);
74
75 isc_buffer_activeregion(source, &sregion);
76 isc_buffer_availableregion(target, &tregion);
77 if (sregion.length < 4)
78 return (ISC_R_UNEXPECTEDEND);
79 if (tregion.length < 4)
80 return (ISC_R_NOSPACE);
81
82 memmove(tregion.base, sregion.base, 4);
83 isc_buffer_forward(source, 4);
84 isc_buffer_add(target, 4);
85 return (ISC_R_SUCCESS);
86 }
87
88 static inline isc_result_t
towire_in_a(ARGS_TOWIRE)89 towire_in_a(ARGS_TOWIRE) {
90 isc_region_t region;
91
92 REQUIRE(rdata->type == dns_rdatatype_a);
93 REQUIRE(rdata->rdclass == dns_rdataclass_in);
94 REQUIRE(rdata->length == 4);
95
96 UNUSED(cctx);
97
98 isc_buffer_availableregion(target, ®ion);
99 if (region.length < rdata->length)
100 return (ISC_R_NOSPACE);
101 memmove(region.base, rdata->data, rdata->length);
102 isc_buffer_add(target, 4);
103 return (ISC_R_SUCCESS);
104 }
105
106 static inline int
compare_in_a(ARGS_COMPARE)107 compare_in_a(ARGS_COMPARE) {
108 isc_region_t r1;
109 isc_region_t r2;
110
111 REQUIRE(rdata1->type == rdata2->type);
112 REQUIRE(rdata1->rdclass == rdata2->rdclass);
113 REQUIRE(rdata1->type == dns_rdatatype_a);
114 REQUIRE(rdata1->rdclass == dns_rdataclass_in);
115 REQUIRE(rdata1->length == 4);
116 REQUIRE(rdata2->length == 4);
117
118 dns_rdata_toregion(rdata1, &r1);
119 dns_rdata_toregion(rdata2, &r2);
120 return (isc_region_compare(&r1, &r2));
121 }
122
123 static inline isc_result_t
fromstruct_in_a(ARGS_FROMSTRUCT)124 fromstruct_in_a(ARGS_FROMSTRUCT) {
125 dns_rdata_in_a_t *a;
126 uint32_t n;
127
128 REQUIRE(type == dns_rdatatype_a);
129 REQUIRE(rdclass == dns_rdataclass_in);
130 REQUIRE(((dns_rdata_in_a_t *)source) != NULL);
131 REQUIRE(((dns_rdata_in_a_t *)source)->common.rdtype == type);
132 REQUIRE(((dns_rdata_in_a_t *)source)->common.rdclass == rdclass);
133
134 a = source;
135
136 UNUSED(type);
137 UNUSED(rdclass);
138
139 n = ntohl(a->in_addr.s_addr);
140
141 return (uint32_tobuffer(n, target));
142 }
143
144
145 static inline isc_result_t
tostruct_in_a(ARGS_TOSTRUCT)146 tostruct_in_a(ARGS_TOSTRUCT) {
147 dns_rdata_in_a_t *a;
148 uint32_t n;
149 isc_region_t region;
150
151 REQUIRE(((dns_rdata_in_a_t *)target) != NULL);
152 REQUIRE(rdata->type == dns_rdatatype_a);
153 REQUIRE(rdata->rdclass == dns_rdataclass_in);
154 REQUIRE(rdata->length == 4);
155
156 a = target;
157
158 UNUSED(mctx);
159
160 a->common.rdclass = rdata->rdclass;
161 a->common.rdtype = rdata->type;
162 ISC_LINK_INIT(&a->common, link);
163
164 dns_rdata_toregion(rdata, ®ion);
165 n = uint32_fromregion(®ion);
166 a->in_addr.s_addr = htonl(n);
167
168 return (ISC_R_SUCCESS);
169 }
170
171 static inline void
freestruct_in_a(ARGS_FREESTRUCT)172 freestruct_in_a(ARGS_FREESTRUCT) {
173 dns_rdata_in_a_t *a;
174
175 REQUIRE(((dns_rdata_in_a_t *)source) != NULL);
176 REQUIRE(((dns_rdata_in_a_t *)source)->common.rdtype == dns_rdatatype_a);
177 REQUIRE(((dns_rdata_in_a_t *)source)->common.rdclass ==
178 dns_rdataclass_in);
179
180 a = source;
181
182 UNUSED(a);
183 }
184
185 static inline isc_result_t
additionaldata_in_a(ARGS_ADDLDATA)186 additionaldata_in_a(ARGS_ADDLDATA) {
187 REQUIRE(rdata->type == dns_rdatatype_a);
188 REQUIRE(rdata->rdclass == dns_rdataclass_in);
189
190 UNUSED(rdata);
191 UNUSED(add);
192 UNUSED(arg);
193
194 return (ISC_R_SUCCESS);
195 }
196
197 static inline isc_result_t
digest_in_a(ARGS_DIGEST)198 digest_in_a(ARGS_DIGEST) {
199 isc_region_t r;
200
201 REQUIRE(rdata->type == dns_rdatatype_a);
202 REQUIRE(rdata->rdclass == dns_rdataclass_in);
203
204 dns_rdata_toregion(rdata, &r);
205
206 return ((digest)(arg, &r));
207 }
208
209 static inline bool
checkowner_in_a(ARGS_CHECKOWNER)210 checkowner_in_a(ARGS_CHECKOWNER) {
211 dns_name_t prefix, suffix;
212
213 REQUIRE(type == dns_rdatatype_a);
214 REQUIRE(rdclass == dns_rdataclass_in);
215
216 UNUSED(type);
217 UNUSED(rdclass);
218
219 /*
220 * Handle Active Directory gc._msdcs.<forest> name.
221 */
222 if (dns_name_countlabels(name) > 2U) {
223 dns_name_init(&prefix, NULL);
224 dns_name_init(&suffix, NULL);
225 dns_name_split(name, dns_name_countlabels(name) - 2,
226 &prefix, &suffix);
227 if (dns_name_equal(&gc_msdcs, &prefix) &&
228 dns_name_ishostname(&suffix, false))
229 return (true);
230 }
231
232 return (dns_name_ishostname(name, wildcard));
233 }
234
235 static inline bool
checknames_in_a(ARGS_CHECKNAMES)236 checknames_in_a(ARGS_CHECKNAMES) {
237
238 REQUIRE(rdata->type == dns_rdatatype_a);
239 REQUIRE(rdata->rdclass == dns_rdataclass_in);
240
241 UNUSED(rdata);
242 UNUSED(owner);
243 UNUSED(bad);
244
245 return (true);
246 }
247
248 static inline int
casecompare_in_a(ARGS_COMPARE)249 casecompare_in_a(ARGS_COMPARE) {
250 return (compare_in_a(rdata1, rdata2));
251 }
252
253 #endif /* RDATA_IN_1_A_1_C */
254