2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001, 2003 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: a6_38.c,v 1.46.2.3 2004/03/09 06:11:35 marka Exp $ */
22 #ifndef RDATA_IN_1_A6_28_C
23 #define RDATA_IN_1_A6_28_C
27 #define RRTYPE_A6_ATTRIBUTES (0)
29 static inline isc_result_t
30 fromtext_in_a6(ARGS_FROMTEXT
) {
32 unsigned char addr
[16];
33 unsigned char prefixlen
;
40 REQUIRE(rdclass
== 1);
49 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
51 if (token
.value
.as_ulong
> 128U)
54 prefixlen
= (unsigned char)token
.value
.as_ulong
;
55 RETERR(mem_tobuffer(target
, &prefixlen
, 1));
60 if (prefixlen
!= 128) {
68 RETERR(isc_lex_getmastertoken(lexer
, &token
,
71 if (inet_pton(AF_INET6
, token
.value
.as_pointer
, addr
) != 1)
72 RETTOK(DNS_R_BADAAAA
);
73 mask
= 0xff >> (prefixlen
% 8);
75 RETERR(mem_tobuffer(target
, &addr
[octets
], 16 - octets
));
79 return (ISC_R_SUCCESS
);
81 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
83 dns_name_init(&name
, NULL
);
84 buffer_fromregion(&buffer
, &token
.value
.as_region
);
85 origin
= (origin
!= NULL
) ? origin
: dns_rootname
;
86 RETTOK(dns_name_fromtext(&name
, &buffer
, origin
, downcase
, target
));
87 return (ISC_R_SUCCESS
);
90 static inline isc_result_t
91 totext_in_a6(ARGS_TOTEXT
) {
93 unsigned char addr
[16];
94 unsigned char prefixlen
;
97 char buf
[sizeof "128"];
102 REQUIRE(rdata
->type
== 38);
103 REQUIRE(rdata
->rdclass
== 1);
104 REQUIRE(rdata
->length
!= 0);
106 dns_rdata_toregion(rdata
, &sr
);
107 prefixlen
= sr
.base
[0];
108 INSIST(prefixlen
<= 128);
109 isc_region_consume(&sr
, 1);
110 sprintf(buf
, "%u", prefixlen
);
111 RETERR(str_totext(buf
, target
));
112 RETERR(str_totext(" ", target
));
114 if (prefixlen
!= 128) {
115 octets
= prefixlen
/8;
116 memset(addr
, 0, sizeof addr
);
117 memcpy(&addr
[octets
], sr
.base
, 16 - octets
);
118 mask
= 0xff >> (prefixlen
% 8);
119 addr
[octets
] &= mask
;
121 ar
.length
= sizeof(addr
);
122 RETERR(inet_totext(AF_INET6
, &ar
, target
));
123 isc_region_consume(&sr
, 16 - octets
);
127 return (ISC_R_SUCCESS
);
129 RETERR(str_totext(" ", target
));
130 dns_name_init(&name
, NULL
);
131 dns_name_init(&prefix
, NULL
);
132 dns_name_fromregion(&name
, &sr
);
133 sub
= name_prefix(&name
, tctx
->origin
, &prefix
);
134 return (dns_name_totext(&prefix
, sub
, target
));
137 static inline isc_result_t
138 fromwire_in_a6(ARGS_FROMWIRE
) {
140 unsigned char prefixlen
;
141 unsigned char octets
;
146 REQUIRE(rdclass
== 1);
151 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
153 isc_buffer_activeregion(source
, &sr
);
158 return (ISC_R_UNEXPECTEDEND
);
159 prefixlen
= sr
.base
[0];
161 return (ISC_R_RANGE
);
162 isc_region_consume(&sr
, 1);
163 RETERR(mem_tobuffer(target
, &prefixlen
, 1));
164 isc_buffer_forward(source
, 1);
169 if (prefixlen
!= 128) {
170 octets
= 16 - prefixlen
/ 8;
171 if (sr
.length
< octets
)
172 return (ISC_R_UNEXPECTEDEND
);
173 mask
= 0xff >> (prefixlen
% 8);
174 sr
.base
[0] &= mask
; /* Ensure pad bits are zero. */
175 RETERR(mem_tobuffer(target
, sr
.base
, octets
));
176 isc_buffer_forward(source
, octets
);
180 return (ISC_R_SUCCESS
);
182 dns_name_init(&name
, NULL
);
183 return (dns_name_fromwire(&name
, source
, dctx
, downcase
, target
));
186 static inline isc_result_t
187 towire_in_a6(ARGS_TOWIRE
) {
190 dns_offsets_t offsets
;
191 unsigned char prefixlen
;
192 unsigned char octets
;
194 REQUIRE(rdata
->type
== 38);
195 REQUIRE(rdata
->rdclass
== 1);
196 REQUIRE(rdata
->length
!= 0);
198 dns_compress_setmethods(cctx
, DNS_COMPRESS_NONE
);
199 dns_rdata_toregion(rdata
, &sr
);
200 prefixlen
= sr
.base
[0];
201 INSIST(prefixlen
<= 128);
203 octets
= 1 + 16 - prefixlen
/ 8;
204 RETERR(mem_tobuffer(target
, sr
.base
, octets
));
205 isc_region_consume(&sr
, octets
);
208 return (ISC_R_SUCCESS
);
210 dns_name_init(&name
, offsets
);
211 dns_name_fromregion(&name
, &sr
);
212 return (dns_name_towire(&name
, cctx
, target
));
216 compare_in_a6(ARGS_COMPARE
) {
218 unsigned char prefixlen1
, prefixlen2
;
219 unsigned char octets
;
222 isc_region_t region1
;
223 isc_region_t region2
;
225 REQUIRE(rdata1
->type
== rdata2
->type
);
226 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
227 REQUIRE(rdata1
->type
== 38);
228 REQUIRE(rdata1
->rdclass
== 1);
229 REQUIRE(rdata1
->length
!= 0);
230 REQUIRE(rdata2
->length
!= 0);
232 dns_rdata_toregion(rdata1
, ®ion1
);
233 dns_rdata_toregion(rdata2
, ®ion2
);
234 prefixlen1
= region1
.base
[0];
235 prefixlen2
= region2
.base
[0];
236 isc_region_consume(®ion1
, 1);
237 isc_region_consume(®ion2
, 1);
238 if (prefixlen1
< prefixlen2
)
240 else if (prefixlen1
> prefixlen2
)
243 * Prefix lengths are equal.
245 octets
= 16 - prefixlen1
/ 8;
248 order
= memcmp(region1
.base
, region2
.base
, octets
);
254 * Address suffixes are equal.
258 isc_region_consume(®ion1
, octets
);
259 isc_region_consume(®ion2
, octets
);
262 dns_name_init(&name1
, NULL
);
263 dns_name_init(&name2
, NULL
);
264 dns_name_fromregion(&name1
, ®ion1
);
265 dns_name_fromregion(&name2
, ®ion2
);
266 return (dns_name_rdatacompare(&name1
, &name2
));
269 static inline isc_result_t
270 fromstruct_in_a6(ARGS_FROMSTRUCT
) {
271 dns_rdata_in_a6_t
*a6
= source
;
279 REQUIRE(rdclass
== 1);
280 REQUIRE(source
!= NULL
);
281 REQUIRE(a6
->common
.rdtype
== type
);
282 REQUIRE(a6
->common
.rdclass
== rdclass
);
287 if (a6
->prefixlen
> 128)
288 return (ISC_R_RANGE
);
290 RETERR(uint8_tobuffer(a6
->prefixlen
, target
));
293 if (a6
->prefixlen
!= 128) {
294 octets
= 16 - a6
->prefixlen
/ 8;
295 bits
= a6
->prefixlen
% 8;
297 mask
= 0xffU
>> bits
;
298 first
= a6
->in6_addr
.s6_addr
[16 - octets
] & mask
;
299 RETERR(uint8_tobuffer(first
, target
));
303 RETERR(mem_tobuffer(target
,
304 a6
->in6_addr
.s6_addr
+ 16 - octets
,
308 if (a6
->prefixlen
== 0)
309 return (ISC_R_SUCCESS
);
310 dns_name_toregion(&a6
->prefix
, ®ion
);
311 return (isc_buffer_copyregion(target
, ®ion
));
314 static inline isc_result_t
315 tostruct_in_a6(ARGS_TOSTRUCT
) {
316 dns_rdata_in_a6_t
*a6
= target
;
317 unsigned char octets
;
321 REQUIRE(rdata
->type
== 38);
322 REQUIRE(rdata
->rdclass
== 1);
323 REQUIRE(target
!= NULL
);
324 REQUIRE(rdata
->length
!= 0);
326 a6
->common
.rdclass
= rdata
->rdclass
;
327 a6
->common
.rdtype
= rdata
->type
;
328 ISC_LINK_INIT(&a6
->common
, link
);
330 dns_rdata_toregion(rdata
, &r
);
332 a6
->prefixlen
= uint8_fromregion(&r
);
333 isc_region_consume(&r
, 1);
334 memset(a6
->in6_addr
.s6_addr
, 0, sizeof(a6
->in6_addr
.s6_addr
));
339 if (a6
->prefixlen
!= 128) {
340 octets
= 16 - a6
->prefixlen
/ 8;
341 INSIST(r
.length
>= octets
);
342 memcpy(a6
->in6_addr
.s6_addr
+ 16 - octets
, r
.base
, octets
);
343 isc_region_consume(&r
, octets
);
349 dns_name_init(&a6
->prefix
, NULL
);
350 if (a6
->prefixlen
!= 0) {
351 dns_name_init(&name
, NULL
);
352 dns_name_fromregion(&name
, &r
);
353 RETERR(name_duporclone(&name
, mctx
, &a6
->prefix
));
356 return (ISC_R_SUCCESS
);
360 freestruct_in_a6(ARGS_FREESTRUCT
) {
361 dns_rdata_in_a6_t
*a6
= source
;
363 REQUIRE(source
!= NULL
);
364 REQUIRE(a6
->common
.rdclass
== 1);
365 REQUIRE(a6
->common
.rdtype
== 38);
367 if (a6
->mctx
== NULL
)
370 if (dns_name_dynamic(&a6
->prefix
))
371 dns_name_free(&a6
->prefix
, a6
->mctx
);
375 static inline isc_result_t
376 additionaldata_in_a6(ARGS_ADDLDATA
) {
377 REQUIRE(rdata
->type
== 38);
378 REQUIRE(rdata
->rdclass
== 1);
384 return (ISC_R_SUCCESS
);
387 static inline isc_result_t
388 digest_in_a6(ARGS_DIGEST
) {
390 unsigned char prefixlen
, octets
;
394 REQUIRE(rdata
->type
== 38);
395 REQUIRE(rdata
->rdclass
== 1);
397 dns_rdata_toregion(rdata
, &r1
);
399 prefixlen
= r1
.base
[0];
400 octets
= 1 + 16 - prefixlen
/ 8;
403 result
= (digest
)(arg
, &r1
);
404 if (result
!= ISC_R_SUCCESS
)
407 return (ISC_R_SUCCESS
);
409 isc_region_consume(&r2
, octets
);
410 dns_name_init(&name
, NULL
);
411 dns_name_fromregion(&name
, &r2
);
412 return (dns_name_digest(&name
, digest
, arg
));
415 #endif /* RDATA_IN_1_A6_38_C */