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 <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 (int);
62 static int setsupportedmap (struct sadb_supported
*);
63 static struct sadb_alg
*findsupportedalg (u_int
, u_int
);
64 static int pfkey_send_x1 (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
, u_int
);
68 static int pfkey_send_x2 (int, u_int
, u_int
, u_int
,
69 struct sockaddr_storage
*, struct sockaddr_storage
*, u_int32_t
);
70 static int pfkey_send_x3 (int, u_int
, u_int
);
71 static int pfkey_send_x4 (int, u_int
, struct sockaddr_storage
*, struct sockaddr_storage
*, u_int
,
72 struct sockaddr_storage
*, struct sockaddr_storage
*, u_int
, u_int
, u_int64_t
, u_int64_t
,
73 char *, int, u_int32_t
, char *, char *, char *, u_int
);
74 static int pfkey_send_x5 (int, u_int
, u_int32_t
);
76 static caddr_t
pfkey_setsadbmsg (caddr_t
, caddr_t
, u_int
, u_int
,
77 u_int
, u_int32_t
, pid_t
);
78 static caddr_t
pfkey_setsadbsa (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 (caddr_t
, caddr_t
, u_int
,
81 struct sockaddr_storage
*, u_int
, u_int
);
82 static caddr_t
pfkey_setsadbkey (caddr_t
, caddr_t
, u_int
, caddr_t
, u_int
);
83 static caddr_t
pfkey_setsadblifetime (caddr_t
, caddr_t
, u_int
, u_int32_t
,
84 u_int32_t
, u_int32_t
, u_int32_t
);
85 static caddr_t
pfkey_setsadbipsecif(caddr_t
, caddr_t
, char *,
87 static caddr_t
pfkey_setsadbxsa2 (caddr_t
, caddr_t
, u_int32_t
, u_int32_t
, u_int
);
89 #ifdef SADB_X_EXT_NAT_T_TYPE
90 static caddr_t
pfkey_set_natt_type (caddr_t
, caddr_t
, u_int
, u_int8_t
);
91 static caddr_t
pfkey_set_natt_port (caddr_t
, caddr_t
, u_int
, u_int16_t
);
93 #ifdef SADB_X_EXT_NAT_T_FRAG
94 static caddr_t
pfkey_set_natt_frag (caddr_t
, caddr_t
, u_int
, u_int16_t
);
98 * make and search supported algorithm structure.
100 static struct sadb_supported
*ipsec_supported
[] = { NULL
, NULL
, NULL
,
101 #ifdef SADB_X_SATYPE_TCPSIGNATURE
106 static int supported_map
[] = {
109 SADB_X_SATYPE_IPCOMP
,
110 #ifdef SADB_X_SATYPE_TCPSIGNATURE
111 SADB_X_SATYPE_TCPSIGNATURE
,
116 findsupportedmap(int satype
)
120 for (i
= 0; i
< sizeof(supported_map
)/sizeof(supported_map
[0]); i
++)
121 if (supported_map
[i
] == satype
)
126 static struct sadb_alg
*
127 findsupportedalg(u_int satype
, u_int alg_id
)
134 algno
= findsupportedmap((int)satype
);
136 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
139 if (ipsec_supported
[algno
] == NULL
) {
140 __ipsec_errcode
= EIPSEC_DO_GET_SUPP_LIST
;
144 tlen
= ipsec_supported
[algno
]->sadb_supported_len
145 - sizeof(struct sadb_supported
);
146 p
= (void *)(ipsec_supported
[algno
] + 1);
148 if (tlen
< sizeof(struct sadb_alg
)) {
152 if (((struct sadb_alg
*)(void *)p
)->sadb_alg_id
== alg_id
)
155 tlen
-= sizeof(struct sadb_alg
);
156 p
+= sizeof(struct sadb_alg
);
159 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
164 setsupportedmap(struct sadb_supported
*sup
)
166 struct sadb_supported
**ipsup
;
168 switch (sup
->sadb_supported_exttype
) {
169 case SADB_EXT_SUPPORTED_AUTH
:
170 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_AH
)];
172 case SADB_EXT_SUPPORTED_ENCRYPT
:
173 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_ESP
)];
176 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
183 *ipsup
= malloc((size_t)sup
->sadb_supported_len
);
185 __ipsec_set_strerror(strerror(errno
));
188 memcpy(*ipsup
, sup
, (size_t)sup
->sadb_supported_len
);
194 * check key length against algorithm specified.
195 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
196 * augument, and only calls to ipsec_check_keylen2();
197 * keylen is the unit of bit.
203 ipsec_check_keylen(u_int supported
, u_int alg_id
, u_int keylen
)
209 case SADB_EXT_SUPPORTED_AUTH
:
210 satype
= SADB_SATYPE_AH
;
212 case SADB_EXT_SUPPORTED_ENCRYPT
:
213 satype
= SADB_SATYPE_ESP
;
216 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
220 return ipsec_check_keylen2(satype
, alg_id
, keylen
);
224 * check key length against algorithm specified.
225 * satype is one of satype defined at pfkeyv2.h.
226 * keylen is the unit of bit.
232 ipsec_check_keylen2(u_int satype
, u_int alg_id
, u_int keylen
)
234 struct sadb_alg
*alg
;
236 alg
= findsupportedalg(satype
, alg_id
);
240 if (keylen
< alg
->sadb_alg_minbits
|| keylen
> alg
->sadb_alg_maxbits
) {
241 fprintf(stderr
, "%d %d %d\n", keylen
, alg
->sadb_alg_minbits
,
242 alg
->sadb_alg_maxbits
);
243 __ipsec_errcode
= EIPSEC_INVAL_KEYLEN
;
247 __ipsec_errcode
= EIPSEC_NO_ERROR
;
252 * get max/min key length against algorithm specified.
253 * satype is one of satype defined at pfkeyv2.h.
254 * keylen is the unit of bit.
260 ipsec_get_keylen(u_int supported
, u_int alg_id
, struct sadb_alg
*alg0
)
262 struct sadb_alg
*alg
;
267 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
272 case SADB_EXT_SUPPORTED_AUTH
:
273 satype
= SADB_SATYPE_AH
;
275 case SADB_EXT_SUPPORTED_ENCRYPT
:
276 satype
= SADB_SATYPE_ESP
;
279 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
283 alg
= findsupportedalg(satype
, alg_id
);
287 memcpy(alg0
, alg
, sizeof(*alg0
));
289 __ipsec_errcode
= EIPSEC_NO_ERROR
;
294 * set the rate for SOFT lifetime against HARD one.
295 * If rate is more than 100 or equal to zero, then set to 100.
297 static u_int soft_lifetime_allocations_rate
= PFKEY_SOFT_LIFETIME_RATE
;
298 static u_int soft_lifetime_bytes_rate
= PFKEY_SOFT_LIFETIME_RATE
;
299 static u_int soft_lifetime_addtime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
300 static u_int soft_lifetime_usetime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
303 pfkey_set_softrate(u_int type
, u_int rate
)
305 __ipsec_errcode
= EIPSEC_NO_ERROR
;
307 if (rate
> 100 || rate
== 0)
311 case SADB_X_LIFETIME_ALLOCATIONS
:
312 soft_lifetime_allocations_rate
= rate
;
314 case SADB_X_LIFETIME_BYTES
:
315 soft_lifetime_bytes_rate
= rate
;
317 case SADB_X_LIFETIME_ADDTIME
:
318 soft_lifetime_addtime_rate
= rate
;
320 case SADB_X_LIFETIME_USETIME
:
321 soft_lifetime_usetime_rate
= rate
;
325 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
330 * get current rate for SOFT lifetime against HARD one.
331 * ATTENTION: ~0 is returned if invalid type was passed.
334 pfkey_get_softrate(u_int type
)
337 case SADB_X_LIFETIME_ALLOCATIONS
:
338 return soft_lifetime_allocations_rate
;
339 case SADB_X_LIFETIME_BYTES
:
340 return soft_lifetime_bytes_rate
;
341 case SADB_X_LIFETIME_ADDTIME
:
342 return soft_lifetime_addtime_rate
;
343 case SADB_X_LIFETIME_USETIME
:
344 return soft_lifetime_usetime_rate
;
351 * sending SADB_GETSPI message to the kernel.
353 * positive: success and return length sent.
354 * -1 : error occured, and set errno.
357 pfkey_send_getspi(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
358 u_int32_t min
, u_int32_t max
, u_int32_t reqid
, u_int use_addtime
, u_int64_t l_addtime
, u_int32_t seq
, u_int always_expire
)
360 struct sadb_msg
*newmsg
;
363 int need_spirange
= 0;
368 if (src
== NULL
|| dst
== NULL
) {
369 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
372 if (src
->ss_family
!= dst
->ss_family
) {
373 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
376 if (min
> max
|| (min
> 0 && min
<= 255)) {
377 __ipsec_errcode
= EIPSEC_INVAL_SPI
;
380 switch (src
->ss_family
) {
382 plen
= sizeof(struct in_addr
) << 3;
385 plen
= sizeof(struct in6_addr
) << 3;
388 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
392 /* create new sadb_msg to send. */
393 len
= sizeof(struct sadb_msg
)
394 + sizeof(struct sadb_x_sa2
)
395 + sizeof(struct sadb_address
)
396 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
397 + sizeof(struct sadb_address
)
398 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
))
399 + ((use_addtime
) ? sizeof(struct sadb_lifetime
) : 0);
401 if (min
> 255 && max
< (u_int
)~0) {
403 len
+= sizeof(struct sadb_spirange
);
406 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
407 __ipsec_set_strerror(strerror(errno
));
410 ep
= ((caddr_t
)(void *)newmsg
) + len
;
412 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSPI
,
413 (u_int
)len
, satype
, seq
, getpid());
419 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
, always_expire
);
425 /* set sadb_address for source */
426 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
433 /* set sadb_address for destination */
434 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
442 /* set sadb_lifetime, only hard lifetime applicable for larval SAs */
443 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
451 /* proccessing spi range */
453 struct sadb_spirange spirange
;
455 if (p
+ sizeof(spirange
) > ep
) {
460 memset(&spirange
, 0, sizeof(spirange
));
461 spirange
.sadb_spirange_len
= PFKEY_UNIT64(sizeof(spirange
));
462 spirange
.sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
463 spirange
.sadb_spirange_min
= min
;
464 spirange
.sadb_spirange_max
= max
;
466 memcpy(p
, &spirange
, sizeof(spirange
));
468 p
+= sizeof(spirange
);
476 len
= pfkey_send(so
, newmsg
, len
);
482 __ipsec_errcode
= EIPSEC_NO_ERROR
;
488 * sending SADB_UPDATE message to the kernel.
489 * The length of key material is a_keylen + e_keylen.
491 * positive: success and return length sent.
492 * -1 : error occured, and set errno.
495 pfkey_send_update(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
496 u_int32_t spi
, u_int32_t reqid
, u_int wsize
, caddr_t keymat
, u_int e_type
, u_int e_keylen
,
497 u_int a_type
, u_int a_keylen
, u_int flags
, u_int32_t l_alloc
, u_int64_t l_bytes
,
498 u_int64_t l_addtime
, u_int64_t l_usetime
, u_int32_t seq
, u_int16_t port
, u_int always_expire
)
501 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
503 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
504 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
505 (u_int
)l_usetime
, seq
, port
, always_expire
)) < 0)
513 * sending SADB_ADD message to the kernel.
514 * The length of key material is a_keylen + e_keylen.
516 * positive: success and return length sent.
517 * -1 : error occured, and set errno.
520 pfkey_send_add(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
,
521 u_int32_t spi
, u_int32_t reqid
, u_int wsize
, caddr_t keymat
, u_int e_type
, u_int e_keylen
,
522 u_int a_type
, u_int a_keylen
, u_int flags
, u_int32_t l_alloc
, u_int64_t l_bytes
,
523 u_int64_t l_addtime
, u_int64_t l_usetime
, u_int32_t seq
, u_int16_t port
, u_int always_expire
)
526 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
528 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
529 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
530 (u_int
)l_usetime
, seq
, port
, always_expire
)) < 0)
538 * sending SADB_DELETE message to the kernel.
540 * positive: success and return length sent.
541 * -1 : error occured, and set errno.
544 pfkey_send_delete(so
, satype
, mode
, src
, dst
, spi
)
547 struct sockaddr_storage
*src
, *dst
;
551 if ((len
= pfkey_send_x2(so
, SADB_DELETE
, satype
, mode
, src
, dst
, spi
)) < 0)
558 * sending SADB_DELETE without spi to the kernel. This is
559 * the "delete all" request (an extension also present in
563 * positive: success and return length sent
564 * -1 : error occured, and set errno
568 pfkey_send_delete_all(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
)
570 struct sadb_msg
*newmsg
;
577 if (src
== NULL
|| dst
== NULL
) {
578 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
581 if (src
->ss_family
!= dst
->ss_family
) {
582 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
585 switch (src
->ss_family
) {
587 plen
= sizeof(struct in_addr
) << 3;
590 plen
= sizeof(struct in6_addr
) << 3;
593 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
597 /* create new sadb_msg to reply. */
598 len
= sizeof(struct sadb_msg
)
599 + sizeof(struct sadb_address
)
600 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
601 + sizeof(struct sadb_address
)
602 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
));
604 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
605 __ipsec_set_strerror(strerror(errno
));
608 ep
= ((caddr_t
)(void *)newmsg
) + len
;
610 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_DELETE
, (u_int
)len
,
611 satype
, 0, getpid());
616 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
622 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
630 len
= pfkey_send(so
, newmsg
, len
);
636 __ipsec_errcode
= EIPSEC_NO_ERROR
;
641 * sending SADB_GET message to the kernel.
643 * positive: success and return length sent.
644 * -1 : error occured, and set errno.
647 pfkey_send_get(int so
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
, struct sockaddr_storage
*dst
, u_int32_t spi
)
650 if ((len
= pfkey_send_x2(so
, SADB_GET
, satype
, mode
, src
, dst
, spi
)) < 0)
657 * sending SADB_REGISTER message to the kernel.
659 * positive: success and return length sent.
660 * -1 : error occured, and set errno.
663 pfkey_send_register(int so
, u_int satype
)
667 if (satype
== PF_UNSPEC
) {
669 algno
< sizeof(supported_map
)/sizeof(supported_map
[0]);
671 if (ipsec_supported
[algno
]) {
672 free(ipsec_supported
[algno
]);
673 ipsec_supported
[algno
] = NULL
;
677 algno
= findsupportedmap((int)satype
);
679 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
683 if (ipsec_supported
[algno
]) {
684 free(ipsec_supported
[algno
]);
685 ipsec_supported
[algno
] = NULL
;
689 if ((len
= pfkey_send_x3(so
, SADB_REGISTER
, satype
)) < 0)
696 * receiving SADB_REGISTER message from the kernel, and copy buffer for
697 * sadb_supported returned into ipsec_supported.
699 * 0: success and return length sent.
700 * -1: error occured, and set errno.
703 pfkey_recv_register(int so
)
705 pid_t pid
= getpid();
706 struct sadb_msg
*newmsg
;
709 /* receive message */
711 if ((newmsg
= pfkey_recv(so
)) == NULL
)
713 if (newmsg
->sadb_msg_type
== SADB_REGISTER
&&
714 newmsg
->sadb_msg_pid
== pid
)
720 newmsg
->sadb_msg_len
= PFKEY_UNUNIT64(newmsg
->sadb_msg_len
);
722 error
= pfkey_set_supported(newmsg
, newmsg
->sadb_msg_len
);
726 __ipsec_errcode
= EIPSEC_NO_ERROR
;
732 * receiving SADB_REGISTER message from the kernel, and copy buffer for
733 * sadb_supported returned into ipsec_supported.
734 * NOTE: sadb_msg_len must be host order.
736 * tlen: msg length, it's to makeing sure.
738 * 0: success and return length sent.
739 * -1: error occured, and set errno.
742 pfkey_set_supported(struct sadb_msg
*msg
, int tlen
)
744 struct sadb_supported
*sup
;
749 if (msg
->sadb_msg_len
!= tlen
) {
750 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
757 p
+= sizeof(struct sadb_msg
);
761 if (ep
< p
+ sizeof(*sup
) ||
762 PFKEY_EXTLEN(sup
) < sizeof(*sup
) ||
763 ep
< p
+ sup
->sadb_supported_len
) {
768 switch (sup
->sadb_supported_exttype
) {
769 case SADB_EXT_SUPPORTED_AUTH
:
770 case SADB_EXT_SUPPORTED_ENCRYPT
:
773 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
778 sup
->sadb_supported_len
= PFKEY_EXTLEN(sup
);
780 /* set supported map */
781 if (setsupportedmap(sup
) != 0)
784 p
+= sup
->sadb_supported_len
;
788 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
792 __ipsec_errcode
= EIPSEC_NO_ERROR
;
798 * sending SADB_FLUSH message to the kernel.
800 * positive: success and return length sent.
801 * -1 : error occured, and set errno.
804 pfkey_send_flush(int so
, u_int satype
)
808 if ((len
= pfkey_send_x3(so
, SADB_FLUSH
, satype
)) < 0)
815 * sending SADB_DUMP message to the kernel.
817 * positive: success and return length sent.
818 * -1 : error occured, and set errno.
821 pfkey_send_dump(int so
, u_int satype
)
825 if ((len
= pfkey_send_x3(so
, SADB_DUMP
, satype
)) < 0)
832 * sending SADB_X_PROMISC message to the kernel.
833 * NOTE that this function handles promisc mode toggle only.
835 * flag: set promisc off if zero, set promisc on if non-zero.
837 * positive: success and return length sent.
838 * -1 : error occured, and set errno.
839 * 0 : error occured, and set errno.
840 * others: a pointer to new allocated buffer in which supported
844 pfkey_send_promisc_toggle(int so
, int flag
)
848 if ((len
= pfkey_send_x3(so
, SADB_X_PROMISC
,
849 (u_int
)(flag
? 1 : 0))) < 0)
856 * sending SADB_X_SPDADD message to the kernel.
858 * positive: success and return length sent.
859 * -1 : error occured, and set errno.
862 pfkey_send_spdadd(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
863 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
867 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
868 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
869 (u_int64_t
)0, (u_int64_t
)0,
870 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
877 * sending SADB_X_SPDADD message to the kernel.
879 * positive: success and return length sent.
880 * -1 : error occured, and set errno.
883 pfkey_send_spdadd_with_interface(int so
, struct sockaddr_storage
*src
, struct sockaddr_storage
*src_end
, u_int prefs
, struct sockaddr_storage
*dst
,
884 struct sockaddr_storage
*dst_end
, u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
, char *ipsec_if
,
885 char *internal_if
, char *outgoing_if
, u_int disabled
)
889 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
890 src
, src_end
, prefs
, dst
, dst_end
, prefd
, proto
,
891 (u_int64_t
)0, (u_int64_t
)0,
892 policy
, policylen
, seq
, ipsec_if
, internal_if
, outgoing_if
, disabled
)) < 0)
899 * sending SADB_X_SPDADD message to the kernel.
901 * positive: success and return length sent.
902 * -1 : error occured, and set errno.
905 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
,
906 caddr_t policy
, int policylen
, u_int32_t seq
)
910 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
911 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
913 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
920 * sending SADB_X_SPDUPDATE message to the kernel.
922 * positive: success and return length sent.
923 * -1 : error occured, and set errno.
926 pfkey_send_spdupdate(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
927 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
931 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
932 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
933 (u_int64_t
)0, (u_int64_t
)0,
934 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
941 * sending SADB_X_SPDUPDATE message to the kernel.
943 * positive: success and return length sent.
944 * -1 : error occured, and set errno.
947 pfkey_send_spdupdate2(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
948 u_int prefd
, u_int proto
, u_int64_t ltime
, u_int64_t vtime
,
949 caddr_t policy
, int policylen
, u_int32_t seq
)
953 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
954 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
956 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
963 * sending SADB_X_SPDDELETE message to the kernel.
965 * positive: success and return length sent.
966 * -1 : error occured, and set errno.
969 pfkey_send_spddelete(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
970 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
974 if (policylen
!= sizeof(struct sadb_x_policy
)) {
975 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
979 if ((len
= pfkey_send_x4(so
, SADB_X_SPDDELETE
,
980 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
981 (u_int64_t
)0, (u_int64_t
)0,
982 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
989 * sending SADB_X_SPDDELETE message to the kernel.
991 * positive: success and return length sent.
992 * -1 : error occured, and set errno.
995 pfkey_send_spddelete2(int so
, u_int32_t spid
)
999 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDELETE2
, spid
)) < 0)
1006 pfkey_send_spdenable(int so
, u_int32_t spid
)
1010 if ((len
= pfkey_send_x5(so
, SADB_X_SPDENABLE
, spid
)) < 0)
1017 pfkey_send_spddisable(int so
, u_int32_t spid
)
1021 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDISABLE
, spid
)) < 0)
1028 * sending SADB_X_SPDGET message to the kernel.
1030 * positive: success and return length sent.
1031 * -1 : error occured, and set errno.
1034 pfkey_send_spdget(int so
, u_int32_t spid
)
1038 if ((len
= pfkey_send_x5(so
, SADB_X_SPDGET
, spid
)) < 0)
1045 * sending SADB_X_SPDSETIDX message to the kernel.
1047 * positive: success and return length sent.
1048 * -1 : error occured, and set errno.
1051 pfkey_send_spdsetidx(int so
, struct sockaddr_storage
*src
, u_int prefs
, struct sockaddr_storage
*dst
,
1052 u_int prefd
, u_int proto
, caddr_t policy
, int policylen
, u_int32_t seq
)
1056 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1057 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1061 if ((len
= pfkey_send_x4(so
, SADB_X_SPDSETIDX
,
1062 src
, NULL
, prefs
, dst
, NULL
, prefd
, proto
,
1063 (u_int64_t
)0, (u_int64_t
)0,
1064 policy
, policylen
, seq
, NULL
, NULL
, NULL
, 0)) < 0)
1071 * sending SADB_SPDFLUSH message to the kernel.
1073 * positive: success and return length sent.
1074 * -1 : error occured, and set errno.
1077 pfkey_send_spdflush(int so
)
1081 if ((len
= pfkey_send_x3(so
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
)) < 0)
1088 * sending SADB_SPDDUMP message to the kernel.
1090 * positive: success and return length sent.
1091 * -1 : error occured, and set errno.
1094 pfkey_send_spddump(int so
)
1098 if ((len
= pfkey_send_x3(so
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
)) < 0)
1105 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1107 pfkey_send_x1(int so
, u_int type
, u_int satype
, u_int mode
, struct sockaddr_storage
*src
,
1108 struct sockaddr_storage
*dst
, u_int32_t spi
, u_int32_t reqid
, u_int wsize
,
1109 caddr_t keymat
, u_int e_type
, u_int e_keylen
, u_int a_type
, u_int a_keylen
, u_int flags
,
1110 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
,
1111 u_int always_expire
)
1113 struct sadb_msg
*newmsg
;
1119 /* validity check */
1120 if (src
== NULL
|| dst
== NULL
) {
1121 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1124 if (src
->ss_family
!= dst
->ss_family
) {
1125 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1128 switch (src
->ss_family
) {
1130 plen
= sizeof(struct in_addr
) << 3;
1133 plen
= sizeof(struct in6_addr
) << 3;
1136 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1141 case SADB_SATYPE_ESP
:
1142 if (e_type
== SADB_EALG_NONE
) {
1143 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1147 case SADB_SATYPE_AH
:
1148 if (e_type
!= SADB_EALG_NONE
) {
1149 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1152 if (a_type
== SADB_AALG_NONE
) {
1153 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1157 case SADB_X_SATYPE_IPCOMP
:
1158 if (e_type
== SADB_X_CALG_NONE
) {
1159 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1162 if (a_type
!= SADB_AALG_NONE
) {
1163 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1167 #ifdef SADB_X_AALG_TCP_MD5
1168 case SADB_X_SATYPE_TCPSIGNATURE
:
1169 if (e_type
!= SADB_EALG_NONE
) {
1170 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1173 if (a_type
!= SADB_X_AALG_TCP_MD5
) {
1174 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1180 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1184 /* create new sadb_msg to reply. */
1185 len
= sizeof(struct sadb_msg
)
1186 + sizeof(struct sadb_sa_2
)
1187 + sizeof(struct sadb_x_sa2
)
1188 + sizeof(struct sadb_address
)
1189 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1190 + sizeof(struct sadb_address
)
1191 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
))
1192 + sizeof(struct sadb_lifetime
)
1193 + sizeof(struct sadb_lifetime
);
1195 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
)
1196 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1197 if (a_type
!= SADB_AALG_NONE
)
1198 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1200 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1201 __ipsec_set_strerror(strerror(errno
));
1204 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1206 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1207 satype
, seq
, getpid());
1212 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
, port
);
1217 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
, always_expire
);
1222 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1228 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1235 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
) {
1236 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1243 if (a_type
!= SADB_AALG_NONE
) {
1244 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1245 keymat
+ e_keylen
, a_keylen
);
1252 /* set sadb_lifetime for destination */
1253 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1254 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1259 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1260 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1272 len
= pfkey_send(so
, newmsg
, len
);
1278 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1283 /* sending SADB_DELETE or SADB_GET message to the kernel */
1286 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
)
1288 struct sadb_msg
*newmsg
;
1294 /* validity check */
1295 if (src
== NULL
|| dst
== NULL
) {
1296 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1299 if (src
->ss_family
!= dst
->ss_family
) {
1300 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1303 switch (src
->ss_family
) {
1305 plen
= sizeof(struct in_addr
) << 3;
1308 plen
= sizeof(struct in6_addr
) << 3;
1311 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1315 /* create new sadb_msg to reply. */
1316 len
= sizeof(struct sadb_msg
)
1317 + sizeof(struct sadb_sa_2
)
1318 + sizeof(struct sadb_address
)
1319 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1320 + sizeof(struct sadb_address
)
1321 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst
));
1323 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1324 __ipsec_set_strerror(strerror(errno
));
1327 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1329 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1335 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0, 0);
1340 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1346 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1348 if (!p
|| p
!= ep
) {
1354 len
= pfkey_send(so
, newmsg
, len
);
1360 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1365 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1369 pfkey_send_x3(int so
, u_int type
, u_int satype
)
1371 struct sadb_msg
*newmsg
;
1376 /* validity check */
1378 case SADB_X_PROMISC
:
1379 if (satype
!= 0 && satype
!= 1) {
1380 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1386 case SADB_SATYPE_UNSPEC
:
1387 case SADB_SATYPE_AH
:
1388 case SADB_SATYPE_ESP
:
1389 case SADB_X_SATYPE_IPCOMP
:
1390 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1391 case SADB_X_SATYPE_TCPSIGNATURE
:
1395 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1400 /* create new sadb_msg to send. */
1401 len
= sizeof(struct sadb_msg
);
1403 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1404 __ipsec_set_strerror(strerror(errno
));
1407 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1409 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1411 if (!p
|| p
!= ep
) {
1417 len
= pfkey_send(so
, newmsg
, len
);
1423 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1427 /* sending SADB_X_SPDADD message to the kernel */
1429 pfkey_send_x4(int so
, u_int type
, struct sockaddr_storage
*src
, struct sockaddr_storage
*src_end
, u_int prefs
, struct sockaddr_storage
*dst
, struct sockaddr_storage
*dst_end
,
1430 u_int prefd
, u_int proto
, u_int64_t ltime
, u_int64_t vtime
, char *policy
, int policylen
, u_int32_t seq
, char *ipsec_if
, char *internal_if
, char *outgoing_if
,
1433 struct sadb_msg
*newmsg
;
1438 int include_ipsec_if_msg
= 0;
1440 /* validity check */
1441 if (src
== NULL
|| dst
== NULL
) {
1442 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1445 if (src
->ss_family
!= dst
->ss_family
) {
1446 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1450 switch (src
->ss_family
) {
1452 plen
= sizeof(struct in_addr
) << 3;
1455 plen
= sizeof(struct in6_addr
) << 3;
1458 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1461 if (prefs
> plen
|| prefd
> plen
) {
1462 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1466 if (ipsec_if
|| internal_if
|| outgoing_if
|| disabled
) {
1467 include_ipsec_if_msg
= 1;
1470 /* create new sadb_msg to reply. */
1471 len
= sizeof(struct sadb_msg
)
1472 + sizeof(struct sadb_address
)
1473 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1474 + ((src_end
) ? sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src_end
)) : 0)
1475 + sizeof(struct sadb_address
)
1476 + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)src
))
1477 + ((dst_end
) ? sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)dst_end
)) : 0)
1478 + ((include_ipsec_if_msg
) ? sizeof(struct sadb_x_ipsecif
) : 0)
1479 + sizeof(struct sadb_lifetime
)
1482 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1483 __ipsec_set_strerror(strerror(errno
));
1486 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1488 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1489 SADB_SATYPE_UNSPEC
, seq
, getpid());
1495 p
= pfkey_setsadbaddr(p
, ep
, SADB_X_EXT_ADDR_RANGE_SRC_START
, src
, prefs
, proto
);
1500 p
= pfkey_setsadbaddr(p
, ep
, SADB_X_EXT_ADDR_RANGE_SRC_END
, src_end
, prefs
, proto
);
1506 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1513 p
= pfkey_setsadbaddr(p
, ep
, SADB_X_EXT_ADDR_RANGE_DST_START
, dst
, prefd
, proto
);
1518 p
= pfkey_setsadbaddr(p
, ep
, SADB_X_EXT_ADDR_RANGE_DST_END
, dst_end
, prefd
, proto
);
1524 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1530 if (include_ipsec_if_msg
) {
1531 p
= pfkey_setsadbipsecif(p
, ep
, internal_if
, outgoing_if
, ipsec_if
, disabled
);
1537 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1538 0, 0, (u_int
)ltime
, (u_int
)vtime
);
1539 if (!p
|| p
+ policylen
!= ep
) {
1543 memcpy(p
, policy
, (size_t)policylen
);
1546 len
= pfkey_send(so
, newmsg
, len
);
1552 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1556 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1558 pfkey_send_x5(int so
, u_int type
, u_int32_t spid
)
1560 struct sadb_msg
*newmsg
;
1561 struct sadb_x_policy xpl
;
1566 /* create new sadb_msg to reply. */
1567 len
= sizeof(struct sadb_msg
)
1570 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1571 __ipsec_set_strerror(strerror(errno
));
1574 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1576 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1577 SADB_SATYPE_UNSPEC
, 0, getpid());
1583 if (p
+ sizeof(xpl
) != ep
) {
1587 memset(&xpl
, 0, sizeof(xpl
));
1588 xpl
.sadb_x_policy_len
= PFKEY_UNIT64(sizeof(xpl
));
1589 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
1590 xpl
.sadb_x_policy_id
= spid
;
1591 memcpy(p
, &xpl
, sizeof(xpl
));
1594 len
= pfkey_send(so
, newmsg
, len
);
1600 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1608 * others : success and return value of socket.
1614 int bufsiz
= 0; /* Max allowed by default */
1615 const unsigned long newbufk
= 1536;
1616 unsigned long oldmax
;
1617 size_t oldmaxsize
= sizeof(oldmax
);
1618 unsigned long newmax
= newbufk
* (1024 + 128);
1620 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
1621 __ipsec_set_strerror(strerror(errno
));
1626 * This is a temporary workaround for KAME PR 154.
1627 * Don't really care even if it fails.
1629 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax
, &oldmaxsize
, &newmax
, sizeof(newmax
)) != 0)
1630 bufsiz
= 233016; /* Max allowed by default */
1632 bufsiz
= newbufk
* 1024;
1634 setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
1635 setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
1637 if (bufsiz
== newbufk
* 1024)
1638 sysctlbyname("kern.ipc.maxsockbuf", NULL
, NULL
, &oldmax
, oldmaxsize
);
1640 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1651 pfkey_close_sock(int so
)
1655 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1660 * receive sadb_msg data, and return pointer to new buffer allocated.
1661 * Must free this buffer later.
1663 * NULL : error occured.
1664 * others : a pointer to sadb_msg structure.
1666 * XXX should be rewritten to pass length explicitly
1671 struct sadb_msg buf
, *newmsg
;
1675 while ((len
= recv(so
, (void *)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
1678 __ipsec_set_strerror(strerror(errno
));
1682 if (len
< sizeof(buf
)) {
1683 recv(so
, (void *)&buf
, sizeof(buf
), 0);
1684 __ipsec_errcode
= EIPSEC_MAX
;
1688 /* read real message */
1689 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
1690 if ((newmsg
= CALLOC((size_t)reallen
, struct sadb_msg
*)) == 0) {
1691 __ipsec_set_strerror(strerror(errno
));
1695 while ((len
= recv(so
, (void *)newmsg
, (socklen_t
)reallen
, 0)) < 0) {
1698 __ipsec_set_strerror(strerror(errno
));
1703 if (len
!= reallen
) {
1704 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1709 /* don't trust what the kernel says, validate! */
1710 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
1711 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1716 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1721 * send message to a socket.
1723 * others: success and return length sent.
1727 pfkey_send(int so
, struct sadb_msg
*msg
, int len
)
1729 if ((len
= send(so
, (void *)msg
, (socklen_t
)len
, 0)) < 0) {
1730 __ipsec_set_strerror(strerror(errno
));
1734 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1740 * NOTE: These functions are derived from netkey/key.c in KAME.
1743 * set the pointer to each header in this message buffer.
1744 * IN: msg: pointer to message buffer.
1745 * mhp: pointer to the buffer initialized like below:
1746 * caddr_t mhp[SADB_EXT_MAX + 1];
1750 * XXX should be rewritten to obtain length explicitly
1753 pfkey_align(struct sadb_msg
*msg
, caddr_t
*mhp
)
1755 struct sadb_ext
*ext
;
1758 caddr_t ep
; /* XXX should be passed from upper layer */
1760 /* validity check */
1761 if (msg
== NULL
|| mhp
== NULL
) {
1762 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1767 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
1770 mhp
[0] = (void *)msg
;
1774 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
1776 /* skip base header */
1777 p
+= sizeof(struct sadb_msg
);
1781 if (ep
< p
+ sizeof(*ext
) || PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
1782 ep
< p
+ PFKEY_EXTLEN(ext
)) {
1783 /* invalid format */
1787 /* duplicate check */
1788 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1789 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
1790 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1795 switch (ext
->sadb_ext_type
) {
1797 case SADB_EXT_LIFETIME_CURRENT
:
1798 case SADB_EXT_LIFETIME_HARD
:
1799 case SADB_EXT_LIFETIME_SOFT
:
1800 case SADB_EXT_ADDRESS_SRC
:
1801 case SADB_EXT_ADDRESS_DST
:
1802 case SADB_EXT_ADDRESS_PROXY
:
1803 case SADB_EXT_KEY_AUTH
:
1804 /* XXX should to be check weak keys. */
1805 case SADB_EXT_KEY_ENCRYPT
:
1806 /* XXX should to be check weak keys. */
1807 case SADB_EXT_IDENTITY_SRC
:
1808 case SADB_EXT_IDENTITY_DST
:
1809 case SADB_EXT_SENSITIVITY
:
1810 case SADB_EXT_PROPOSAL
:
1811 case SADB_EXT_SUPPORTED_AUTH
:
1812 case SADB_EXT_SUPPORTED_ENCRYPT
:
1813 case SADB_EXT_SPIRANGE
:
1814 case SADB_X_EXT_POLICY
:
1815 case SADB_X_EXT_SA2
:
1816 case SADB_EXT_SESSION_ID
:
1817 case SADB_EXT_SASTAT
:
1818 #ifdef SADB_X_EXT_NAT_T_TYPE
1819 case SADB_X_EXT_NAT_T_TYPE
:
1820 case SADB_X_EXT_NAT_T_SPORT
:
1821 case SADB_X_EXT_NAT_T_DPORT
:
1822 case SADB_X_EXT_NAT_T_OA
:
1824 #ifdef SADB_X_EXT_TAG
1825 case SADB_X_EXT_TAG
:
1827 #ifdef SADB_X_EXT_PACKET
1828 case SADB_X_EXT_PACKET
:
1830 case SADB_X_EXT_IPSECIF
:
1831 case SADB_X_EXT_ADDR_RANGE_SRC_START
:
1832 case SADB_X_EXT_ADDR_RANGE_SRC_END
:
1833 case SADB_X_EXT_ADDR_RANGE_DST_START
:
1834 case SADB_X_EXT_ADDR_RANGE_DST_END
:
1835 mhp
[ext
->sadb_ext_type
] = (void *)ext
;
1838 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1842 p
+= PFKEY_EXTLEN(ext
);
1846 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
1850 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1855 * check basic usage for sadb_msg,
1856 * NOTE: This routine is derived from netkey/key.c in KAME.
1857 * IN: msg: pointer to message buffer.
1858 * mhp: pointer to the buffer initialized like below:
1860 * caddr_t mhp[SADB_EXT_MAX + 1];
1866 pfkey_check(caddr_t
* mhp
)
1868 struct sadb_msg
*msg
;
1870 /* validity check */
1871 if (mhp
== NULL
|| mhp
[0] == NULL
) {
1872 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1876 msg
= (void *)mhp
[0];
1879 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
1880 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
1885 if (msg
->sadb_msg_type
> SADB_MAX
) {
1886 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
1891 switch (msg
->sadb_msg_satype
) {
1892 case SADB_SATYPE_UNSPEC
:
1893 switch (msg
->sadb_msg_type
) {
1901 #ifdef SADB_X_NAT_T_NEW_MAPPING
1902 case SADB_X_NAT_T_NEW_MAPPING
:
1904 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1908 case SADB_SATYPE_ESP
:
1909 case SADB_SATYPE_AH
:
1910 case SADB_X_SATYPE_IPCOMP
:
1911 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1912 case SADB_X_SATYPE_TCPSIGNATURE
:
1914 switch (msg
->sadb_msg_type
) {
1916 case SADB_X_SPDDELETE
:
1918 case SADB_X_SPDDUMP
:
1919 case SADB_X_SPDFLUSH
:
1920 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1923 #ifdef SADB_X_NAT_T_NEW_MAPPING
1924 if (msg
->sadb_msg_type
== SADB_X_NAT_T_NEW_MAPPING
&&
1925 msg
->sadb_msg_satype
!= SADB_SATYPE_ESP
) {
1926 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1931 case SADB_SATYPE_RSVP
:
1932 case SADB_SATYPE_OSPFV2
:
1933 case SADB_SATYPE_RIPV2
:
1934 case SADB_SATYPE_MIP
:
1935 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
1937 case 1: /* XXX: What does it do ? */
1938 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
1942 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1946 /* check field of upper layer protocol and address family */
1947 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
1948 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
1949 struct sadb_address
*src0
, *dst0
;
1951 src0
= (void *)(mhp
[SADB_EXT_ADDRESS_SRC
]);
1952 dst0
= (void *)(mhp
[SADB_EXT_ADDRESS_DST
]);
1954 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
1955 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
1959 if (PFKEY_ADDR_SADDR(src0
)->sa_family
1960 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
1961 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1965 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
1970 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1975 * prefixlen == 0 is valid because there must be the case
1976 * all addresses are matched.
1980 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1985 * set data into sadb_msg.
1986 * `buf' must has been allocated sufficiently.
1989 pfkey_setsadbmsg(caddr_t buf
, caddr_t lim
, u_int type
, u_int tlen
, u_int satype
, u_int32_t seq
, pid_t pid
)
1995 len
= sizeof(struct sadb_msg
);
1997 if (buf
+ len
> lim
)
2001 p
->sadb_msg_version
= PF_KEY_V2
;
2002 p
->sadb_msg_type
= type
;
2003 p
->sadb_msg_errno
= 0;
2004 p
->sadb_msg_satype
= satype
;
2005 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
2006 p
->sadb_msg_reserved
= 0;
2007 p
->sadb_msg_seq
= seq
;
2008 p
->sadb_msg_pid
= (u_int32_t
)pid
;
2014 * copy secasvar data into sadb_address.
2015 * `buf' must has been allocated sufficiently.
2018 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
)
2020 struct sadb_sa_2
*p
;
2024 len
= sizeof(struct sadb_sa_2
);
2026 if (buf
+ len
> lim
)
2030 p
->sa
.sadb_sa_len
= PFKEY_UNIT64(len
);
2031 p
->sa
.sadb_sa_exttype
= SADB_EXT_SA
;
2032 p
->sa
.sadb_sa_spi
= spi
;
2033 p
->sa
.sadb_sa_replay
= wsize
;
2034 p
->sa
.sadb_sa_state
= SADB_SASTATE_LARVAL
;
2035 p
->sa
.sadb_sa_auth
= auth
;
2036 p
->sa
.sadb_sa_encrypt
= enc
;
2037 p
->sa
.sadb_sa_flags
= flags
;
2038 p
->sadb_sa_natt_port
= port
;
2044 * set data into sadb_address.
2045 * `buf' must has been allocated sufficiently.
2046 * prefixlen is in bits.
2049 pfkey_setsadbaddr(caddr_t buf
, caddr_t lim
, u_int exttype
, struct sockaddr_storage
*saddr
, u_int prefixlen
, u_int ul_proto
)
2051 struct sadb_address
*p
;
2055 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr
*)saddr
));
2057 if (buf
+ len
> lim
)
2061 p
->sadb_address_len
= PFKEY_UNIT64(len
);
2062 p
->sadb_address_exttype
= exttype
& 0xffff;
2063 p
->sadb_address_proto
= ul_proto
& 0xff;
2064 p
->sadb_address_prefixlen
= prefixlen
;
2065 p
->sadb_address_reserved
= 0;
2067 memcpy(p
+ 1, saddr
, (size_t)sysdep_sa_len((struct sockaddr
*)saddr
));
2073 * set sadb_key structure after clearing buffer with zero.
2074 * OUT: the pointer of buf + len.
2077 pfkey_setsadbkey(caddr_t buf
, caddr_t lim
, u_int type
, caddr_t key
, u_int keylen
)
2083 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
2085 if (buf
+ len
> lim
)
2089 p
->sadb_key_len
= PFKEY_UNIT64(len
);
2090 p
->sadb_key_exttype
= type
;
2091 p
->sadb_key_bits
= keylen
<< 3;
2092 p
->sadb_key_reserved
= 0;
2094 memcpy(p
+ 1, key
, keylen
);
2100 * set sadb_lifetime structure after clearing buffer with zero.
2101 * OUT: the pointer of buf + len.
2104 pfkey_setsadblifetime(caddr_t buf
, caddr_t lim
, u_int type
, u_int32_t l_alloc
,
2105 u_int32_t l_bytes
, u_int32_t l_addtime
, u_int32_t l_usetime
)
2107 struct sadb_lifetime
*p
;
2111 len
= sizeof(struct sadb_lifetime
);
2113 if (buf
+ len
> lim
)
2117 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2118 p
->sadb_lifetime_exttype
= type
;
2121 case SADB_EXT_LIFETIME_SOFT
:
2122 p
->sadb_lifetime_allocations
2123 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2124 p
->sadb_lifetime_bytes
2125 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2126 p
->sadb_lifetime_addtime
2127 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2128 p
->sadb_lifetime_usetime
2129 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2131 case SADB_EXT_LIFETIME_HARD
:
2132 p
->sadb_lifetime_allocations
= l_alloc
;
2133 p
->sadb_lifetime_bytes
= l_bytes
;
2134 p
->sadb_lifetime_addtime
= l_addtime
;
2135 p
->sadb_lifetime_usetime
= l_usetime
;
2143 pfkey_setsadbipsecif(caddr_t buf
, caddr_t lim
, char *internal_if
, char *outgoing_if
, char *ipsec_if
, int init_disabled
)
2145 struct sadb_x_ipsecif
*p
;
2149 len
= sizeof(struct sadb_x_ipsecif
);
2151 if (buf
+ len
> lim
)
2155 p
->sadb_x_ipsecif_len
= PFKEY_UNIT64(len
);
2156 p
->sadb_x_ipsecif_exttype
= SADB_X_EXT_IPSECIF
;
2158 if (internal_if
!= NULL
)
2159 strncpy(p
->sadb_x_ipsecif_internal_if
, internal_if
, sizeof(p
->sadb_x_ipsecif_internal_if
));
2160 if (outgoing_if
!= NULL
)
2161 strncpy(p
->sadb_x_ipsecif_outgoing_if
, outgoing_if
, sizeof(p
->sadb_x_ipsecif_outgoing_if
));
2162 if (ipsec_if
!= NULL
)
2163 strncpy(p
->sadb_x_ipsecif_ipsec_if
, ipsec_if
, sizeof(p
->sadb_x_ipsecif_ipsec_if
));
2165 p
->sadb_x_ipsecif_init_disabled
= init_disabled
;
2171 * copy secasvar data into sadb_address.
2172 * `buf' must has been allocated sufficiently.
2175 pfkey_setsadbxsa2(caddr_t buf
, caddr_t lim
, u_int32_t mode0
, u_int32_t reqid
, u_int always_expire
)
2177 struct sadb_x_sa2
*p
;
2178 u_int8_t mode
= mode0
& 0xff;
2182 len
= sizeof(struct sadb_x_sa2
);
2184 if (buf
+ len
> lim
)
2188 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2189 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2190 p
->sadb_x_sa2_mode
= mode
;
2191 p
->sadb_x_sa2_reqid
= reqid
;
2192 p
->sadb_x_sa2_alwaysexpire
= always_expire
;
2193 #ifdef SADB_X_EXT_SA2_DELETE_ON_DETACH
2194 p
->sadb_x_sa2_flags
|= SADB_X_EXT_SA2_DELETE_ON_DETACH
;
2195 #endif /* SADB_X_EXT_SA2_DELETE_ON_DETACH */
2200 #ifdef SADB_X_EXT_NAT_T_TYPE
2202 pfkey_set_natt_type(caddr_t buf
, caddr_t lim
, u_int type
, u_int8_t l_natt_type
)
2204 struct sadb_x_nat_t_type
*p
;
2208 len
= sizeof(struct sadb_x_nat_t_type
);
2210 if (buf
+ len
> lim
)
2214 p
->sadb_x_nat_t_type_len
= PFKEY_UNIT64(len
);
2215 p
->sadb_x_nat_t_type_exttype
= type
;
2216 p
->sadb_x_nat_t_type_type
= l_natt_type
;
2222 pfkey_set_natt_port(caddr_t buf
, caddr_t lim
, u_int type
, u_int16_t l_natt_port
)
2224 struct sadb_x_nat_t_port
*p
;
2228 len
= sizeof(struct sadb_x_nat_t_port
);
2230 if (buf
+ len
> lim
)
2234 p
->sadb_x_nat_t_port_len
= PFKEY_UNIT64(len
);
2235 p
->sadb_x_nat_t_port_exttype
= type
;
2236 p
->sadb_x_nat_t_port_port
= htons(l_natt_port
);
2242 #ifdef SADB_X_EXT_NAT_T_FRAG
2244 pfkey_set_natt_frag(caddr_t buf
, caddr_t lim
, u_int type
, u_int16_t l_natt_frag
)
2246 struct sadb_x_nat_t_frag
*p
;
2250 len
= sizeof(struct sadb_x_nat_t_frag
);
2252 if (buf
+ len
> lim
)
2256 p
->sadb_x_nat_t_frag_len
= PFKEY_UNIT64(len
);
2257 p
->sadb_x_nat_t_frag_exttype
= type
;
2258 p
->sadb_x_nat_t_frag_fraglen
= l_natt_frag
;
2266 pfkey_setsadbsession_id (caddr_t buf
,
2268 u_int64_t session_ids
[],
2269 u_int32_t max_session_ids
)
2271 struct sadb_session_id
*p
;
2274 if (!max_session_ids
)
2280 if (buf
+ len
> lim
)
2284 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
2285 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
2286 p
->sadb_session_id_v
[0] = session_ids
[0];
2287 if (max_session_ids
> 1)
2288 p
->sadb_session_id_v
[1] = session_ids
[1];
2294 pfkey_setsadbsastats (caddr_t buf
,
2297 struct sastat
*stats
,
2298 u_int32_t max_stats
)
2300 struct sadb_sastat
*p
;
2301 u_int len
, list_len
;
2303 if (!stats
|| !max_stats
)
2306 p
= ALIGNED_CAST(__typeof__(p
))buf
; // Wcast-align fix - buffer passed to here is malloc'd message buffer
2307 list_len
= sizeof(*stats
) * max_stats
;
2308 len
= sizeof(*p
) + PFKEY_ALIGN8(list_len
);
2310 if (buf
+ len
> lim
)
2314 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
2315 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
2316 p
->sadb_sastat_dir
= dir
;
2317 p
->sadb_sastat_list_len
= max_stats
;
2318 bcopy(stats
, p
+ 1, list_len
);
2324 pfkey_send_getsastats (int so
,
2326 u_int64_t
*session_ids
,
2327 u_int32_t max_session_ids
,
2329 struct sastat
*stats
,
2330 u_int32_t max_stats
)
2332 struct sadb_msg
*newmsg
;
2334 int list_len
, out_len
, len
;
2337 if (!session_ids
|| !stats
|| !max_stats
) {
2341 list_len
= sizeof(*stats
) * max_stats
;
2342 /* create new sadb_msg to send. */
2343 out_len
= sizeof(struct sadb_msg
) + sizeof(struct sadb_session_id
) + sizeof(struct sadb_sastat
) + PFKEY_ALIGN8(list_len
);
2345 if ((newmsg
= CALLOC((size_t)out_len
, struct sadb_msg
*)) == NULL
) {
2346 __ipsec_set_strerror(strerror(errno
));
2349 ep
= ((caddr_t
)(void *)newmsg
) + out_len
;
2351 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSASTAT
, (u_int
)out_len
, SADB_SATYPE_UNSPEC
, seq
, getpid());
2357 p
= pfkey_setsadbsession_id(p
, ep
, session_ids
, max_session_ids
);
2363 p
= pfkey_setsadbsastats(p
, ep
, dir
, stats
, max_stats
);
2370 len
= pfkey_send(so
, newmsg
, out_len
);
2376 __ipsec_errcode
= EIPSEC_NO_ERROR
;