]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / bind9 / lib / dns / rdata / generic / ipseckey_45.c
1 /*
2  * Copyright (C) 2005  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and 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: ipseckey_45.c,v 1.2.2.1 2005/07/07 03:17:36 marka Exp $ */
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         dns_name_t prefix;
124         isc_boolean_t sub;
125         char buf[sizeof("255 ")];
126         unsigned short num;
127         unsigned short gateway;
128
129         REQUIRE(rdata->type == 45);
130         REQUIRE(rdata->length >= 3);
131
132         dns_name_init(&name, NULL);
133         dns_name_init(&prefix, NULL);
134         
135         if (rdata->data[1] > 3U)
136                 return (ISC_R_NOTIMPLEMENTED);
137
138         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
139                 RETERR(str_totext("( ", target));
140
141         /*
142          * Precendence.
143          */
144         dns_rdata_toregion(rdata, &region);
145         num = uint8_fromregion(&region);
146         isc_region_consume(&region, 1);
147         sprintf(buf, "%u ", num);
148         RETERR(str_totext(buf, target));
149
150         /*
151          * Gateway type.
152          */
153         gateway = uint8_fromregion(&region);
154         isc_region_consume(&region, 1);
155         sprintf(buf, "%u ", gateway);
156         RETERR(str_totext(buf, target));
157
158         /*
159          * Algorithm.
160          */
161         num = uint8_fromregion(&region);
162         isc_region_consume(&region, 1);
163         sprintf(buf, "%u ", num);
164         RETERR(str_totext(buf, target));
165
166         /*
167          * Gateway.
168          */
169         switch (gateway) {
170         case 0:
171                 RETERR(str_totext(".", target));
172                 break;
173
174         case 1:
175                 RETERR(inet_totext(AF_INET, &region, target));
176                 isc_region_consume(&region, 4);
177                 break;
178
179         case 2:
180                 RETERR(inet_totext(AF_INET6, &region, target));
181                 isc_region_consume(&region, 16);
182                 break;
183
184         case 3:
185                 dns_name_fromregion(&name, &region);
186                 sub = name_prefix(&name, tctx->origin, &prefix);
187                 RETERR(dns_name_totext(&prefix, sub, target));
188                 isc_region_consume(&region, name_length(&name));
189                 break;
190         }
191
192         /*
193          * Key.
194          */
195         if (region.length > 0U) {
196                 RETERR(str_totext(tctx->linebreak, target));
197                 RETERR(isc_base64_totext(&region, tctx->width - 2,
198                                          tctx->linebreak, target));
199         }
200
201         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
202                 RETERR(str_totext(" )", target));
203         return (ISC_R_SUCCESS);
204 }
205
206 static inline isc_result_t
207 fromwire_ipseckey(ARGS_FROMWIRE) {
208         dns_name_t name;
209         isc_region_t region;
210
211         REQUIRE(type == 45);
212
213         UNUSED(type);
214         UNUSED(rdclass);
215
216         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
217
218         dns_name_init(&name, NULL);
219
220         isc_buffer_activeregion(source, &region);
221         if (region.length < 3)
222                 return (ISC_R_UNEXPECTEDEND);
223
224         switch (region.base[1]) {
225         case 0:
226                 isc_buffer_forward(source, region.length);
227                 return (mem_tobuffer(target, region.base, region.length));
228
229         case 1:
230                 if (region.length < 7)
231                         return (ISC_R_UNEXPECTEDEND);
232                 isc_buffer_forward(source, region.length);
233                 return (mem_tobuffer(target, region.base, region.length));
234
235         case 2:
236                 if (region.length < 19)
237                         return (ISC_R_UNEXPECTEDEND);
238                 isc_buffer_forward(source, region.length);
239                 return (mem_tobuffer(target, region.base, region.length));
240
241         case 3:
242                 RETERR(mem_tobuffer(target, region.base, 3));
243                 isc_buffer_forward(source, 3);
244                 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
245                 isc_buffer_activeregion(source, &region);
246                 return(mem_tobuffer(target, region.base, region.length));
247
248         default:
249                 return (ISC_R_NOTIMPLEMENTED);
250         }
251 }
252
253 static inline isc_result_t
254 towire_ipseckey(ARGS_TOWIRE) {
255         isc_region_t region;
256
257         REQUIRE(rdata->type == 45);
258         REQUIRE(rdata->length != 0);
259
260         UNUSED(cctx);
261
262         dns_rdata_toregion(rdata, &region);
263         return (mem_tobuffer(target, region.base, region.length));
264 }
265
266 static inline int
267 compare_ipseckey(ARGS_COMPARE) {
268         isc_region_t region1;
269         isc_region_t region2;
270
271         REQUIRE(rdata1->type == rdata2->type);
272         REQUIRE(rdata1->rdclass == rdata2->rdclass);
273         REQUIRE(rdata1->type == 45);
274         REQUIRE(rdata1->length >= 3);
275         REQUIRE(rdata2->length >= 3);
276
277         dns_rdata_toregion(rdata1, &region1);
278         dns_rdata_toregion(rdata2, &region2);
279
280         return (isc_region_compare(&region1, &region2));
281 }
282
283 static inline isc_result_t
284 fromstruct_ipseckey(ARGS_FROMSTRUCT) {
285         dns_rdata_ipseckey_t *ipseckey = source;
286         isc_region_t region;
287         isc_uint32_t n;
288
289         REQUIRE(type == 45);
290         REQUIRE(source != NULL);
291         REQUIRE(ipseckey->common.rdtype == type);
292         REQUIRE(ipseckey->common.rdclass == rdclass);
293
294         UNUSED(type);
295         UNUSED(rdclass);
296
297         if (ipseckey->gateway_type > 3U)
298                 return (ISC_R_NOTIMPLEMENTED);
299
300         RETERR(uint8_tobuffer(ipseckey->precedence, target));
301         RETERR(uint8_tobuffer(ipseckey->gateway_type, target));
302         RETERR(uint8_tobuffer(ipseckey->algorithm, target));
303
304         switch  (ipseckey->gateway_type) {
305         case 0:
306                 break;
307
308         case 1:
309                 n = ntohl(ipseckey->in_addr.s_addr);
310                 RETERR(uint32_tobuffer(n, target));
311                 break;
312
313         case 2:
314                 RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16));
315                 break;
316
317         case 3:
318                 dns_name_toregion(&ipseckey->gateway, &region);
319                 RETERR(isc_buffer_copyregion(target, &region));
320                 break;
321         }
322
323         return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength));
324 }
325
326 static inline isc_result_t
327 tostruct_ipseckey(ARGS_TOSTRUCT) {
328         isc_region_t region;
329         dns_rdata_ipseckey_t *ipseckey = target;
330         dns_name_t name;
331         isc_uint32_t n;
332
333         REQUIRE(rdata->type == 45);
334         REQUIRE(target != NULL);
335         REQUIRE(rdata->length >= 3);
336
337         if (rdata->data[1] > 3U)
338                 return (ISC_R_NOTIMPLEMENTED);
339
340         ipseckey->common.rdclass = rdata->rdclass;
341         ipseckey->common.rdtype = rdata->type;
342         ISC_LINK_INIT(&ipseckey->common, link);
343
344         dns_name_init(&name, NULL);
345         dns_rdata_toregion(rdata, &region);
346
347         ipseckey->precedence = uint8_fromregion(&region);
348         isc_region_consume(&region, 1);
349
350         ipseckey->gateway_type = uint8_fromregion(&region);
351         isc_region_consume(&region, 1);
352
353         ipseckey->algorithm = uint8_fromregion(&region);
354         isc_region_consume(&region, 1);
355
356         switch (ipseckey->gateway_type) {
357         case 0:
358                 break;
359
360         case 1:
361                 n = uint32_fromregion(&region);
362                 ipseckey->in_addr.s_addr = htonl(n);
363                 isc_region_consume(&region, 4);
364                 break;
365
366         case 2:
367                 memcpy(ipseckey->in6_addr.s6_addr, region.base, 16);
368                 isc_region_consume(&region, 16);
369                 break;
370
371         case 3:
372                 dns_name_init(&ipseckey->gateway, NULL);
373                 dns_name_fromregion(&name, &region);
374                 RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
375                 isc_region_consume(&region, name_length(&name));
376                 break;
377         }
378
379         ipseckey->keylength = region.length;
380         if (ipseckey->keylength != 0U) {
381                 ipseckey->key = mem_maybedup(mctx, region.base,
382                                              ipseckey->keylength);
383                 if (ipseckey->key == NULL) {
384                         if (ipseckey->gateway_type == 3)
385                                 dns_name_free(&ipseckey->gateway,
386                                               ipseckey->mctx);
387                         return (ISC_R_NOMEMORY);
388                 }
389         } else
390                 ipseckey->key = NULL;
391
392         ipseckey->mctx = mctx;
393         return (ISC_R_SUCCESS);
394 }
395
396 static inline void
397 freestruct_ipseckey(ARGS_FREESTRUCT) {
398         dns_rdata_ipseckey_t *ipseckey = source;
399
400         REQUIRE(source != NULL);
401         REQUIRE(ipseckey->common.rdtype == 45);
402
403         if (ipseckey->mctx == NULL)
404                 return;
405
406         if (ipseckey->gateway_type == 3)
407                 dns_name_free(&ipseckey->gateway, ipseckey->mctx);
408
409         if (ipseckey->key != NULL)
410                 isc_mem_free(ipseckey->mctx, ipseckey->key);
411
412         ipseckey->mctx = NULL;
413 }
414
415 static inline isc_result_t
416 additionaldata_ipseckey(ARGS_ADDLDATA) {
417
418         REQUIRE(rdata->type == 45);
419
420         UNUSED(rdata);
421         UNUSED(add);
422         UNUSED(arg);
423
424         return (ISC_R_SUCCESS);
425 }
426
427 static inline isc_result_t
428 digest_ipseckey(ARGS_DIGEST) {
429         isc_region_t region;
430
431         REQUIRE(rdata->type == 45);
432
433         dns_rdata_toregion(rdata, &region);
434         return ((digest)(arg, &region));
435 }
436
437 static inline isc_boolean_t
438 checkowner_ipseckey(ARGS_CHECKOWNER) {
439
440         REQUIRE(type == 45);
441
442         UNUSED(name);
443         UNUSED(type);
444         UNUSED(rdclass);
445         UNUSED(wildcard);
446
447         return (ISC_TRUE);
448 }
449
450 static inline isc_boolean_t
451 checknames_ipseckey(ARGS_CHECKNAMES) {
452
453         REQUIRE(rdata->type == 45);
454
455         UNUSED(rdata);
456         UNUSED(owner);
457         UNUSED(bad);
458
459         return (ISC_TRUE);
460 }
461
462 #endif  /* RDATA_GENERIC_IPSECKEY_45_C */