]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / dns / rdata / generic / ipseckey_45.c
1 /*
2  * Copyright (C) 2005, 2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id$ */
18
19 #ifndef RDATA_GENERIC_IPSECKEY_45_C
20 #define RDATA_GENERIC_IPSECKEY_45_C
21
22 #include <string.h>
23
24 #include <isc/net.h>
25
26 #define RRTYPE_IPSECKEY_ATTRIBUTES (0)
27
28 static inline isc_result_t
29 fromtext_ipseckey(ARGS_FROMTEXT) {
30         isc_token_t token;
31         dns_name_t name;
32         isc_buffer_t buffer;
33         unsigned int gateway;
34         struct in_addr addr;
35         unsigned char addr6[16];
36         isc_region_t region;
37
38         REQUIRE(type == 45);
39
40         UNUSED(type);
41         UNUSED(rdclass);
42         UNUSED(callbacks);
43
44         /*
45          * Precedence.
46          */
47         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
48                                       ISC_FALSE));
49         if (token.value.as_ulong > 0xffU)
50                 RETTOK(ISC_R_RANGE);
51         RETERR(uint8_tobuffer(token.value.as_ulong, target));
52
53         /*
54          * Gateway type.
55          */
56         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
57                                       ISC_FALSE));
58         if (token.value.as_ulong > 0x3U)
59                 RETTOK(ISC_R_RANGE);
60         RETERR(uint8_tobuffer(token.value.as_ulong, target));
61         gateway = token.value.as_ulong;
62
63         /*
64          * Algorithm.
65          */
66         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
67                                       ISC_FALSE));
68         if (token.value.as_ulong > 0xffU)
69                 RETTOK(ISC_R_RANGE);
70         RETERR(uint8_tobuffer(token.value.as_ulong, target));
71
72         /*
73          * Gateway.
74          */
75         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
76                                       ISC_FALSE));
77
78         switch (gateway) {
79         case 0:
80                 if (strcmp(DNS_AS_STR(token), ".") != 0)
81                         RETTOK(DNS_R_SYNTAX);
82                 break;
83
84         case 1:
85                 if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
86                         RETTOK(DNS_R_BADDOTTEDQUAD);
87                 isc_buffer_availableregion(target, &region);
88                 if (region.length < 4)
89                         return (ISC_R_NOSPACE);
90                 memcpy(region.base, &addr, 4);
91                 isc_buffer_add(target, 4);
92                 break;
93
94         case 2:
95                 if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1)
96                         RETTOK(DNS_R_BADAAAA);
97                 isc_buffer_availableregion(target, &region);
98                 if (region.length < 16)
99                         return (ISC_R_NOSPACE);
100                 memcpy(region.base, addr6, 16);
101                 isc_buffer_add(target, 16);
102                 break;
103
104         case 3:
105                 dns_name_init(&name, NULL);
106                 buffer_fromregion(&buffer, &token.value.as_region);
107                 origin = (origin != NULL) ? origin : dns_rootname;
108                 RETTOK(dns_name_fromtext(&name, &buffer, origin,
109                                          options, target));
110                 break;
111         }
112
113         /*
114          * Public key.
115          */
116         return (isc_base64_tobuffer(lexer, target, -1));
117 }
118
119 static inline isc_result_t
120 totext_ipseckey(ARGS_TOTEXT) {
121         isc_region_t region;
122         dns_name_t name;
123         char buf[sizeof("255 ")];
124         unsigned short num;
125         unsigned short gateway;
126
127         REQUIRE(rdata->type == 45);
128         REQUIRE(rdata->length >= 3);
129
130         dns_name_init(&name, NULL);
131
132         if (rdata->data[1] > 3U)
133                 return (ISC_R_NOTIMPLEMENTED);
134
135         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
136                 RETERR(str_totext("( ", target));
137
138         /*
139          * Precedence.
140          */
141         dns_rdata_toregion(rdata, &region);
142         num = uint8_fromregion(&region);
143         isc_region_consume(&region, 1);
144         sprintf(buf, "%u ", num);
145         RETERR(str_totext(buf, target));
146
147         /*
148          * Gateway type.
149          */
150         gateway = uint8_fromregion(&region);
151         isc_region_consume(&region, 1);
152         sprintf(buf, "%u ", gateway);
153         RETERR(str_totext(buf, target));
154
155         /*
156          * Algorithm.
157          */
158         num = uint8_fromregion(&region);
159         isc_region_consume(&region, 1);
160         sprintf(buf, "%u ", num);
161         RETERR(str_totext(buf, target));
162
163         /*
164          * Gateway.
165          */
166         switch (gateway) {
167         case 0:
168                 RETERR(str_totext(".", target));
169                 break;
170
171         case 1:
172                 RETERR(inet_totext(AF_INET, &region, target));
173                 isc_region_consume(&region, 4);
174                 break;
175
176         case 2:
177                 RETERR(inet_totext(AF_INET6, &region, target));
178                 isc_region_consume(&region, 16);
179                 break;
180
181         case 3:
182                 dns_name_fromregion(&name, &region);
183                 RETERR(dns_name_totext(&name, ISC_FALSE, target));
184                 isc_region_consume(&region, name_length(&name));
185                 break;
186         }
187
188         /*
189          * Key.
190          */
191         if (region.length > 0U) {
192                 RETERR(str_totext(tctx->linebreak, target));
193                 RETERR(isc_base64_totext(&region, tctx->width - 2,
194                                          tctx->linebreak, target));
195         }
196
197         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
198                 RETERR(str_totext(" )", target));
199         return (ISC_R_SUCCESS);
200 }
201
202 static inline isc_result_t
203 fromwire_ipseckey(ARGS_FROMWIRE) {
204         dns_name_t name;
205         isc_region_t region;
206
207         REQUIRE(type == 45);
208
209         UNUSED(type);
210         UNUSED(rdclass);
211
212         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
213
214         dns_name_init(&name, NULL);
215
216         isc_buffer_activeregion(source, &region);
217         if (region.length < 3)
218                 return (ISC_R_UNEXPECTEDEND);
219
220         switch (region.base[1]) {
221         case 0:
222                 isc_buffer_forward(source, region.length);
223                 return (mem_tobuffer(target, region.base, region.length));
224
225         case 1:
226                 if (region.length < 7)
227                         return (ISC_R_UNEXPECTEDEND);
228                 isc_buffer_forward(source, region.length);
229                 return (mem_tobuffer(target, region.base, region.length));
230
231         case 2:
232                 if (region.length < 19)
233                         return (ISC_R_UNEXPECTEDEND);
234                 isc_buffer_forward(source, region.length);
235                 return (mem_tobuffer(target, region.base, region.length));
236
237         case 3:
238                 RETERR(mem_tobuffer(target, region.base, 3));
239                 isc_buffer_forward(source, 3);
240                 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
241                 isc_buffer_activeregion(source, &region);
242                 isc_buffer_forward(source, region.length);
243                 return(mem_tobuffer(target, region.base, region.length));
244
245         default:
246                 return (ISC_R_NOTIMPLEMENTED);
247         }
248 }
249
250 static inline isc_result_t
251 towire_ipseckey(ARGS_TOWIRE) {
252         isc_region_t region;
253
254         REQUIRE(rdata->type == 45);
255         REQUIRE(rdata->length != 0);
256
257         UNUSED(cctx);
258
259         dns_rdata_toregion(rdata, &region);
260         return (mem_tobuffer(target, region.base, region.length));
261 }
262
263 static inline int
264 compare_ipseckey(ARGS_COMPARE) {
265         isc_region_t region1;
266         isc_region_t region2;
267
268         REQUIRE(rdata1->type == rdata2->type);
269         REQUIRE(rdata1->rdclass == rdata2->rdclass);
270         REQUIRE(rdata1->type == 45);
271         REQUIRE(rdata1->length >= 3);
272         REQUIRE(rdata2->length >= 3);
273
274         dns_rdata_toregion(rdata1, &region1);
275         dns_rdata_toregion(rdata2, &region2);
276
277         return (isc_region_compare(&region1, &region2));
278 }
279
280 static inline isc_result_t
281 fromstruct_ipseckey(ARGS_FROMSTRUCT) {
282         dns_rdata_ipseckey_t *ipseckey = source;
283         isc_region_t region;
284         isc_uint32_t n;
285
286         REQUIRE(type == 45);
287         REQUIRE(source != NULL);
288         REQUIRE(ipseckey->common.rdtype == type);
289         REQUIRE(ipseckey->common.rdclass == rdclass);
290
291         UNUSED(type);
292         UNUSED(rdclass);
293
294         if (ipseckey->gateway_type > 3U)
295                 return (ISC_R_NOTIMPLEMENTED);
296
297         RETERR(uint8_tobuffer(ipseckey->precedence, target));
298         RETERR(uint8_tobuffer(ipseckey->gateway_type, target));
299         RETERR(uint8_tobuffer(ipseckey->algorithm, target));
300
301         switch  (ipseckey->gateway_type) {
302         case 0:
303                 break;
304
305         case 1:
306                 n = ntohl(ipseckey->in_addr.s_addr);
307                 RETERR(uint32_tobuffer(n, target));
308                 break;
309
310         case 2:
311                 RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16));
312                 break;
313
314         case 3:
315                 dns_name_toregion(&ipseckey->gateway, &region);
316                 RETERR(isc_buffer_copyregion(target, &region));
317                 break;
318         }
319
320         return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength));
321 }
322
323 static inline isc_result_t
324 tostruct_ipseckey(ARGS_TOSTRUCT) {
325         isc_region_t region;
326         dns_rdata_ipseckey_t *ipseckey = target;
327         dns_name_t name;
328         isc_uint32_t n;
329
330         REQUIRE(rdata->type == 45);
331         REQUIRE(target != NULL);
332         REQUIRE(rdata->length >= 3);
333
334         if (rdata->data[1] > 3U)
335                 return (ISC_R_NOTIMPLEMENTED);
336
337         ipseckey->common.rdclass = rdata->rdclass;
338         ipseckey->common.rdtype = rdata->type;
339         ISC_LINK_INIT(&ipseckey->common, link);
340
341         dns_name_init(&name, NULL);
342         dns_rdata_toregion(rdata, &region);
343
344         ipseckey->precedence = uint8_fromregion(&region);
345         isc_region_consume(&region, 1);
346
347         ipseckey->gateway_type = uint8_fromregion(&region);
348         isc_region_consume(&region, 1);
349
350         ipseckey->algorithm = uint8_fromregion(&region);
351         isc_region_consume(&region, 1);
352
353         switch (ipseckey->gateway_type) {
354         case 0:
355                 break;
356
357         case 1:
358                 n = uint32_fromregion(&region);
359                 ipseckey->in_addr.s_addr = htonl(n);
360                 isc_region_consume(&region, 4);
361                 break;
362
363         case 2:
364                 memcpy(ipseckey->in6_addr.s6_addr, region.base, 16);
365                 isc_region_consume(&region, 16);
366                 break;
367
368         case 3:
369                 dns_name_init(&ipseckey->gateway, NULL);
370                 dns_name_fromregion(&name, &region);
371                 RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
372                 isc_region_consume(&region, name_length(&name));
373                 break;
374         }
375
376         ipseckey->keylength = region.length;
377         if (ipseckey->keylength != 0U) {
378                 ipseckey->key = mem_maybedup(mctx, region.base,
379                                              ipseckey->keylength);
380                 if (ipseckey->key == NULL) {
381                         if (ipseckey->gateway_type == 3)
382                                 dns_name_free(&ipseckey->gateway,
383                                               ipseckey->mctx);
384                         return (ISC_R_NOMEMORY);
385                 }
386         } else
387                 ipseckey->key = NULL;
388
389         ipseckey->mctx = mctx;
390         return (ISC_R_SUCCESS);
391 }
392
393 static inline void
394 freestruct_ipseckey(ARGS_FREESTRUCT) {
395         dns_rdata_ipseckey_t *ipseckey = source;
396
397         REQUIRE(source != NULL);
398         REQUIRE(ipseckey->common.rdtype == 45);
399
400         if (ipseckey->mctx == NULL)
401                 return;
402
403         if (ipseckey->gateway_type == 3)
404                 dns_name_free(&ipseckey->gateway, ipseckey->mctx);
405
406         if (ipseckey->key != NULL)
407                 isc_mem_free(ipseckey->mctx, ipseckey->key);
408
409         ipseckey->mctx = NULL;
410 }
411
412 static inline isc_result_t
413 additionaldata_ipseckey(ARGS_ADDLDATA) {
414
415         REQUIRE(rdata->type == 45);
416
417         UNUSED(rdata);
418         UNUSED(add);
419         UNUSED(arg);
420
421         return (ISC_R_SUCCESS);
422 }
423
424 static inline isc_result_t
425 digest_ipseckey(ARGS_DIGEST) {
426         isc_region_t region;
427
428         REQUIRE(rdata->type == 45);
429
430         dns_rdata_toregion(rdata, &region);
431         return ((digest)(arg, &region));
432 }
433
434 static inline isc_boolean_t
435 checkowner_ipseckey(ARGS_CHECKOWNER) {
436
437         REQUIRE(type == 45);
438
439         UNUSED(name);
440         UNUSED(type);
441         UNUSED(rdclass);
442         UNUSED(wildcard);
443
444         return (ISC_TRUE);
445 }
446
447 static inline isc_boolean_t
448 checknames_ipseckey(ARGS_CHECKNAMES) {
449
450         REQUIRE(rdata->type == 45);
451
452         UNUSED(rdata);
453         UNUSED(owner);
454         UNUSED(bad);
455
456         return (ISC_TRUE);
457 }
458
459 static inline int
460 casecompare_ipseckey(ARGS_COMPARE) {
461         isc_region_t region1;
462         isc_region_t region2;
463         dns_name_t name1;
464         dns_name_t name2;
465         int order;
466
467         REQUIRE(rdata1->type == rdata2->type);
468         REQUIRE(rdata1->rdclass == rdata2->rdclass);
469         REQUIRE(rdata1->type == 45);
470         REQUIRE(rdata1->length >= 3);
471         REQUIRE(rdata2->length >= 3);
472
473         dns_rdata_toregion(rdata1, &region1);
474         dns_rdata_toregion(rdata2, &region2);
475
476         if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3)
477                 return (isc_region_compare(&region1, &region2));
478
479         dns_name_init(&name1, NULL);
480         dns_name_init(&name2, NULL);
481
482         isc_region_consume(&region1, 3);
483         isc_region_consume(&region2, 3);
484
485         dns_name_fromregion(&name1, &region1);
486         dns_name_fromregion(&name2, &region2);
487
488         order = dns_name_rdatacompare(&name1, &name2);
489         if (order != 0)
490                 return (order);
491
492         isc_region_consume(&region1, name_length(&name1));
493         isc_region_consume(&region2, name_length(&name2));
494
495         return (isc_region_compare(&region1, &region2));
496 }
497
498 #endif  /* RDATA_GENERIC_IPSECKEY_45_C */