1 /* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <System/net/pfkeyv2.h>
42 #include <net/pfkeyv2.h>
44 #include <netinet/in.h>
45 #ifdef HAVE_NETINET6_IPSEC
46 # include <netinet6/ipsec.h>
48 # include <netinet/ipsec.h>
57 #include "ipsec_strerror.h"
60 #define CALLOC(size, cast) (cast)calloc(1, (size))
62 static int findsupportedmap
__P((int));
63 static int setsupportedmap
__P((struct sadb_supported
*));
64 static struct sadb_alg
*findsupportedalg
__P((u_int
, u_int
));
66 static int pfkey_send_x1
__P((int, u_int
, u_int
, u_int
, struct sockaddr
*,
67 struct sockaddr
*, u_int32_t
, u_int32_t
, u_int
, caddr_t
,
68 u_int
, u_int
, u_int
, u_int
, u_int
, u_int32_t
, u_int32_t
,
69 u_int32_t
, u_int32_t
, u_int32_t
, u_int16_t
));
71 static int pfkey_send_x1
__P((int, u_int
, u_int
, u_int
, struct sockaddr
*,
72 struct sockaddr
*, u_int32_t
, u_int32_t
, u_int
, caddr_t
,
73 u_int
, u_int
, u_int
, u_int
, u_int
, u_int32_t
, u_int32_t
,
74 u_int32_t
, u_int32_t
, u_int32_t
,
75 u_int8_t
, u_int16_t
, u_int16_t
, struct sockaddr
*, u_int16_t
));
77 static int pfkey_send_x2
__P((int, u_int
, u_int
, u_int
,
78 struct sockaddr
*, struct sockaddr
*, u_int32_t
));
79 static int pfkey_send_x3
__P((int, u_int
, u_int
));
80 static int pfkey_send_x4
__P((int, u_int
, struct sockaddr
*, u_int
,
81 struct sockaddr
*, u_int
, u_int
, u_int64_t
, u_int64_t
,
82 char *, int, u_int32_t
));
83 static int pfkey_send_x5
__P((int, u_int
, u_int32_t
));
85 static caddr_t pfkey_setsadbmsg
__P((caddr_t
, caddr_t
, u_int
, u_int
,
86 u_int
, u_int32_t
, pid_t
));
88 static caddr_t pfkey_setsadbsa
__P((caddr_t
, caddr_t
, u_int32_t
, u_int
,
89 u_int
, u_int
, u_int32_t
, u_int16_t
));
91 static caddr_t pfkey_setsadbsa
__P((caddr_t
, caddr_t
, u_int32_t
, u_int
,
92 u_int
, u_int
, u_int32_t
));
94 static caddr_t pfkey_setsadbaddr
__P((caddr_t
, caddr_t
, u_int
,
95 struct sockaddr
*, u_int
, u_int
));
96 static caddr_t pfkey_setsadbkey
__P((caddr_t
, caddr_t
, u_int
, caddr_t
, u_int
));
97 static caddr_t pfkey_setsadblifetime
__P((caddr_t
, caddr_t
, u_int
, u_int32_t
,
98 u_int32_t
, u_int32_t
, u_int32_t
));
99 static caddr_t pfkey_setsadbxsa2
__P((caddr_t
, caddr_t
, u_int32_t
, u_int32_t
));
101 #ifdef SADB_X_EXT_NAT_T_TYPE
102 static caddr_t pfkey_set_natt_type
__P((caddr_t
, caddr_t
, u_int
, u_int8_t
));
103 static caddr_t pfkey_set_natt_port
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
105 #ifdef SADB_X_EXT_NAT_T_FRAG
106 static caddr_t pfkey_set_natt_frag
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
110 * make and search supported algorithm structure.
112 static struct sadb_supported
*ipsec_supported
[] = { NULL
, NULL
, NULL
,
113 #ifdef SADB_X_SATYPE_TCPSIGNATURE
118 static int supported_map
[] = {
121 SADB_X_SATYPE_IPCOMP
,
122 #ifdef SADB_X_SATYPE_TCPSIGNATURE
123 SADB_X_SATYPE_TCPSIGNATURE
,
128 findsupportedmap(satype
)
133 for (i
= 0; i
< sizeof(supported_map
)/sizeof(supported_map
[0]); i
++)
134 if (supported_map
[i
] == satype
)
139 static struct sadb_alg
*
140 findsupportedalg(satype
, alg_id
)
141 u_int satype
, alg_id
;
148 algno
= findsupportedmap((int)satype
);
150 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
153 if (ipsec_supported
[algno
] == NULL
) {
154 __ipsec_errcode
= EIPSEC_DO_GET_SUPP_LIST
;
158 tlen
= ipsec_supported
[algno
]->sadb_supported_len
159 - sizeof(struct sadb_supported
);
160 p
= (void *)(ipsec_supported
[algno
] + 1);
162 if (tlen
< sizeof(struct sadb_alg
)) {
166 if (((struct sadb_alg
*)(void *)p
)->sadb_alg_id
== alg_id
)
169 tlen
-= sizeof(struct sadb_alg
);
170 p
+= sizeof(struct sadb_alg
);
173 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
179 struct sadb_supported
*sup
;
181 struct sadb_supported
**ipsup
;
183 switch (sup
->sadb_supported_exttype
) {
184 case SADB_EXT_SUPPORTED_AUTH
:
185 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_AH
)];
187 case SADB_EXT_SUPPORTED_ENCRYPT
:
188 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_ESP
)];
191 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
198 *ipsup
= malloc((size_t)sup
->sadb_supported_len
);
200 __ipsec_set_strerror(strerror(errno
));
203 memcpy(*ipsup
, sup
, (size_t)sup
->sadb_supported_len
);
209 * check key length against algorithm specified.
210 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
211 * augument, and only calls to ipsec_check_keylen2();
212 * keylen is the unit of bit.
218 ipsec_check_keylen(supported
, alg_id
, keylen
)
227 case SADB_EXT_SUPPORTED_AUTH
:
228 satype
= SADB_SATYPE_AH
;
230 case SADB_EXT_SUPPORTED_ENCRYPT
:
231 satype
= SADB_SATYPE_ESP
;
234 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
238 return ipsec_check_keylen2(satype
, alg_id
, keylen
);
242 * check key length against algorithm specified.
243 * satype is one of satype defined at pfkeyv2.h.
244 * keylen is the unit of bit.
250 ipsec_check_keylen2(satype
, alg_id
, keylen
)
255 struct sadb_alg
*alg
;
257 alg
= findsupportedalg(satype
, alg_id
);
261 if (keylen
< alg
->sadb_alg_minbits
|| keylen
> alg
->sadb_alg_maxbits
) {
262 fprintf(stderr
, "%d %d %d\n", keylen
, alg
->sadb_alg_minbits
,
263 alg
->sadb_alg_maxbits
);
264 __ipsec_errcode
= EIPSEC_INVAL_KEYLEN
;
268 __ipsec_errcode
= EIPSEC_NO_ERROR
;
273 * get max/min key length against algorithm specified.
274 * satype is one of satype defined at pfkeyv2.h.
275 * keylen is the unit of bit.
281 ipsec_get_keylen(supported
, alg_id
, alg0
)
282 u_int supported
, alg_id
;
283 struct sadb_alg
*alg0
;
285 struct sadb_alg
*alg
;
290 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
295 case SADB_EXT_SUPPORTED_AUTH
:
296 satype
= SADB_SATYPE_AH
;
298 case SADB_EXT_SUPPORTED_ENCRYPT
:
299 satype
= SADB_SATYPE_ESP
;
302 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
306 alg
= findsupportedalg(satype
, alg_id
);
310 memcpy(alg0
, alg
, sizeof(*alg0
));
312 __ipsec_errcode
= EIPSEC_NO_ERROR
;
317 * set the rate for SOFT lifetime against HARD one.
318 * If rate is more than 100 or equal to zero, then set to 100.
320 static u_int soft_lifetime_allocations_rate
= PFKEY_SOFT_LIFETIME_RATE
;
321 static u_int soft_lifetime_bytes_rate
= PFKEY_SOFT_LIFETIME_RATE
;
322 static u_int soft_lifetime_addtime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
323 static u_int soft_lifetime_usetime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
326 pfkey_set_softrate(type
, rate
)
329 __ipsec_errcode
= EIPSEC_NO_ERROR
;
331 if (rate
> 100 || rate
== 0)
335 case SADB_X_LIFETIME_ALLOCATIONS
:
336 soft_lifetime_allocations_rate
= rate
;
338 case SADB_X_LIFETIME_BYTES
:
339 soft_lifetime_bytes_rate
= rate
;
341 case SADB_X_LIFETIME_ADDTIME
:
342 soft_lifetime_addtime_rate
= rate
;
344 case SADB_X_LIFETIME_USETIME
:
345 soft_lifetime_usetime_rate
= rate
;
349 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
354 * get current rate for SOFT lifetime against HARD one.
355 * ATTENTION: ~0 is returned if invalid type was passed.
358 pfkey_get_softrate(type
)
362 case SADB_X_LIFETIME_ALLOCATIONS
:
363 return soft_lifetime_allocations_rate
;
364 case SADB_X_LIFETIME_BYTES
:
365 return soft_lifetime_bytes_rate
;
366 case SADB_X_LIFETIME_ADDTIME
:
367 return soft_lifetime_addtime_rate
;
368 case SADB_X_LIFETIME_USETIME
:
369 return soft_lifetime_usetime_rate
;
376 * sending SADB_GETSPI message to the kernel.
378 * positive: success and return length sent.
379 * -1 : error occured, and set errno.
382 pfkey_send_getspi(so
, satype
, mode
, src
, dst
, min
, max
, reqid
, seq
)
385 struct sockaddr
*src
, *dst
;
386 u_int32_t min
, max
, reqid
, seq
;
388 struct sadb_msg
*newmsg
;
391 int need_spirange
= 0;
396 if (src
== NULL
|| dst
== NULL
) {
397 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
400 if (src
->sa_family
!= dst
->sa_family
) {
401 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
404 if (min
> max
|| (min
> 0 && min
<= 255)) {
405 __ipsec_errcode
= EIPSEC_INVAL_SPI
;
408 switch (src
->sa_family
) {
410 plen
= sizeof(struct in_addr
) << 3;
413 plen
= sizeof(struct in6_addr
) << 3;
416 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
420 /* create new sadb_msg to send. */
421 len
= sizeof(struct sadb_msg
)
422 + sizeof(struct sadb_x_sa2
)
423 + sizeof(struct sadb_address
)
424 + PFKEY_ALIGN8(sysdep_sa_len(src
))
425 + sizeof(struct sadb_address
)
426 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
428 if (min
> 255 && max
< (u_int
)~0) {
430 len
+= sizeof(struct sadb_spirange
);
433 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
434 __ipsec_set_strerror(strerror(errno
));
437 ep
= ((caddr_t
)(void *)newmsg
) + len
;
439 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSPI
,
440 (u_int
)len
, satype
, seq
, getpid());
446 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
452 /* set sadb_address for source */
453 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
460 /* set sadb_address for destination */
461 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
468 /* proccessing spi range */
470 struct sadb_spirange spirange
;
472 if (p
+ sizeof(spirange
) > ep
) {
477 memset(&spirange
, 0, sizeof(spirange
));
478 spirange
.sadb_spirange_len
= PFKEY_UNIT64(sizeof(spirange
));
479 spirange
.sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
480 spirange
.sadb_spirange_min
= min
;
481 spirange
.sadb_spirange_max
= max
;
483 memcpy(p
, &spirange
, sizeof(spirange
));
485 p
+= sizeof(spirange
);
493 len
= pfkey_send(so
, newmsg
, len
);
499 __ipsec_errcode
= EIPSEC_NO_ERROR
;
506 * sending SADB_UPDATE message to the kernel.
507 * The length of key material is a_keylen + e_keylen.
509 * positive: success and return length sent.
510 * -1 : error occured, and set errno.
513 pfkey_send_update(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
514 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
515 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
517 u_int satype
, mode
, wsize
;
518 struct sockaddr
*src
, *dst
;
519 u_int32_t spi
, reqid
;
521 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
523 u_int64_t l_bytes
, l_addtime
, l_usetime
;
528 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
530 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
531 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
532 (u_int
)l_usetime
, seq
, port
)) < 0)
540 * sending SADB_ADD message to the kernel.
541 * The length of key material is a_keylen + e_keylen.
543 * positive: success and return length sent.
544 * -1 : error occured, and set errno.
547 pfkey_send_add(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
548 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
549 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
551 u_int satype
, mode
, wsize
;
552 struct sockaddr
*src
, *dst
;
553 u_int32_t spi
, reqid
;
555 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
557 u_int64_t l_bytes
, l_addtime
, l_usetime
;
562 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
564 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
565 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
566 (u_int
)l_usetime
, seq
, port
)) < 0)
573 #else /* __APPLE__ */
576 * sending SADB_UPDATE message to the kernel.
577 * The length of key material is a_keylen + e_keylen.
579 * positive: success and return length sent.
580 * -1 : error occured, and set errno.
583 pfkey_send_update(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
584 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
585 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)
587 u_int satype
, mode
, wsize
;
588 struct sockaddr
*src
, *dst
;
589 u_int32_t spi
, reqid
;
591 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
593 u_int64_t l_bytes
, l_addtime
, l_usetime
;
597 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
599 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
600 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
601 (u_int
)l_usetime
, seq
, 0, 0, 0, NULL
, 0)) < 0)
607 #ifdef SADB_X_EXT_NAT_T_TYPE
609 pfkey_send_update_nat(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
610 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
611 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
,
612 l_natt_type
, l_natt_sport
, l_natt_dport
, l_natt_oa
,
615 u_int satype
, mode
, wsize
;
616 struct sockaddr
*src
, *dst
;
617 u_int32_t spi
, reqid
;
619 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
621 u_int64_t l_bytes
, l_addtime
, l_usetime
;
623 u_int8_t l_natt_type
;
624 u_int16_t l_natt_sport
, l_natt_dport
;
625 struct sockaddr
*l_natt_oa
;
626 u_int16_t l_natt_frag
;
629 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
631 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
632 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
633 (u_int
)l_usetime
, seq
, l_natt_type
, l_natt_sport
,
634 l_natt_dport
, l_natt_oa
, l_natt_frag
)) < 0)
642 * sending SADB_ADD message to the kernel.
643 * The length of key material is a_keylen + e_keylen.
645 * positive: success and return length sent.
646 * -1 : error occured, and set errno.
649 pfkey_send_add(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
650 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
651 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)
653 u_int satype
, mode
, wsize
;
654 struct sockaddr
*src
, *dst
;
655 u_int32_t spi
, reqid
;
657 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
659 u_int64_t l_bytes
, l_addtime
, l_usetime
;
663 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
665 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
666 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
667 (u_int
)l_usetime
, seq
, 0, 0, 0, NULL
, 0)) < 0)
673 #ifdef SADB_X_EXT_NAT_T_TYPE
675 pfkey_send_add_nat(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
676 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
677 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
,
678 l_natt_type
, l_natt_sport
, l_natt_dport
, l_natt_oa
,
681 u_int satype
, mode
, wsize
;
682 struct sockaddr
*src
, *dst
;
683 u_int32_t spi
, reqid
;
685 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
687 u_int64_t l_bytes
, l_addtime
, l_usetime
;
689 u_int8_t l_natt_type
;
690 u_int16_t l_natt_sport
, l_natt_dport
;
691 struct sockaddr
*l_natt_oa
;
692 u_int16_t l_natt_frag
;
695 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
697 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
698 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
699 (u_int
)l_usetime
, seq
, l_natt_type
, l_natt_sport
,
700 l_natt_dport
, l_natt_oa
, l_natt_frag
)) < 0)
706 #endif /* __APPLE__ */
709 * sending SADB_DELETE message to the kernel.
711 * positive: success and return length sent.
712 * -1 : error occured, and set errno.
715 pfkey_send_delete(so
, satype
, mode
, src
, dst
, spi
)
718 struct sockaddr
*src
, *dst
;
722 if ((len
= pfkey_send_x2(so
, SADB_DELETE
, satype
, mode
, src
, dst
, spi
)) < 0)
729 * sending SADB_DELETE without spi to the kernel. This is
730 * the "delete all" request (an extension also present in
734 * positive: success and return length sent
735 * -1 : error occured, and set errno
739 pfkey_send_delete_all(so
, satype
, mode
, src
, dst
)
742 struct sockaddr
*src
, *dst
;
744 struct sadb_msg
*newmsg
;
751 if (src
== NULL
|| dst
== NULL
) {
752 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
755 if (src
->sa_family
!= dst
->sa_family
) {
756 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
759 switch (src
->sa_family
) {
761 plen
= sizeof(struct in_addr
) << 3;
764 plen
= sizeof(struct in6_addr
) << 3;
767 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
771 /* create new sadb_msg to reply. */
772 len
= sizeof(struct sadb_msg
)
773 + sizeof(struct sadb_address
)
774 + PFKEY_ALIGN8(sysdep_sa_len(src
))
775 + sizeof(struct sadb_address
)
776 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
778 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
779 __ipsec_set_strerror(strerror(errno
));
782 ep
= ((caddr_t
)(void *)newmsg
) + len
;
784 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_DELETE
, (u_int
)len
,
785 satype
, 0, getpid());
790 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
796 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
804 len
= pfkey_send(so
, newmsg
, len
);
810 __ipsec_errcode
= EIPSEC_NO_ERROR
;
815 * sending SADB_GET message to the kernel.
817 * positive: success and return length sent.
818 * -1 : error occured, and set errno.
821 pfkey_send_get(so
, satype
, mode
, src
, dst
, spi
)
824 struct sockaddr
*src
, *dst
;
828 if ((len
= pfkey_send_x2(so
, SADB_GET
, satype
, mode
, src
, dst
, spi
)) < 0)
835 * sending SADB_REGISTER message to the kernel.
837 * positive: success and return length sent.
838 * -1 : error occured, and set errno.
841 pfkey_send_register(so
, satype
)
847 if (satype
== PF_UNSPEC
) {
849 algno
< sizeof(supported_map
)/sizeof(supported_map
[0]);
851 if (ipsec_supported
[algno
]) {
852 free(ipsec_supported
[algno
]);
853 ipsec_supported
[algno
] = NULL
;
857 algno
= findsupportedmap((int)satype
);
859 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
863 if (ipsec_supported
[algno
]) {
864 free(ipsec_supported
[algno
]);
865 ipsec_supported
[algno
] = NULL
;
869 if ((len
= pfkey_send_x3(so
, SADB_REGISTER
, satype
)) < 0)
876 * receiving SADB_REGISTER message from the kernel, and copy buffer for
877 * sadb_supported returned into ipsec_supported.
879 * 0: success and return length sent.
880 * -1: error occured, and set errno.
883 pfkey_recv_register(so
)
886 pid_t pid
= getpid();
887 struct sadb_msg
*newmsg
;
890 /* receive message */
892 if ((newmsg
= pfkey_recv(so
)) == NULL
)
894 if (newmsg
->sadb_msg_type
== SADB_REGISTER
&&
895 newmsg
->sadb_msg_pid
== pid
)
901 newmsg
->sadb_msg_len
= PFKEY_UNUNIT64(newmsg
->sadb_msg_len
);
903 error
= pfkey_set_supported(newmsg
, newmsg
->sadb_msg_len
);
907 __ipsec_errcode
= EIPSEC_NO_ERROR
;
913 * receiving SADB_REGISTER message from the kernel, and copy buffer for
914 * sadb_supported returned into ipsec_supported.
915 * NOTE: sadb_msg_len must be host order.
917 * tlen: msg length, it's to makeing sure.
919 * 0: success and return length sent.
920 * -1: error occured, and set errno.
923 pfkey_set_supported(msg
, tlen
)
924 struct sadb_msg
*msg
;
927 struct sadb_supported
*sup
;
932 if (msg
->sadb_msg_len
!= tlen
) {
933 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
940 p
+= sizeof(struct sadb_msg
);
944 if (ep
< p
+ sizeof(*sup
) ||
945 PFKEY_EXTLEN(sup
) < sizeof(*sup
) ||
946 ep
< p
+ sup
->sadb_supported_len
) {
951 switch (sup
->sadb_supported_exttype
) {
952 case SADB_EXT_SUPPORTED_AUTH
:
953 case SADB_EXT_SUPPORTED_ENCRYPT
:
956 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
961 sup
->sadb_supported_len
= PFKEY_EXTLEN(sup
);
963 /* set supported map */
964 if (setsupportedmap(sup
) != 0)
967 p
+= sup
->sadb_supported_len
;
971 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
975 __ipsec_errcode
= EIPSEC_NO_ERROR
;
981 * sending SADB_FLUSH message to the kernel.
983 * positive: success and return length sent.
984 * -1 : error occured, and set errno.
987 pfkey_send_flush(so
, satype
)
993 if ((len
= pfkey_send_x3(so
, SADB_FLUSH
, satype
)) < 0)
1000 * sending SADB_DUMP message to the kernel.
1002 * positive: success and return length sent.
1003 * -1 : error occured, and set errno.
1006 pfkey_send_dump(so
, satype
)
1012 if ((len
= pfkey_send_x3(so
, SADB_DUMP
, satype
)) < 0)
1019 * sending SADB_X_PROMISC message to the kernel.
1020 * NOTE that this function handles promisc mode toggle only.
1022 * flag: set promisc off if zero, set promisc on if non-zero.
1024 * positive: success and return length sent.
1025 * -1 : error occured, and set errno.
1026 * 0 : error occured, and set errno.
1027 * others: a pointer to new allocated buffer in which supported
1031 pfkey_send_promisc_toggle(so
, flag
)
1037 if ((len
= pfkey_send_x3(so
, SADB_X_PROMISC
,
1038 (u_int
)(flag
? 1 : 0))) < 0)
1045 * sending SADB_X_SPDADD message to the kernel.
1047 * positive: success and return length sent.
1048 * -1 : error occured, and set errno.
1051 pfkey_send_spdadd(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1053 struct sockaddr
*src
, *dst
;
1054 u_int prefs
, prefd
, proto
;
1061 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
1062 src
, prefs
, dst
, prefd
, proto
,
1063 (u_int64_t
)0, (u_int64_t
)0,
1064 policy
, policylen
, seq
)) < 0)
1071 * sending SADB_X_SPDADD message to the kernel.
1073 * positive: success and return length sent.
1074 * -1 : error occured, and set errno.
1077 pfkey_send_spdadd2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
1078 policy
, policylen
, seq
)
1080 struct sockaddr
*src
, *dst
;
1081 u_int prefs
, prefd
, proto
;
1082 u_int64_t ltime
, vtime
;
1089 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
1090 src
, prefs
, dst
, prefd
, proto
,
1092 policy
, policylen
, seq
)) < 0)
1099 * sending SADB_X_SPDUPDATE message to the kernel.
1101 * positive: success and return length sent.
1102 * -1 : error occured, and set errno.
1105 pfkey_send_spdupdate(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1107 struct sockaddr
*src
, *dst
;
1108 u_int prefs
, prefd
, proto
;
1115 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
1116 src
, prefs
, dst
, prefd
, proto
,
1117 (u_int64_t
)0, (u_int64_t
)0,
1118 policy
, policylen
, seq
)) < 0)
1125 * sending SADB_X_SPDUPDATE message to the kernel.
1127 * positive: success and return length sent.
1128 * -1 : error occured, and set errno.
1131 pfkey_send_spdupdate2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
1132 policy
, policylen
, seq
)
1134 struct sockaddr
*src
, *dst
;
1135 u_int prefs
, prefd
, proto
;
1136 u_int64_t ltime
, vtime
;
1143 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
1144 src
, prefs
, dst
, prefd
, proto
,
1146 policy
, policylen
, seq
)) < 0)
1153 * sending SADB_X_SPDDELETE message to the kernel.
1155 * positive: success and return length sent.
1156 * -1 : error occured, and set errno.
1159 pfkey_send_spddelete(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1161 struct sockaddr
*src
, *dst
;
1162 u_int prefs
, prefd
, proto
;
1169 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1170 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1174 if ((len
= pfkey_send_x4(so
, SADB_X_SPDDELETE
,
1175 src
, prefs
, dst
, prefd
, proto
,
1176 (u_int64_t
)0, (u_int64_t
)0,
1177 policy
, policylen
, seq
)) < 0)
1184 * sending SADB_X_SPDDELETE message to the kernel.
1186 * positive: success and return length sent.
1187 * -1 : error occured, and set errno.
1190 pfkey_send_spddelete2(so
, spid
)
1196 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDELETE2
, spid
)) < 0)
1203 * sending SADB_X_SPDGET message to the kernel.
1205 * positive: success and return length sent.
1206 * -1 : error occured, and set errno.
1209 pfkey_send_spdget(so
, spid
)
1215 if ((len
= pfkey_send_x5(so
, SADB_X_SPDGET
, spid
)) < 0)
1222 * sending SADB_X_SPDSETIDX message to the kernel.
1224 * positive: success and return length sent.
1225 * -1 : error occured, and set errno.
1228 pfkey_send_spdsetidx(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1230 struct sockaddr
*src
, *dst
;
1231 u_int prefs
, prefd
, proto
;
1238 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1239 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1243 if ((len
= pfkey_send_x4(so
, SADB_X_SPDSETIDX
,
1244 src
, prefs
, dst
, prefd
, proto
,
1245 (u_int64_t
)0, (u_int64_t
)0,
1246 policy
, policylen
, seq
)) < 0)
1253 * sending SADB_SPDFLUSH message to the kernel.
1255 * positive: success and return length sent.
1256 * -1 : error occured, and set errno.
1259 pfkey_send_spdflush(so
)
1264 if ((len
= pfkey_send_x3(so
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
)) < 0)
1271 * sending SADB_SPDDUMP message to the kernel.
1273 * positive: success and return length sent.
1274 * -1 : error occured, and set errno.
1277 pfkey_send_spddump(so
)
1282 if ((len
= pfkey_send_x3(so
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
)) < 0)
1289 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1291 pfkey_send_x1(so
, type
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
1292 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1293 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
1295 u_int type
, satype
, mode
;
1296 struct sockaddr
*src
, *dst
;
1297 u_int32_t spi
, reqid
;
1300 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1301 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
;
1304 struct sadb_msg
*newmsg
;
1310 /* validity check */
1311 if (src
== NULL
|| dst
== NULL
) {
1312 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1315 if (src
->sa_family
!= dst
->sa_family
) {
1316 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1319 switch (src
->sa_family
) {
1321 plen
= sizeof(struct in_addr
) << 3;
1324 plen
= sizeof(struct in6_addr
) << 3;
1327 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1332 case SADB_SATYPE_ESP
:
1333 if (e_type
== SADB_EALG_NONE
) {
1334 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1338 case SADB_SATYPE_AH
:
1339 if (e_type
!= SADB_EALG_NONE
) {
1340 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1343 if (a_type
== SADB_AALG_NONE
) {
1344 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1348 case SADB_X_SATYPE_IPCOMP
:
1349 if (e_type
== SADB_X_CALG_NONE
) {
1350 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1353 if (a_type
!= SADB_AALG_NONE
) {
1354 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1358 #ifdef SADB_X_AALG_TCP_MD5
1359 case SADB_X_SATYPE_TCPSIGNATURE
:
1360 if (e_type
!= SADB_EALG_NONE
) {
1361 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1364 if (a_type
!= SADB_X_AALG_TCP_MD5
) {
1365 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1371 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1375 /* create new sadb_msg to reply. */
1376 len
= sizeof(struct sadb_msg
)
1377 + sizeof(struct sadb_sa_2
)
1378 + sizeof(struct sadb_x_sa2
)
1379 + sizeof(struct sadb_address
)
1380 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1381 + sizeof(struct sadb_address
)
1382 + PFKEY_ALIGN8(sysdep_sa_len(dst
))
1383 + sizeof(struct sadb_lifetime
)
1384 + sizeof(struct sadb_lifetime
);
1386 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
)
1387 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1388 if (a_type
!= SADB_AALG_NONE
)
1389 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1391 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1392 __ipsec_set_strerror(strerror(errno
));
1395 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1397 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1398 satype
, seq
, getpid());
1403 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
, port
);
1408 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
1413 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1419 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1426 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
) {
1427 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1434 if (a_type
!= SADB_AALG_NONE
) {
1435 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1436 keymat
+ e_keylen
, a_keylen
);
1443 /* set sadb_lifetime for destination */
1444 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1445 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1450 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1451 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1463 len
= pfkey_send(so
, newmsg
, len
);
1469 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1473 #else /* __APPLE__ */
1475 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1477 pfkey_send_x1(so
, type
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
1478 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1479 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
,
1480 l_natt_type
, l_natt_sport
, l_natt_dport
, l_natt_oa
,
1483 u_int type
, satype
, mode
;
1484 struct sockaddr
*src
, *dst
, *l_natt_oa
;
1485 u_int32_t spi
, reqid
;
1488 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1489 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
;
1490 u_int16_t l_natt_sport
, l_natt_dport
;
1491 u_int8_t l_natt_type
;
1492 u_int16_t l_natt_frag
;
1494 struct sadb_msg
*newmsg
;
1500 /* validity check */
1501 if (src
== NULL
|| dst
== NULL
) {
1502 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1505 if (src
->sa_family
!= dst
->sa_family
) {
1506 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1509 switch (src
->sa_family
) {
1511 plen
= sizeof(struct in_addr
) << 3;
1514 plen
= sizeof(struct in6_addr
) << 3;
1517 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1522 case SADB_SATYPE_ESP
:
1523 if (e_type
== SADB_EALG_NONE
) {
1524 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1528 case SADB_SATYPE_AH
:
1529 if (e_type
!= SADB_EALG_NONE
) {
1530 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1533 if (a_type
== SADB_AALG_NONE
) {
1534 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1538 case SADB_X_SATYPE_IPCOMP
:
1539 if (e_type
== SADB_X_CALG_NONE
) {
1540 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1543 if (a_type
!= SADB_AALG_NONE
) {
1544 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1548 #ifdef SADB_X_AALG_TCP_MD5
1549 case SADB_X_SATYPE_TCPSIGNATURE
:
1550 if (e_type
!= SADB_EALG_NONE
) {
1551 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1554 if (a_type
!= SADB_X_AALG_TCP_MD5
) {
1555 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1561 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1565 /* create new sadb_msg to reply. */
1566 len
= sizeof(struct sadb_msg
)
1567 + sizeof(struct sadb_sa
)
1568 + sizeof(struct sadb_x_sa2
)
1569 + sizeof(struct sadb_address
)
1570 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1571 + sizeof(struct sadb_address
)
1572 + PFKEY_ALIGN8(sysdep_sa_len(dst
))
1573 + sizeof(struct sadb_lifetime
)
1574 + sizeof(struct sadb_lifetime
);
1576 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
)
1577 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1578 if (a_type
!= SADB_AALG_NONE
)
1579 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1581 #ifdef SADB_X_EXT_NAT_T_TYPE
1582 /* add nat-t packets */
1585 case SADB_SATYPE_ESP
:
1586 case SADB_X_SATYPE_IPCOMP
:
1589 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1593 len
+= sizeof(struct sadb_x_nat_t_type
);
1594 len
+= sizeof(struct sadb_x_nat_t_port
);
1595 len
+= sizeof(struct sadb_x_nat_t_port
);
1597 len
+= sizeof(struct sadb_address
) +
1598 PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa
));
1599 #ifdef SADB_X_EXT_NAT_T_FRAG
1601 len
+= sizeof(struct sadb_x_nat_t_frag
);
1606 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1607 __ipsec_set_strerror(strerror(errno
));
1610 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1612 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1613 satype
, seq
, getpid());
1618 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
);
1623 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
1628 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1634 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1641 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
) {
1642 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1649 if (a_type
!= SADB_AALG_NONE
) {
1650 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1651 keymat
+ e_keylen
, a_keylen
);
1658 /* set sadb_lifetime for destination */
1659 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1660 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1665 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1666 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1672 #ifdef SADB_X_EXT_NAT_T_TYPE
1673 /* Add nat-t messages */
1675 p
= pfkey_set_natt_type(p
, ep
, SADB_X_EXT_NAT_T_TYPE
, l_natt_type
);
1681 p
= pfkey_set_natt_port(p
, ep
, SADB_X_EXT_NAT_T_SPORT
,
1688 p
= pfkey_set_natt_port(p
, ep
, SADB_X_EXT_NAT_T_DPORT
,
1696 p
= pfkey_setsadbaddr(p
, ep
, SADB_X_EXT_NAT_T_OA
,
1698 (u_int
)PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa
)),
1707 #ifdef SADB_X_EXT_NAT_T_FRAG
1708 p
= pfkey_set_natt_frag(p
, ep
, SADB_X_EXT_NAT_T_FRAG
,
1725 len
= pfkey_send(so
, newmsg
, len
);
1731 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1734 #endif /* __APPLE__ */
1736 /* sending SADB_DELETE or SADB_GET message to the kernel */
1739 pfkey_send_x2(so
, type
, satype
, mode
, src
, dst
, spi
)
1741 u_int type
, satype
, mode
;
1742 struct sockaddr
*src
, *dst
;
1745 struct sadb_msg
*newmsg
;
1751 /* validity check */
1752 if (src
== NULL
|| dst
== NULL
) {
1753 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1756 if (src
->sa_family
!= dst
->sa_family
) {
1757 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1760 switch (src
->sa_family
) {
1762 plen
= sizeof(struct in_addr
) << 3;
1765 plen
= sizeof(struct in6_addr
) << 3;
1768 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1772 /* create new sadb_msg to reply. */
1773 len
= sizeof(struct sadb_msg
)
1775 + sizeof(struct sadb_sa_2
)
1777 + sizeof(struct sadb_sa
)
1779 + sizeof(struct sadb_address
)
1780 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1781 + sizeof(struct sadb_address
)
1782 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
1784 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1785 __ipsec_set_strerror(strerror(errno
));
1788 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1790 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1797 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0, 0);
1799 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0);
1805 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1811 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1813 if (!p
|| p
!= ep
) {
1819 len
= pfkey_send(so
, newmsg
, len
);
1825 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1830 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1834 pfkey_send_x3(so
, type
, satype
)
1838 struct sadb_msg
*newmsg
;
1843 /* validity check */
1845 case SADB_X_PROMISC
:
1846 if (satype
!= 0 && satype
!= 1) {
1847 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1853 case SADB_SATYPE_UNSPEC
:
1854 case SADB_SATYPE_AH
:
1855 case SADB_SATYPE_ESP
:
1856 case SADB_X_SATYPE_IPCOMP
:
1857 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1858 case SADB_X_SATYPE_TCPSIGNATURE
:
1862 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1867 /* create new sadb_msg to send. */
1868 len
= sizeof(struct sadb_msg
);
1870 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1871 __ipsec_set_strerror(strerror(errno
));
1874 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1876 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1878 if (!p
|| p
!= ep
) {
1884 len
= pfkey_send(so
, newmsg
, len
);
1890 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1894 /* sending SADB_X_SPDADD message to the kernel */
1896 pfkey_send_x4(so
, type
, src
, prefs
, dst
, prefd
, proto
,
1897 ltime
, vtime
, policy
, policylen
, seq
)
1899 struct sockaddr
*src
, *dst
;
1900 u_int type
, prefs
, prefd
, proto
;
1901 u_int64_t ltime
, vtime
;
1906 struct sadb_msg
*newmsg
;
1912 /* validity check */
1913 if (src
== NULL
|| dst
== NULL
) {
1914 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1917 if (src
->sa_family
!= dst
->sa_family
) {
1918 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1922 switch (src
->sa_family
) {
1924 plen
= sizeof(struct in_addr
) << 3;
1927 plen
= sizeof(struct in6_addr
) << 3;
1930 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1933 if (prefs
> plen
|| prefd
> plen
) {
1934 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1938 /* create new sadb_msg to reply. */
1939 len
= sizeof(struct sadb_msg
)
1940 + sizeof(struct sadb_address
)
1941 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1942 + sizeof(struct sadb_address
)
1943 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1944 + sizeof(struct sadb_lifetime
)
1947 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1948 __ipsec_set_strerror(strerror(errno
));
1951 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1953 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1954 SADB_SATYPE_UNSPEC
, seq
, getpid());
1959 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1964 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1969 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1970 0, 0, (u_int
)ltime
, (u_int
)vtime
);
1971 if (!p
|| p
+ policylen
!= ep
) {
1975 memcpy(p
, policy
, (size_t)policylen
);
1978 len
= pfkey_send(so
, newmsg
, len
);
1984 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1988 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1990 pfkey_send_x5(so
, type
, spid
)
1995 struct sadb_msg
*newmsg
;
1996 struct sadb_x_policy xpl
;
2001 /* create new sadb_msg to reply. */
2002 len
= sizeof(struct sadb_msg
)
2005 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
2006 __ipsec_set_strerror(strerror(errno
));
2009 ep
= ((caddr_t
)(void *)newmsg
) + len
;
2011 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
2012 SADB_SATYPE_UNSPEC
, 0, getpid());
2018 if (p
+ sizeof(xpl
) != ep
) {
2022 memset(&xpl
, 0, sizeof(xpl
));
2023 xpl
.sadb_x_policy_len
= PFKEY_UNIT64(sizeof(xpl
));
2024 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
2025 xpl
.sadb_x_policy_id
= spid
;
2026 memcpy(p
, &xpl
, sizeof(xpl
));
2029 len
= pfkey_send(so
, newmsg
, len
);
2035 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2043 * others : success and return value of socket.
2049 int bufsiz
= 0; /* Max allowed by default */
2050 const unsigned long newbufk
= 1536;
2051 unsigned long oldmax
;
2052 size_t oldmaxsize
= sizeof(oldmax
);
2053 unsigned long newmax
= newbufk
* (1024 + 128);
2055 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
2056 __ipsec_set_strerror(strerror(errno
));
2061 * This is a temporary workaround for KAME PR 154.
2062 * Don't really care even if it fails.
2064 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax
, &oldmaxsize
, &newmax
, sizeof(newmax
)) != 0)
2065 bufsiz
= 233016; /* Max allowed by default */
2067 bufsiz
= newbufk
* 1024;
2069 setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
2070 setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
2072 if (bufsiz
== newbufk
* 1024)
2073 sysctlbyname("kern.ipc.maxsockbuf", NULL
, NULL
, &oldmax
, oldmaxsize
);
2075 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2091 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2096 * receive sadb_msg data, and return pointer to new buffer allocated.
2097 * Must free this buffer later.
2099 * NULL : error occured.
2100 * others : a pointer to sadb_msg structure.
2102 * XXX should be rewritten to pass length explicitly
2108 struct sadb_msg buf
, *newmsg
;
2111 while ((len
= recv(so
, (void *)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
2114 __ipsec_set_strerror(strerror(errno
));
2118 if (len
< sizeof(buf
)) {
2119 recv(so
, (void *)&buf
, sizeof(buf
), 0);
2120 __ipsec_errcode
= EIPSEC_MAX
;
2124 /* read real message */
2125 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
2126 if ((newmsg
= CALLOC((size_t)reallen
, struct sadb_msg
*)) == 0) {
2127 __ipsec_set_strerror(strerror(errno
));
2131 while ((len
= recv(so
, (void *)newmsg
, (socklen_t
)reallen
, 0)) < 0) {
2134 __ipsec_set_strerror(strerror(errno
));
2139 if (len
!= reallen
) {
2140 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
2145 /* don't trust what the kernel says, validate! */
2146 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
2147 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
2152 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2157 * send message to a socket.
2159 * others: success and return length sent.
2163 pfkey_send(so
, msg
, len
)
2165 struct sadb_msg
*msg
;
2168 if ((len
= send(so
, (void *)msg
, (socklen_t
)len
, 0)) < 0) {
2169 __ipsec_set_strerror(strerror(errno
));
2173 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2179 * NOTE: These functions are derived from netkey/key.c in KAME.
2182 * set the pointer to each header in this message buffer.
2183 * IN: msg: pointer to message buffer.
2184 * mhp: pointer to the buffer initialized like below:
2185 * caddr_t mhp[SADB_EXT_MAX + 1];
2189 * XXX should be rewritten to obtain length explicitly
2192 pfkey_align(msg
, mhp
)
2193 struct sadb_msg
*msg
;
2196 struct sadb_ext
*ext
;
2199 caddr_t ep
; /* XXX should be passed from upper layer */
2201 /* validity check */
2202 if (msg
== NULL
|| mhp
== NULL
) {
2203 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
2208 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
2211 mhp
[0] = (void *)msg
;
2215 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
2217 /* skip base header */
2218 p
+= sizeof(struct sadb_msg
);
2222 if (ep
< p
+ sizeof(*ext
) || PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
2223 ep
< p
+ PFKEY_EXTLEN(ext
)) {
2224 /* invalid format */
2228 /* duplicate check */
2229 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
2230 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
2231 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
2236 switch (ext
->sadb_ext_type
) {
2238 case SADB_EXT_LIFETIME_CURRENT
:
2239 case SADB_EXT_LIFETIME_HARD
:
2240 case SADB_EXT_LIFETIME_SOFT
:
2241 case SADB_EXT_ADDRESS_SRC
:
2242 case SADB_EXT_ADDRESS_DST
:
2243 case SADB_EXT_ADDRESS_PROXY
:
2244 case SADB_EXT_KEY_AUTH
:
2245 /* XXX should to be check weak keys. */
2246 case SADB_EXT_KEY_ENCRYPT
:
2247 /* XXX should to be check weak keys. */
2248 case SADB_EXT_IDENTITY_SRC
:
2249 case SADB_EXT_IDENTITY_DST
:
2250 case SADB_EXT_SENSITIVITY
:
2251 case SADB_EXT_PROPOSAL
:
2252 case SADB_EXT_SUPPORTED_AUTH
:
2253 case SADB_EXT_SUPPORTED_ENCRYPT
:
2254 case SADB_EXT_SPIRANGE
:
2255 case SADB_X_EXT_POLICY
:
2256 case SADB_X_EXT_SA2
:
2257 case SADB_EXT_SESSION_ID
:
2258 case SADB_EXT_SASTAT
:
2259 #ifdef SADB_X_EXT_NAT_T_TYPE
2260 case SADB_X_EXT_NAT_T_TYPE
:
2261 case SADB_X_EXT_NAT_T_SPORT
:
2262 case SADB_X_EXT_NAT_T_DPORT
:
2263 case SADB_X_EXT_NAT_T_OA
:
2265 #ifdef SADB_X_EXT_TAG
2266 case SADB_X_EXT_TAG
:
2268 #ifdef SADB_X_EXT_PACKET
2269 case SADB_X_EXT_PACKET
:
2272 mhp
[ext
->sadb_ext_type
] = (void *)ext
;
2275 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
2279 p
+= PFKEY_EXTLEN(ext
);
2283 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
2287 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2292 * check basic usage for sadb_msg,
2293 * NOTE: This routine is derived from netkey/key.c in KAME.
2294 * IN: msg: pointer to message buffer.
2295 * mhp: pointer to the buffer initialized like below:
2297 * caddr_t mhp[SADB_EXT_MAX + 1];
2306 struct sadb_msg
*msg
;
2308 /* validity check */
2309 if (mhp
== NULL
|| mhp
[0] == NULL
) {
2310 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
2314 msg
= (void *)mhp
[0];
2317 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
2318 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
2323 if (msg
->sadb_msg_type
> SADB_MAX
) {
2324 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
2329 switch (msg
->sadb_msg_satype
) {
2330 case SADB_SATYPE_UNSPEC
:
2331 switch (msg
->sadb_msg_type
) {
2339 #ifdef SADB_X_NAT_T_NEW_MAPPING
2340 case SADB_X_NAT_T_NEW_MAPPING
:
2342 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2346 case SADB_SATYPE_ESP
:
2347 case SADB_SATYPE_AH
:
2348 case SADB_X_SATYPE_IPCOMP
:
2349 #ifdef SADB_X_SATYPE_TCPSIGNATURE
2350 case SADB_X_SATYPE_TCPSIGNATURE
:
2352 switch (msg
->sadb_msg_type
) {
2354 case SADB_X_SPDDELETE
:
2356 case SADB_X_SPDDUMP
:
2357 case SADB_X_SPDFLUSH
:
2358 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2361 #ifdef SADB_X_NAT_T_NEW_MAPPING
2362 if (msg
->sadb_msg_type
== SADB_X_NAT_T_NEW_MAPPING
&&
2363 msg
->sadb_msg_satype
!= SADB_SATYPE_ESP
) {
2364 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2369 case SADB_SATYPE_RSVP
:
2370 case SADB_SATYPE_OSPFV2
:
2371 case SADB_SATYPE_RIPV2
:
2372 case SADB_SATYPE_MIP
:
2373 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
2375 case 1: /* XXX: What does it do ? */
2376 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
2380 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2384 /* check field of upper layer protocol and address family */
2385 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
2386 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
2387 struct sadb_address
*src0
, *dst0
;
2389 src0
= (void *)(mhp
[SADB_EXT_ADDRESS_SRC
]);
2390 dst0
= (void *)(mhp
[SADB_EXT_ADDRESS_DST
]);
2392 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
2393 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
2397 if (PFKEY_ADDR_SADDR(src0
)->sa_family
2398 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
2399 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
2403 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
2408 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
2413 * prefixlen == 0 is valid because there must be the case
2414 * all addresses are matched.
2418 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2423 * set data into sadb_msg.
2424 * `buf' must has been allocated sufficiently.
2427 pfkey_setsadbmsg(buf
, lim
, type
, tlen
, satype
, seq
, pid
)
2439 len
= sizeof(struct sadb_msg
);
2441 if (buf
+ len
> lim
)
2445 p
->sadb_msg_version
= PF_KEY_V2
;
2446 p
->sadb_msg_type
= type
;
2447 p
->sadb_msg_errno
= 0;
2448 p
->sadb_msg_satype
= satype
;
2449 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
2450 p
->sadb_msg_reserved
= 0;
2451 p
->sadb_msg_seq
= seq
;
2452 p
->sadb_msg_pid
= (u_int32_t
)pid
;
2459 * copy secasvar data into sadb_address.
2460 * `buf' must has been allocated sufficiently.
2463 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
, port
)
2466 u_int32_t spi
, flags
;
2467 u_int wsize
, auth
, enc
;
2470 struct sadb_sa_2
*p
;
2474 len
= sizeof(struct sadb_sa_2
);
2476 if (buf
+ len
> lim
)
2480 p
->sa
.sadb_sa_len
= PFKEY_UNIT64(len
);
2481 p
->sa
.sadb_sa_exttype
= SADB_EXT_SA
;
2482 p
->sa
.sadb_sa_spi
= spi
;
2483 p
->sa
.sadb_sa_replay
= wsize
;
2484 p
->sa
.sadb_sa_state
= SADB_SASTATE_LARVAL
;
2485 p
->sa
.sadb_sa_auth
= auth
;
2486 p
->sa
.sadb_sa_encrypt
= enc
;
2487 p
->sa
.sadb_sa_flags
= flags
;
2488 p
->sadb_sa_natt_port
= port
;
2495 * copy secasvar data into sadb_address.
2496 * `buf' must has been allocated sufficiently.
2499 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
)
2502 u_int32_t spi
, flags
;
2503 u_int wsize
, auth
, enc
;
2509 len
= sizeof(struct sadb_sa
);
2511 if (buf
+ len
> lim
)
2515 p
->sadb_sa_len
= PFKEY_UNIT64(len
);
2516 p
->sadb_sa_exttype
= SADB_EXT_SA
;
2517 p
->sadb_sa_spi
= spi
;
2518 p
->sadb_sa_replay
= wsize
;
2519 p
->sadb_sa_state
= SADB_SASTATE_LARVAL
;
2520 p
->sadb_sa_auth
= auth
;
2521 p
->sadb_sa_encrypt
= enc
;
2522 p
->sadb_sa_flags
= flags
;
2523 p
->sadb_sa_natt_port
= port
;
2530 * set data into sadb_address.
2531 * `buf' must has been allocated sufficiently.
2532 * prefixlen is in bits.
2535 pfkey_setsadbaddr(buf
, lim
, exttype
, saddr
, prefixlen
, ul_proto
)
2539 struct sockaddr
*saddr
;
2543 struct sadb_address
*p
;
2547 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len(saddr
));
2549 if (buf
+ len
> lim
)
2553 p
->sadb_address_len
= PFKEY_UNIT64(len
);
2554 p
->sadb_address_exttype
= exttype
& 0xffff;
2555 p
->sadb_address_proto
= ul_proto
& 0xff;
2556 p
->sadb_address_prefixlen
= prefixlen
;
2557 p
->sadb_address_reserved
= 0;
2559 memcpy(p
+ 1, saddr
, (size_t)sysdep_sa_len(saddr
));
2565 * set sadb_key structure after clearing buffer with zero.
2566 * OUT: the pointer of buf + len.
2569 pfkey_setsadbkey(buf
, lim
, type
, key
, keylen
)
2579 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
2581 if (buf
+ len
> lim
)
2585 p
->sadb_key_len
= PFKEY_UNIT64(len
);
2586 p
->sadb_key_exttype
= type
;
2587 p
->sadb_key_bits
= keylen
<< 3;
2588 p
->sadb_key_reserved
= 0;
2590 memcpy(p
+ 1, key
, keylen
);
2596 * set sadb_lifetime structure after clearing buffer with zero.
2597 * OUT: the pointer of buf + len.
2600 pfkey_setsadblifetime(buf
, lim
, type
, l_alloc
, l_bytes
, l_addtime
, l_usetime
)
2604 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
;
2606 struct sadb_lifetime
*p
;
2610 len
= sizeof(struct sadb_lifetime
);
2612 if (buf
+ len
> lim
)
2616 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2617 p
->sadb_lifetime_exttype
= type
;
2620 case SADB_EXT_LIFETIME_SOFT
:
2621 p
->sadb_lifetime_allocations
2622 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2623 p
->sadb_lifetime_bytes
2624 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2625 p
->sadb_lifetime_addtime
2626 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2627 p
->sadb_lifetime_usetime
2628 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2630 case SADB_EXT_LIFETIME_HARD
:
2631 p
->sadb_lifetime_allocations
= l_alloc
;
2632 p
->sadb_lifetime_bytes
= l_bytes
;
2633 p
->sadb_lifetime_addtime
= l_addtime
;
2634 p
->sadb_lifetime_usetime
= l_usetime
;
2642 * copy secasvar data into sadb_address.
2643 * `buf' must has been allocated sufficiently.
2646 pfkey_setsadbxsa2(buf
, lim
, mode0
, reqid
)
2652 struct sadb_x_sa2
*p
;
2653 u_int8_t mode
= mode0
& 0xff;
2657 len
= sizeof(struct sadb_x_sa2
);
2659 if (buf
+ len
> lim
)
2663 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2664 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2665 p
->sadb_x_sa2_mode
= mode
;
2666 p
->sadb_x_sa2_reqid
= reqid
;
2671 #ifdef SADB_X_EXT_NAT_T_TYPE
2673 pfkey_set_natt_type(buf
, lim
, type
, l_natt_type
)
2677 u_int8_t l_natt_type
;
2679 struct sadb_x_nat_t_type
*p
;
2683 len
= sizeof(struct sadb_x_nat_t_type
);
2685 if (buf
+ len
> lim
)
2689 p
->sadb_x_nat_t_type_len
= PFKEY_UNIT64(len
);
2690 p
->sadb_x_nat_t_type_exttype
= type
;
2691 p
->sadb_x_nat_t_type_type
= l_natt_type
;
2697 pfkey_set_natt_port(buf
, lim
, type
, l_natt_port
)
2701 u_int16_t l_natt_port
;
2703 struct sadb_x_nat_t_port
*p
;
2707 len
= sizeof(struct sadb_x_nat_t_port
);
2709 if (buf
+ len
> lim
)
2713 p
->sadb_x_nat_t_port_len
= PFKEY_UNIT64(len
);
2714 p
->sadb_x_nat_t_port_exttype
= type
;
2715 p
->sadb_x_nat_t_port_port
= htons(l_natt_port
);
2721 #ifdef SADB_X_EXT_NAT_T_FRAG
2723 pfkey_set_natt_frag(buf
, lim
, type
, l_natt_frag
)
2727 u_int16_t l_natt_frag
;
2729 struct sadb_x_nat_t_frag
*p
;
2733 len
= sizeof(struct sadb_x_nat_t_frag
);
2735 if (buf
+ len
> lim
)
2739 p
->sadb_x_nat_t_frag_len
= PFKEY_UNIT64(len
);
2740 p
->sadb_x_nat_t_frag_exttype
= type
;
2741 p
->sadb_x_nat_t_frag_fraglen
= l_natt_frag
;
2748 pfkey_setsadbsession_id (caddr_t buf
,
2750 u_int64_t session_ids
[],
2751 u_int32_t max_session_ids
)
2753 struct sadb_session_id
*p
;
2756 if (!max_session_ids
)
2762 if (buf
+ len
> lim
)
2766 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
2767 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
2768 p
->sadb_session_id_v
[0] = session_ids
[0];
2769 if (max_session_ids
> 1)
2770 p
->sadb_session_id_v
[1] = session_ids
[1];
2776 pfkey_setsadbsastats (caddr_t buf
,
2779 struct sastat
*stats
,
2780 u_int32_t max_stats
)
2782 struct sadb_sastat
*p
;
2783 u_int len
, list_len
;
2785 if (!stats
|| !max_stats
)
2788 p
= (__typeof__(p
))buf
;
2789 list_len
= sizeof(*stats
) * max_stats
;
2790 len
= sizeof(*p
) + PFKEY_ALIGN8(list_len
);
2792 if (buf
+ len
> lim
)
2796 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
2797 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
2798 p
->sadb_sastat_dir
= dir
;
2799 p
->sadb_sastat_list_len
= max_stats
;
2800 bcopy(stats
, p
+ 1, list_len
);
2806 pfkey_send_getsastats (int so
,
2808 u_int64_t
*session_ids
,
2809 u_int32_t max_session_ids
,
2811 struct sastat
*stats
,
2812 u_int32_t max_stats
)
2814 struct sadb_msg
*newmsg
;
2816 int list_len
, out_len
, len
;
2819 if (!session_ids
|| !stats
|| !max_stats
) {
2823 list_len
= sizeof(*stats
) * max_stats
;
2824 /* create new sadb_msg to send. */
2825 out_len
= sizeof(struct sadb_msg
) + sizeof(struct sadb_session_id
) + sizeof(struct sadb_sastat
) + PFKEY_ALIGN8(list_len
);
2827 if ((newmsg
= CALLOC((size_t)out_len
, struct sadb_msg
*)) == NULL
) {
2828 __ipsec_set_strerror(strerror(errno
));
2831 ep
= ((caddr_t
)(void *)newmsg
) + out_len
;
2833 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSASTAT
, (u_int
)out_len
, SADB_SATYPE_UNSPEC
, seq
, getpid());
2839 p
= pfkey_setsadbsession_id(p
, ep
, session_ids
, max_session_ids
);
2845 p
= pfkey_setsadbsastats(p
, ep
, dir
, stats
, max_stats
);
2852 len
= pfkey_send(so
, newmsg
, out_len
);
2858 __ipsec_errcode
= EIPSEC_NO_ERROR
;