1 /* $NetBSD: nxt_30.c,v 1.4 2014/12/10 04:37:59 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: nxt_30.c,v 1.65 2009/12/04 22:06:37 tbox Exp */
22 /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
26 #ifndef RDATA_GENERIC_NXT_30_C
27 #define RDATA_GENERIC_NXT_30_C
30 * The attributes do not include DNS_RDATATYPEATTR_SINGLETON
31 * because we must be able to handle a parent/child NXT pair.
33 #define RRTYPE_NXT_ATTRIBUTES (0)
35 static inline isc_result_t
36 fromtext_nxt(ARGS_FROMTEXT
) {
41 unsigned char bm
[8*1024]; /* 64k bits */
42 dns_rdatatype_t covered
;
43 dns_rdatatype_t maxcovered
= 0;
44 isc_boolean_t first
= ISC_TRUE
;
56 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
58 dns_name_init(&name
, NULL
);
59 buffer_fromregion(&buffer
, &token
.value
.as_region
);
60 origin
= (origin
!= NULL
) ? origin
: dns_rootname
;
61 RETTOK(dns_name_fromtext(&name
, &buffer
, origin
, options
, target
));
63 memset(bm
, 0, sizeof(bm
));
65 RETERR(isc_lex_getmastertoken(lexer
, &token
,
66 isc_tokentype_string
, ISC_TRUE
));
67 if (token
.type
!= isc_tokentype_string
)
69 n
= strtol(DNS_AS_STR(token
), &e
, 10);
70 if (e
!= DNS_AS_STR(token
) && *e
== '\0') {
71 covered
= (dns_rdatatype_t
)n
;
72 } else if (dns_rdatatype_fromtext(&covered
,
73 &token
.value
.as_textregion
) == DNS_R_UNKNOWN
)
74 RETTOK(DNS_R_UNKNOWN
);
76 * NXT is only specified for types 1..127.
78 if (covered
< 1 || covered
> 127)
80 if (first
|| covered
> maxcovered
)
83 bm
[covered
/8] |= (0x80>>(covered
%8));
85 isc_lex_ungettoken(lexer
, &token
);
87 return (ISC_R_SUCCESS
);
88 n
= (maxcovered
+ 8) / 8;
89 return (mem_tobuffer(target
, bm
, n
));
92 static inline isc_result_t
93 totext_nxt(ARGS_TOTEXT
) {
100 REQUIRE(rdata
->type
== 30);
101 REQUIRE(rdata
->length
!= 0);
103 dns_name_init(&name
, NULL
);
104 dns_name_init(&prefix
, NULL
);
105 dns_rdata_toregion(rdata
, &sr
);
106 dns_name_fromregion(&name
, &sr
);
107 isc_region_consume(&sr
, name_length(&name
));
108 sub
= name_prefix(&name
, tctx
->origin
, &prefix
);
109 RETERR(dns_name_totext(&prefix
, sub
, target
));
111 for (i
= 0; i
< sr
.length
; i
++) {
113 for (j
= 0; j
< 8; j
++)
114 if ((sr
.base
[i
] & (0x80 >> j
)) != 0) {
115 dns_rdatatype_t t
= i
* 8 + j
;
116 RETERR(str_totext(" ", target
));
117 if (dns_rdatatype_isknown(t
)) {
118 RETERR(dns_rdatatype_totext(t
,
121 char buf
[sizeof("65535")];
122 sprintf(buf
, "%u", t
);
123 RETERR(str_totext(buf
,
128 return (ISC_R_SUCCESS
);
131 static inline isc_result_t
132 fromwire_nxt(ARGS_FROMWIRE
) {
141 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
143 dns_name_init(&name
, NULL
);
144 RETERR(dns_name_fromwire(&name
, source
, dctx
, options
, target
));
146 isc_buffer_activeregion(source
, &sr
);
147 if (sr
.length
> 0 && (sr
.base
[0] & 0x80) == 0 &&
148 ((sr
.length
> 16) || sr
.base
[sr
.length
- 1] == 0))
149 return (DNS_R_BADBITMAP
);
150 RETERR(mem_tobuffer(target
, sr
.base
, sr
.length
));
151 isc_buffer_forward(source
, sr
.length
);
152 return (ISC_R_SUCCESS
);
155 static inline isc_result_t
156 towire_nxt(ARGS_TOWIRE
) {
159 dns_offsets_t offsets
;
161 REQUIRE(rdata
->type
== 30);
162 REQUIRE(rdata
->length
!= 0);
164 dns_compress_setmethods(cctx
, DNS_COMPRESS_NONE
);
165 dns_name_init(&name
, offsets
);
166 dns_rdata_toregion(rdata
, &sr
);
167 dns_name_fromregion(&name
, &sr
);
168 isc_region_consume(&sr
, name_length(&name
));
169 RETERR(dns_name_towire(&name
, cctx
, target
));
171 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
175 compare_nxt(ARGS_COMPARE
) {
182 REQUIRE(rdata1
->type
== rdata2
->type
);
183 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
184 REQUIRE(rdata1
->type
== 30);
185 REQUIRE(rdata1
->length
!= 0);
186 REQUIRE(rdata2
->length
!= 0);
188 dns_name_init(&name1
, NULL
);
189 dns_name_init(&name2
, NULL
);
190 dns_rdata_toregion(rdata1
, &r1
);
191 dns_rdata_toregion(rdata2
, &r2
);
192 dns_name_fromregion(&name1
, &r1
);
193 dns_name_fromregion(&name2
, &r2
);
194 order
= dns_name_rdatacompare(&name1
, &name2
);
198 return (isc_region_compare(&r1
, &r2
));
201 static inline isc_result_t
202 fromstruct_nxt(ARGS_FROMSTRUCT
) {
203 dns_rdata_nxt_t
*nxt
= source
;
207 REQUIRE(source
!= NULL
);
208 REQUIRE(nxt
->common
.rdtype
== type
);
209 REQUIRE(nxt
->common
.rdclass
== rdclass
);
210 REQUIRE(nxt
->typebits
!= NULL
|| nxt
->len
== 0);
211 if (nxt
->typebits
!= NULL
&& (nxt
->typebits
[0] & 0x80) == 0) {
212 REQUIRE(nxt
->len
<= 16);
213 REQUIRE(nxt
->typebits
[nxt
->len
- 1] != 0);
219 dns_name_toregion(&nxt
->next
, ®ion
);
220 RETERR(isc_buffer_copyregion(target
, ®ion
));
222 return (mem_tobuffer(target
, nxt
->typebits
, nxt
->len
));
225 static inline isc_result_t
226 tostruct_nxt(ARGS_TOSTRUCT
) {
228 dns_rdata_nxt_t
*nxt
= target
;
231 REQUIRE(rdata
->type
== 30);
232 REQUIRE(target
!= NULL
);
233 REQUIRE(rdata
->length
!= 0);
235 nxt
->common
.rdclass
= rdata
->rdclass
;
236 nxt
->common
.rdtype
= rdata
->type
;
237 ISC_LINK_INIT(&nxt
->common
, link
);
239 dns_name_init(&name
, NULL
);
240 dns_rdata_toregion(rdata
, ®ion
);
241 dns_name_fromregion(&name
, ®ion
);
242 isc_region_consume(®ion
, name_length(&name
));
243 dns_name_init(&nxt
->next
, NULL
);
244 RETERR(name_duporclone(&name
, mctx
, &nxt
->next
));
246 nxt
->len
= region
.length
;
247 nxt
->typebits
= mem_maybedup(mctx
, region
.base
, region
.length
);
248 if (nxt
->typebits
== NULL
)
252 return (ISC_R_SUCCESS
);
256 dns_name_free(&nxt
->next
, mctx
);
257 return (ISC_R_NOMEMORY
);
261 freestruct_nxt(ARGS_FREESTRUCT
) {
262 dns_rdata_nxt_t
*nxt
= source
;
264 REQUIRE(source
!= NULL
);
265 REQUIRE(nxt
->common
.rdtype
== 30);
267 if (nxt
->mctx
== NULL
)
270 dns_name_free(&nxt
->next
, nxt
->mctx
);
271 if (nxt
->typebits
!= NULL
)
272 isc_mem_free(nxt
->mctx
, nxt
->typebits
);
276 static inline isc_result_t
277 additionaldata_nxt(ARGS_ADDLDATA
) {
278 REQUIRE(rdata
->type
== 30);
284 return (ISC_R_SUCCESS
);
287 static inline isc_result_t
288 digest_nxt(ARGS_DIGEST
) {
293 REQUIRE(rdata
->type
== 30);
295 dns_rdata_toregion(rdata
, &r
);
296 dns_name_init(&name
, NULL
);
297 dns_name_fromregion(&name
, &r
);
298 result
= dns_name_digest(&name
, digest
, arg
);
299 if (result
!= ISC_R_SUCCESS
)
301 isc_region_consume(&r
, name_length(&name
));
303 return ((digest
)(arg
, &r
));
306 static inline isc_boolean_t
307 checkowner_nxt(ARGS_CHECKOWNER
) {
319 static inline isc_boolean_t
320 checknames_nxt(ARGS_CHECKNAMES
) {
322 REQUIRE(rdata
->type
== 30);
332 casecompare_nxt(ARGS_COMPARE
) {
333 return (compare_nxt(rdata1
, rdata2
));
335 #endif /* RDATA_GENERIC_NXT_30_C */