2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and 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.
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.
18 /* $Id: soa_6.c,v 1.53.2.1 2004/03/09 06:11:34 marka Exp $ */
20 /* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */
22 #ifndef RDATA_GENERIC_SOA_6_C
23 #define RDATA_GENERIC_SOA_6_C
25 #define RRTYPE_SOA_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON)
27 static inline isc_result_t
28 fromtext_soa(ARGS_FROMTEXT
) {
41 origin
= (origin
!= NULL
) ? origin
: dns_rootname
;
43 for (i
= 0 ; i
< 2 ; i
++) {
44 RETERR(isc_lex_getmastertoken(lexer
, &token
,
48 dns_name_init(&name
, NULL
);
49 buffer_fromregion(&buffer
, &token
.value
.as_region
);
50 RETTOK(dns_name_fromtext(&name
, &buffer
, origin
,
54 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
56 RETERR(uint32_tobuffer(token
.value
.as_ulong
, target
));
58 for (i
= 0; i
< 4; i
++) {
59 RETERR(isc_lex_getmastertoken(lexer
, &token
,
62 RETTOK(dns_counter_fromtext(&token
.value
.as_textregion
, &n
));
63 RETERR(uint32_tobuffer(n
, target
));
66 return (ISC_R_SUCCESS
);
69 static const char *soa_fieldnames
[5] = {
70 "serial", "refresh", "retry", "expire", "minimum"
73 static inline isc_result_t
74 totext_soa(ARGS_TOTEXT
) {
81 isc_boolean_t multiline
;
82 isc_boolean_t comment
;
84 REQUIRE(rdata
->type
== 6);
85 REQUIRE(rdata
->length
!= 0);
87 multiline
= ISC_TF((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0);
88 comment
= ISC_TF((tctx
->flags
& DNS_STYLEFLAG_COMMENT
) != 0);
90 dns_name_init(&mname
, NULL
);
91 dns_name_init(&rname
, NULL
);
92 dns_name_init(&prefix
, NULL
);
94 dns_rdata_toregion(rdata
, &dregion
);
96 dns_name_fromregion(&mname
, &dregion
);
97 isc_region_consume(&dregion
, name_length(&mname
));
99 dns_name_fromregion(&rname
, &dregion
);
100 isc_region_consume(&dregion
, name_length(&rname
));
102 sub
= name_prefix(&mname
, tctx
->origin
, &prefix
);
103 RETERR(dns_name_totext(&prefix
, sub
, target
));
105 RETERR(str_totext(" ", target
));
107 sub
= name_prefix(&rname
, tctx
->origin
, &prefix
);
108 RETERR(dns_name_totext(&prefix
, sub
, target
));
111 RETERR(str_totext(" (" , target
));
112 RETERR(str_totext(tctx
->linebreak
, target
));
114 for (i
= 0; i
< 5 ; i
++) {
115 char buf
[sizeof "2147483647"];
118 num
= uint32_fromregion(&dregion
);
119 isc_region_consume(&dregion
, 4);
120 numlen
= sprintf(buf
, "%lu", num
);
121 INSIST(numlen
> 0 && numlen
< sizeof "2147483647");
122 RETERR(str_totext(buf
, target
));
123 if (multiline
&& comment
) {
124 RETERR(str_totext(" ; " + numlen
, target
));
125 RETERR(str_totext(soa_fieldnames
[i
], target
));
126 /* Print times in week/day/hour/minute/second form */
128 RETERR(str_totext(" (", target
));
129 RETERR(dns_ttl_totext(num
, ISC_TRUE
, target
));
130 RETERR(str_totext(")", target
));
132 RETERR(str_totext(tctx
->linebreak
, target
));
134 RETERR(str_totext(tctx
->linebreak
, target
));
139 RETERR(str_totext(")", target
));
141 return (ISC_R_SUCCESS
);
144 static inline isc_result_t
145 fromwire_soa(ARGS_FROMWIRE
) {
148 isc_region_t sregion
;
149 isc_region_t tregion
;
156 dns_decompress_setmethods(dctx
, DNS_COMPRESS_GLOBAL14
);
158 dns_name_init(&mname
, NULL
);
159 dns_name_init(&rname
, NULL
);
161 RETERR(dns_name_fromwire(&mname
, source
, dctx
, downcase
, target
));
162 RETERR(dns_name_fromwire(&rname
, source
, dctx
, downcase
, target
));
164 isc_buffer_activeregion(source
, &sregion
);
165 isc_buffer_availableregion(target
, &tregion
);
167 if (sregion
.length
< 20)
168 return (ISC_R_UNEXPECTEDEND
);
169 if (tregion
.length
< 20)
170 return (ISC_R_NOSPACE
);
172 memcpy(tregion
.base
, sregion
.base
, 20);
173 isc_buffer_forward(source
, 20);
174 isc_buffer_add(target
, 20);
176 return (ISC_R_SUCCESS
);
179 static inline isc_result_t
180 towire_soa(ARGS_TOWIRE
) {
181 isc_region_t sregion
;
182 isc_region_t tregion
;
185 dns_offsets_t moffsets
;
186 dns_offsets_t roffsets
;
188 REQUIRE(rdata
->type
== 6);
189 REQUIRE(rdata
->length
!= 0);
191 dns_compress_setmethods(cctx
, DNS_COMPRESS_GLOBAL14
);
193 dns_name_init(&mname
, moffsets
);
194 dns_name_init(&rname
, roffsets
);
196 dns_rdata_toregion(rdata
, &sregion
);
198 dns_name_fromregion(&mname
, &sregion
);
199 isc_region_consume(&sregion
, name_length(&mname
));
200 RETERR(dns_name_towire(&mname
, cctx
, target
));
202 dns_name_fromregion(&rname
, &sregion
);
203 isc_region_consume(&sregion
, name_length(&rname
));
204 RETERR(dns_name_towire(&rname
, cctx
, target
));
206 isc_buffer_availableregion(target
, &tregion
);
207 if (tregion
.length
< 20)
208 return (ISC_R_NOSPACE
);
210 memcpy(tregion
.base
, sregion
.base
, 20);
211 isc_buffer_add(target
, 20);
212 return (ISC_R_SUCCESS
);
216 compare_soa(ARGS_COMPARE
) {
217 isc_region_t region1
;
218 isc_region_t region2
;
223 REQUIRE(rdata1
->type
== rdata2
->type
);
224 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
225 REQUIRE(rdata1
->type
== 6);
226 REQUIRE(rdata1
->length
!= 0);
227 REQUIRE(rdata2
->length
!= 0);
229 dns_name_init(&name1
, NULL
);
230 dns_name_init(&name2
, NULL
);
232 dns_rdata_toregion(rdata1
, ®ion1
);
233 dns_rdata_toregion(rdata2
, ®ion2
);
235 dns_name_fromregion(&name1
, ®ion1
);
236 dns_name_fromregion(&name2
, ®ion2
);
238 order
= dns_name_rdatacompare(&name1
, &name2
);
242 isc_region_consume(®ion1
, name_length(&name1
));
243 isc_region_consume(®ion2
, name_length(&name2
));
245 dns_name_init(&name1
, NULL
);
246 dns_name_init(&name2
, NULL
);
248 dns_name_fromregion(&name1
, ®ion1
);
249 dns_name_fromregion(&name2
, ®ion2
);
251 order
= dns_name_rdatacompare(&name1
, &name2
);
255 isc_region_consume(®ion1
, name_length(&name1
));
256 isc_region_consume(®ion2
, name_length(&name2
));
258 return (compare_region(®ion1
, ®ion2
));
261 static inline isc_result_t
262 fromstruct_soa(ARGS_FROMSTRUCT
) {
263 dns_rdata_soa_t
*soa
= source
;
267 REQUIRE(source
!= NULL
);
268 REQUIRE(soa
->common
.rdtype
== type
);
269 REQUIRE(soa
->common
.rdclass
== rdclass
);
274 dns_name_toregion(&soa
->origin
, ®ion
);
275 RETERR(isc_buffer_copyregion(target
, ®ion
));
276 dns_name_toregion(&soa
->contact
, ®ion
);
277 RETERR(isc_buffer_copyregion(target
, ®ion
));
278 RETERR(uint32_tobuffer(soa
->serial
, target
));
279 RETERR(uint32_tobuffer(soa
->refresh
, target
));
280 RETERR(uint32_tobuffer(soa
->retry
, target
));
281 RETERR(uint32_tobuffer(soa
->expire
, target
));
282 return (uint32_tobuffer(soa
->minimum
, target
));
285 static inline isc_result_t
286 tostruct_soa(ARGS_TOSTRUCT
) {
288 dns_rdata_soa_t
*soa
= target
;
292 REQUIRE(rdata
->type
== 6);
293 REQUIRE(target
!= NULL
);
294 REQUIRE(rdata
->length
!= 0);
296 soa
->common
.rdclass
= rdata
->rdclass
;
297 soa
->common
.rdtype
= rdata
->type
;
298 ISC_LINK_INIT(&soa
->common
, link
);
301 dns_rdata_toregion(rdata
, ®ion
);
303 dns_name_init(&name
, NULL
);
304 dns_name_fromregion(&name
, ®ion
);
305 isc_region_consume(®ion
, name_length(&name
));
306 dns_name_init(&soa
->origin
, NULL
);
307 RETERR(name_duporclone(&name
, mctx
, &soa
->origin
));
309 dns_name_fromregion(&name
, ®ion
);
310 isc_region_consume(®ion
, name_length(&name
));
311 dns_name_init(&soa
->contact
, NULL
);
312 result
= name_duporclone(&name
, mctx
, &soa
->contact
);
313 if (result
!= ISC_R_SUCCESS
)
316 soa
->serial
= uint32_fromregion(®ion
);
317 isc_region_consume(®ion
, 4);
319 soa
->refresh
= uint32_fromregion(®ion
);
320 isc_region_consume(®ion
, 4);
322 soa
->retry
= uint32_fromregion(®ion
);
323 isc_region_consume(®ion
, 4);
325 soa
->expire
= uint32_fromregion(®ion
);
326 isc_region_consume(®ion
, 4);
328 soa
->minimum
= uint32_fromregion(®ion
);
331 return (ISC_R_SUCCESS
);
335 dns_name_free(&soa
->origin
, mctx
);
336 return (ISC_R_NOMEMORY
);
340 freestruct_soa(ARGS_FREESTRUCT
) {
341 dns_rdata_soa_t
*soa
= source
;
343 REQUIRE(source
!= NULL
);
344 REQUIRE(soa
->common
.rdtype
== 6);
346 if (soa
->mctx
== NULL
)
349 dns_name_free(&soa
->origin
, soa
->mctx
);
350 dns_name_free(&soa
->contact
, soa
->mctx
);
354 static inline isc_result_t
355 additionaldata_soa(ARGS_ADDLDATA
) {
360 REQUIRE(rdata
->type
== 6);
362 return (ISC_R_SUCCESS
);
365 static inline isc_result_t
366 digest_soa(ARGS_DIGEST
) {
370 REQUIRE(rdata
->type
== 6);
372 dns_rdata_toregion(rdata
, &r
);
374 dns_name_init(&name
, NULL
);
375 dns_name_fromregion(&name
, &r
);
376 RETERR(dns_name_digest(&name
, digest
, arg
));
377 isc_region_consume(&r
, name_length(&name
));
379 dns_name_init(&name
, NULL
);
380 dns_name_fromregion(&name
, &r
);
381 RETERR(dns_name_digest(&name
, digest
, arg
));
382 isc_region_consume(&r
, name_length(&name
));
384 return ((digest
)(arg
, &r
));
387 #endif /* RDATA_GENERIC_SOA_6_C */