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>
39 #include <System/net/pfkeyv2.h>
40 #include <sys/sysctl.h>
41 #include <netinet/in.h>
42 #ifdef HAVE_NETINET6_IPSEC
43 # include <netinet6/ipsec.h>
45 # include <netinet/ipsec.h>
56 #include "ipsec_strerror.h"
59 #define CALLOC(size, cast) (cast)calloc(1, (size))
61 static int findsupportedmap
__P((int));
62 static int setsupportedmap
__P((struct sadb_supported
*));
63 static struct sadb_alg
*findsupportedalg
__P((u_int
, u_int
));
64 static int pfkey_send_x1
__P((int, u_int
, u_int
, u_int
, struct sockaddr_storage
*,
65 struct sockaddr_storage
*, u_int32_t
, u_int32_t
, u_int
, caddr_t
,
66 u_int
, u_int
, u_int
, u_int
, u_int
, u_int32_t
, u_int32_t
,
67 u_int32_t
, u_int32_t
, u_int32_t
, u_int16_t
));
68 static int pfkey_send_x2
__P((int, u_int
, u_int
, u_int
,
69 struct sockaddr_storage
*, struct sockaddr_storage
*, u_int32_t
));
70 static int pfkey_send_x3
__P((int, u_int
, u_int
));
71 static int pfkey_send_x4
__P((int, u_int
, struct sockaddr_storage
*, u_int
,
72 struct sockaddr_storage
*, u_int
, u_int
, u_int64_t
, u_int64_t
,
73 char *, int, u_int32_t
));
74 static int pfkey_send_x5
__P((int, u_int
, u_int32_t
));
76 static caddr_t pfkey_setsadbmsg
__P((caddr_t
, caddr_t
, u_int
, u_int
,
77 u_int
, u_int32_t
, pid_t
));
78 static caddr_t pfkey_setsadbsa
__P((caddr_t
, caddr_t
, u_int32_t
, u_int
,
79 u_int
, u_int
, u_int32_t
, u_int16_t
));
80 static caddr_t pfkey_setsadbaddr
__P((caddr_t
, caddr_t
, u_int
,
81 struct sockaddr_storage
*, u_int
, u_int
));
82 static caddr_t pfkey_setsadbkey
__P((caddr_t
, caddr_t
, u_int
, caddr_t
, u_int
));
83 static caddr_t pfkey_setsadblifetime
__P((caddr_t
, caddr_t
, u_int
, u_int32_t
,
84 u_int32_t
, u_int32_t
, u_int32_t
));
85 static caddr_t pfkey_setsadbxsa2
__P((caddr_t
, caddr_t
, u_int32_t
, u_int32_t
));
87 #ifdef SADB_X_EXT_NAT_T_TYPE
88 static caddr_t pfkey_set_natt_type
__P((caddr_t
, caddr_t
, u_int
, u_int8_t
));
89 static caddr_t pfkey_set_natt_port
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
91 #ifdef SADB_X_EXT_NAT_T_FRAG
92 static caddr_t pfkey_set_natt_frag
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
96 * make and search supported algorithm structure.
98 static struct sadb_supported
*ipsec_supported
[] = { NULL
, NULL
, NULL
,
99 #ifdef SADB_X_SATYPE_TCPSIGNATURE
104 static int supported_map
[] = {
107 SADB_X_SATYPE_IPCOMP
,
108 #ifdef SADB_X_SATYPE_TCPSIGNATURE
109 SADB_X_SATYPE_TCPSIGNATURE
,
114 findsupportedmap(int satype
)
118 for (i
= 0; i
< sizeof(supported_map
)/sizeof(supported_map
[0]); i
++)
119 if (supported_map
[i
] == satype
)
124 static struct sadb_alg
*
125 findsupportedalg(u_int satype
, u_int alg_id
)
132 algno
= findsupportedmap((int)satype
);
134 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
137 if (ipsec_supported
[algno
] == NULL
) {
138 __ipsec_errcode
= EIPSEC_DO_GET_SUPP_LIST
;
142 tlen
= ipsec_supported
[algno
]->sadb_supported_len
143 - sizeof(struct sadb_supported
);
144 p
= (void *)(ipsec_supported
[algno
] + 1);
146 if (tlen
< sizeof(struct sadb_alg
)) {
150 if (((struct sadb_alg
*)(void *)p
)->sadb_alg_id
== alg_id
)
153 tlen
-= sizeof(struct sadb_alg
);
154 p
+= sizeof(struct sadb_alg
);
157 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
162 setsupportedmap(struct sadb_supported
*sup
)
164 struct sadb_supported
**ipsup
;
166 switch (sup
->sadb_supported_exttype
) {
167 case SADB_EXT_SUPPORTED_AUTH
:
168 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_AH
)];
170 case SADB_EXT_SUPPORTED_ENCRYPT
:
171 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_ESP
)];
174 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
181 *ipsup
= malloc((size_t)sup
->sadb_supported_len
);
183 __ipsec_set_strerror(strerror(errno
));
186 memcpy(*ipsup
, sup
, (size_t)sup
->sadb_supported_len
);
192 * check key length against algorithm specified.
193 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
194 * augument, and only calls to ipsec_check_keylen2();
195 * keylen is the unit of bit.
201 ipsec_check_keylen(u_int supported
, u_int alg_id
, u_int keylen
)
207 case SADB_EXT_SUPPORTED_AUTH
:
208 satype
= SADB_SATYPE_AH
;
210 case SADB_EXT_SUPPORTED_ENCRYPT
:
211 satype
= SADB_SATYPE_ESP
;
214 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
218 return ipsec_check_keylen2(satype
, alg_id
, keylen
);
222 * check key length against algorithm specified.
223 * satype is one of satype defined at pfkeyv2.h.
224 * keylen is the unit of bit.
230 ipsec_check_keylen2(u_int satype
, u_int alg_id
, u_int keylen
)
232 struct sadb_alg
*alg
;
234 alg
= findsupportedalg(satype
, alg_id
);
238 if (keylen
< alg
->sadb_alg_minbits
|| keylen
> alg
->sadb_alg_maxbits
) {
239 fprintf(stderr
, "%d %d %d\n", keylen
, alg
->sadb_alg_minbits
,
240 alg
->sadb_alg_maxbits
);
241 __ipsec_errcode
= EIPSEC_INVAL_KEYLEN
;
245 __ipsec_errcode
= EIPSEC_NO_ERROR
;
250 * get max/min key length against algorithm specified.
251 * satype is one of satype defined at pfkeyv2.h.
252 * keylen is the unit of bit.
258 ipsec_get_keylen(u_int supported
, u_int alg_id
, struct sadb_alg
*alg0
)
260 struct sadb_alg
*alg
;
265 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
270 case SADB_EXT_SUPPORTED_AUTH
:
271 satype
= SADB_SATYPE_AH
;
273 case SADB_EXT_SUPPORTED_ENCRYPT
:
274 satype
= SADB_SATYPE_ESP
;
277 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
281 alg
= findsupportedalg(satype
, alg_id
);
285 memcpy(alg0
, alg
, sizeof(*alg0
));
287 __ipsec_errcode
= EIPSEC_NO_ERROR
;
292 * set the rate for SOFT lifetime against HARD one.
293 * If rate is more than 100 or equal to zero, then set to 100.
295 static u_int soft_lifetime_allocations_rate
= PFKEY_SOFT_LIFETIME_RATE
;
296 static u_int soft_lifetime_bytes_rate
= PFKEY_SOFT_LIFETIME_RATE
;
297 static u_int soft_lifetime_addtime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
298 static u_int soft_lifetime_usetime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
301 pfkey_set_softrate(u_int type
, u_int rate
)
303 __ipsec_errcode
= EIPSEC_NO_ERROR
;
305 if (rate
> 100 || rate
== 0)
309 case SADB_X_LIFETIME_ALLOCATIONS
:
310 soft_lifetime_allocations_rate
= rate
;
312 case SADB_X_LIFETIME_BYTES
:
313 soft_lifetime_bytes_rate
= rate
;
315 case SADB_X_LIFETIME_ADDTIME
:
316 soft_lifetime_addtime_rate
= rate
;
318 case SADB_X_LIFETIME_USETIME
:
319 soft_lifetime_usetime_rate
= rate
;
323 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
328 * get current rate for SOFT lifetime against HARD one.
329 * ATTENTION: ~0 is returned if invalid type was passed.
332 pfkey_get_softrate(u_int type
)
335 case SADB_X_LIFETIME_ALLOCATIONS
:
336 return soft_lifetime_allocations_rate
;
337 case SADB_X_LIFETIME_BYTES
:
338 return soft_lifetime_bytes_rate
;
339 case SADB_X_LIFETIME_ADDTIME
:
340 return soft_lifetime_addtime_rate
;
341 case SADB_X_LIFETIME_USETIME
:
342 return soft_lifetime_usetime_rate
;
349 * sending SADB_GETSPI message to the kernel.
351 * positive: success and return length sent.
352 * -1 : error occured, and set errno.
355 pfkey_send_getspi(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
356 u_int32_t min
, u_int32_t max
, u_int32_t reqid
, u_int32_t seq
)
358 struct sadb_msg
*newmsg
;
361 int need_spirange
= 0;
366 if (src
== NULL
|| dst
== NULL
) {
367 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
370 if (src
->ss_family
!= dst
->ss_family
) {
371 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
374 if (min
> max
|| (min
> 0 && min
<= 255)) {
375 __ipsec_errcode
= EIPSEC_INVAL_SPI
;
378 switch (src
->ss_family
) {
380 plen
= sizeof(struct in_addr
) << 3;
383 plen
= sizeof(struct in6_addr
) << 3;
386 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
390 /* create new sadb_msg to send. */
391 len
= sizeof(struct sadb_msg
)
392 + sizeof(struct sadb_x_sa2
)
393 + sizeof(struct sadb_address
)
394 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
395 + sizeof(struct sadb_address
)
396 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
));
398 if (min
> 255 && max
< (u_int
)~0) {
400 len
+= sizeof(struct sadb_spirange
);
403 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
404 __ipsec_set_strerror(strerror(errno
));
407 ep
= ((caddr_t
)(void *)newmsg
) + len
;
409 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSPI
,
410 (u_int
)len
, satype
, seq
, getpid());
416 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
422 /* set sadb_address for source */
423 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
430 /* set sadb_address for destination */
431 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
438 /* proccessing spi range */
440 struct sadb_spirange spirange
;
442 if (p
+ sizeof(spirange
) > ep
) {
447 memset(&spirange
, 0, sizeof(spirange
));
448 spirange
.sadb_spirange_len
= PFKEY_UNIT64(sizeof(spirange
));
449 spirange
.sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
450 spirange
.sadb_spirange_min
= min
;
451 spirange
.sadb_spirange_max
= max
;
453 memcpy(p
, &spirange
, sizeof(spirange
));
455 p
+= sizeof(spirange
);
463 len
= pfkey_send(so
, newmsg
, len
);
469 __ipsec_errcode
= EIPSEC_NO_ERROR
;
475 * sending SADB_UPDATE message to the kernel.
476 * The length of key material is a_keylen + e_keylen.
478 * positive: success and return length sent.
479 * -1 : error occured, and set errno.
482 pfkey_send_update(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
483 u_int32_t spi
, u_int32_t reqid
, u_int wsize
, caddr_t keymat
, u_int e_type
, u_int e_keylen
,
484 u_int a_type
, u_int a_keylen
, u_int flags
, u_int32_t l_alloc
, u_int64_t l_bytes
,
485 u_int64_t l_addtime
, u_int64_t l_usetime
, u_int32_t seq
, u_int16_t port
)
488 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
490 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
491 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
492 (u_int
)l_usetime
, seq
, port
)) < 0)
500 * sending SADB_ADD message to the kernel.
501 * The length of key material is a_keylen + e_keylen.
503 * positive: success and return length sent.
504 * -1 : error occured, and set errno.
507 pfkey_send_add(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
508 u_int32_t spi
, u_int32_t reqid
, u_int wsize
, caddr_t keymat
, u_int e_type
, u_int e_keylen
,
509 u_int a_type
, u_int a_keylen
, u_int flags
, u_int32_t l_alloc
, u_int64_t l_bytes
,
510 u_int64_t l_addtime
, u_int64_t l_usetime
, u_int32_t seq
, u_int16_t port
)
513 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
515 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
516 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
517 (u_int
)l_usetime
, seq
, port
)) < 0)
525 * sending SADB_DELETE message to the kernel.
527 * positive: success and return length sent.
528 * -1 : error occured, and set errno.
531 pfkey_send_delete(so
, satype
, mode
, src
, dst
, spi
)
534 struct sockaddr_storage
*src
, *dst
;
538 if ((len
= pfkey_send_x2(so
, SADB_DELETE
, satype
, mode
, src
, dst
, spi
)) < 0)
545 * sending SADB_DELETE without spi to the kernel. This is
546 * the "delete all" request (an extension also present in
550 * positive: success and return length sent
551 * -1 : error occured, and set errno
555 pfkey_send_delete_all(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
)
557 struct sadb_msg
*newmsg
;
564 if (src
== NULL
|| dst
== NULL
) {
565 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
568 if (src
->ss_family
!= dst
->ss_family
) {
569 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
572 switch (src
->ss_family
) {
574 plen
= sizeof(struct in_addr
) << 3;
577 plen
= sizeof(struct in6_addr
) << 3;
580 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
584 /* create new sadb_msg to reply. */
585 len
= sizeof(struct sadb_msg
)
586 + sizeof(struct sadb_address
)
587 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
588 + sizeof(struct sadb_address
)
589 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
));
591 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
592 __ipsec_set_strerror(strerror(errno
));
595 ep
= ((caddr_t
)(void *)newmsg
) + len
;
597 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_DELETE
, (u_int
)len
,
598 satype
, 0, getpid());
603 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
609 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
617 len
= pfkey_send(so
, newmsg
, len
);
623 __ipsec_errcode
= EIPSEC_NO_ERROR
;
628 * sending SADB_GET message to the kernel.
630 * positive: success and return length sent.
631 * -1 : error occured, and set errno.
634 pfkey_send_get(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
, u_int32_t spi
)
637 if ((len
= pfkey_send_x2(so
, SADB_GET
, satype
, mode
, src
, dst
, spi
)) < 0)
644 * sending SADB_REGISTER message to the kernel.
646 * positive: success and return length sent.
647 * -1 : error occured, and set errno.
650 pfkey_send_register(int so
, u_int satype
)
654 if (satype
== PF_UNSPEC
) {
656 algno
< sizeof(supported_map
)/sizeof(supported_map
[0]);
658 if (ipsec_supported
[algno
]) {
659 free(ipsec_supported
[algno
]);
660 ipsec_supported
[algno
] = NULL
;
664 algno
= findsupportedmap((int)satype
);
666 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
670 if (ipsec_supported
[algno
]) {
671 free(ipsec_supported
[algno
]);
672 ipsec_supported
[algno
] = NULL
;
676 if ((len
= pfkey_send_x3(so
, SADB_REGISTER
, satype
)) < 0)
683 * receiving SADB_REGISTER message from the kernel, and copy buffer for
684 * sadb_supported returned into ipsec_supported.
686 * 0: success and return length sent.
687 * -1: error occured, and set errno.
690 pfkey_recv_register(int so
)
692 pid_t pid
= getpid();
693 struct sadb_msg
*newmsg
;
696 /* receive message */
698 if ((newmsg
= pfkey_recv(so
)) == NULL
)
700 if (newmsg
->sadb_msg_type
== SADB_REGISTER
&&
701 newmsg
->sadb_msg_pid
== pid
)
707 newmsg
->sadb_msg_len
= PFKEY_UNUNIT64(newmsg
->sadb_msg_len
);
709 error
= pfkey_set_supported(newmsg
, newmsg
->sadb_msg_len
);
713 __ipsec_errcode
= EIPSEC_NO_ERROR
;
719 * receiving SADB_REGISTER message from the kernel, and copy buffer for
720 * sadb_supported returned into ipsec_supported.
721 * NOTE: sadb_msg_len must be host order.
723 * tlen: msg length, it's to makeing sure.
725 * 0: success and return length sent.
726 * -1: error occured, and set errno.
729 pfkey_set_supported(struct sadb_msg
*msg
, int tlen
)
731 struct sadb_supported
*sup
;
736 if (msg
->sadb_msg_len
!= tlen
) {
737 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
744 p
+= sizeof(struct sadb_msg
);
748 if (ep
< p
+ sizeof(*sup
) ||
749 PFKEY_EXTLEN(sup
) < sizeof(*sup
) ||
750 ep
< p
+ sup
->sadb_supported_len
) {
755 switch (sup
->sadb_supported_exttype
) {
756 case SADB_EXT_SUPPORTED_AUTH
:
757 case SADB_EXT_SUPPORTED_ENCRYPT
:
760 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
765 sup
->sadb_supported_len
= PFKEY_EXTLEN(sup
);
767 /* set supported map */
768 if (setsupportedmap(sup
) != 0)
771 p
+= sup
->sadb_supported_len
;
775 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
779 __ipsec_errcode
= EIPSEC_NO_ERROR
;
785 * sending SADB_FLUSH message to the kernel.
787 * positive: success and return length sent.
788 * -1 : error occured, and set errno.
791 pfkey_send_flush(int so
, u_int satype
)
795 if ((len
= pfkey_send_x3(so
, SADB_FLUSH
, satype
)) < 0)
802 * sending SADB_DUMP message to the kernel.
804 * positive: success and return length sent.
805 * -1 : error occured, and set errno.
808 pfkey_send_dump(int so
, u_int satype
)
812 if ((len
= pfkey_send_x3(so
, SADB_DUMP
, satype
)) < 0)
819 * sending SADB_X_PROMISC message to the kernel.
820 * NOTE that this function handles promisc mode toggle only.
822 * flag: set promisc off if zero, set promisc on if non-zero.
824 * positive: success and return length sent.
825 * -1 : error occured, and set errno.
826 * 0 : error occured, and set errno.
827 * others: a pointer to new allocated buffer in which supported
831 pfkey_send_promisc_toggle(int so
, int flag
)
835 if ((len
= pfkey_send_x3(so
, SADB_X_PROMISC
,
836 (u_int
)(flag
? 1 : 0))) < 0)
843 * sending SADB_X_SPDADD message to the kernel.
845 * positive: success and return length sent.
846 * -1 : error occured, and set errno.
849 pfkey_send_spdadd(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
850 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
854 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
855 src
, prefs
, dst
, prefd
, proto
,
856 (u_int64_t
)0, (u_int64_t
)0,
857 policy
, policylen
, seq
)) < 0)
864 * sending SADB_X_SPDADD message to the kernel.
866 * positive: success and return length sent.
867 * -1 : error occured, and set errno.
870 pfkey_send_spdadd2(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
, u_int prefd
, u_int proto
, u_int64_t ltime
, u_int64_t vtime
,
871 caddr_t policy
, int policylen
, u_int32_t seq
)
875 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
876 src
, prefs
, dst
, prefd
, proto
,
878 policy
, policylen
, seq
)) < 0)
885 * sending SADB_X_SPDUPDATE message to the kernel.
887 * positive: success and return length sent.
888 * -1 : error occured, and set errno.
891 pfkey_send_spdupdate(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
892 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
896 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
897 src
, prefs
, dst
, prefd
, proto
,
898 (u_int64_t
)0, (u_int64_t
)0,
899 policy
, policylen
, seq
)) < 0)
906 * sending SADB_X_SPDUPDATE message to the kernel.
908 * positive: success and return length sent.
909 * -1 : error occured, and set errno.
912 pfkey_send_spdupdate2(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
913 u_int prefd
, u_int proto
, u_int64_t ltime
, u_int64_t vtime
,
914 caddr_t policy
, int policylen
, u_int32_t seq
)
918 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
919 src
, prefs
, dst
, prefd
, proto
,
921 policy
, policylen
, seq
)) < 0)
928 * sending SADB_X_SPDDELETE message to the kernel.
930 * positive: success and return length sent.
931 * -1 : error occured, and set errno.
934 pfkey_send_spddelete(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
935 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
939 if (policylen
!= sizeof(struct sadb_x_policy
)) {
940 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
944 if ((len
= pfkey_send_x4(so
, SADB_X_SPDDELETE
,
945 src
, prefs
, dst
, prefd
, proto
,
946 (u_int64_t
)0, (u_int64_t
)0,
947 policy
, policylen
, seq
)) < 0)
954 * sending SADB_X_SPDDELETE message to the kernel.
956 * positive: success and return length sent.
957 * -1 : error occured, and set errno.
960 pfkey_send_spddelete2(int so
, u_int32_t spid
)
964 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDELETE2
, spid
)) < 0)
971 * sending SADB_X_SPDGET message to the kernel.
973 * positive: success and return length sent.
974 * -1 : error occured, and set errno.
977 pfkey_send_spdget(int so
, u_int32_t spid
)
981 if ((len
= pfkey_send_x5(so
, SADB_X_SPDGET
, spid
)) < 0)
988 * sending SADB_X_SPDSETIDX message to the kernel.
990 * positive: success and return length sent.
991 * -1 : error occured, and set errno.
994 pfkey_send_spdsetidx(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
995 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
999 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1000 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1004 if ((len
= pfkey_send_x4(so
, SADB_X_SPDSETIDX
,
1005 src
, prefs
, dst
, prefd
, proto
,
1006 (u_int64_t
)0, (u_int64_t
)0,
1007 policy
, policylen
, seq
)) < 0)
1014 * sending SADB_SPDFLUSH message to the kernel.
1016 * positive: success and return length sent.
1017 * -1 : error occured, and set errno.
1020 pfkey_send_spdflush(int so
)
1024 if ((len
= pfkey_send_x3(so
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
)) < 0)
1031 * sending SADB_SPDDUMP message to the kernel.
1033 * positive: success and return length sent.
1034 * -1 : error occured, and set errno.
1037 pfkey_send_spddump(int so
)
1041 if ((len
= pfkey_send_x3(so
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
)) < 0)
1048 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1050 pfkey_send_x1(int so
, u_int type
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
,
1051 struct sockaddr_storage
*dst
, u_int32_t spi
, u_int32_t reqid
, u_int wsize
,
1052 caddr_t keymat
, u_int e_type
, u_int e_keylen
, u_int a_type
, u_int a_keylen
, u_int flags
,
1053 u_int32_t l_alloc
, u_int32_t l_bytes
, u_int32_t l_addtime
, u_int32_t l_usetime
, u_int32_t seq
, u_int16_t port
)
1055 struct sadb_msg
*newmsg
;
1061 /* validity check */
1062 if (src
== NULL
|| dst
== NULL
) {
1063 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1066 if (src
->ss_family
!= dst
->ss_family
) {
1067 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1070 switch (src
->ss_family
) {
1072 plen
= sizeof(struct in_addr
) << 3;
1075 plen
= sizeof(struct in6_addr
) << 3;
1078 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1083 case SADB_SATYPE_ESP
:
1084 if (e_type
== SADB_EALG_NONE
) {
1085 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1089 case SADB_SATYPE_AH
:
1090 if (e_type
!= SADB_EALG_NONE
) {
1091 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1094 if (a_type
== SADB_AALG_NONE
) {
1095 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1099 case SADB_X_SATYPE_IPCOMP
:
1100 if (e_type
== SADB_X_CALG_NONE
) {
1101 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1104 if (a_type
!= SADB_AALG_NONE
) {
1105 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1109 #ifdef SADB_X_AALG_TCP_MD5
1110 case SADB_X_SATYPE_TCPSIGNATURE
:
1111 if (e_type
!= SADB_EALG_NONE
) {
1112 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1115 if (a_type
!= SADB_X_AALG_TCP_MD5
) {
1116 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1122 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1126 /* create new sadb_msg to reply. */
1127 len
= sizeof(struct sadb_msg
)
1128 + sizeof(struct sadb_sa_2
)
1129 + sizeof(struct sadb_x_sa2
)
1130 + sizeof(struct sadb_address
)
1131 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1132 + sizeof(struct sadb_address
)
1133 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
))
1134 + sizeof(struct sadb_lifetime
)
1135 + sizeof(struct sadb_lifetime
);
1137 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
)
1138 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1139 if (a_type
!= SADB_AALG_NONE
)
1140 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1142 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1143 __ipsec_set_strerror(strerror(errno
));
1146 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1148 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1149 satype
, seq
, getpid());
1154 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
, port
);
1159 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
1164 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1170 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1177 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
) {
1178 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1185 if (a_type
!= SADB_AALG_NONE
) {
1186 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1187 keymat
+ e_keylen
, a_keylen
);
1194 /* set sadb_lifetime for destination */
1195 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1196 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1201 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1202 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1214 len
= pfkey_send(so
, newmsg
, len
);
1220 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1225 /* sending SADB_DELETE or SADB_GET message to the kernel */
1228 pfkey_send_x2(int so
, u_int type
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
, u_int32_t spi
)
1230 struct sadb_msg
*newmsg
;
1236 /* validity check */
1237 if (src
== NULL
|| dst
== NULL
) {
1238 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1241 if (src
->ss_family
!= dst
->ss_family
) {
1242 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1245 switch (src
->ss_family
) {
1247 plen
= sizeof(struct in_addr
) << 3;
1250 plen
= sizeof(struct in6_addr
) << 3;
1253 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1257 /* create new sadb_msg to reply. */
1258 len
= sizeof(struct sadb_msg
)
1259 + sizeof(struct sadb_sa_2
)
1260 + sizeof(struct sadb_address
)
1261 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1262 + sizeof(struct sadb_address
)
1263 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
));
1265 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1266 __ipsec_set_strerror(strerror(errno
));
1269 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1271 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1277 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0, 0);
1282 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1288 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1290 if (!p
|| p
!= ep
) {
1296 len
= pfkey_send(so
, newmsg
, len
);
1302 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1307 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1311 pfkey_send_x3(int so
, u_int type
, u_int satype
)
1313 struct sadb_msg
*newmsg
;
1318 /* validity check */
1320 case SADB_X_PROMISC
:
1321 if (satype
!= 0 && satype
!= 1) {
1322 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1328 case SADB_SATYPE_UNSPEC
:
1329 case SADB_SATYPE_AH
:
1330 case SADB_SATYPE_ESP
:
1331 case SADB_X_SATYPE_IPCOMP
:
1332 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1333 case SADB_X_SATYPE_TCPSIGNATURE
:
1337 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1342 /* create new sadb_msg to send. */
1343 len
= sizeof(struct sadb_msg
);
1345 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1346 __ipsec_set_strerror(strerror(errno
));
1349 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1351 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1353 if (!p
|| p
!= ep
) {
1359 len
= pfkey_send(so
, newmsg
, len
);
1365 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1369 /* sending SADB_X_SPDADD message to the kernel */
1371 pfkey_send_x4(int so
, u_int type
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
, u_int prefd
, u_int proto
,
1372 u_int64_t ltime
, u_int64_t vtime
, char *policy
, int policylen
, u_int32_t seq
)
1374 struct sadb_msg
*newmsg
;
1380 /* validity check */
1381 if (src
== NULL
|| dst
== NULL
) {
1382 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1385 if (src
->ss_family
!= dst
->ss_family
) {
1386 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1390 switch (src
->ss_family
) {
1392 plen
= sizeof(struct in_addr
) << 3;
1395 plen
= sizeof(struct in6_addr
) << 3;
1398 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1401 if (prefs
> plen
|| prefd
> plen
) {
1402 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1406 /* create new sadb_msg to reply. */
1407 len
= sizeof(struct sadb_msg
)
1408 + sizeof(struct sadb_address
)
1409 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1410 + sizeof(struct sadb_address
)
1411 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1412 + sizeof(struct sadb_lifetime
)
1415 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1416 __ipsec_set_strerror(strerror(errno
));
1419 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1421 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1422 SADB_SATYPE_UNSPEC
, seq
, getpid());
1427 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1432 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1437 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1438 0, 0, (u_int
)ltime
, (u_int
)vtime
);
1439 if (!p
|| p
+ policylen
!= ep
) {
1443 memcpy(p
, policy
, (size_t)policylen
);
1446 len
= pfkey_send(so
, newmsg
, len
);
1452 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1456 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1458 pfkey_send_x5(int so
, u_int type
, u_int32_t spid
)
1460 struct sadb_msg
*newmsg
;
1461 struct sadb_x_policy xpl
;
1466 /* create new sadb_msg to reply. */
1467 len
= sizeof(struct sadb_msg
)
1470 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1471 __ipsec_set_strerror(strerror(errno
));
1474 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1476 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1477 SADB_SATYPE_UNSPEC
, 0, getpid());
1483 if (p
+ sizeof(xpl
) != ep
) {
1487 memset(&xpl
, 0, sizeof(xpl
));
1488 xpl
.sadb_x_policy_len
= PFKEY_UNIT64(sizeof(xpl
));
1489 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
1490 xpl
.sadb_x_policy_id
= spid
;
1491 memcpy(p
, &xpl
, sizeof(xpl
));
1494 len
= pfkey_send(so
, newmsg
, len
);
1500 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1508 * others : success and return value of socket.
1514 int bufsiz
= 0; /* Max allowed by default */
1515 const unsigned long newbufk
= 1536;
1516 unsigned long oldmax
;
1517 size_t oldmaxsize
= sizeof(oldmax
);
1518 unsigned long newmax
= newbufk
* (1024 + 128);
1520 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
1521 __ipsec_set_strerror(strerror(errno
));
1526 * This is a temporary workaround for KAME PR 154.
1527 * Don't really care even if it fails.
1529 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax
, &oldmaxsize
, &newmax
, sizeof(newmax
)) != 0)
1530 bufsiz
= 233016; /* Max allowed by default */
1532 bufsiz
= newbufk
* 1024;
1534 setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
1535 setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
1537 if (bufsiz
== newbufk
* 1024)
1538 sysctlbyname("kern.ipc.maxsockbuf", NULL
, NULL
, &oldmax
, oldmaxsize
);
1540 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1555 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1560 * receive sadb_msg data, and return pointer to new buffer allocated.
1561 * Must free this buffer later.
1563 * NULL : error occured.
1564 * others : a pointer to sadb_msg structure.
1566 * XXX should be rewritten to pass length explicitly
1571 struct sadb_msg buf
, *newmsg
;
1575 while ((len
= recv(so
, (void *)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
1578 __ipsec_set_strerror(strerror(errno
));
1582 if (len
< sizeof(buf
)) {
1583 recv(so
, (void *)&buf
, sizeof(buf
), 0);
1584 __ipsec_errcode
= EIPSEC_MAX
;
1588 /* read real message */
1589 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
1590 if ((newmsg
= CALLOC((size_t)reallen
, struct sadb_msg
*)) == 0) {
1591 __ipsec_set_strerror(strerror(errno
));
1595 while ((len
= recv(so
, (void *)newmsg
, (socklen_t
)reallen
, 0)) < 0) {
1598 __ipsec_set_strerror(strerror(errno
));
1603 if (len
!= reallen
) {
1604 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1609 /* don't trust what the kernel says, validate! */
1610 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
1611 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1616 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1621 * send message to a socket.
1623 * others: success and return length sent.
1627 pfkey_send(int so
, struct sadb_msg
*msg
, int len
)
1629 if ((len
= send(so
, (void *)msg
, (socklen_t
)len
, 0)) < 0) {
1630 __ipsec_set_strerror(strerror(errno
));
1634 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1640 * NOTE: These functions are derived from netkey/key.c in KAME.
1643 * set the pointer to each header in this message buffer.
1644 * IN: msg: pointer to message buffer.
1645 * mhp: pointer to the buffer initialized like below:
1646 * caddr_t mhp[SADB_EXT_MAX + 1];
1650 * XXX should be rewritten to obtain length explicitly
1653 pfkey_align(struct sadb_msg
*msg
, caddr_t
*mhp
)
1655 struct sadb_ext
*ext
;
1658 caddr_t ep
; /* XXX should be passed from upper layer */
1660 /* validity check */
1661 if (msg
== NULL
|| mhp
== NULL
) {
1662 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1667 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
1670 mhp
[0] = (void *)msg
;
1674 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
1676 /* skip base header */
1677 p
+= sizeof(struct sadb_msg
);
1681 if (ep
< p
+ sizeof(*ext
) || PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
1682 ep
< p
+ PFKEY_EXTLEN(ext
)) {
1683 /* invalid format */
1687 /* duplicate check */
1688 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1689 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
1690 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1695 switch (ext
->sadb_ext_type
) {
1697 case SADB_EXT_LIFETIME_CURRENT
:
1698 case SADB_EXT_LIFETIME_HARD
:
1699 case SADB_EXT_LIFETIME_SOFT
:
1700 case SADB_EXT_ADDRESS_SRC
:
1701 case SADB_EXT_ADDRESS_DST
:
1702 case SADB_EXT_ADDRESS_PROXY
:
1703 case SADB_EXT_KEY_AUTH
:
1704 /* XXX should to be check weak keys. */
1705 case SADB_EXT_KEY_ENCRYPT
:
1706 /* XXX should to be check weak keys. */
1707 case SADB_EXT_IDENTITY_SRC
:
1708 case SADB_EXT_IDENTITY_DST
:
1709 case SADB_EXT_SENSITIVITY
:
1710 case SADB_EXT_PROPOSAL
:
1711 case SADB_EXT_SUPPORTED_AUTH
:
1712 case SADB_EXT_SUPPORTED_ENCRYPT
:
1713 case SADB_EXT_SPIRANGE
:
1714 case SADB_X_EXT_POLICY
:
1715 case SADB_X_EXT_SA2
:
1716 case SADB_EXT_SESSION_ID
:
1717 case SADB_EXT_SASTAT
:
1718 #ifdef SADB_X_EXT_NAT_T_TYPE
1719 case SADB_X_EXT_NAT_T_TYPE
:
1720 case SADB_X_EXT_NAT_T_SPORT
:
1721 case SADB_X_EXT_NAT_T_DPORT
:
1722 case SADB_X_EXT_NAT_T_OA
:
1724 #ifdef SADB_X_EXT_TAG
1725 case SADB_X_EXT_TAG
:
1727 #ifdef SADB_X_EXT_PACKET
1728 case SADB_X_EXT_PACKET
:
1731 mhp
[ext
->sadb_ext_type
] = (void *)ext
;
1734 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1738 p
+= PFKEY_EXTLEN(ext
);
1742 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
1746 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1751 * check basic usage for sadb_msg,
1752 * NOTE: This routine is derived from netkey/key.c in KAME.
1753 * IN: msg: pointer to message buffer.
1754 * mhp: pointer to the buffer initialized like below:
1756 * caddr_t mhp[SADB_EXT_MAX + 1];
1762 pfkey_check(caddr_t
* mhp
)
1764 struct sadb_msg
*msg
;
1766 /* validity check */
1767 if (mhp
== NULL
|| mhp
[0] == NULL
) {
1768 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1772 msg
= (void *)mhp
[0];
1775 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
1776 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
1781 if (msg
->sadb_msg_type
> SADB_MAX
) {
1782 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
1787 switch (msg
->sadb_msg_satype
) {
1788 case SADB_SATYPE_UNSPEC
:
1789 switch (msg
->sadb_msg_type
) {
1797 #ifdef SADB_X_NAT_T_NEW_MAPPING
1798 case SADB_X_NAT_T_NEW_MAPPING
:
1800 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1804 case SADB_SATYPE_ESP
:
1805 case SADB_SATYPE_AH
:
1806 case SADB_X_SATYPE_IPCOMP
:
1807 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1808 case SADB_X_SATYPE_TCPSIGNATURE
:
1810 switch (msg
->sadb_msg_type
) {
1812 case SADB_X_SPDDELETE
:
1814 case SADB_X_SPDDUMP
:
1815 case SADB_X_SPDFLUSH
:
1816 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1819 #ifdef SADB_X_NAT_T_NEW_MAPPING
1820 if (msg
->sadb_msg_type
== SADB_X_NAT_T_NEW_MAPPING
&&
1821 msg
->sadb_msg_satype
!= SADB_SATYPE_ESP
) {
1822 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1827 case SADB_SATYPE_RSVP
:
1828 case SADB_SATYPE_OSPFV2
:
1829 case SADB_SATYPE_RIPV2
:
1830 case SADB_SATYPE_MIP
:
1831 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
1833 case 1: /* XXX: What does it do ? */
1834 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
1838 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1842 /* check field of upper layer protocol and address family */
1843 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
1844 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
1845 struct sadb_address
*src0
, *dst0
;
1847 src0
= (void *)(mhp
[SADB_EXT_ADDRESS_SRC
]);
1848 dst0
= (void *)(mhp
[SADB_EXT_ADDRESS_DST
]);
1850 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
1851 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
1855 if (PFKEY_ADDR_SADDR(src0
)->sa_family
1856 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
1857 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1861 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
1866 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1871 * prefixlen == 0 is valid because there must be the case
1872 * all addresses are matched.
1876 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1881 * set data into sadb_msg.
1882 * `buf' must has been allocated sufficiently.
1885 pfkey_setsadbmsg(caddr_t buf
, caddr_t lim
, u_int type
, u_int tlen
, u_int satype
, u_int32_t seq
, pid_t pid
)
1891 len
= sizeof(struct sadb_msg
);
1893 if (buf
+ len
> lim
)
1897 p
->sadb_msg_version
= PF_KEY_V2
;
1898 p
->sadb_msg_type
= type
;
1899 p
->sadb_msg_errno
= 0;
1900 p
->sadb_msg_satype
= satype
;
1901 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
1902 p
->sadb_msg_reserved
= 0;
1903 p
->sadb_msg_seq
= seq
;
1904 p
->sadb_msg_pid
= (u_int32_t
)pid
;
1910 * copy secasvar data into sadb_address.
1911 * `buf' must has been allocated sufficiently.
1914 pfkey_setsadbsa(caddr_t buf
, caddr_t lim
, u_int32_t spi
, u_int wsize
, u_int auth
, u_int enc
, u_int32_t flags
, u_int16_t port
)
1916 struct sadb_sa_2
*p
;
1920 len
= sizeof(struct sadb_sa_2
);
1922 if (buf
+ len
> lim
)
1926 p
->sa
.sadb_sa_len
= PFKEY_UNIT64(len
);
1927 p
->sa
.sadb_sa_exttype
= SADB_EXT_SA
;
1928 p
->sa
.sadb_sa_spi
= spi
;
1929 p
->sa
.sadb_sa_replay
= wsize
;
1930 p
->sa
.sadb_sa_state
= SADB_SASTATE_LARVAL
;
1931 p
->sa
.sadb_sa_auth
= auth
;
1932 p
->sa
.sadb_sa_encrypt
= enc
;
1933 p
->sa
.sadb_sa_flags
= flags
;
1934 p
->sadb_sa_natt_port
= port
;
1940 * set data into sadb_address.
1941 * `buf' must has been allocated sufficiently.
1942 * prefixlen is in bits.
1945 pfkey_setsadbaddr(caddr_t buf
, caddr_t lim
, u_int exttype
, struct sockaddr_storage
*saddr
, u_int prefixlen
, u_int ul_proto
)
1947 struct sadb_address
*p
;
1951 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)saddr
));
1953 if (buf
+ len
> lim
)
1957 p
->sadb_address_len
= PFKEY_UNIT64(len
);
1958 p
->sadb_address_exttype
= exttype
& 0xffff;
1959 p
->sadb_address_proto
= ul_proto
& 0xff;
1960 p
->sadb_address_prefixlen
= prefixlen
;
1961 p
->sadb_address_reserved
= 0;
1963 memcpy(p
+ 1, saddr
, (size_t)sysdep_sa_len((struct sockaddr
*)saddr
));
1969 * set sadb_key structure after clearing buffer with zero.
1970 * OUT: the pointer of buf + len.
1973 pfkey_setsadbkey(caddr_t buf
, caddr_t lim
, u_int type
, caddr_t key
, u_int keylen
)
1979 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
1981 if (buf
+ len
> lim
)
1985 p
->sadb_key_len
= PFKEY_UNIT64(len
);
1986 p
->sadb_key_exttype
= type
;
1987 p
->sadb_key_bits
= keylen
<< 3;
1988 p
->sadb_key_reserved
= 0;
1990 memcpy(p
+ 1, key
, keylen
);
1996 * set sadb_lifetime structure after clearing buffer with zero.
1997 * OUT: the pointer of buf + len.
2000 pfkey_setsadblifetime(caddr_t buf
, caddr_t lim
, u_int type
, u_int32_t l_alloc
,
2001 u_int32_t l_bytes
, u_int32_t l_addtime
, u_int32_t l_usetime
)
2003 struct sadb_lifetime
*p
;
2007 len
= sizeof(struct sadb_lifetime
);
2009 if (buf
+ len
> lim
)
2013 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2014 p
->sadb_lifetime_exttype
= type
;
2017 case SADB_EXT_LIFETIME_SOFT
:
2018 p
->sadb_lifetime_allocations
2019 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2020 p
->sadb_lifetime_bytes
2021 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2022 p
->sadb_lifetime_addtime
2023 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2024 p
->sadb_lifetime_usetime
2025 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2027 case SADB_EXT_LIFETIME_HARD
:
2028 p
->sadb_lifetime_allocations
= l_alloc
;
2029 p
->sadb_lifetime_bytes
= l_bytes
;
2030 p
->sadb_lifetime_addtime
= l_addtime
;
2031 p
->sadb_lifetime_usetime
= l_usetime
;
2039 * copy secasvar data into sadb_address.
2040 * `buf' must has been allocated sufficiently.
2043 pfkey_setsadbxsa2(caddr_t buf
, caddr_t lim
, u_int32_t mode0
, u_int32_t reqid
)
2045 struct sadb_x_sa2
*p
;
2046 u_int8_t mode
= mode0
& 0xff;
2050 len
= sizeof(struct sadb_x_sa2
);
2052 if (buf
+ len
> lim
)
2056 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2057 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2058 p
->sadb_x_sa2_mode
= mode
;
2059 p
->sadb_x_sa2_reqid
= reqid
;
2064 #ifdef SADB_X_EXT_NAT_T_TYPE
2066 pfkey_set_natt_type(caddr_t buf
, caddr_t lim
, u_int type
, u_int8_t l_natt_type
)
2068 struct sadb_x_nat_t_type
*p
;
2072 len
= sizeof(struct sadb_x_nat_t_type
);
2074 if (buf
+ len
> lim
)
2078 p
->sadb_x_nat_t_type_len
= PFKEY_UNIT64(len
);
2079 p
->sadb_x_nat_t_type_exttype
= type
;
2080 p
->sadb_x_nat_t_type_type
= l_natt_type
;
2086 pfkey_set_natt_port(caddr_t buf
, caddr_t lim
, u_int type
, u_int16_t l_natt_port
)
2088 struct sadb_x_nat_t_port
*p
;
2092 len
= sizeof(struct sadb_x_nat_t_port
);
2094 if (buf
+ len
> lim
)
2098 p
->sadb_x_nat_t_port_len
= PFKEY_UNIT64(len
);
2099 p
->sadb_x_nat_t_port_exttype
= type
;
2100 p
->sadb_x_nat_t_port_port
= htons(l_natt_port
);
2106 #ifdef SADB_X_EXT_NAT_T_FRAG
2108 pfkey_set_natt_frag(caddr_t buf
, caddr_t lim
, u_int type
, u_int16_t l_natt_frag
)
2110 struct sadb_x_nat_t_frag
*p
;
2114 len
= sizeof(struct sadb_x_nat_t_frag
);
2116 if (buf
+ len
> lim
)
2120 p
->sadb_x_nat_t_frag_len
= PFKEY_UNIT64(len
);
2121 p
->sadb_x_nat_t_frag_exttype
= type
;
2122 p
->sadb_x_nat_t_frag_fraglen
= l_natt_frag
;
2130 pfkey_setsadbsession_id (caddr_t buf
,
2132 u_int64_t session_ids
[],
2133 u_int32_t max_session_ids
)
2135 struct sadb_session_id
*p
;
2138 if (!max_session_ids
)
2144 if (buf
+ len
> lim
)
2148 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
2149 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
2150 p
->sadb_session_id_v
[0] = session_ids
[0];
2151 if (max_session_ids
> 1)
2152 p
->sadb_session_id_v
[1] = session_ids
[1];
2158 pfkey_setsadbsastats (caddr_t buf
,
2161 struct sastat
*stats
,
2162 u_int32_t max_stats
)
2164 struct sadb_sastat
*p
;
2165 u_int len
, list_len
;
2167 if (!stats
|| !max_stats
)
2170 p
= ALIGNED_CAST(__typeof__(p
))buf
; // Wcast-align fix - buffer passed to here is malloc'd message buffer
2171 list_len
= sizeof(*stats
) * max_stats
;
2172 len
= sizeof(*p
) + PFKEY_ALIGN8(list_len
);
2174 if (buf
+ len
> lim
)
2178 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
2179 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
2180 p
->sadb_sastat_dir
= dir
;
2181 p
->sadb_sastat_list_len
= max_stats
;
2182 bcopy(stats
, p
+ 1, list_len
);
2188 pfkey_send_getsastats (int so
,
2190 u_int64_t
*session_ids
,
2191 u_int32_t max_session_ids
,
2193 struct sastat
*stats
,
2194 u_int32_t max_stats
)
2196 struct sadb_msg
*newmsg
;
2198 int list_len
, out_len
, len
;
2201 if (!session_ids
|| !stats
|| !max_stats
) {
2205 list_len
= sizeof(*stats
) * max_stats
;
2206 /* create new sadb_msg to send. */
2207 out_len
= sizeof(struct sadb_msg
) + sizeof(struct sadb_session_id
) + sizeof(struct sadb_sastat
) + PFKEY_ALIGN8(list_len
);
2209 if ((newmsg
= CALLOC((size_t)out_len
, struct sadb_msg
*)) == NULL
) {
2210 __ipsec_set_strerror(strerror(errno
));
2213 ep
= ((caddr_t
)(void *)newmsg
) + out_len
;
2215 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSASTAT
, (u_int
)out_len
, SADB_SATYPE_UNSPEC
, seq
, getpid());
2221 p
= pfkey_setsadbsession_id(p
, ep
, session_ids
, max_session_ids
);
2227 p
= pfkey_setsadbsastats(p
, ep
, dir
, stats
, max_stats
);
2234 len
= pfkey_send(so
, newmsg
, out_len
);
2240 __ipsec_errcode
= EIPSEC_NO_ERROR
;