1/*
2 * Copyright (C) 2004, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2002  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: a_1.c,v 1.55 2009/12/04 22:06:37 tbox Exp $ */
19
20/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
21
22#ifndef RDATA_IN_1_A_1_C
23#define RDATA_IN_1_A_1_C
24
25#include <string.h>
26
27#include <isc/net.h>
28
29#define RRTYPE_A_ATTRIBUTES (0)
30
31static inline isc_result_t
32fromtext_in_a(ARGS_FROMTEXT) {
33	isc_token_t token;
34	struct in_addr addr;
35	isc_region_t region;
36
37	REQUIRE(type == 1);
38	REQUIRE(rdclass == 1);
39
40	UNUSED(type);
41	UNUSED(origin);
42	UNUSED(options);
43	UNUSED(rdclass);
44
45	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
46				      ISC_FALSE));
47
48	if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
49		RETTOK(DNS_R_BADDOTTEDQUAD);
50	isc_buffer_availableregion(target, &region);
51	if (region.length < 4)
52		return (ISC_R_NOSPACE);
53	memcpy(region.base, &addr, 4);
54	isc_buffer_add(target, 4);
55	return (ISC_R_SUCCESS);
56}
57
58static inline isc_result_t
59totext_in_a(ARGS_TOTEXT) {
60	isc_region_t region;
61
62	REQUIRE(rdata->type == 1);
63	REQUIRE(rdata->rdclass == 1);
64	REQUIRE(rdata->length == 4);
65
66	UNUSED(tctx);
67
68	dns_rdata_toregion(rdata, &region);
69	return (inet_totext(AF_INET, &region, target));
70}
71
72static inline isc_result_t
73fromwire_in_a(ARGS_FROMWIRE) {
74	isc_region_t sregion;
75	isc_region_t tregion;
76
77	REQUIRE(type == 1);
78	REQUIRE(rdclass == 1);
79
80	UNUSED(type);
81	UNUSED(dctx);
82	UNUSED(options);
83	UNUSED(rdclass);
84
85	isc_buffer_activeregion(source, &sregion);
86	isc_buffer_availableregion(target, &tregion);
87	if (sregion.length < 4)
88		return (ISC_R_UNEXPECTEDEND);
89	if (tregion.length < 4)
90		return (ISC_R_NOSPACE);
91
92	memcpy(tregion.base, sregion.base, 4);
93	isc_buffer_forward(source, 4);
94	isc_buffer_add(target, 4);
95	return (ISC_R_SUCCESS);
96}
97
98static inline isc_result_t
99towire_in_a(ARGS_TOWIRE) {
100	isc_region_t region;
101
102	REQUIRE(rdata->type == 1);
103	REQUIRE(rdata->rdclass == 1);
104	REQUIRE(rdata->length == 4);
105
106	UNUSED(cctx);
107
108	isc_buffer_availableregion(target, &region);
109	if (region.length < rdata->length)
110		return (ISC_R_NOSPACE);
111	memcpy(region.base, rdata->data, rdata->length);
112	isc_buffer_add(target, 4);
113	return (ISC_R_SUCCESS);
114}
115
116static inline int
117compare_in_a(ARGS_COMPARE) {
118	isc_region_t r1;
119	isc_region_t r2;
120
121	REQUIRE(rdata1->type == rdata2->type);
122	REQUIRE(rdata1->rdclass == rdata2->rdclass);
123	REQUIRE(rdata1->type == 1);
124	REQUIRE(rdata1->rdclass == 1);
125	REQUIRE(rdata1->length == 4);
126	REQUIRE(rdata2->length == 4);
127
128	dns_rdata_toregion(rdata1, &r1);
129	dns_rdata_toregion(rdata2, &r2);
130	return (isc_region_compare(&r1, &r2));
131}
132
133static inline isc_result_t
134fromstruct_in_a(ARGS_FROMSTRUCT) {
135	dns_rdata_in_a_t *a = source;
136	isc_uint32_t n;
137
138	REQUIRE(type == 1);
139	REQUIRE(rdclass == 1);
140	REQUIRE(source != NULL);
141	REQUIRE(a->common.rdtype == type);
142	REQUIRE(a->common.rdclass == rdclass);
143
144	UNUSED(type);
145	UNUSED(rdclass);
146
147	n = ntohl(a->in_addr.s_addr);
148
149	return (uint32_tobuffer(n, target));
150}
151
152
153static inline isc_result_t
154tostruct_in_a(ARGS_TOSTRUCT) {
155	dns_rdata_in_a_t *a = target;
156	isc_uint32_t n;
157	isc_region_t region;
158
159	REQUIRE(rdata->type == 1);
160	REQUIRE(rdata->rdclass == 1);
161	REQUIRE(rdata->length == 4);
162
163	UNUSED(mctx);
164
165	a->common.rdclass = rdata->rdclass;
166	a->common.rdtype = rdata->type;
167	ISC_LINK_INIT(&a->common, link);
168
169	dns_rdata_toregion(rdata, &region);
170	n = uint32_fromregion(&region);
171	a->in_addr.s_addr = htonl(n);
172
173	return (ISC_R_SUCCESS);
174}
175
176static inline void
177freestruct_in_a(ARGS_FREESTRUCT) {
178	dns_rdata_in_a_t *a = source;
179
180	REQUIRE(source != NULL);
181	REQUIRE(a->common.rdtype == 1);
182	REQUIRE(a->common.rdclass == 1);
183
184	UNUSED(a);
185}
186
187static inline isc_result_t
188additionaldata_in_a(ARGS_ADDLDATA) {
189	REQUIRE(rdata->type == 1);
190	REQUIRE(rdata->rdclass == 1);
191
192	UNUSED(rdata);
193	UNUSED(add);
194	UNUSED(arg);
195
196	return (ISC_R_SUCCESS);
197}
198
199static inline isc_result_t
200digest_in_a(ARGS_DIGEST) {
201	isc_region_t r;
202
203	REQUIRE(rdata->type == 1);
204	REQUIRE(rdata->rdclass == 1);
205
206	dns_rdata_toregion(rdata, &r);
207
208	return ((digest)(arg, &r));
209}
210
211static inline isc_boolean_t
212checkowner_in_a(ARGS_CHECKOWNER) {
213
214	REQUIRE(type == 1);
215	REQUIRE(rdclass == 1);
216
217	UNUSED(type);
218	UNUSED(rdclass);
219
220	return (dns_name_ishostname(name, wildcard));
221}
222
223static inline isc_boolean_t
224checknames_in_a(ARGS_CHECKNAMES) {
225
226	REQUIRE(rdata->type == 1);
227	REQUIRE(rdata->rdclass == 1);
228
229	UNUSED(rdata);
230	UNUSED(owner);
231	UNUSED(bad);
232
233	return (ISC_TRUE);
234}
235
236static inline int
237casecompare_in_a(ARGS_COMPARE) {
238	return (compare_in_a(rdata1, rdata2));
239}
240
241#endif	/* RDATA_IN_1_A_1_C */
242