]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/pfkey.c
mDNSResponder-320.5.1.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / pfkey.c
1 /*
2 * Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /* $FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
17 /* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */
18
19 /*
20 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. Neither the name of the project nor the names of its contributors
32 * may be used to endorse or promote products derived from this software
33 * without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 */
47
48 #include <sys/types.h>
49 #include <sys/param.h>
50 #include <sys/socket.h>
51 #include <net/pfkeyv2.h>
52 #include <netinet/in.h>
53 #include <netinet6/ipsec.h>
54
55 #include <stdlib.h>
56 #include <unistd.h>
57 #include <string.h>
58 #include <errno.h>
59 #include <stdio.h>
60 #include <TargetConditionals.h>
61
62 #include "ipsec_strerror.h"
63 #include "libpfkey.h"
64 #include "ipsec_options.h"
65
66 #if TARGET_OS_EMBEDDED
67 #ifndef MDNS_NO_IPSEC
68 #define MDNS_NO_IPSEC 1
69 #endif
70 #endif
71
72 #ifndef MDNS_NO_IPSEC
73
74 #define CALLOC(size, cast) (cast)calloc(1, (size))
75
76 static int findsupportedmap __P((int));
77 static int setsupportedmap __P((struct sadb_supported *));
78 static struct sadb_alg *findsupportedalg __P((u_int, u_int));
79 static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
80 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
81 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
82 u_int32_t, u_int32_t, u_int32_t));
83 static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
84 struct sockaddr *, struct sockaddr *, u_int32_t));
85 static int pfkey_send_x3 __P((int, u_int, u_int));
86 static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
87 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
88 char *, int, u_int32_t));
89 static int pfkey_send_x5 __P((int, u_int, u_int32_t));
90
91 static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
92 u_int, u_int32_t, pid_t));
93 static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
94 u_int, u_int, u_int32_t));
95 static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
96 struct sockaddr *, u_int, u_int));
97 static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
98 static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
99 u_int32_t, u_int32_t, u_int32_t));
100 static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
101
102 /*
103 * make and search supported algorithm structure.
104 */
105 static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
106
107 static int supported_map[] = {
108 SADB_SATYPE_AH,
109 SADB_SATYPE_ESP,
110 SADB_X_SATYPE_IPCOMP,
111 };
112
113 static int
114 findsupportedmap(satype)
115 int satype;
116 {
117 int i;
118
119 for (i = 0; (unsigned int)i < sizeof(supported_map)/sizeof(supported_map[0]); i++)
120 if (supported_map[i] == satype)
121 return i;
122 return -1;
123 }
124
125 static struct sadb_alg *
126 findsupportedalg(satype, alg_id)
127 u_int satype, alg_id;
128 {
129 int algno;
130 int tlen;
131 caddr_t p;
132
133 /* validity check */
134 algno = findsupportedmap(satype);
135 if (algno == -1) {
136 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
137 return NULL;
138 }
139 if (ipsec_supported[algno] == NULL) {
140 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
141 return NULL;
142 }
143
144 tlen = ipsec_supported[algno]->sadb_supported_len
145 - sizeof(struct sadb_supported);
146 p = (caddr_t)(ipsec_supported[algno] + 1);
147 while (tlen > 0) {
148 if ((unsigned int)tlen < sizeof(struct sadb_alg)) {
149 /* invalid format */
150 break;
151 }
152 if (((struct sadb_alg *)p)->sadb_alg_id == alg_id)
153 return (struct sadb_alg *)p;
154
155 tlen -= sizeof(struct sadb_alg);
156 p += sizeof(struct sadb_alg);
157 }
158
159 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
160 return NULL;
161 }
162
163 static int
164 setsupportedmap(sup)
165 struct sadb_supported *sup;
166 {
167 struct sadb_supported **ipsup;
168
169 switch (sup->sadb_supported_exttype) {
170 case SADB_EXT_SUPPORTED_AUTH:
171 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)];
172 break;
173 case SADB_EXT_SUPPORTED_ENCRYPT:
174 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)];
175 break;
176 default:
177 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
178 return -1;
179 }
180
181 if (*ipsup)
182 free(*ipsup);
183
184 *ipsup = malloc(sup->sadb_supported_len);
185 if (!*ipsup) {
186 __ipsec_set_strerror(strerror(errno));
187 return -1;
188 }
189 memcpy(*ipsup, sup, sup->sadb_supported_len);
190
191 return 0;
192 }
193
194 /*
195 * check key length against algorithm specified.
196 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
197 * augument, and only calls to ipsec_check_keylen2();
198 * keylen is the unit of bit.
199 * OUT:
200 * -1: invalid.
201 * 0: valid.
202 */
203 int
204 ipsec_check_keylen(supported, alg_id, keylen)
205 u_int supported;
206 u_int alg_id;
207 u_int keylen;
208 {
209 int satype;
210
211 /* validity check */
212 switch (supported) {
213 case SADB_EXT_SUPPORTED_AUTH:
214 satype = SADB_SATYPE_AH;
215 break;
216 case SADB_EXT_SUPPORTED_ENCRYPT:
217 satype = SADB_SATYPE_ESP;
218 break;
219 default:
220 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
221 return -1;
222 }
223
224 return ipsec_check_keylen2(satype, alg_id, keylen);
225 }
226
227 /*
228 * check key length against algorithm specified.
229 * satype is one of satype defined at pfkeyv2.h.
230 * keylen is the unit of bit.
231 * OUT:
232 * -1: invalid.
233 * 0: valid.
234 */
235 int
236 ipsec_check_keylen2(satype, alg_id, keylen)
237 u_int satype;
238 u_int alg_id;
239 u_int keylen;
240 {
241 struct sadb_alg *alg;
242
243 alg = findsupportedalg(satype, alg_id);
244 if (!alg)
245 return -1;
246
247 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) {
248 __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
249 return -1;
250 }
251
252 __ipsec_errcode = EIPSEC_NO_ERROR;
253 return 0;
254 }
255
256 /*
257 * get max/min key length against algorithm specified.
258 * satype is one of satype defined at pfkeyv2.h.
259 * keylen is the unit of bit.
260 * OUT:
261 * -1: invalid.
262 * 0: valid.
263 */
264 int
265 ipsec_get_keylen(supported, alg_id, alg0)
266 u_int supported, alg_id;
267 struct sadb_alg *alg0;
268 {
269 struct sadb_alg *alg;
270 u_int satype;
271
272 /* validity check */
273 if (!alg0) {
274 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
275 return -1;
276 }
277
278 switch (supported) {
279 case SADB_EXT_SUPPORTED_AUTH:
280 satype = SADB_SATYPE_AH;
281 break;
282 case SADB_EXT_SUPPORTED_ENCRYPT:
283 satype = SADB_SATYPE_ESP;
284 break;
285 default:
286 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
287 return -1;
288 }
289
290 alg = findsupportedalg(satype, alg_id);
291 if (!alg)
292 return -1;
293
294 memcpy(alg0, alg, sizeof(*alg0));
295
296 __ipsec_errcode = EIPSEC_NO_ERROR;
297 return 0;
298 }
299
300 /*
301 * set the rate for SOFT lifetime against HARD one.
302 * If rate is more than 100 or equal to zero, then set to 100.
303 */
304 static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
305 static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
306 static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
307 static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
308
309 u_int
310 pfkey_set_softrate(type, rate)
311 u_int type, rate;
312 {
313 __ipsec_errcode = EIPSEC_NO_ERROR;
314
315 if (rate > 100 || rate == 0)
316 rate = 100;
317
318 switch (type) {
319 case SADB_X_LIFETIME_ALLOCATIONS:
320 soft_lifetime_allocations_rate = rate;
321 return 0;
322 case SADB_X_LIFETIME_BYTES:
323 soft_lifetime_bytes_rate = rate;
324 return 0;
325 case SADB_X_LIFETIME_ADDTIME:
326 soft_lifetime_addtime_rate = rate;
327 return 0;
328 case SADB_X_LIFETIME_USETIME:
329 soft_lifetime_usetime_rate = rate;
330 return 0;
331 }
332
333 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
334 return 1;
335 }
336
337 /*
338 * get current rate for SOFT lifetime against HARD one.
339 * ATTENTION: ~0 is returned if invalid type was passed.
340 */
341 u_int
342 pfkey_get_softrate(type)
343 u_int type;
344 {
345 switch (type) {
346 case SADB_X_LIFETIME_ALLOCATIONS:
347 return soft_lifetime_allocations_rate;
348 case SADB_X_LIFETIME_BYTES:
349 return soft_lifetime_bytes_rate;
350 case SADB_X_LIFETIME_ADDTIME:
351 return soft_lifetime_addtime_rate;
352 case SADB_X_LIFETIME_USETIME:
353 return soft_lifetime_usetime_rate;
354 }
355
356 return ~0;
357 }
358
359 /*
360 * sending SADB_GETSPI message to the kernel.
361 * OUT:
362 * positive: success and return length sent.
363 * -1 : error occured, and set errno.
364 */
365 int
366 pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
367 int so;
368 u_int satype, mode;
369 struct sockaddr *src, *dst;
370 u_int32_t min, max, reqid, seq;
371 {
372 struct sadb_msg *newmsg;
373 caddr_t ep;
374 int len;
375 int need_spirange = 0;
376 caddr_t p;
377 int plen;
378
379 /* validity check */
380 if (src == NULL || dst == NULL) {
381 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
382 return -1;
383 }
384 if (src->sa_family != dst->sa_family) {
385 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
386 return -1;
387 }
388 if (min > max || (min > 0 && min <= 255)) {
389 __ipsec_errcode = EIPSEC_INVAL_SPI;
390 return -1;
391 }
392 switch (src->sa_family) {
393 case AF_INET:
394 plen = sizeof(struct in_addr) << 3;
395 break;
396 case AF_INET6:
397 plen = sizeof(struct in6_addr) << 3;
398 break;
399 default:
400 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
401 return -1;
402 }
403
404 /* create new sadb_msg to send. */
405 len = sizeof(struct sadb_msg)
406 + sizeof(struct sadb_x_sa2)
407 + sizeof(struct sadb_address)
408 + PFKEY_ALIGN8(src->sa_len)
409 + sizeof(struct sadb_address)
410 + PFKEY_ALIGN8(dst->sa_len);
411
412 if (min > (u_int32_t)255 && max < (u_int32_t)~0) {
413 need_spirange++;
414 len += sizeof(struct sadb_spirange);
415 }
416
417 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
418 __ipsec_set_strerror(strerror(errno));
419 return -1;
420 }
421 ep = ((caddr_t)newmsg) + len;
422
423 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI,
424 len, satype, seq, getpid());
425 if (!p) {
426 free(newmsg);
427 return -1;
428 }
429
430 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
431 if (!p) {
432 free(newmsg);
433 return -1;
434 }
435
436 /* set sadb_address for source */
437 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
438 IPSEC_ULPROTO_ANY);
439 if (!p) {
440 free(newmsg);
441 return -1;
442 }
443
444 /* set sadb_address for destination */
445 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
446 IPSEC_ULPROTO_ANY);
447 if (!p) {
448 free(newmsg);
449 return -1;
450 }
451
452 /* proccessing spi range */
453 if (need_spirange) {
454 struct sadb_spirange spirange;
455
456 if (p + sizeof(spirange) > ep) {
457 free(newmsg);
458 return -1;
459 }
460
461 memset(&spirange, 0, sizeof(spirange));
462 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange));
463 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
464 spirange.sadb_spirange_min = min;
465 spirange.sadb_spirange_max = max;
466
467 memcpy(p, &spirange, sizeof(spirange));
468
469 p += sizeof(spirange);
470 }
471 if (p != ep) {
472 free(newmsg);
473 return -1;
474 }
475
476 /* send message */
477 len = pfkey_send(so, newmsg, len);
478 free(newmsg);
479
480 if (len < 0)
481 return -1;
482
483 __ipsec_errcode = EIPSEC_NO_ERROR;
484 return len;
485 }
486
487 /*
488 * sending SADB_UPDATE message to the kernel.
489 * The length of key material is a_keylen + e_keylen.
490 * OUT:
491 * positive: success and return length sent.
492 * -1 : error occured, and set errno.
493 */
494 int
495 pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
496 keymat, e_type, e_keylen, a_type, a_keylen, flags,
497 l_alloc, l_bytes, l_addtime, l_usetime, seq)
498 int so;
499 u_int satype, mode, wsize;
500 struct sockaddr *src, *dst;
501 u_int32_t spi, reqid;
502 caddr_t keymat;
503 u_int e_type, e_keylen, a_type, a_keylen, flags;
504 u_int32_t l_alloc;
505 u_int64_t l_bytes, l_addtime, l_usetime;
506 u_int32_t seq;
507 {
508 int len;
509 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
510 reqid, wsize,
511 keymat, e_type, e_keylen, a_type, a_keylen, flags,
512 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
513 return -1;
514
515 return len;
516 }
517
518 /*
519 * sending SADB_ADD message to the kernel.
520 * The length of key material is a_keylen + e_keylen.
521 * OUT:
522 * positive: success and return length sent.
523 * -1 : error occured, and set errno.
524 */
525 int
526 pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
527 keymat, e_type, e_keylen, a_type, a_keylen, flags,
528 l_alloc, l_bytes, l_addtime, l_usetime, seq)
529 int so;
530 u_int satype, mode, wsize;
531 struct sockaddr *src, *dst;
532 u_int32_t spi, reqid;
533 caddr_t keymat;
534 u_int e_type, e_keylen, a_type, a_keylen, flags;
535 u_int32_t l_alloc;
536 u_int64_t l_bytes, l_addtime, l_usetime;
537 u_int32_t seq;
538 {
539 int len;
540 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
541 reqid, wsize,
542 keymat, e_type, e_keylen, a_type, a_keylen, flags,
543 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
544 return -1;
545
546 return len;
547 }
548
549 /*
550 * sending SADB_DELETE message to the kernel.
551 * OUT:
552 * positive: success and return length sent.
553 * -1 : error occured, and set errno.
554 */
555 int
556 pfkey_send_delete(so, satype, mode, src, dst, spi)
557 int so;
558 u_int satype, mode;
559 struct sockaddr *src, *dst;
560 u_int32_t spi;
561 {
562 int len;
563 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
564 return -1;
565
566 return len;
567 }
568
569 /*
570 * sending SADB_DELETE without spi to the kernel. This is
571 * the "delete all" request (an extension also present in
572 * Solaris).
573 *
574 * OUT:
575 * positive: success and return length sent
576 * -1 : error occured, and set errno
577 */
578 int
579 pfkey_send_delete_all(so, satype, mode, src, dst)
580 int so;
581 u_int satype, mode;
582 struct sockaddr *src, *dst;
583 {
584 struct sadb_msg *newmsg;
585 int len;
586 caddr_t p;
587 int plen;
588 caddr_t ep;
589
590 (void)mode;
591
592 /* validity check */
593 if (src == NULL || dst == NULL) {
594 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
595 return -1;
596 }
597 if (src->sa_family != dst->sa_family) {
598 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
599 return -1;
600 }
601 switch (src->sa_family) {
602 case AF_INET:
603 plen = sizeof(struct in_addr) << 3;
604 break;
605 case AF_INET6:
606 plen = sizeof(struct in6_addr) << 3;
607 break;
608 default:
609 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
610 return -1;
611 }
612
613 /* create new sadb_msg to reply. */
614 len = sizeof(struct sadb_msg)
615 + sizeof(struct sadb_address)
616 + PFKEY_ALIGN8(src->sa_len)
617 + sizeof(struct sadb_address)
618 + PFKEY_ALIGN8(dst->sa_len);
619
620 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
621 __ipsec_set_strerror(strerror(errno));
622 return -1;
623 }
624 ep = ((caddr_t)newmsg) + len;
625
626 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
627 getpid());
628 if (!p) {
629 free(newmsg);
630 return -1;
631 }
632 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
633 IPSEC_ULPROTO_ANY);
634 if (!p) {
635 free(newmsg);
636 return -1;
637 }
638 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
639 IPSEC_ULPROTO_ANY);
640 if (!p || p != ep) {
641 free(newmsg);
642 return -1;
643 }
644
645 /* send message */
646 len = pfkey_send(so, newmsg, len);
647 free(newmsg);
648
649 if (len < 0)
650 return -1;
651
652 __ipsec_errcode = EIPSEC_NO_ERROR;
653 return len;
654 }
655
656 /*
657 * sending SADB_GET message to the kernel.
658 * OUT:
659 * positive: success and return length sent.
660 * -1 : error occured, and set errno.
661 */
662 int
663 pfkey_send_get(so, satype, mode, src, dst, spi)
664 int so;
665 u_int satype, mode;
666 struct sockaddr *src, *dst;
667 u_int32_t spi;
668 {
669 int len;
670 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
671 return -1;
672
673 return len;
674 }
675
676 /*
677 * sending SADB_REGISTER message to the kernel.
678 * OUT:
679 * positive: success and return length sent.
680 * -1 : error occured, and set errno.
681 */
682 int
683 pfkey_send_register(so, satype)
684 int so;
685 u_int satype;
686 {
687 int len, algno;
688
689 if (satype == PF_UNSPEC) {
690 for (algno = 0;
691 (unsigned int)algno < sizeof(supported_map)/sizeof(supported_map[0]);
692 algno++) {
693 if (ipsec_supported[algno]) {
694 free(ipsec_supported[algno]);
695 ipsec_supported[algno] = NULL;
696 }
697 }
698 } else {
699 algno = findsupportedmap(satype);
700 if (algno == -1) {
701 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
702 return -1;
703 }
704
705 if (ipsec_supported[algno]) {
706 free(ipsec_supported[algno]);
707 ipsec_supported[algno] = NULL;
708 }
709 }
710
711 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
712 return -1;
713
714 return len;
715 }
716
717 /*
718 * receiving SADB_REGISTER message from the kernel, and copy buffer for
719 * sadb_supported returned into ipsec_supported.
720 * OUT:
721 * 0: success and return length sent.
722 * -1: error occured, and set errno.
723 */
724 int
725 pfkey_recv_register(so)
726 int so;
727 {
728 pid_t pid = getpid();
729 struct sadb_msg *newmsg;
730 int error = -1;
731
732 /* receive message */
733 do {
734 if ((newmsg = pfkey_recv(so)) == NULL)
735 return -1;
736 } while (newmsg->sadb_msg_type != SADB_REGISTER
737 || (pid_t)newmsg->sadb_msg_pid != pid);
738
739 /* check and fix */
740 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
741
742 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
743 free(newmsg);
744
745 if (error == 0)
746 __ipsec_errcode = EIPSEC_NO_ERROR;
747
748 return error;
749 }
750
751 /*
752 * receiving SADB_REGISTER message from the kernel, and copy buffer for
753 * sadb_supported returned into ipsec_supported.
754 * NOTE: sadb_msg_len must be host order.
755 * IN:
756 * tlen: msg length, it's to makeing sure.
757 * OUT:
758 * 0: success and return length sent.
759 * -1: error occured, and set errno.
760 */
761 int
762 pfkey_set_supported(msg, tlen)
763 struct sadb_msg *msg;
764 int tlen;
765 {
766 struct sadb_supported *sup;
767 caddr_t p;
768 caddr_t ep;
769
770 /* validity */
771 if (msg->sadb_msg_len != tlen) {
772 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
773 return -1;
774 }
775
776 p = (caddr_t)msg;
777 ep = p + tlen;
778
779 p += sizeof(struct sadb_msg);
780
781 while (p < ep) {
782 sup = (struct sadb_supported *)p;
783 if (ep < p + sizeof(*sup) ||
784 (size_t)PFKEY_EXTLEN(sup) < sizeof(*sup) ||
785 ep < p + sup->sadb_supported_len) {
786 /* invalid format */
787 break;
788 }
789
790 switch (sup->sadb_supported_exttype) {
791 case SADB_EXT_SUPPORTED_AUTH:
792 case SADB_EXT_SUPPORTED_ENCRYPT:
793 break;
794 default:
795 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
796 return -1;
797 }
798
799 /* fixed length */
800 sup->sadb_supported_len = PFKEY_EXTLEN(sup);
801
802 /* set supported map */
803 if (setsupportedmap(sup) != 0)
804 return -1;
805
806 p += sup->sadb_supported_len;
807 }
808
809 if (p != ep) {
810 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
811 return -1;
812 }
813
814 __ipsec_errcode = EIPSEC_NO_ERROR;
815
816 return 0;
817 }
818
819 /*
820 * sending SADB_FLUSH message to the kernel.
821 * OUT:
822 * positive: success and return length sent.
823 * -1 : error occured, and set errno.
824 */
825 int
826 pfkey_send_flush(so, satype)
827 int so;
828 u_int satype;
829 {
830 int len;
831
832 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
833 return -1;
834
835 return len;
836 }
837
838 /*
839 * sending SADB_DUMP message to the kernel.
840 * OUT:
841 * positive: success and return length sent.
842 * -1 : error occured, and set errno.
843 */
844 int
845 pfkey_send_dump(so, satype)
846 int so;
847 u_int satype;
848 {
849 int len;
850
851 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
852 return -1;
853
854 return len;
855 }
856
857 /*
858 * sending SADB_X_PROMISC message to the kernel.
859 * NOTE that this function handles promisc mode toggle only.
860 * IN:
861 * flag: set promisc off if zero, set promisc on if non-zero.
862 * OUT:
863 * positive: success and return length sent.
864 * -1 : error occured, and set errno.
865 * 0 : error occured, and set errno.
866 * others: a pointer to new allocated buffer in which supported
867 * algorithms is.
868 */
869 int
870 pfkey_send_promisc_toggle(so, flag)
871 int so;
872 int flag;
873 {
874 int len;
875
876 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
877 return -1;
878
879 return len;
880 }
881
882 /*
883 * sending SADB_X_SPDADD message to the kernel.
884 * OUT:
885 * positive: success and return length sent.
886 * -1 : error occured, and set errno.
887 */
888 int
889 pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
890 int so;
891 struct sockaddr *src, *dst;
892 u_int prefs, prefd, proto;
893 caddr_t policy;
894 int policylen;
895 u_int32_t seq;
896 {
897 int len;
898
899 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
900 src, prefs, dst, prefd, proto,
901 0, 0,
902 policy, policylen, seq)) < 0)
903 return -1;
904
905 return len;
906 }
907
908 /*
909 * sending SADB_X_SPDADD message to the kernel.
910 * OUT:
911 * positive: success and return length sent.
912 * -1 : error occured, and set errno.
913 */
914 int
915 pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
916 policy, policylen, seq)
917 int so;
918 struct sockaddr *src, *dst;
919 u_int prefs, prefd, proto;
920 u_int64_t ltime, vtime;
921 caddr_t policy;
922 int policylen;
923 u_int32_t seq;
924 {
925 int len;
926
927 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
928 src, prefs, dst, prefd, proto,
929 ltime, vtime,
930 policy, policylen, seq)) < 0)
931 return -1;
932
933 return len;
934 }
935
936 /*
937 * sending SADB_X_SPDUPDATE message to the kernel.
938 * OUT:
939 * positive: success and return length sent.
940 * -1 : error occured, and set errno.
941 */
942 int
943 pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
944 int so;
945 struct sockaddr *src, *dst;
946 u_int prefs, prefd, proto;
947 caddr_t policy;
948 int policylen;
949 u_int32_t seq;
950 {
951 int len;
952
953 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
954 src, prefs, dst, prefd, proto,
955 0, 0,
956 policy, policylen, seq)) < 0)
957 return -1;
958
959 return len;
960 }
961
962 /*
963 * sending SADB_X_SPDUPDATE message to the kernel.
964 * OUT:
965 * positive: success and return length sent.
966 * -1 : error occured, and set errno.
967 */
968 int
969 pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
970 policy, policylen, seq)
971 int so;
972 struct sockaddr *src, *dst;
973 u_int prefs, prefd, proto;
974 u_int64_t ltime, vtime;
975 caddr_t policy;
976 int policylen;
977 u_int32_t seq;
978 {
979 int len;
980
981 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
982 src, prefs, dst, prefd, proto,
983 ltime, vtime,
984 policy, policylen, seq)) < 0)
985 return -1;
986
987 return len;
988 }
989
990 /*
991 * sending SADB_X_SPDDELETE message to the kernel.
992 * OUT:
993 * positive: success and return length sent.
994 * -1 : error occured, and set errno.
995 */
996 int
997 pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
998 int so;
999 struct sockaddr *src, *dst;
1000 u_int prefs, prefd, proto;
1001 caddr_t policy;
1002 int policylen;
1003 u_int32_t seq;
1004 {
1005 int len;
1006
1007 if (policylen != sizeof(struct sadb_x_policy)) {
1008 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1009 return -1;
1010 }
1011
1012 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
1013 src, prefs, dst, prefd, proto,
1014 0, 0,
1015 policy, policylen, seq)) < 0)
1016 return -1;
1017
1018 return len;
1019 }
1020
1021 /*
1022 * sending SADB_X_SPDDELETE message to the kernel.
1023 * OUT:
1024 * positive: success and return length sent.
1025 * -1 : error occured, and set errno.
1026 */
1027 int
1028 pfkey_send_spddelete2(so, spid)
1029 int so;
1030 u_int32_t spid;
1031 {
1032 int len;
1033
1034 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
1035 return -1;
1036
1037 return len;
1038 }
1039
1040 /*
1041 * sending SADB_X_SPDGET message to the kernel.
1042 * OUT:
1043 * positive: success and return length sent.
1044 * -1 : error occured, and set errno.
1045 */
1046 int
1047 pfkey_send_spdget(so, spid)
1048 int so;
1049 u_int32_t spid;
1050 {
1051 int len;
1052
1053 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
1054 return -1;
1055
1056 return len;
1057 }
1058
1059 /*
1060 * sending SADB_X_SPDSETIDX message to the kernel.
1061 * OUT:
1062 * positive: success and return length sent.
1063 * -1 : error occured, and set errno.
1064 */
1065 int
1066 pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1067 int so;
1068 struct sockaddr *src, *dst;
1069 u_int prefs, prefd, proto;
1070 caddr_t policy;
1071 int policylen;
1072 u_int32_t seq;
1073 {
1074 int len;
1075
1076 if (policylen != sizeof(struct sadb_x_policy)) {
1077 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1078 return -1;
1079 }
1080
1081 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
1082 src, prefs, dst, prefd, proto,
1083 0, 0,
1084 policy, policylen, seq)) < 0)
1085 return -1;
1086
1087 return len;
1088 }
1089
1090 /*
1091 * sending SADB_SPDFLUSH message to the kernel.
1092 * OUT:
1093 * positive: success and return length sent.
1094 * -1 : error occured, and set errno.
1095 */
1096 int
1097 pfkey_send_spdflush(so)
1098 int so;
1099 {
1100 int len;
1101
1102 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
1103 return -1;
1104
1105 return len;
1106 }
1107
1108 /*
1109 * sending SADB_SPDDUMP message to the kernel.
1110 * OUT:
1111 * positive: success and return length sent.
1112 * -1 : error occured, and set errno.
1113 */
1114 int
1115 pfkey_send_spddump(so)
1116 int so;
1117 {
1118 int len;
1119
1120 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
1121 return -1;
1122
1123 return len;
1124 }
1125
1126 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1127 static int
1128 pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
1129 keymat, e_type, e_keylen, a_type, a_keylen, flags,
1130 l_alloc, l_bytes, l_addtime, l_usetime, seq)
1131 int so;
1132 u_int type, satype, mode;
1133 struct sockaddr *src, *dst;
1134 u_int32_t spi, reqid;
1135 u_int wsize;
1136 caddr_t keymat;
1137 u_int e_type, e_keylen, a_type, a_keylen, flags;
1138 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
1139 {
1140 struct sadb_msg *newmsg;
1141 int len;
1142 caddr_t p;
1143 int plen;
1144 caddr_t ep;
1145
1146 /* validity check */
1147 if (src == NULL || dst == NULL) {
1148 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1149 return -1;
1150 }
1151 if (src->sa_family != dst->sa_family) {
1152 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1153 return -1;
1154 }
1155 switch (src->sa_family) {
1156 case AF_INET:
1157 plen = sizeof(struct in_addr) << 3;
1158 break;
1159 case AF_INET6:
1160 plen = sizeof(struct in6_addr) << 3;
1161 break;
1162 default:
1163 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1164 return -1;
1165 }
1166
1167 switch (satype) {
1168 case SADB_SATYPE_ESP:
1169 if (e_type == SADB_EALG_NONE) {
1170 __ipsec_errcode = EIPSEC_NO_ALGS;
1171 return -1;
1172 }
1173 break;
1174 case SADB_SATYPE_AH:
1175 if (e_type != SADB_EALG_NONE) {
1176 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1177 return -1;
1178 }
1179 if (a_type == SADB_AALG_NONE) {
1180 __ipsec_errcode = EIPSEC_NO_ALGS;
1181 return -1;
1182 }
1183 break;
1184 case SADB_X_SATYPE_IPCOMP:
1185 if (e_type == SADB_X_CALG_NONE) {
1186 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1187 return -1;
1188 }
1189 if (a_type != SADB_AALG_NONE) {
1190 __ipsec_errcode = EIPSEC_NO_ALGS;
1191 return -1;
1192 }
1193 break;
1194 default:
1195 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1196 return -1;
1197 }
1198
1199 /* create new sadb_msg to reply. */
1200 len = sizeof(struct sadb_msg)
1201 + sizeof(struct sadb_sa)
1202 + sizeof(struct sadb_x_sa2)
1203 + sizeof(struct sadb_address)
1204 + PFKEY_ALIGN8(src->sa_len)
1205 + sizeof(struct sadb_address)
1206 + PFKEY_ALIGN8(dst->sa_len)
1207 + sizeof(struct sadb_lifetime)
1208 + sizeof(struct sadb_lifetime);
1209
1210 if (e_type != SADB_EALG_NONE)
1211 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1212 if (a_type != SADB_AALG_NONE)
1213 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1214
1215 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1216 __ipsec_set_strerror(strerror(errno));
1217 return -1;
1218 }
1219 ep = ((caddr_t)newmsg) + len;
1220
1221 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1222 satype, seq, getpid());
1223 if (!p) {
1224 free(newmsg);
1225 return -1;
1226 }
1227 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
1228 if (!p) {
1229 free(newmsg);
1230 return -1;
1231 }
1232 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1233 if (!p) {
1234 free(newmsg);
1235 return -1;
1236 }
1237 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1238 IPSEC_ULPROTO_ANY);
1239 if (!p) {
1240 free(newmsg);
1241 return -1;
1242 }
1243 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1244 IPSEC_ULPROTO_ANY);
1245 if (!p) {
1246 free(newmsg);
1247 return -1;
1248 }
1249
1250 if (e_type != SADB_EALG_NONE) {
1251 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1252 keymat, e_keylen);
1253 if (!p) {
1254 free(newmsg);
1255 return -1;
1256 }
1257 }
1258 if (a_type != SADB_AALG_NONE) {
1259 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1260 keymat + e_keylen, a_keylen);
1261 if (!p) {
1262 free(newmsg);
1263 return -1;
1264 }
1265 }
1266
1267 /* set sadb_lifetime for destination */
1268 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1269 l_alloc, l_bytes, l_addtime, l_usetime);
1270 if (!p) {
1271 free(newmsg);
1272 return -1;
1273 }
1274 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1275 l_alloc, l_bytes, l_addtime, l_usetime);
1276 if (!p || p != ep) {
1277 free(newmsg);
1278 return -1;
1279 }
1280
1281 /* send message */
1282 len = pfkey_send(so, newmsg, len);
1283 free(newmsg);
1284
1285 if (len < 0)
1286 return -1;
1287
1288 __ipsec_errcode = EIPSEC_NO_ERROR;
1289 return len;
1290 }
1291
1292 /* sending SADB_DELETE or SADB_GET message to the kernel */
1293 static int
1294 pfkey_send_x2(so, type, satype, mode, src, dst, spi)
1295 int so;
1296 u_int type, satype, mode;
1297 struct sockaddr *src, *dst;
1298 u_int32_t spi;
1299 {
1300 struct sadb_msg *newmsg;
1301 int len;
1302 caddr_t p;
1303 int plen;
1304 caddr_t ep;
1305
1306 (void)mode;
1307
1308 /* validity check */
1309 if (src == NULL || dst == NULL) {
1310 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1311 return -1;
1312 }
1313 if (src->sa_family != dst->sa_family) {
1314 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1315 return -1;
1316 }
1317 switch (src->sa_family) {
1318 case AF_INET:
1319 plen = sizeof(struct in_addr) << 3;
1320 break;
1321 case AF_INET6:
1322 plen = sizeof(struct in6_addr) << 3;
1323 break;
1324 default:
1325 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1326 return -1;
1327 }
1328
1329 /* create new sadb_msg to reply. */
1330 len = sizeof(struct sadb_msg)
1331 + sizeof(struct sadb_sa)
1332 + sizeof(struct sadb_address)
1333 + PFKEY_ALIGN8(src->sa_len)
1334 + sizeof(struct sadb_address)
1335 + PFKEY_ALIGN8(dst->sa_len);
1336
1337 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1338 __ipsec_set_strerror(strerror(errno));
1339 return -1;
1340 }
1341 ep = ((caddr_t)newmsg) + len;
1342
1343 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1344 getpid());
1345 if (!p) {
1346 free(newmsg);
1347 return -1;
1348 }
1349 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
1350 if (!p) {
1351 free(newmsg);
1352 return -1;
1353 }
1354 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1355 IPSEC_ULPROTO_ANY);
1356 if (!p) {
1357 free(newmsg);
1358 return -1;
1359 }
1360 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1361 IPSEC_ULPROTO_ANY);
1362 if (!p || p != ep) {
1363 free(newmsg);
1364 return -1;
1365 }
1366
1367 /* send message */
1368 len = pfkey_send(so, newmsg, len);
1369 free(newmsg);
1370
1371 if (len < 0)
1372 return -1;
1373
1374 __ipsec_errcode = EIPSEC_NO_ERROR;
1375 return len;
1376 }
1377
1378 /*
1379 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1380 * to the kernel
1381 */
1382 static int
1383 pfkey_send_x3(so, type, satype)
1384 int so;
1385 u_int type, satype;
1386 {
1387 struct sadb_msg *newmsg;
1388 int len;
1389 caddr_t p;
1390 caddr_t ep;
1391
1392 /* validity check */
1393 switch (type) {
1394 case SADB_X_PROMISC:
1395 if (satype != 0 && satype != 1) {
1396 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1397 return -1;
1398 }
1399 break;
1400 default:
1401 switch (satype) {
1402 case SADB_SATYPE_UNSPEC:
1403 case SADB_SATYPE_AH:
1404 case SADB_SATYPE_ESP:
1405 case SADB_X_SATYPE_IPCOMP:
1406 break;
1407 default:
1408 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1409 return -1;
1410 }
1411 }
1412
1413 /* create new sadb_msg to send. */
1414 len = sizeof(struct sadb_msg);
1415
1416 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1417 __ipsec_set_strerror(strerror(errno));
1418 return -1;
1419 }
1420 ep = ((caddr_t)newmsg) + len;
1421
1422 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1423 getpid());
1424 if (!p || p != ep) {
1425 free(newmsg);
1426 return -1;
1427 }
1428
1429 /* send message */
1430 len = pfkey_send(so, newmsg, len);
1431 free(newmsg);
1432
1433 if (len < 0)
1434 return -1;
1435
1436 __ipsec_errcode = EIPSEC_NO_ERROR;
1437 return len;
1438 }
1439
1440 /* sending SADB_X_SPDADD message to the kernel */
1441 static int
1442 pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
1443 ltime, vtime, policy, policylen, seq)
1444 int so;
1445 struct sockaddr *src, *dst;
1446 u_int type, prefs, prefd, proto;
1447 u_int64_t ltime, vtime;
1448 char *policy;
1449 int policylen;
1450 u_int32_t seq;
1451 {
1452 struct sadb_msg *newmsg;
1453 int len;
1454 caddr_t p;
1455 int plen;
1456 caddr_t ep;
1457
1458 /* validity check */
1459 if (src == NULL || dst == NULL) {
1460 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1461 return -1;
1462 }
1463 if (src->sa_family != dst->sa_family) {
1464 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1465 return -1;
1466 }
1467
1468 switch (src->sa_family) {
1469 case AF_INET:
1470 plen = sizeof(struct in_addr) << 3;
1471 break;
1472 case AF_INET6:
1473 plen = sizeof(struct in6_addr) << 3;
1474 break;
1475 default:
1476 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1477 return -1;
1478 }
1479 if (prefs > (u_int)plen || prefd > (u_int)plen) {
1480 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
1481 return -1;
1482 }
1483
1484 /* create new sadb_msg to reply. */
1485 len = sizeof(struct sadb_msg)
1486 + sizeof(struct sadb_address)
1487 + PFKEY_ALIGN8(src->sa_len)
1488 + sizeof(struct sadb_address)
1489 + PFKEY_ALIGN8(src->sa_len)
1490 + sizeof(struct sadb_lifetime)
1491 + policylen;
1492
1493 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1494 __ipsec_set_strerror(strerror(errno));
1495 return -1;
1496 }
1497 ep = ((caddr_t)newmsg) + len;
1498
1499 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1500 SADB_SATYPE_UNSPEC, seq, getpid());
1501 if (!p) {
1502 free(newmsg);
1503 return -1;
1504 }
1505 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
1506 if (!p) {
1507 free(newmsg);
1508 return -1;
1509 }
1510 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
1511 if (!p) {
1512 free(newmsg);
1513 return -1;
1514 }
1515 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1516 0, 0, ltime, vtime);
1517 if (!p || p + policylen != ep) {
1518 free(newmsg);
1519 return -1;
1520 }
1521 memcpy(p, policy, policylen);
1522
1523 /* send message */
1524 len = pfkey_send(so, newmsg, len);
1525 free(newmsg);
1526
1527 if (len < 0)
1528 return -1;
1529
1530 __ipsec_errcode = EIPSEC_NO_ERROR;
1531 return len;
1532 }
1533
1534 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1535 static int
1536 pfkey_send_x5(so, type, spid)
1537 int so;
1538 u_int type;
1539 u_int32_t spid;
1540 {
1541 struct sadb_msg *newmsg;
1542 struct sadb_x_policy xpl;
1543 int len;
1544 caddr_t p;
1545 caddr_t ep;
1546
1547 /* create new sadb_msg to reply. */
1548 len = sizeof(struct sadb_msg)
1549 + sizeof(xpl);
1550
1551 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1552 __ipsec_set_strerror(strerror(errno));
1553 return -1;
1554 }
1555 ep = ((caddr_t)newmsg) + len;
1556
1557 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1558 SADB_SATYPE_UNSPEC, 0, getpid());
1559 if (!p) {
1560 free(newmsg);
1561 return -1;
1562 }
1563
1564 if (p + sizeof(xpl) != ep) {
1565 free(newmsg);
1566 return -1;
1567 }
1568 memset(&xpl, 0, sizeof(xpl));
1569 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
1570 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1571 xpl.sadb_x_policy_id = spid;
1572 memcpy(p, &xpl, sizeof(xpl));
1573
1574 /* send message */
1575 len = pfkey_send(so, newmsg, len);
1576 free(newmsg);
1577
1578 if (len < 0)
1579 return -1;
1580
1581 __ipsec_errcode = EIPSEC_NO_ERROR;
1582 return len;
1583 }
1584
1585 /*
1586 * open a socket.
1587 * OUT:
1588 * -1: fail.
1589 * others : success and return value of socket.
1590 */
1591 int
1592 pfkey_open()
1593 {
1594 int so;
1595 const int bufsiz = 128 * 1024; /*is 128K enough?*/
1596
1597 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
1598 __ipsec_set_strerror(strerror(errno));
1599 return -1;
1600 }
1601
1602 /*
1603 * This is a temporary workaround for KAME PR 154.
1604 * Don't really care even if it fails.
1605 */
1606 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
1607 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
1608
1609 __ipsec_errcode = EIPSEC_NO_ERROR;
1610 return so;
1611 }
1612
1613 /*
1614 * close a socket.
1615 * OUT:
1616 * 0: success.
1617 * -1: fail.
1618 */
1619 void
1620 pfkey_close(so)
1621 int so;
1622 {
1623 (void)close(so);
1624
1625 __ipsec_errcode = EIPSEC_NO_ERROR;
1626 return;
1627 }
1628
1629 /*
1630 * receive sadb_msg data, and return pointer to new buffer allocated.
1631 * Must free this buffer later.
1632 * OUT:
1633 * NULL : error occured.
1634 * others : a pointer to sadb_msg structure.
1635 *
1636 * XXX should be rewritten to pass length explicitly
1637 */
1638 struct sadb_msg *
1639 pfkey_recv(so)
1640 int so;
1641 {
1642 struct sadb_msg buf, *newmsg;
1643 int len, reallen;
1644
1645 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
1646 if (errno == EINTR)
1647 continue;
1648 __ipsec_set_strerror(strerror(errno));
1649 return NULL;
1650 }
1651
1652 if ((size_t)len < sizeof(buf)) {
1653 recv(so, (caddr_t)&buf, sizeof(buf), 0);
1654 __ipsec_errcode = EIPSEC_MAX;
1655 return NULL;
1656 }
1657
1658 /* read real message */
1659 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
1660 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) {
1661 __ipsec_set_strerror(strerror(errno));
1662 return NULL;
1663 }
1664
1665 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
1666 if (errno == EINTR)
1667 continue;
1668 __ipsec_set_strerror(strerror(errno));
1669 free(newmsg);
1670 return NULL;
1671 }
1672
1673 if (len != reallen) {
1674 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1675 free(newmsg);
1676 return NULL;
1677 }
1678
1679 /* don't trust what the kernel says, validate! */
1680 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
1681 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1682 free(newmsg);
1683 return NULL;
1684 }
1685
1686 __ipsec_errcode = EIPSEC_NO_ERROR;
1687 return newmsg;
1688 }
1689
1690 /*
1691 * send message to a socket.
1692 * OUT:
1693 * others: success and return length sent.
1694 * -1 : fail.
1695 */
1696 int
1697 pfkey_send(so, msg, len)
1698 int so;
1699 struct sadb_msg *msg;
1700 int len;
1701 {
1702 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
1703 __ipsec_set_strerror(strerror(errno));
1704 return -1;
1705 }
1706
1707 __ipsec_errcode = EIPSEC_NO_ERROR;
1708 return len;
1709 }
1710
1711 /*
1712 * %%% Utilities
1713 * NOTE: These functions are derived from netkey/key.c in KAME.
1714 */
1715 /*
1716 * set the pointer to each header in this message buffer.
1717 * IN: msg: pointer to message buffer.
1718 * mhp: pointer to the buffer initialized like below:
1719 * caddr_t mhp[SADB_EXT_MAX + 1];
1720 * OUT: -1: invalid.
1721 * 0: valid.
1722 *
1723 * XXX should be rewritten to obtain length explicitly
1724 */
1725 int
1726 pfkey_align(msg, mhp)
1727 struct sadb_msg *msg;
1728 caddr_t *mhp;
1729 {
1730 struct sadb_ext *ext;
1731 int i;
1732 caddr_t p;
1733 caddr_t ep; /* XXX should be passed from upper layer */
1734
1735 /* validity check */
1736 if (msg == NULL || mhp == NULL) {
1737 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1738 return -1;
1739 }
1740
1741 /* initialize */
1742 for (i = 0; i < SADB_EXT_MAX + 1; i++)
1743 mhp[i] = NULL;
1744
1745 mhp[0] = (caddr_t)msg;
1746
1747 /* initialize */
1748 p = (caddr_t) msg;
1749 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
1750
1751 /* skip base header */
1752 p += sizeof(struct sadb_msg);
1753
1754 while (p < ep) {
1755 ext = (struct sadb_ext *)p;
1756 if (ep < p + sizeof(*ext) || (size_t)PFKEY_EXTLEN(ext) < sizeof(*ext) ||
1757 ep < p + PFKEY_EXTLEN(ext)) {
1758 /* invalid format */
1759 break;
1760 }
1761
1762 /* duplicate check */
1763 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1764 if (mhp[ext->sadb_ext_type] != NULL) {
1765 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1766 return -1;
1767 }
1768
1769 /* set pointer */
1770 switch (ext->sadb_ext_type) {
1771 case SADB_EXT_SA:
1772 case SADB_EXT_LIFETIME_CURRENT:
1773 case SADB_EXT_LIFETIME_HARD:
1774 case SADB_EXT_LIFETIME_SOFT:
1775 case SADB_EXT_ADDRESS_SRC:
1776 case SADB_EXT_ADDRESS_DST:
1777 case SADB_EXT_ADDRESS_PROXY:
1778 case SADB_EXT_KEY_AUTH:
1779 /* XXX should to be check weak keys. */
1780 case SADB_EXT_KEY_ENCRYPT:
1781 /* XXX should to be check weak keys. */
1782 case SADB_EXT_IDENTITY_SRC:
1783 case SADB_EXT_IDENTITY_DST:
1784 case SADB_EXT_SENSITIVITY:
1785 case SADB_EXT_PROPOSAL:
1786 case SADB_EXT_SUPPORTED_AUTH:
1787 case SADB_EXT_SUPPORTED_ENCRYPT:
1788 case SADB_EXT_SPIRANGE:
1789 case SADB_X_EXT_POLICY:
1790 case SADB_X_EXT_SA2:
1791 mhp[ext->sadb_ext_type] = (caddr_t)ext;
1792 break;
1793 default:
1794 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1795 return -1;
1796 }
1797
1798 p += PFKEY_EXTLEN(ext);
1799 }
1800
1801 if (p != ep) {
1802 __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
1803 return -1;
1804 }
1805
1806 __ipsec_errcode = EIPSEC_NO_ERROR;
1807 return 0;
1808 }
1809
1810 /*
1811 * check basic usage for sadb_msg,
1812 * NOTE: This routine is derived from netkey/key.c in KAME.
1813 * IN: msg: pointer to message buffer.
1814 * mhp: pointer to the buffer initialized like below:
1815 *
1816 * caddr_t mhp[SADB_EXT_MAX + 1];
1817 *
1818 * OUT: -1: invalid.
1819 * 0: valid.
1820 */
1821 int
1822 pfkey_check(mhp)
1823 caddr_t *mhp;
1824 {
1825 struct sadb_msg *msg;
1826
1827 /* validity check */
1828 if (mhp == NULL || mhp[0] == NULL) {
1829 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1830 return -1;
1831 }
1832
1833 msg = (struct sadb_msg *)mhp[0];
1834
1835 /* check version */
1836 if (msg->sadb_msg_version != PF_KEY_V2) {
1837 __ipsec_errcode = EIPSEC_INVAL_VERSION;
1838 return -1;
1839 }
1840
1841 /* check type */
1842 if (msg->sadb_msg_type > SADB_MAX) {
1843 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
1844 return -1;
1845 }
1846
1847 /* check SA type */
1848 switch (msg->sadb_msg_satype) {
1849 case SADB_SATYPE_UNSPEC:
1850 switch (msg->sadb_msg_type) {
1851 case SADB_GETSPI:
1852 case SADB_UPDATE:
1853 case SADB_ADD:
1854 case SADB_DELETE:
1855 case SADB_GET:
1856 case SADB_ACQUIRE:
1857 case SADB_EXPIRE:
1858 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1859 return -1;
1860 }
1861 break;
1862 case SADB_SATYPE_ESP:
1863 case SADB_SATYPE_AH:
1864 case SADB_X_SATYPE_IPCOMP:
1865 switch (msg->sadb_msg_type) {
1866 case SADB_X_SPDADD:
1867 case SADB_X_SPDDELETE:
1868 case SADB_X_SPDGET:
1869 case SADB_X_SPDDUMP:
1870 case SADB_X_SPDFLUSH:
1871 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1872 return -1;
1873 }
1874 break;
1875 case SADB_SATYPE_RSVP:
1876 case SADB_SATYPE_OSPFV2:
1877 case SADB_SATYPE_RIPV2:
1878 case SADB_SATYPE_MIP:
1879 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
1880 return -1;
1881 case 1: /* XXX: What does it do ? */
1882 if (msg->sadb_msg_type == SADB_X_PROMISC)
1883 break;
1884 /*FALLTHROUGH*/
1885 default:
1886 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1887 return -1;
1888 }
1889
1890 /* check field of upper layer protocol and address family */
1891 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
1892 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
1893 struct sadb_address *src0, *dst0;
1894
1895 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]);
1896 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
1897
1898 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
1899 __ipsec_errcode = EIPSEC_PROTO_MISMATCH;
1900 return -1;
1901 }
1902
1903 if (PFKEY_ADDR_SADDR(src0)->sa_family
1904 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
1905 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1906 return -1;
1907 }
1908
1909 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
1910 case AF_INET:
1911 case AF_INET6:
1912 break;
1913 default:
1914 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1915 return -1;
1916 }
1917
1918 /*
1919 * prefixlen == 0 is valid because there must be the case
1920 * all addresses are matched.
1921 */
1922 }
1923
1924 __ipsec_errcode = EIPSEC_NO_ERROR;
1925 return 0;
1926 }
1927
1928 /*
1929 * set data into sadb_msg.
1930 * `buf' must has been allocated sufficiently.
1931 */
1932 static caddr_t
1933 pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
1934 caddr_t buf;
1935 caddr_t lim;
1936 u_int type, satype;
1937 u_int tlen;
1938 u_int32_t seq;
1939 pid_t pid;
1940 {
1941 struct sadb_msg *p;
1942 u_int len;
1943
1944 p = (struct sadb_msg *)buf;
1945 len = sizeof(struct sadb_msg);
1946
1947 if (buf + len > lim)
1948 return NULL;
1949
1950 memset(p, 0, len);
1951 p->sadb_msg_version = PF_KEY_V2;
1952 p->sadb_msg_type = type;
1953 p->sadb_msg_errno = 0;
1954 p->sadb_msg_satype = satype;
1955 p->sadb_msg_len = PFKEY_UNIT64(tlen);
1956 p->sadb_msg_reserved = 0;
1957 p->sadb_msg_seq = seq;
1958 p->sadb_msg_pid = (u_int32_t)pid;
1959
1960 return(buf + len);
1961 }
1962
1963 /*
1964 * copy secasvar data into sadb_address.
1965 * `buf' must has been allocated sufficiently.
1966 */
1967 static caddr_t
1968 pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
1969 caddr_t buf;
1970 caddr_t lim;
1971 u_int32_t spi, flags;
1972 u_int wsize, auth, enc;
1973 {
1974 struct sadb_sa *p;
1975 u_int len;
1976
1977 p = (struct sadb_sa *)buf;
1978 len = sizeof(struct sadb_sa);
1979
1980 if (buf + len > lim)
1981 return NULL;
1982
1983 memset(p, 0, len);
1984 p->sadb_sa_len = PFKEY_UNIT64(len);
1985 p->sadb_sa_exttype = SADB_EXT_SA;
1986 p->sadb_sa_spi = spi;
1987 p->sadb_sa_replay = wsize;
1988 p->sadb_sa_state = SADB_SASTATE_LARVAL;
1989 p->sadb_sa_auth = auth;
1990 p->sadb_sa_encrypt = enc;
1991 p->sadb_sa_flags = flags;
1992
1993 return(buf + len);
1994 }
1995
1996 /*
1997 * set data into sadb_address.
1998 * `buf' must has been allocated sufficiently.
1999 * prefixlen is in bits.
2000 */
2001 static caddr_t
2002 pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
2003 caddr_t buf;
2004 caddr_t lim;
2005 u_int exttype;
2006 struct sockaddr *saddr;
2007 u_int prefixlen;
2008 u_int ul_proto;
2009 {
2010 struct sadb_address *p;
2011 u_int len;
2012
2013 p = (struct sadb_address *)buf;
2014 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
2015
2016 if (buf + len > lim)
2017 return NULL;
2018
2019 memset(p, 0, len);
2020 p->sadb_address_len = PFKEY_UNIT64(len);
2021 p->sadb_address_exttype = exttype & 0xffff;
2022 p->sadb_address_proto = ul_proto & 0xff;
2023 p->sadb_address_prefixlen = prefixlen;
2024 p->sadb_address_reserved = 0;
2025
2026 memcpy(p + 1, saddr, saddr->sa_len);
2027
2028 return(buf + len);
2029 }
2030
2031 /*
2032 * set sadb_key structure after clearing buffer with zero.
2033 * OUT: the pointer of buf + len.
2034 */
2035 static caddr_t
2036 pfkey_setsadbkey(buf, lim, type, key, keylen)
2037 caddr_t buf;
2038 caddr_t lim;
2039 caddr_t key;
2040 u_int type, keylen;
2041 {
2042 struct sadb_key *p;
2043 u_int len;
2044
2045 p = (struct sadb_key *)buf;
2046 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
2047
2048 if (buf + len > lim)
2049 return NULL;
2050
2051 memset(p, 0, len);
2052 p->sadb_key_len = PFKEY_UNIT64(len);
2053 p->sadb_key_exttype = type;
2054 p->sadb_key_bits = keylen << 3;
2055 p->sadb_key_reserved = 0;
2056
2057 memcpy(p + 1, key, keylen);
2058
2059 return buf + len;
2060 }
2061
2062 /*
2063 * set sadb_lifetime structure after clearing buffer with zero.
2064 * OUT: the pointer of buf + len.
2065 */
2066 static caddr_t
2067 pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
2068 caddr_t buf;
2069 caddr_t lim;
2070 u_int type;
2071 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
2072 {
2073 struct sadb_lifetime *p;
2074 u_int len;
2075
2076 p = (struct sadb_lifetime *)buf;
2077 len = sizeof(struct sadb_lifetime);
2078
2079 if (buf + len > lim)
2080 return NULL;
2081
2082 memset(p, 0, len);
2083 p->sadb_lifetime_len = PFKEY_UNIT64(len);
2084 p->sadb_lifetime_exttype = type;
2085
2086 switch (type) {
2087 case SADB_EXT_LIFETIME_SOFT:
2088 p->sadb_lifetime_allocations
2089 = (l_alloc * soft_lifetime_allocations_rate) /100;
2090 p->sadb_lifetime_bytes
2091 = (l_bytes * soft_lifetime_bytes_rate) /100;
2092 p->sadb_lifetime_addtime
2093 = (l_addtime * soft_lifetime_addtime_rate) /100;
2094 p->sadb_lifetime_usetime
2095 = (l_usetime * soft_lifetime_usetime_rate) /100;
2096 break;
2097 case SADB_EXT_LIFETIME_HARD:
2098 p->sadb_lifetime_allocations = l_alloc;
2099 p->sadb_lifetime_bytes = l_bytes;
2100 p->sadb_lifetime_addtime = l_addtime;
2101 p->sadb_lifetime_usetime = l_usetime;
2102 break;
2103 }
2104
2105 return buf + len;
2106 }
2107
2108 /*
2109 * copy secasvar data into sadb_address.
2110 * `buf' must has been allocated sufficiently.
2111 */
2112 static caddr_t
2113 pfkey_setsadbxsa2(buf, lim, mode0, reqid)
2114 caddr_t buf;
2115 caddr_t lim;
2116 u_int32_t mode0;
2117 u_int32_t reqid;
2118 {
2119 struct sadb_x_sa2 *p;
2120 u_int8_t mode = mode0 & 0xff;
2121 u_int len;
2122
2123 p = (struct sadb_x_sa2 *)buf;
2124 len = sizeof(struct sadb_x_sa2);
2125
2126 if (buf + len > lim)
2127 return NULL;
2128
2129 memset(p, 0, len);
2130 p->sadb_x_sa2_len = PFKEY_UNIT64(len);
2131 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
2132 p->sadb_x_sa2_mode = mode;
2133 p->sadb_x_sa2_reqid = reqid;
2134
2135 return(buf + len);
2136 }
2137
2138 #endif /* ndef MDNS_NO_IPSEC */