1 /* $NetBSD: ipseckey_45.c,v 1.6 2014/12/10 04:37:59 christos Exp $ */
4 * Copyright (C) 2005, 2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
21 #ifndef RDATA_GENERIC_IPSECKEY_45_C
22 #define RDATA_GENERIC_IPSECKEY_45_C
28 #define RRTYPE_IPSECKEY_ATTRIBUTES (0)
30 static inline isc_result_t
31 fromtext_ipseckey(ARGS_FROMTEXT
) {
37 unsigned char addr6
[16];
49 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
51 if (token
.value
.as_ulong
> 0xffU
)
53 RETERR(uint8_tobuffer(token
.value
.as_ulong
, target
));
58 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
60 if (token
.value
.as_ulong
> 0x3U
)
62 RETERR(uint8_tobuffer(token
.value
.as_ulong
, target
));
63 gateway
= token
.value
.as_ulong
;
68 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
70 if (token
.value
.as_ulong
> 0xffU
)
72 RETERR(uint8_tobuffer(token
.value
.as_ulong
, target
));
77 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
82 if (strcmp(DNS_AS_STR(token
), ".") != 0)
87 if (getquad(DNS_AS_STR(token
), &addr
, lexer
, callbacks
) != 1)
88 RETTOK(DNS_R_BADDOTTEDQUAD
);
89 isc_buffer_availableregion(target
, ®ion
);
90 if (region
.length
< 4)
91 return (ISC_R_NOSPACE
);
92 memmove(region
.base
, &addr
, 4);
93 isc_buffer_add(target
, 4);
97 if (inet_pton(AF_INET6
, DNS_AS_STR(token
), addr6
) != 1)
98 RETTOK(DNS_R_BADAAAA
);
99 isc_buffer_availableregion(target
, ®ion
);
100 if (region
.length
< 16)
101 return (ISC_R_NOSPACE
);
102 memmove(region
.base
, addr6
, 16);
103 isc_buffer_add(target
, 16);
107 dns_name_init(&name
, NULL
);
108 buffer_fromregion(&buffer
, &token
.value
.as_region
);
109 origin
= (origin
!= NULL
) ? origin
: dns_rootname
;
110 RETTOK(dns_name_fromtext(&name
, &buffer
, origin
,
118 return (isc_base64_tobuffer(lexer
, target
, -1));
121 static inline isc_result_t
122 totext_ipseckey(ARGS_TOTEXT
) {
125 char buf
[sizeof("255 ")];
127 unsigned short gateway
;
129 REQUIRE(rdata
->type
== 45);
130 REQUIRE(rdata
->length
>= 3);
132 dns_name_init(&name
, NULL
);
134 if (rdata
->data
[1] > 3U)
135 return (ISC_R_NOTIMPLEMENTED
);
137 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
138 RETERR(str_totext("( ", target
));
143 dns_rdata_toregion(rdata
, ®ion
);
144 num
= uint8_fromregion(®ion
);
145 isc_region_consume(®ion
, 1);
146 sprintf(buf
, "%u ", num
);
147 RETERR(str_totext(buf
, target
));
152 gateway
= uint8_fromregion(®ion
);
153 isc_region_consume(®ion
, 1);
154 sprintf(buf
, "%u ", gateway
);
155 RETERR(str_totext(buf
, target
));
160 num
= uint8_fromregion(®ion
);
161 isc_region_consume(®ion
, 1);
162 sprintf(buf
, "%u ", num
);
163 RETERR(str_totext(buf
, target
));
170 RETERR(str_totext(".", target
));
174 RETERR(inet_totext(AF_INET
, ®ion
, target
));
175 isc_region_consume(®ion
, 4);
179 RETERR(inet_totext(AF_INET6
, ®ion
, target
));
180 isc_region_consume(®ion
, 16);
184 dns_name_fromregion(&name
, ®ion
);
185 RETERR(dns_name_totext(&name
, ISC_FALSE
, target
));
186 isc_region_consume(®ion
, name_length(&name
));
193 if (region
.length
> 0U) {
194 RETERR(str_totext(tctx
->linebreak
, target
));
195 if (tctx
->width
== 0) /* No splitting */
196 RETERR(isc_base64_totext(®ion
, 60, "", target
));
198 RETERR(isc_base64_totext(®ion
, tctx
->width
- 2,
199 tctx
->linebreak
, target
));
202 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
203 RETERR(str_totext(" )", target
));
204 return (ISC_R_SUCCESS
);
207 static inline isc_result_t
208 fromwire_ipseckey(ARGS_FROMWIRE
) {
217 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
219 dns_name_init(&name
, NULL
);
221 isc_buffer_activeregion(source
, ®ion
);
222 if (region
.length
< 3)
223 return (ISC_R_UNEXPECTEDEND
);
225 switch (region
.base
[1]) {
227 isc_buffer_forward(source
, region
.length
);
228 return (mem_tobuffer(target
, region
.base
, region
.length
));
231 if (region
.length
< 7)
232 return (ISC_R_UNEXPECTEDEND
);
233 isc_buffer_forward(source
, region
.length
);
234 return (mem_tobuffer(target
, region
.base
, region
.length
));
237 if (region
.length
< 19)
238 return (ISC_R_UNEXPECTEDEND
);
239 isc_buffer_forward(source
, region
.length
);
240 return (mem_tobuffer(target
, region
.base
, region
.length
));
243 RETERR(mem_tobuffer(target
, region
.base
, 3));
244 isc_buffer_forward(source
, 3);
245 RETERR(dns_name_fromwire(&name
, source
, dctx
, options
, target
));
246 isc_buffer_activeregion(source
, ®ion
);
247 isc_buffer_forward(source
, region
.length
);
248 return(mem_tobuffer(target
, region
.base
, region
.length
));
251 return (ISC_R_NOTIMPLEMENTED
);
255 static inline isc_result_t
256 towire_ipseckey(ARGS_TOWIRE
) {
259 REQUIRE(rdata
->type
== 45);
260 REQUIRE(rdata
->length
!= 0);
264 dns_rdata_toregion(rdata
, ®ion
);
265 return (mem_tobuffer(target
, region
.base
, region
.length
));
269 compare_ipseckey(ARGS_COMPARE
) {
270 isc_region_t region1
;
271 isc_region_t region2
;
273 REQUIRE(rdata1
->type
== rdata2
->type
);
274 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
275 REQUIRE(rdata1
->type
== 45);
276 REQUIRE(rdata1
->length
>= 3);
277 REQUIRE(rdata2
->length
>= 3);
279 dns_rdata_toregion(rdata1
, ®ion1
);
280 dns_rdata_toregion(rdata2
, ®ion2
);
282 return (isc_region_compare(®ion1
, ®ion2
));
285 static inline isc_result_t
286 fromstruct_ipseckey(ARGS_FROMSTRUCT
) {
287 dns_rdata_ipseckey_t
*ipseckey
= source
;
292 REQUIRE(source
!= NULL
);
293 REQUIRE(ipseckey
->common
.rdtype
== type
);
294 REQUIRE(ipseckey
->common
.rdclass
== rdclass
);
299 if (ipseckey
->gateway_type
> 3U)
300 return (ISC_R_NOTIMPLEMENTED
);
302 RETERR(uint8_tobuffer(ipseckey
->precedence
, target
));
303 RETERR(uint8_tobuffer(ipseckey
->gateway_type
, target
));
304 RETERR(uint8_tobuffer(ipseckey
->algorithm
, target
));
306 switch (ipseckey
->gateway_type
) {
311 n
= ntohl(ipseckey
->in_addr
.s_addr
);
312 RETERR(uint32_tobuffer(n
, target
));
316 RETERR(mem_tobuffer(target
, ipseckey
->in6_addr
.s6_addr
, 16));
320 dns_name_toregion(&ipseckey
->gateway
, ®ion
);
321 RETERR(isc_buffer_copyregion(target
, ®ion
));
325 return (mem_tobuffer(target
, ipseckey
->key
, ipseckey
->keylength
));
328 static inline isc_result_t
329 tostruct_ipseckey(ARGS_TOSTRUCT
) {
331 dns_rdata_ipseckey_t
*ipseckey
= target
;
335 REQUIRE(rdata
->type
== 45);
336 REQUIRE(target
!= NULL
);
337 REQUIRE(rdata
->length
>= 3);
339 if (rdata
->data
[1] > 3U)
340 return (ISC_R_NOTIMPLEMENTED
);
342 ipseckey
->common
.rdclass
= rdata
->rdclass
;
343 ipseckey
->common
.rdtype
= rdata
->type
;
344 ISC_LINK_INIT(&ipseckey
->common
, link
);
346 dns_name_init(&name
, NULL
);
347 dns_rdata_toregion(rdata
, ®ion
);
349 ipseckey
->precedence
= uint8_fromregion(®ion
);
350 isc_region_consume(®ion
, 1);
352 ipseckey
->gateway_type
= uint8_fromregion(®ion
);
353 isc_region_consume(®ion
, 1);
355 ipseckey
->algorithm
= uint8_fromregion(®ion
);
356 isc_region_consume(®ion
, 1);
358 switch (ipseckey
->gateway_type
) {
363 n
= uint32_fromregion(®ion
);
364 ipseckey
->in_addr
.s_addr
= htonl(n
);
365 isc_region_consume(®ion
, 4);
369 memmove(ipseckey
->in6_addr
.s6_addr
, region
.base
, 16);
370 isc_region_consume(®ion
, 16);
374 dns_name_init(&ipseckey
->gateway
, NULL
);
375 dns_name_fromregion(&name
, ®ion
);
376 RETERR(name_duporclone(&name
, mctx
, &ipseckey
->gateway
));
377 isc_region_consume(®ion
, name_length(&name
));
381 ipseckey
->keylength
= region
.length
;
382 if (ipseckey
->keylength
!= 0U) {
383 ipseckey
->key
= mem_maybedup(mctx
, region
.base
,
384 ipseckey
->keylength
);
385 if (ipseckey
->key
== NULL
) {
386 if (ipseckey
->gateway_type
== 3)
387 dns_name_free(&ipseckey
->gateway
,
389 return (ISC_R_NOMEMORY
);
392 ipseckey
->key
= NULL
;
394 ipseckey
->mctx
= mctx
;
395 return (ISC_R_SUCCESS
);
399 freestruct_ipseckey(ARGS_FREESTRUCT
) {
400 dns_rdata_ipseckey_t
*ipseckey
= source
;
402 REQUIRE(source
!= NULL
);
403 REQUIRE(ipseckey
->common
.rdtype
== 45);
405 if (ipseckey
->mctx
== NULL
)
408 if (ipseckey
->gateway_type
== 3)
409 dns_name_free(&ipseckey
->gateway
, ipseckey
->mctx
);
411 if (ipseckey
->key
!= NULL
)
412 isc_mem_free(ipseckey
->mctx
, ipseckey
->key
);
414 ipseckey
->mctx
= NULL
;
417 static inline isc_result_t
418 additionaldata_ipseckey(ARGS_ADDLDATA
) {
420 REQUIRE(rdata
->type
== 45);
426 return (ISC_R_SUCCESS
);
429 static inline isc_result_t
430 digest_ipseckey(ARGS_DIGEST
) {
433 REQUIRE(rdata
->type
== 45);
435 dns_rdata_toregion(rdata
, ®ion
);
436 return ((digest
)(arg
, ®ion
));
439 static inline isc_boolean_t
440 checkowner_ipseckey(ARGS_CHECKOWNER
) {
452 static inline isc_boolean_t
453 checknames_ipseckey(ARGS_CHECKNAMES
) {
455 REQUIRE(rdata
->type
== 45);
465 casecompare_ipseckey(ARGS_COMPARE
) {
466 isc_region_t region1
;
467 isc_region_t region2
;
472 REQUIRE(rdata1
->type
== rdata2
->type
);
473 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
474 REQUIRE(rdata1
->type
== 45);
475 REQUIRE(rdata1
->length
>= 3);
476 REQUIRE(rdata2
->length
>= 3);
478 dns_rdata_toregion(rdata1
, ®ion1
);
479 dns_rdata_toregion(rdata2
, ®ion2
);
481 if (memcmp(region1
.base
, region2
.base
, 3) != 0 || region1
.base
[1] != 3)
482 return (isc_region_compare(®ion1
, ®ion2
));
484 dns_name_init(&name1
, NULL
);
485 dns_name_init(&name2
, NULL
);
487 isc_region_consume(®ion1
, 3);
488 isc_region_consume(®ion2
, 3);
490 dns_name_fromregion(&name1
, ®ion1
);
491 dns_name_fromregion(&name2
, ®ion2
);
493 order
= dns_name_rdatacompare(&name1
, &name2
);
497 isc_region_consume(®ion1
, name_length(&name1
));
498 isc_region_consume(®ion2
, name_length(&name2
));
500 return (isc_region_compare(®ion1
, ®ion2
));
503 #endif /* RDATA_GENERIC_IPSECKEY_45_C */