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
)
1774 + sizeof(struct sadb_sa
)
1775 + sizeof(struct sadb_address
)
1776 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1777 + sizeof(struct sadb_address
)
1778 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
1780 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1781 __ipsec_set_strerror(strerror(errno
));
1784 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1786 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1793 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0, 0);
1795 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0);
1801 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1807 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1809 if (!p
|| p
!= ep
) {
1815 len
= pfkey_send(so
, newmsg
, len
);
1821 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1826 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1830 pfkey_send_x3(so
, type
, satype
)
1834 struct sadb_msg
*newmsg
;
1839 /* validity check */
1841 case SADB_X_PROMISC
:
1842 if (satype
!= 0 && satype
!= 1) {
1843 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1849 case SADB_SATYPE_UNSPEC
:
1850 case SADB_SATYPE_AH
:
1851 case SADB_SATYPE_ESP
:
1852 case SADB_X_SATYPE_IPCOMP
:
1853 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1854 case SADB_X_SATYPE_TCPSIGNATURE
:
1858 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1863 /* create new sadb_msg to send. */
1864 len
= sizeof(struct sadb_msg
);
1866 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1867 __ipsec_set_strerror(strerror(errno
));
1870 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1872 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1874 if (!p
|| p
!= ep
) {
1880 len
= pfkey_send(so
, newmsg
, len
);
1886 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1890 /* sending SADB_X_SPDADD message to the kernel */
1892 pfkey_send_x4(so
, type
, src
, prefs
, dst
, prefd
, proto
,
1893 ltime
, vtime
, policy
, policylen
, seq
)
1895 struct sockaddr
*src
, *dst
;
1896 u_int type
, prefs
, prefd
, proto
;
1897 u_int64_t ltime
, vtime
;
1902 struct sadb_msg
*newmsg
;
1908 /* validity check */
1909 if (src
== NULL
|| dst
== NULL
) {
1910 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1913 if (src
->sa_family
!= dst
->sa_family
) {
1914 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1918 switch (src
->sa_family
) {
1920 plen
= sizeof(struct in_addr
) << 3;
1923 plen
= sizeof(struct in6_addr
) << 3;
1926 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1929 if (prefs
> plen
|| prefd
> plen
) {
1930 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1934 /* create new sadb_msg to reply. */
1935 len
= sizeof(struct sadb_msg
)
1936 + sizeof(struct sadb_address
)
1937 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1938 + sizeof(struct sadb_address
)
1939 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1940 + sizeof(struct sadb_lifetime
)
1943 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1944 __ipsec_set_strerror(strerror(errno
));
1947 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1949 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1950 SADB_SATYPE_UNSPEC
, seq
, getpid());
1955 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1960 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1965 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1966 0, 0, (u_int
)ltime
, (u_int
)vtime
);
1967 if (!p
|| p
+ policylen
!= ep
) {
1971 memcpy(p
, policy
, (size_t)policylen
);
1974 len
= pfkey_send(so
, newmsg
, len
);
1980 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1984 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1986 pfkey_send_x5(so
, type
, spid
)
1991 struct sadb_msg
*newmsg
;
1992 struct sadb_x_policy xpl
;
1997 /* create new sadb_msg to reply. */
1998 len
= sizeof(struct sadb_msg
)
2001 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
2002 __ipsec_set_strerror(strerror(errno
));
2005 ep
= ((caddr_t
)(void *)newmsg
) + len
;
2007 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
2008 SADB_SATYPE_UNSPEC
, 0, getpid());
2014 if (p
+ sizeof(xpl
) != ep
) {
2018 memset(&xpl
, 0, sizeof(xpl
));
2019 xpl
.sadb_x_policy_len
= PFKEY_UNIT64(sizeof(xpl
));
2020 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
2021 xpl
.sadb_x_policy_id
= spid
;
2022 memcpy(p
, &xpl
, sizeof(xpl
));
2025 len
= pfkey_send(so
, newmsg
, len
);
2031 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2039 * others : success and return value of socket.
2045 int bufsiz
= 0; /* Max allowed by default */
2046 const unsigned long newbufk
= 1536;
2047 unsigned long oldmax
;
2048 size_t oldmaxsize
= sizeof(oldmax
);
2049 unsigned long newmax
= newbufk
* (1024 + 128);
2051 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
2052 __ipsec_set_strerror(strerror(errno
));
2057 * This is a temporary workaround for KAME PR 154.
2058 * Don't really care even if it fails.
2060 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax
, &oldmaxsize
, &newmax
, sizeof(newmax
)) != 0)
2061 bufsiz
= 233016; /* Max allowed by default */
2063 bufsiz
= newbufk
* 1024;
2065 setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
2066 setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
2068 if (bufsiz
== newbufk
* 1024)
2069 sysctlbyname("kern.ipc.maxsockbuf", NULL
, NULL
, &oldmax
, oldmaxsize
);
2071 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2087 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2092 * receive sadb_msg data, and return pointer to new buffer allocated.
2093 * Must free this buffer later.
2095 * NULL : error occured.
2096 * others : a pointer to sadb_msg structure.
2098 * XXX should be rewritten to pass length explicitly
2104 struct sadb_msg buf
, *newmsg
;
2107 while ((len
= recv(so
, (void *)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
2110 __ipsec_set_strerror(strerror(errno
));
2114 if (len
< sizeof(buf
)) {
2115 recv(so
, (void *)&buf
, sizeof(buf
), 0);
2116 __ipsec_errcode
= EIPSEC_MAX
;
2120 /* read real message */
2121 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
2122 if ((newmsg
= CALLOC((size_t)reallen
, struct sadb_msg
*)) == 0) {
2123 __ipsec_set_strerror(strerror(errno
));
2127 while ((len
= recv(so
, (void *)newmsg
, (socklen_t
)reallen
, 0)) < 0) {
2130 __ipsec_set_strerror(strerror(errno
));
2135 if (len
!= reallen
) {
2136 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
2141 /* don't trust what the kernel says, validate! */
2142 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
2143 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
2148 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2153 * send message to a socket.
2155 * others: success and return length sent.
2159 pfkey_send(so
, msg
, len
)
2161 struct sadb_msg
*msg
;
2164 if ((len
= send(so
, (void *)msg
, (socklen_t
)len
, 0)) < 0) {
2165 __ipsec_set_strerror(strerror(errno
));
2169 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2175 * NOTE: These functions are derived from netkey/key.c in KAME.
2178 * set the pointer to each header in this message buffer.
2179 * IN: msg: pointer to message buffer.
2180 * mhp: pointer to the buffer initialized like below:
2181 * caddr_t mhp[SADB_EXT_MAX + 1];
2185 * XXX should be rewritten to obtain length explicitly
2188 pfkey_align(msg
, mhp
)
2189 struct sadb_msg
*msg
;
2192 struct sadb_ext
*ext
;
2195 caddr_t ep
; /* XXX should be passed from upper layer */
2197 /* validity check */
2198 if (msg
== NULL
|| mhp
== NULL
) {
2199 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
2204 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
2207 mhp
[0] = (void *)msg
;
2211 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
2213 /* skip base header */
2214 p
+= sizeof(struct sadb_msg
);
2218 if (ep
< p
+ sizeof(*ext
) || PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
2219 ep
< p
+ PFKEY_EXTLEN(ext
)) {
2220 /* invalid format */
2224 /* duplicate check */
2225 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
2226 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
2227 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
2232 switch (ext
->sadb_ext_type
) {
2234 case SADB_EXT_LIFETIME_CURRENT
:
2235 case SADB_EXT_LIFETIME_HARD
:
2236 case SADB_EXT_LIFETIME_SOFT
:
2237 case SADB_EXT_ADDRESS_SRC
:
2238 case SADB_EXT_ADDRESS_DST
:
2239 case SADB_EXT_ADDRESS_PROXY
:
2240 case SADB_EXT_KEY_AUTH
:
2241 /* XXX should to be check weak keys. */
2242 case SADB_EXT_KEY_ENCRYPT
:
2243 /* XXX should to be check weak keys. */
2244 case SADB_EXT_IDENTITY_SRC
:
2245 case SADB_EXT_IDENTITY_DST
:
2246 case SADB_EXT_SENSITIVITY
:
2247 case SADB_EXT_PROPOSAL
:
2248 case SADB_EXT_SUPPORTED_AUTH
:
2249 case SADB_EXT_SUPPORTED_ENCRYPT
:
2250 case SADB_EXT_SPIRANGE
:
2251 case SADB_X_EXT_POLICY
:
2252 case SADB_X_EXT_SA2
:
2253 case SADB_EXT_SESSION_ID
:
2254 case SADB_EXT_SASTAT
:
2255 #ifdef SADB_X_EXT_NAT_T_TYPE
2256 case SADB_X_EXT_NAT_T_TYPE
:
2257 case SADB_X_EXT_NAT_T_SPORT
:
2258 case SADB_X_EXT_NAT_T_DPORT
:
2259 case SADB_X_EXT_NAT_T_OA
:
2261 #ifdef SADB_X_EXT_TAG
2262 case SADB_X_EXT_TAG
:
2264 #ifdef SADB_X_EXT_PACKET
2265 case SADB_X_EXT_PACKET
:
2268 mhp
[ext
->sadb_ext_type
] = (void *)ext
;
2271 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
2275 p
+= PFKEY_EXTLEN(ext
);
2279 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
2283 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2288 * check basic usage for sadb_msg,
2289 * NOTE: This routine is derived from netkey/key.c in KAME.
2290 * IN: msg: pointer to message buffer.
2291 * mhp: pointer to the buffer initialized like below:
2293 * caddr_t mhp[SADB_EXT_MAX + 1];
2302 struct sadb_msg
*msg
;
2304 /* validity check */
2305 if (mhp
== NULL
|| mhp
[0] == NULL
) {
2306 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
2310 msg
= (void *)mhp
[0];
2313 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
2314 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
2319 if (msg
->sadb_msg_type
> SADB_MAX
) {
2320 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
2325 switch (msg
->sadb_msg_satype
) {
2326 case SADB_SATYPE_UNSPEC
:
2327 switch (msg
->sadb_msg_type
) {
2335 #ifdef SADB_X_NAT_T_NEW_MAPPING
2336 case SADB_X_NAT_T_NEW_MAPPING
:
2338 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2342 case SADB_SATYPE_ESP
:
2343 case SADB_SATYPE_AH
:
2344 case SADB_X_SATYPE_IPCOMP
:
2345 #ifdef SADB_X_SATYPE_TCPSIGNATURE
2346 case SADB_X_SATYPE_TCPSIGNATURE
:
2348 switch (msg
->sadb_msg_type
) {
2350 case SADB_X_SPDDELETE
:
2352 case SADB_X_SPDDUMP
:
2353 case SADB_X_SPDFLUSH
:
2354 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2357 #ifdef SADB_X_NAT_T_NEW_MAPPING
2358 if (msg
->sadb_msg_type
== SADB_X_NAT_T_NEW_MAPPING
&&
2359 msg
->sadb_msg_satype
!= SADB_SATYPE_ESP
) {
2360 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2365 case SADB_SATYPE_RSVP
:
2366 case SADB_SATYPE_OSPFV2
:
2367 case SADB_SATYPE_RIPV2
:
2368 case SADB_SATYPE_MIP
:
2369 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
2371 case 1: /* XXX: What does it do ? */
2372 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
2376 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
2380 /* check field of upper layer protocol and address family */
2381 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
2382 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
2383 struct sadb_address
*src0
, *dst0
;
2385 src0
= (void *)(mhp
[SADB_EXT_ADDRESS_SRC
]);
2386 dst0
= (void *)(mhp
[SADB_EXT_ADDRESS_DST
]);
2388 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
2389 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
2393 if (PFKEY_ADDR_SADDR(src0
)->sa_family
2394 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
2395 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
2399 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
2404 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
2409 * prefixlen == 0 is valid because there must be the case
2410 * all addresses are matched.
2414 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2419 * set data into sadb_msg.
2420 * `buf' must has been allocated sufficiently.
2423 pfkey_setsadbmsg(buf
, lim
, type
, tlen
, satype
, seq
, pid
)
2435 len
= sizeof(struct sadb_msg
);
2437 if (buf
+ len
> lim
)
2441 p
->sadb_msg_version
= PF_KEY_V2
;
2442 p
->sadb_msg_type
= type
;
2443 p
->sadb_msg_errno
= 0;
2444 p
->sadb_msg_satype
= satype
;
2445 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
2446 p
->sadb_msg_reserved
= 0;
2447 p
->sadb_msg_seq
= seq
;
2448 p
->sadb_msg_pid
= (u_int32_t
)pid
;
2455 * copy secasvar data into sadb_address.
2456 * `buf' must has been allocated sufficiently.
2459 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
, port
)
2462 u_int32_t spi
, flags
;
2463 u_int wsize
, auth
, enc
;
2466 struct sadb_sa_2
*p
;
2470 len
= sizeof(struct sadb_sa_2
);
2472 if (buf
+ len
> lim
)
2476 p
->sa
.sadb_sa_len
= PFKEY_UNIT64(len
);
2477 p
->sa
.sadb_sa_exttype
= SADB_EXT_SA
;
2478 p
->sa
.sadb_sa_spi
= spi
;
2479 p
->sa
.sadb_sa_replay
= wsize
;
2480 p
->sa
.sadb_sa_state
= SADB_SASTATE_LARVAL
;
2481 p
->sa
.sadb_sa_auth
= auth
;
2482 p
->sa
.sadb_sa_encrypt
= enc
;
2483 p
->sa
.sadb_sa_flags
= flags
;
2484 p
->sadb_sa_natt_port
= port
;
2491 * copy secasvar data into sadb_address.
2492 * `buf' must has been allocated sufficiently.
2495 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
)
2498 u_int32_t spi
, flags
;
2499 u_int wsize
, auth
, enc
;
2505 len
= sizeof(struct sadb_sa
);
2507 if (buf
+ len
> lim
)
2511 p
->sadb_sa_len
= PFKEY_UNIT64(len
);
2512 p
->sadb_sa_exttype
= SADB_EXT_SA
;
2513 p
->sadb_sa_spi
= spi
;
2514 p
->sadb_sa_replay
= wsize
;
2515 p
->sadb_sa_state
= SADB_SASTATE_LARVAL
;
2516 p
->sadb_sa_auth
= auth
;
2517 p
->sadb_sa_encrypt
= enc
;
2518 p
->sadb_sa_flags
= flags
;
2519 p
->sadb_sa_natt_port
= port
;
2526 * set data into sadb_address.
2527 * `buf' must has been allocated sufficiently.
2528 * prefixlen is in bits.
2531 pfkey_setsadbaddr(buf
, lim
, exttype
, saddr
, prefixlen
, ul_proto
)
2535 struct sockaddr
*saddr
;
2539 struct sadb_address
*p
;
2543 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len(saddr
));
2545 if (buf
+ len
> lim
)
2549 p
->sadb_address_len
= PFKEY_UNIT64(len
);
2550 p
->sadb_address_exttype
= exttype
& 0xffff;
2551 p
->sadb_address_proto
= ul_proto
& 0xff;
2552 p
->sadb_address_prefixlen
= prefixlen
;
2553 p
->sadb_address_reserved
= 0;
2555 memcpy(p
+ 1, saddr
, (size_t)sysdep_sa_len(saddr
));
2561 * set sadb_key structure after clearing buffer with zero.
2562 * OUT: the pointer of buf + len.
2565 pfkey_setsadbkey(buf
, lim
, type
, key
, keylen
)
2575 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
2577 if (buf
+ len
> lim
)
2581 p
->sadb_key_len
= PFKEY_UNIT64(len
);
2582 p
->sadb_key_exttype
= type
;
2583 p
->sadb_key_bits
= keylen
<< 3;
2584 p
->sadb_key_reserved
= 0;
2586 memcpy(p
+ 1, key
, keylen
);
2592 * set sadb_lifetime structure after clearing buffer with zero.
2593 * OUT: the pointer of buf + len.
2596 pfkey_setsadblifetime(buf
, lim
, type
, l_alloc
, l_bytes
, l_addtime
, l_usetime
)
2600 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
;
2602 struct sadb_lifetime
*p
;
2606 len
= sizeof(struct sadb_lifetime
);
2608 if (buf
+ len
> lim
)
2612 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2613 p
->sadb_lifetime_exttype
= type
;
2616 case SADB_EXT_LIFETIME_SOFT
:
2617 p
->sadb_lifetime_allocations
2618 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2619 p
->sadb_lifetime_bytes
2620 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2621 p
->sadb_lifetime_addtime
2622 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2623 p
->sadb_lifetime_usetime
2624 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2626 case SADB_EXT_LIFETIME_HARD
:
2627 p
->sadb_lifetime_allocations
= l_alloc
;
2628 p
->sadb_lifetime_bytes
= l_bytes
;
2629 p
->sadb_lifetime_addtime
= l_addtime
;
2630 p
->sadb_lifetime_usetime
= l_usetime
;
2638 * copy secasvar data into sadb_address.
2639 * `buf' must has been allocated sufficiently.
2642 pfkey_setsadbxsa2(buf
, lim
, mode0
, reqid
)
2648 struct sadb_x_sa2
*p
;
2649 u_int8_t mode
= mode0
& 0xff;
2653 len
= sizeof(struct sadb_x_sa2
);
2655 if (buf
+ len
> lim
)
2659 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2660 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2661 p
->sadb_x_sa2_mode
= mode
;
2662 p
->sadb_x_sa2_reqid
= reqid
;
2667 #ifdef SADB_X_EXT_NAT_T_TYPE
2669 pfkey_set_natt_type(buf
, lim
, type
, l_natt_type
)
2673 u_int8_t l_natt_type
;
2675 struct sadb_x_nat_t_type
*p
;
2679 len
= sizeof(struct sadb_x_nat_t_type
);
2681 if (buf
+ len
> lim
)
2685 p
->sadb_x_nat_t_type_len
= PFKEY_UNIT64(len
);
2686 p
->sadb_x_nat_t_type_exttype
= type
;
2687 p
->sadb_x_nat_t_type_type
= l_natt_type
;
2693 pfkey_set_natt_port(buf
, lim
, type
, l_natt_port
)
2697 u_int16_t l_natt_port
;
2699 struct sadb_x_nat_t_port
*p
;
2703 len
= sizeof(struct sadb_x_nat_t_port
);
2705 if (buf
+ len
> lim
)
2709 p
->sadb_x_nat_t_port_len
= PFKEY_UNIT64(len
);
2710 p
->sadb_x_nat_t_port_exttype
= type
;
2711 p
->sadb_x_nat_t_port_port
= htons(l_natt_port
);
2717 #ifdef SADB_X_EXT_NAT_T_FRAG
2719 pfkey_set_natt_frag(buf
, lim
, type
, l_natt_frag
)
2723 u_int16_t l_natt_frag
;
2725 struct sadb_x_nat_t_frag
*p
;
2729 len
= sizeof(struct sadb_x_nat_t_frag
);
2731 if (buf
+ len
> lim
)
2735 p
->sadb_x_nat_t_frag_len
= PFKEY_UNIT64(len
);
2736 p
->sadb_x_nat_t_frag_exttype
= type
;
2737 p
->sadb_x_nat_t_frag_fraglen
= l_natt_frag
;
2744 pfkey_setsadbsession_id (caddr_t buf
,
2746 u_int64_t session_ids
[],
2747 u_int32_t max_session_ids
)
2749 struct sadb_session_id
*p
;
2752 if (!max_session_ids
)
2758 if (buf
+ len
> lim
)
2762 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
2763 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
2764 p
->sadb_session_id_v
[0] = session_ids
[0];
2765 if (max_session_ids
> 1)
2766 p
->sadb_session_id_v
[1] = session_ids
[1];
2772 pfkey_setsadbsastats (caddr_t buf
,
2775 struct sastat
*stats
,
2776 u_int32_t max_stats
)
2778 struct sadb_sastat
*p
;
2779 u_int len
, list_len
;
2781 if (!stats
|| !max_stats
)
2784 p
= (__typeof__(p
))buf
;
2785 list_len
= sizeof(*stats
) * max_stats
;
2786 len
= sizeof(*p
) + PFKEY_ALIGN8(list_len
);
2788 if (buf
+ len
> lim
)
2792 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
2793 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
2794 p
->sadb_sastat_dir
= dir
;
2795 p
->sadb_sastat_list_len
= max_stats
;
2796 bcopy(stats
, p
+ 1, list_len
);
2802 pfkey_send_getsastats (int so
,
2804 u_int64_t
*session_ids
,
2805 u_int32_t max_session_ids
,
2807 struct sastat
*stats
,
2808 u_int32_t max_stats
)
2810 struct sadb_msg
*newmsg
;
2812 int list_len
, out_len
, len
;
2815 if (!session_ids
|| !stats
|| !max_stats
) {
2819 list_len
= sizeof(*stats
) * max_stats
;
2820 /* create new sadb_msg to send. */
2821 out_len
= sizeof(struct sadb_msg
) + sizeof(struct sadb_session_id
) + sizeof(struct sadb_sastat
) + PFKEY_ALIGN8(list_len
);
2823 if ((newmsg
= CALLOC((size_t)out_len
, struct sadb_msg
*)) == NULL
) {
2824 __ipsec_set_strerror(strerror(errno
));
2827 ep
= ((caddr_t
)(void *)newmsg
) + out_len
;
2829 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSASTAT
, (u_int
)out_len
, SADB_SATYPE_UNSPEC
, seq
, getpid());
2835 p
= pfkey_setsadbsession_id(p
, ep
, session_ids
, max_session_ids
);
2841 p
= pfkey_setsadbsastats(p
, ep
, dir
, stats
, max_stats
);
2848 len
= pfkey_send(so
, newmsg
, out_len
);
2854 __ipsec_errcode
= EIPSEC_NO_ERROR
;