2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
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.
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: nxt_30.c,v 1.63 2007/06/19 23:47:17 tbox Exp $ */
20 /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
24 #ifndef RDATA_GENERIC_NXT_30_C
25 #define RDATA_GENERIC_NXT_30_C
28 * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
29 * because we must be able to handle a parent/child NXT pair.
31 #define RRTYPE_NXT_ATTRIBUTES (0)
33 static inline isc_result_t
34 fromtext_nxt(ARGS_FROMTEXT
) {
39 unsigned char bm
[8*1024]; /* 64k bits */
40 dns_rdatatype_t covered
;
41 dns_rdatatype_t maxcovered
= 0;
42 isc_boolean_t first
= ISC_TRUE
;
54 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
56 dns_name_init(&name
, NULL
);
57 buffer_fromregion(&buffer
, &token
.value
.as_region
);
58 origin
= (origin
!= NULL
) ? origin
: dns_rootname
;
59 RETTOK(dns_name_fromtext(&name
, &buffer
, origin
, options
, target
));
61 memset(bm
, 0, sizeof(bm
));
63 RETERR(isc_lex_getmastertoken(lexer
, &token
,
64 isc_tokentype_string
, ISC_TRUE
));
65 if (token
.type
!= isc_tokentype_string
)
67 n
= strtol(DNS_AS_STR(token
), &e
, 10);
68 if (e
!= DNS_AS_STR(token
) && *e
== '\0') {
69 covered
= (dns_rdatatype_t
)n
;
70 } else if (dns_rdatatype_fromtext(&covered
,
71 &token
.value
.as_textregion
) == DNS_R_UNKNOWN
)
72 RETTOK(DNS_R_UNKNOWN
);
74 * NXT is only specified for types 1..127.
76 if (covered
< 1 || covered
> 127)
78 if (first
|| covered
> maxcovered
)
81 bm
[covered
/8] |= (0x80>>(covered
%8));
83 isc_lex_ungettoken(lexer
, &token
);
85 return (ISC_R_SUCCESS
);
86 n
= (maxcovered
+ 8) / 8;
87 return (mem_tobuffer(target
, bm
, n
));
90 static inline isc_result_t
91 totext_nxt(ARGS_TOTEXT
) {
98 REQUIRE(rdata
->type
== 30);
99 REQUIRE(rdata
->length
!= 0);
101 dns_name_init(&name
, NULL
);
102 dns_name_init(&prefix
, NULL
);
103 dns_rdata_toregion(rdata
, &sr
);
104 dns_name_fromregion(&name
, &sr
);
105 isc_region_consume(&sr
, name_length(&name
));
106 sub
= name_prefix(&name
, tctx
->origin
, &prefix
);
107 RETERR(dns_name_totext(&prefix
, sub
, target
));
109 for (i
= 0; i
< sr
.length
; i
++) {
111 for (j
= 0; j
< 8; j
++)
112 if ((sr
.base
[i
] & (0x80 >> j
)) != 0) {
113 dns_rdatatype_t t
= i
* 8 + j
;
114 RETERR(str_totext(" ", target
));
115 if (dns_rdatatype_isknown(t
)) {
116 RETERR(dns_rdatatype_totext(t
,
119 char buf
[sizeof("65535")];
120 sprintf(buf
, "%u", t
);
121 RETERR(str_totext(buf
,
126 return (ISC_R_SUCCESS
);
129 static inline isc_result_t
130 fromwire_nxt(ARGS_FROMWIRE
) {
139 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
141 dns_name_init(&name
, NULL
);
142 RETERR(dns_name_fromwire(&name
, source
, dctx
, options
, target
));
144 isc_buffer_activeregion(source
, &sr
);
145 if (sr
.length
> 0 && (sr
.base
[0] & 0x80) == 0 &&
146 ((sr
.length
> 16) || sr
.base
[sr
.length
- 1] == 0))
147 return (DNS_R_BADBITMAP
);
148 RETERR(mem_tobuffer(target
, sr
.base
, sr
.length
));
149 isc_buffer_forward(source
, sr
.length
);
150 return (ISC_R_SUCCESS
);
153 static inline isc_result_t
154 towire_nxt(ARGS_TOWIRE
) {
157 dns_offsets_t offsets
;
159 REQUIRE(rdata
->type
== 30);
160 REQUIRE(rdata
->length
!= 0);
162 dns_compress_setmethods(cctx
, DNS_COMPRESS_NONE
);
163 dns_name_init(&name
, offsets
);
164 dns_rdata_toregion(rdata
, &sr
);
165 dns_name_fromregion(&name
, &sr
);
166 isc_region_consume(&sr
, name_length(&name
));
167 RETERR(dns_name_towire(&name
, cctx
, target
));
169 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
173 compare_nxt(ARGS_COMPARE
) {
180 REQUIRE(rdata1
->type
== rdata2
->type
);
181 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
182 REQUIRE(rdata1
->type
== 30);
183 REQUIRE(rdata1
->length
!= 0);
184 REQUIRE(rdata2
->length
!= 0);
186 dns_name_init(&name1
, NULL
);
187 dns_name_init(&name2
, NULL
);
188 dns_rdata_toregion(rdata1
, &r1
);
189 dns_rdata_toregion(rdata2
, &r2
);
190 dns_name_fromregion(&name1
, &r1
);
191 dns_name_fromregion(&name2
, &r2
);
192 order
= dns_name_rdatacompare(&name1
, &name2
);
196 return (isc_region_compare(&r1
, &r2
));
199 static inline isc_result_t
200 fromstruct_nxt(ARGS_FROMSTRUCT
) {
201 dns_rdata_nxt_t
*nxt
= source
;
205 REQUIRE(source
!= NULL
);
206 REQUIRE(nxt
->common
.rdtype
== type
);
207 REQUIRE(nxt
->common
.rdclass
== rdclass
);
208 REQUIRE(nxt
->typebits
!= NULL
|| nxt
->len
== 0);
209 if (nxt
->typebits
!= NULL
&& (nxt
->typebits
[0] & 0x80) == 0) {
210 REQUIRE(nxt
->len
<= 16);
211 REQUIRE(nxt
->typebits
[nxt
->len
- 1] != 0);
217 dns_name_toregion(&nxt
->next
, ®ion
);
218 RETERR(isc_buffer_copyregion(target
, ®ion
));
220 return (mem_tobuffer(target
, nxt
->typebits
, nxt
->len
));
223 static inline isc_result_t
224 tostruct_nxt(ARGS_TOSTRUCT
) {
226 dns_rdata_nxt_t
*nxt
= target
;
229 REQUIRE(rdata
->type
== 30);
230 REQUIRE(target
!= NULL
);
231 REQUIRE(rdata
->length
!= 0);
233 nxt
->common
.rdclass
= rdata
->rdclass
;
234 nxt
->common
.rdtype
= rdata
->type
;
235 ISC_LINK_INIT(&nxt
->common
, link
);
237 dns_name_init(&name
, NULL
);
238 dns_rdata_toregion(rdata
, ®ion
);
239 dns_name_fromregion(&name
, ®ion
);
240 isc_region_consume(®ion
, name_length(&name
));
241 dns_name_init(&nxt
->next
, NULL
);
242 RETERR(name_duporclone(&name
, mctx
, &nxt
->next
));
244 nxt
->len
= region
.length
;
245 nxt
->typebits
= mem_maybedup(mctx
, region
.base
, region
.length
);
246 if (nxt
->typebits
== NULL
)
250 return (ISC_R_SUCCESS
);
254 dns_name_free(&nxt
->next
, mctx
);
255 return (ISC_R_NOMEMORY
);
259 freestruct_nxt(ARGS_FREESTRUCT
) {
260 dns_rdata_nxt_t
*nxt
= source
;
262 REQUIRE(source
!= NULL
);
263 REQUIRE(nxt
->common
.rdtype
== 30);
265 if (nxt
->mctx
== NULL
)
268 dns_name_free(&nxt
->next
, nxt
->mctx
);
269 if (nxt
->typebits
!= NULL
)
270 isc_mem_free(nxt
->mctx
, nxt
->typebits
);
274 static inline isc_result_t
275 additionaldata_nxt(ARGS_ADDLDATA
) {
276 REQUIRE(rdata
->type
== 30);
282 return (ISC_R_SUCCESS
);
285 static inline isc_result_t
286 digest_nxt(ARGS_DIGEST
) {
291 REQUIRE(rdata
->type
== 30);
293 dns_rdata_toregion(rdata
, &r
);
294 dns_name_init(&name
, NULL
);
295 dns_name_fromregion(&name
, &r
);
296 result
= dns_name_digest(&name
, digest
, arg
);
297 if (result
!= ISC_R_SUCCESS
)
299 isc_region_consume(&r
, name_length(&name
));
301 return ((digest
)(arg
, &r
));
304 static inline isc_boolean_t
305 checkowner_nxt(ARGS_CHECKOWNER
) {
317 static inline isc_boolean_t
318 checknames_nxt(ARGS_CHECKNAMES
) {
320 REQUIRE(rdata
->type
== 30);
329 #endif /* RDATA_GENERIC_NXT_30_C */