1 /* $Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 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
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
47 #include <netinet/udp.h>
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/socket.h>
53 #include <sys/queue.h>
54 #include <sys/sysctl.h>
56 #include <net/route.h>
57 #include <System/net/pfkeyv2.h>
59 #include <netinet/in.h>
60 #ifndef HAVE_NETINET6_IPSEC
61 #include <netinet/ipsec.h>
63 #include <netinet6/ipsec.h>
76 #include "localconf.h"
77 #include "remoteconf.h"
78 #include "isakmp_var.h"
80 #include "isakmp_inf.h"
81 #include "ipsec_doi.h"
86 #include "algorithm.h"
94 #include "nattraversal.h"
95 #include "crypto_openssl.h"
96 #include "grabmyaddr.h"
97 #include "vpn_control.h"
98 #include "vpn_control_var.h"
99 #include "ike_session.h"
100 #include "ipsecSessionTracer.h"
101 #include "ipsecMessageTracer.h"
102 #include "power_mgmt.h"
104 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
105 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
109 static u_int ipsecdoi2pfkey_aalg
__P((u_int
));
110 static u_int ipsecdoi2pfkey_ealg
__P((u_int
));
111 static u_int ipsecdoi2pfkey_calg
__P((u_int
));
112 static u_int ipsecdoi2pfkey_alg
__P((u_int
, u_int
));
113 static u_int keylen_aalg
__P((u_int
));
114 static u_int keylen_ealg
__P((u_int
, int));
116 static int pk_recvgetspi
__P((caddr_t
*));
117 static int pk_recvupdate
__P((caddr_t
*));
118 static int pk_recvadd
__P((caddr_t
*));
119 static int pk_recvdelete
__P((caddr_t
*));
120 static int pk_recvacquire
__P((caddr_t
*));
121 static int pk_recvexpire
__P((caddr_t
*));
122 static int pk_recvflush
__P((caddr_t
*));
123 static int getsadbpolicy
__P((caddr_t
*, int *, int, struct ph2handle
*));
124 static int pk_recvspdupdate
__P((caddr_t
*));
125 static int pk_recvspdadd
__P((caddr_t
*));
126 static int pk_recvspddelete
__P((caddr_t
*));
127 static int pk_recvspdexpire
__P((caddr_t
*));
128 static int pk_recvspdget
__P((caddr_t
*));
129 static int pk_recvspddump
__P((caddr_t
*));
130 static int pk_recvspdflush
__P((caddr_t
*));
131 static int pk_recvgetsastat
__P((caddr_t
*));
132 static struct sadb_msg
*pk_recv
__P((int, ssize_t
*));
134 static int (*pkrecvf
[]) __P((caddr_t
*)) = {
142 NULL
, /* SABD_REGISTER */
145 NULL
, /* SADB_DUMP */
146 NULL
, /* SADB_X_PROMISC */
147 NULL
, /* SADB_X_PCHANGE */
152 NULL
, /* SADB_X_SPDACQUIRE */
155 NULL
, /* SADB_X_SPDSETIDX */
157 NULL
, /* SADB_X_SPDDELETE2 */
158 pk_recvgetsastat
, /* SADB_GETSASTAT */
159 NULL
, /* SADB_X_NAT_T_NEW_MAPPING */
160 NULL
, /* SADB_X_MIGRATE */
162 #error "SADB extra message?"
166 static int addnewsp
__P((caddr_t
*));
168 /* cope with old kame headers - ugly */
169 #ifndef SADB_X_AALG_MD5
170 #define SADB_X_AALG_MD5 SADB_AALG_MD5
172 #ifndef SADB_X_AALG_SHA
173 #define SADB_X_AALG_SHA SADB_AALG_SHA
175 #ifndef SADB_X_AALG_NULL
176 #define SADB_X_AALG_NULL SADB_AALG_NULL
179 #ifndef SADB_X_EALG_BLOWFISHCBC
180 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
182 #ifndef SADB_X_EALG_CAST128CBC
183 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
185 #ifndef SADB_X_EALG_RC5CBC
186 #ifdef SADB_EALG_RC5CBC
187 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
193 struct sadb_msg
*msg
;
195 caddr_t mhp
[SADB_EXT_MAX
+ 1];
198 //plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
199 // s_pfkey_type(msg->sadb_msg_type));
200 //plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
203 if (msg
->sadb_msg_errno
) {
206 /* when SPD is empty, treat the state as no error. */
207 if (msg
->sadb_msg_type
== SADB_X_SPDDUMP
&&
208 msg
->sadb_msg_errno
== ENOENT
)
213 plog(pri
, LOCATION
, NULL
,
214 "pfkey %s failed: %s\n",
215 s_pfkey_type(msg
->sadb_msg_type
),
216 strerror(msg
->sadb_msg_errno
));
221 /* check pfkey message. */
222 if (pfkey_align(msg
, mhp
)) {
223 plog(LLV_ERROR
, LOCATION
, NULL
,
224 "libipsec failed pfkey align (%s)\n",
228 if (pfkey_check(mhp
)) {
229 plog(LLV_ERROR
, LOCATION
, NULL
,
230 "libipsec failed pfkey check (%s)\n",
234 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
237 if (msg
->sadb_msg_type
>= ARRAYLEN(pkrecvf
)) {
238 plog(LLV_ERROR
, LOCATION
, NULL
,
239 "unknown PF_KEY message type=%u\n",
244 if (pkrecvf
[msg
->sadb_msg_type
] == NULL
) {
245 plog(LLV_INFO
, LOCATION
, NULL
,
246 "unsupported PF_KEY message %s\n",
247 s_pfkey_type(msg
->sadb_msg_type
));
251 if ((pkrecvf
[msg
->sadb_msg_type
])(mhp
) < 0)
262 * PF_KEY packet handler
269 struct sadb_msg
*msg
;
272 if (slept_at
|| woke_at
) {
273 plog(LLV_DEBUG
, LOCATION
, NULL
,
274 "ignoring pfkey port until power-mgmt event is handled.\n");
278 /* receive pfkey message. */
280 msg
= (struct sadb_msg
*)pk_recv(lcconf
->sock_pfkey
, &len
);
283 plog(LLV_ERROR
, LOCATION
, NULL
,
284 "failed to recv from pfkey (%s)\n",
288 /* short message - msg not ready */
289 plog(LLV_ERROR
, LOCATION
, NULL
,
290 "recv short message from pfkey\n");
294 return pfkey_process(msg
);
300 struct saved_msg_elem
*elem
;
301 struct saved_msg_elem
*elem_tmp
= NULL
;
303 if (slept_at
|| woke_at
) {
304 plog(LLV_DEBUG
, LOCATION
, NULL
,
305 "ignoring (saved) pfkey messages until power-mgmt event is handled.\n");
309 TAILQ_FOREACH_SAFE(elem
, &lcconf
->saved_msg_queue
, chain
, elem_tmp
) {
310 pfkey_process((struct sadb_msg
*)elem
->msg
);
311 TAILQ_REMOVE(&lcconf
->saved_msg_queue
, elem
, chain
);
319 struct sadb_msg
*msg
;
321 struct saved_msg_elem
*elem
;
323 elem
= (struct saved_msg_elem
*)racoon_calloc(sizeof(struct saved_msg_elem
), 1);
327 TAILQ_INSERT_TAIL(&lcconf
->saved_msg_queue
, elem
, chain
);
335 pfkey_dump_sadb(satype
)
340 pid_t pid
= getpid();
341 struct sadb_msg
*msg
= NULL
;
345 if ((s
= privsep_pfkey_open()) < 0) {
346 plog(LLV_ERROR
, LOCATION
, NULL
,
347 "libipsec failed pfkey open: %s\n",
352 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_dump\n");
353 if (pfkey_send_dump(s
, satype
) < 0) {
354 plog(LLV_ERROR
, LOCATION
, NULL
,
355 "libipsec failed dump: %s\n", ipsec_strerror());
362 msg
= pk_recv(s
, &len
);
371 * for multi-processor system this had to be added because the messages can
372 * be interleaved - they won't all be dump messages
374 if (msg
->sadb_msg_type
!= SADB_DUMP
) { /* save for later processing */
380 // ignore dump messages that aren't racoon's
381 if (msg
->sadb_msg_pid
!= pid
)
384 ml
= msg
->sadb_msg_len
<< 3;
385 bl
= buf
? buf
->l
: 0;
386 buf
= vrealloc(buf
, bl
+ ml
);
388 plog(LLV_ERROR
, LOCATION
, NULL
,
389 "failed to reallocate buffer to dump.\n");
392 memcpy(buf
->v
+ bl
, msg
, ml
);
394 if (msg
->sadb_msg_seq
== 0)
407 privsep_pfkey_close(s
);
411 #ifdef ENABLE_ADMINPORT
416 pfkey_flush_sadb(proto
)
421 /* convert to SADB_SATYPE */
422 if ((satype
= admin2pfkey_proto(proto
)) < 0)
425 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_flush\n");
426 if (pfkey_send_flush(lcconf
->sock_pfkey
, satype
) < 0) {
427 plog(LLV_ERROR
, LOCATION
, NULL
,
428 "libipsec failed send flush (%s)\n", ipsec_strerror());
437 * These are the SATYPEs that we manage. We register to get
438 * PF_KEY messages related to these SATYPEs, and we also use
439 * this list to determine which SATYPEs to delete SAs for when
440 * we receive an INITIAL-CONTACT.
442 const struct pfkey_satype pfkey_satypes
[] = {
443 { SADB_SATYPE_AH
, "AH" },
444 { SADB_SATYPE_ESP
, "ESP" },
445 { SADB_X_SATYPE_IPCOMP
, "IPCOMP" },
447 const int pfkey_nsatypes
=
448 sizeof(pfkey_satypes
) / sizeof(pfkey_satypes
[0]);
451 * PF_KEY initialization
458 if ((lcconf
->sock_pfkey
= privsep_pfkey_open()) < 0) {
459 plog(LLV_ERROR
, LOCATION
, NULL
,
460 "libipsec failed pfkey open (%s)\n", ipsec_strerror());
464 for (i
= 0, reg_fail
= 0; i
< pfkey_nsatypes
; i
++) {
465 plog(LLV_DEBUG
, LOCATION
, NULL
,
466 "call pfkey_send_register for %s\n",
467 pfkey_satypes
[i
].ps_name
);
468 if (pfkey_send_register(lcconf
->sock_pfkey
,
469 pfkey_satypes
[i
].ps_satype
) < 0 ||
470 pfkey_recv_register(lcconf
->sock_pfkey
) < 0) {
471 plog(LLV_WARNING
, LOCATION
, NULL
,
472 "failed to register %s (%s)\n",
473 pfkey_satypes
[i
].ps_name
,
479 if (reg_fail
== pfkey_nsatypes
) {
480 plog(LLV_ERROR
, LOCATION
, NULL
,
481 "failed to regist any protocol.\n");
482 pfkey_close(lcconf
->sock_pfkey
);
488 if (pfkey_send_spddump(lcconf
->sock_pfkey
) < 0) {
489 plog(LLV_ERROR
, LOCATION
, NULL
,
490 "libipsec sending spddump failed: %s\n",
492 pfkey_close(lcconf
->sock_pfkey
);
496 if (pfkey_promisc_toggle(1) < 0) {
497 pfkey_close(lcconf
->sock_pfkey
);
504 /* %%% for conversion */
505 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
507 ipsecdoi2pfkey_aalg(hashtype
)
511 case IPSECDOI_ATTR_AUTH_HMAC_MD5
:
512 return SADB_AALG_MD5HMAC
;
513 case IPSECDOI_ATTR_AUTH_HMAC_SHA1
:
514 return SADB_AALG_SHA1HMAC
;
515 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256
:
516 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
517 return SADB_X_AALG_SHA2_256
;
519 return SADB_X_AALG_SHA2_256HMAC
;
521 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384
:
522 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
523 return SADB_X_AALG_SHA2_384
;
525 return SADB_X_AALG_SHA2_384HMAC
;
527 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512
:
528 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
529 return SADB_X_AALG_SHA2_512
;
531 return SADB_X_AALG_SHA2_512HMAC
;
533 case IPSECDOI_ATTR_AUTH_KPDK
: /* need special care */
534 return SADB_AALG_NONE
;
537 case IPSECDOI_ATTR_AUTH_DES_MAC
:
538 plog(LLV_ERROR
, LOCATION
, NULL
,
539 "Not supported hash type: %u\n", hashtype
);
542 case 0: /* reserved */
544 return SADB_AALG_NONE
;
546 plog(LLV_ERROR
, LOCATION
, NULL
,
547 "Invalid hash type: %u\n", hashtype
);
553 /* IPSECDOI_ESP -> SADB_EALG */
555 ipsecdoi2pfkey_ealg(t_id
)
559 case IPSECDOI_ESP_DES_IV64
: /* sa_flags |= SADB_X_EXT_OLD */
560 return SADB_EALG_DESCBC
;
561 case IPSECDOI_ESP_DES
:
562 return SADB_EALG_DESCBC
;
563 case IPSECDOI_ESP_3DES
:
564 return SADB_EALG_3DESCBC
;
565 #ifdef SADB_X_EALG_RC5CBC
566 case IPSECDOI_ESP_RC5
:
567 return SADB_X_EALG_RC5CBC
;
569 case IPSECDOI_ESP_CAST
:
570 return SADB_X_EALG_CAST128CBC
;
571 case IPSECDOI_ESP_BLOWFISH
:
572 return SADB_X_EALG_BLOWFISHCBC
;
573 case IPSECDOI_ESP_DES_IV32
: /* flags |= (SADB_X_EXT_OLD|
575 return SADB_EALG_DESCBC
;
576 case IPSECDOI_ESP_NULL
:
577 return SADB_EALG_NULL
;
578 #ifdef SADB_X_EALG_AESCBC
579 case IPSECDOI_ESP_AES
:
580 return SADB_X_EALG_AESCBC
;
582 #ifdef SADB_X_EALG_TWOFISHCBC
583 case IPSECDOI_ESP_TWOFISH
:
584 return SADB_X_EALG_TWOFISHCBC
;
588 case IPSECDOI_ESP_3IDEA
:
589 case IPSECDOI_ESP_IDEA
:
590 case IPSECDOI_ESP_RC4
:
591 plog(LLV_ERROR
, LOCATION
, NULL
,
592 "Not supported transform: %u\n", t_id
);
595 case 0: /* reserved */
597 plog(LLV_ERROR
, LOCATION
, NULL
,
598 "Invalid transform id: %u\n", t_id
);
604 /* IPCOMP -> SADB_CALG */
606 ipsecdoi2pfkey_calg(t_id
)
610 case IPSECDOI_IPCOMP_OUI
:
611 return SADB_X_CALG_OUI
;
612 case IPSECDOI_IPCOMP_DEFLATE
:
613 return SADB_X_CALG_DEFLATE
;
614 case IPSECDOI_IPCOMP_LZS
:
615 return SADB_X_CALG_LZS
;
617 case 0: /* reserved */
619 plog(LLV_ERROR
, LOCATION
, NULL
,
620 "Invalid transform id: %u\n", t_id
);
626 /* IPSECDOI_PROTO -> SADB_SATYPE */
628 ipsecdoi2pfkey_proto(proto
)
632 case IPSECDOI_PROTO_IPSEC_AH
:
633 return SADB_SATYPE_AH
;
634 case IPSECDOI_PROTO_IPSEC_ESP
:
635 return SADB_SATYPE_ESP
;
636 case IPSECDOI_PROTO_IPCOMP
:
637 return SADB_X_SATYPE_IPCOMP
;
640 plog(LLV_ERROR
, LOCATION
, NULL
,
641 "Invalid ipsec_doi proto: %u\n", proto
);
648 ipsecdoi2pfkey_alg(algclass
, type
)
649 u_int algclass
, type
;
652 case IPSECDOI_ATTR_AUTH
:
653 return ipsecdoi2pfkey_aalg(type
);
654 case IPSECDOI_PROTO_IPSEC_ESP
:
655 return ipsecdoi2pfkey_ealg(type
);
656 case IPSECDOI_PROTO_IPCOMP
:
657 return ipsecdoi2pfkey_calg(type
);
659 plog(LLV_ERROR
, LOCATION
, NULL
,
660 "Invalid ipsec_doi algclass: %u\n", algclass
);
666 /* SADB_SATYPE -> IPSECDOI_PROTO */
668 pfkey2ipsecdoi_proto(satype
)
673 return IPSECDOI_PROTO_IPSEC_AH
;
674 case SADB_SATYPE_ESP
:
675 return IPSECDOI_PROTO_IPSEC_ESP
;
676 case SADB_X_SATYPE_IPCOMP
:
677 return IPSECDOI_PROTO_IPCOMP
;
680 plog(LLV_ERROR
, LOCATION
, NULL
,
681 "Invalid pfkey proto: %u\n", satype
);
687 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
689 ipsecdoi2pfkey_mode(mode
)
693 case IPSECDOI_ATTR_ENC_MODE_TUNNEL
:
695 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC
:
696 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT
:
698 return IPSEC_MODE_TUNNEL
;
699 case IPSECDOI_ATTR_ENC_MODE_TRNS
:
701 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC
:
702 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT
:
704 return IPSEC_MODE_TRANSPORT
;
706 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid mode type: %u\n", mode
);
712 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
714 pfkey2ipsecdoi_mode(mode
)
718 case IPSEC_MODE_TUNNEL
:
719 return IPSECDOI_ATTR_ENC_MODE_TUNNEL
;
720 case IPSEC_MODE_TRANSPORT
:
721 return IPSECDOI_ATTR_ENC_MODE_TRNS
;
723 return IPSECDOI_ATTR_ENC_MODE_ANY
;
725 plog(LLV_ERROR
, LOCATION
, NULL
, "Invalid mode type: %u\n", mode
);
731 /* default key length for encryption algorithm */
733 keylen_aalg(hashtype
)
739 return SADB_AALG_NONE
;
741 res
= alg_ipsec_hmacdef_hashlen(hashtype
);
743 plog(LLV_ERROR
, LOCATION
, NULL
,
744 "invalid hmac algorithm %u.\n", hashtype
);
750 /* default key length for encryption algorithm */
752 keylen_ealg(enctype
, encklen
)
758 res
= alg_ipsec_encdef_keylen(enctype
, encklen
);
760 plog(LLV_ERROR
, LOCATION
, NULL
,
761 "invalid encryption algorithm %u.\n", enctype
);
768 pfkey_convertfromipsecdoi(proto_id
, t_id
, hashtype
,
769 e_type
, e_keylen
, a_type
, a_keylen
, flags
)
781 case IPSECDOI_PROTO_IPSEC_ESP
:
782 if ((*e_type
= ipsecdoi2pfkey_ealg(t_id
)) == ~0)
784 if ((*e_keylen
= keylen_ealg(t_id
, *e_keylen
)) == ~0)
788 if ((*a_type
= ipsecdoi2pfkey_aalg(hashtype
)) == ~0)
790 if ((*a_keylen
= keylen_aalg(hashtype
)) == ~0)
794 if (*e_type
== SADB_EALG_NONE
) {
795 plog(LLV_ERROR
, LOCATION
, NULL
, "no ESP algorithm.\n");
800 case IPSECDOI_PROTO_IPSEC_AH
:
801 if ((*a_type
= ipsecdoi2pfkey_aalg(hashtype
)) == ~0)
803 if ((*a_keylen
= keylen_aalg(hashtype
)) == ~0)
807 if (t_id
== IPSECDOI_ATTR_AUTH_HMAC_MD5
808 && hashtype
== IPSECDOI_ATTR_AUTH_KPDK
) {
809 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
810 *a_type
= SADB_X_AALG_MD5
;
811 *flags
|= SADB_X_EXT_OLD
;
813 *e_type
= SADB_EALG_NONE
;
815 if (*a_type
== SADB_AALG_NONE
) {
816 plog(LLV_ERROR
, LOCATION
, NULL
, "no AH algorithm.\n");
821 case IPSECDOI_PROTO_IPCOMP
:
822 if ((*e_type
= ipsecdoi2pfkey_calg(t_id
)) == ~0)
826 *flags
= SADB_X_EXT_RAWCPI
;
828 *a_type
= SADB_AALG_NONE
;
830 if (*e_type
== SADB_X_CALG_NONE
) {
831 plog(LLV_ERROR
, LOCATION
, NULL
, "no IPCOMP algorithm.\n");
837 plog(LLV_ERROR
, LOCATION
, NULL
, "unknown IPsec protocol.\n");
848 /* called from scheduler */
850 pfkey_timeover_stub(p
)
854 pfkey_timeover((struct ph2handle
*)p
);
859 struct ph2handle
*iph2
;
861 plog(LLV_ERROR
, LOCATION
, NULL
,
862 "%s give up to get IPsec-SA due to time up to wait.\n",
863 saddrwop2str((struct sockaddr
*)iph2
->dst
));
864 SCHED_KILL(iph2
->sce
);
866 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
867 if (iph2
->side
== INITIATOR
)
868 pk_sendeacquire(iph2
);
878 /* send getspi message per ipsec protocol per remote address */
880 * the local address and remote address in ph1handle are dealed
881 * with destination address and source address respectively.
882 * Because SPI is decided by responder.
886 struct ph2handle
*iph2
;
888 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
892 u_int32_t minspi
, maxspi
;
895 if (iph2
->side
== INITIATOR
) {
897 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
900 if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
904 /* for mobile IPv6 */
905 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
906 ipsecdoi_transportmode(pp
)) {
914 for (pr
= pp
->head
; pr
!= NULL
; pr
= pr
->next
) {
917 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
919 plog(LLV_ERROR
, LOCATION
, NULL
,
920 "invalid proto_id %d\n", pr
->proto_id
);
923 /* this works around a bug in Linux kernel where it allocates 4 byte
925 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
933 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
935 plog(LLV_ERROR
, LOCATION
, NULL
,
936 "invalid encmode %d\n", pr
->encmode
);
940 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_getspi\n");
941 if (pfkey_send_getspi(
948 pr
->reqid_in
, iph2
->seq
) < 0) {
949 plog(LLV_ERROR
, LOCATION
, NULL
,
950 "ipseclib failed send getspi (%s)\n",
954 plog(LLV_DEBUG
, LOCATION
, NULL
,
955 "pfkey GETSPI sent: %s\n",
956 sadbsecas2str(dst
, src
, satype
, 0, mode
));
963 * receive GETSPI from kernel.
969 struct sadb_msg
*msg
;
971 struct ph2handle
*iph2
;
972 struct sockaddr_storage
*dst
;
974 int allspiok
, notfound
;
979 if (mhp
[SADB_EXT_SA
] == NULL
980 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
981 plog(LLV_ERROR
, LOCATION
, NULL
,
982 "inappropriate sadb getspi message passed.\n");
985 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
986 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
987 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]); /* note SA dir */
989 /* the message has to be processed or not ? */
990 if (msg
->sadb_msg_pid
!= getpid()) {
991 plog(LLV_DEBUG
, LOCATION
, NULL
,
992 "%s message is not interesting "
993 "because pid %d is not mine.\n",
994 s_pfkey_type(msg
->sadb_msg_type
),
999 iph2
= getph2byseq(msg
->sadb_msg_seq
);
1001 plog(LLV_DEBUG
, LOCATION
, NULL
,
1002 "seq %d of %s message not interesting.\n",
1004 s_pfkey_type(msg
->sadb_msg_type
));
1008 if (iph2
->is_dying
) {
1009 plog(LLV_ERROR
, LOCATION
, NULL
,
1010 "status mismatch phase2 dying (db:%d msg:%d)\n",
1011 iph2
->status
, PHASE2ST_GETSPISENT
);
1015 if (iph2
->status
!= PHASE2ST_GETSPISENT
) {
1016 plog(LLV_ERROR
, LOCATION
, NULL
,
1017 "status mismatch (db:%d msg:%d)\n",
1018 iph2
->status
, PHASE2ST_GETSPISENT
);
1022 // check the underlying iph2->ph1
1024 if (!ike_session_update_ph2_ph1bind(iph2
)) {
1025 plog(LLV_ERROR
, LOCATION
, NULL
,
1026 "can't proceed with getspi for %s. no suitable ISAKMP-SA found \n",
1027 saddrwop2str((struct sockaddr
*)iph2
->dst
));
1035 /* set SPI, and check to get all spi whether or not */
1038 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1039 pp
= iph2
->side
== INITIATOR
? iph2
->proposal
: iph2
->approval
;
1041 for (pr
= pp
->head
; pr
!= NULL
; pr
= pr
->next
) {
1042 if (pr
->proto_id
== proto_id
&& pr
->spi
== 0) {
1043 pr
->spi
= sa
->sadb_sa_spi
;
1045 plog(LLV_DEBUG
, LOCATION
, NULL
,
1046 "pfkey GETSPI succeeded: %s\n",
1047 sadbsecas2str(iph2
->dst
, iph2
->src
,
1048 msg
->sadb_msg_satype
,
1050 ipsecdoi2pfkey_mode(pr
->encmode
)));
1053 allspiok
= 0; /* not get all spi */
1057 plog(LLV_ERROR
, LOCATION
, NULL
,
1058 "get spi for unknown address %s\n",
1059 saddrwop2str((struct sockaddr
*)iph2
->dst
));
1068 iph2
->status
= PHASE2ST_GETSPIDONE
;
1069 if (isakmp_post_getspi(iph2
) < 0) {
1070 plog(LLV_ERROR
, LOCATION
, NULL
,
1071 "failed to start post getspi.\n");
1088 struct ph2handle
*iph2
;
1091 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
1092 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1094 u_int64_t lifebyte
= 0;
1095 u_int wsize
= 4; /* XXX static size of window */
1097 struct ph2natt natt
;
1100 if (iph2
->approval
== NULL
) {
1101 plog(LLV_ERROR
, LOCATION
, NULL
,
1102 "no approvaled SAs found.\n");
1105 if (iph2
->side
== INITIATOR
)
1106 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
1107 else if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
1110 /* for mobile IPv6 */
1111 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
1112 ipsecdoi_transportmode(iph2
->approval
)) {
1120 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1121 /* validity check */
1122 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
1124 plog(LLV_ERROR
, LOCATION
, NULL
,
1125 "invalid proto_id %d\n", pr
->proto_id
);
1128 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
1129 /* IPCOMP has no replay window */
1132 #ifdef ENABLE_SAMODE_UNSPECIFIED
1133 mode
= IPSEC_MODE_ANY
;
1135 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
1137 plog(LLV_ERROR
, LOCATION
, NULL
,
1138 "invalid encmode %d\n", pr
->encmode
);
1143 /* set algorithm type and key length */
1144 e_keylen
= pr
->head
->encklen
;
1145 if (pfkey_convertfromipsecdoi(
1150 &a_type
, &a_keylen
, &flags
) < 0)
1154 lifebyte
= iph2
->approval
->lifebyte
* 1024,
1160 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_update\n");
1161 if (pr
->udp_encap
) {
1162 memset (&natt
, 0, sizeof (natt
));
1163 natt
.sport
= extract_port (iph2
->ph1
->remote
);
1164 flags
|= SADB_X_EXT_NATT
;
1165 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) {
1166 if (iph2
->ph1
->rmconf
->natt_keepalive
== TRUE
)
1167 flags
|= SADB_X_EXT_NATT_KEEPALIVE
;
1169 if (iph2
->ph1
->rmconf
->natt_multiple_user
== TRUE
&&
1170 mode
== IPSEC_MODE_TRANSPORT
&&
1171 src
->ss_family
== AF_INET
) {
1172 flags
|= SADB_X_EXT_NATT_MULTIPLEUSERS
;
1174 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1175 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1176 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1180 memset (&natt
, 0, sizeof (natt
));
1183 if (pfkey_send_update(
1193 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1194 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1195 iph2
->seq
, natt
.sport
) < 0) {
1196 plog(LLV_ERROR
, LOCATION
, NULL
,
1197 "libipsec failed send update (%s)\n",
1202 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_update\n");
1203 if (pfkey_send_update(
1213 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1214 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1215 iph2
->seq
, 0) < 0) {
1216 plog(LLV_ERROR
, LOCATION
, NULL
,
1217 "libipsec failed send update (%s)\n",
1221 #endif /* ENABLE_NATT */
1223 if (!lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
])
1227 * It maybe good idea to call backupsa_to_file() after
1228 * racoon will receive the sadb_update messages.
1229 * But it is impossible because there is not key in the
1230 * information from the kernel.
1232 if (backupsa_to_file(satype
, mode
, (struct sockaddr
*)dst
, (struct sockaddr
*)src
,
1233 pr
->spi
, pr
->reqid_in
, 4,
1235 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1236 0, iph2
->approval
->lifebyte
* 1024,
1237 iph2
->approval
->lifetime
, 0,
1239 plog(LLV_ERROR
, LOCATION
, NULL
,
1240 "backuped SA failed: %s\n",
1241 sadbsecas2str(dst
, src
,
1242 satype
, pr
->spi
, mode
));
1244 plog(LLV_DEBUG
, LOCATION
, NULL
,
1245 "backuped SA: %s\n",
1246 sadbsecas2str(dst
, src
,
1247 satype
, pr
->spi
, mode
));
1257 struct sadb_msg
*msg
;
1259 struct sockaddr_storage
*src
, *dst
;
1260 struct ph2handle
*iph2
;
1261 u_int proto_id
, encmode
, sa_mode
;
1265 /* ignore this message because of local test mode. */
1271 || mhp
[SADB_EXT_SA
] == NULL
1272 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1273 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
1274 plog(LLV_ERROR
, LOCATION
, NULL
,
1275 "inappropriate sadb update message passed.\n");
1278 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1279 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1280 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1281 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1283 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1285 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1287 /* the message has to be processed or not ? */
1288 if (msg
->sadb_msg_pid
!= getpid()) {
1289 plog(LLV_DEBUG
, LOCATION
, NULL
,
1290 "%s message is not interesting "
1291 "because pid %d is not mine.\n",
1292 s_pfkey_type(msg
->sadb_msg_type
),
1297 iph2
= getph2byseq(msg
->sadb_msg_seq
);
1299 plog(LLV_DEBUG
, LOCATION
, NULL
,
1300 "seq %d of %s message not interesting.\n",
1302 s_pfkey_type(msg
->sadb_msg_type
));
1306 if (iph2
->is_dying
) {
1307 plog(LLV_ERROR
, LOCATION
, NULL
,
1308 "status mismatch phase2 dying (db:%d msg:%d)\n",
1309 iph2
->status
, PHASE2ST_ADDSA
);
1313 if (iph2
->status
!= PHASE2ST_ADDSA
) {
1314 plog(LLV_ERROR
, LOCATION
, NULL
,
1315 "status mismatch (db:%d msg:%d)\n",
1316 iph2
->status
, PHASE2ST_ADDSA
);
1320 /* check to complete all keys ? */
1321 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1322 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1323 if (proto_id
== ~0) {
1324 plog(LLV_ERROR
, LOCATION
, NULL
,
1325 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
1328 encmode
= pfkey2ipsecdoi_mode(sa_mode
);
1329 if (encmode
== ~0) {
1330 plog(LLV_ERROR
, LOCATION
, NULL
,
1331 "invalid encmode %d\n", sa_mode
);
1335 if (pr
->proto_id
== proto_id
1336 && pr
->spi
== sa
->sadb_sa_spi
) {
1338 plog(LLV_DEBUG
, LOCATION
, NULL
,
1339 "pfkey UPDATE succeeded: %s\n",
1340 sadbsecas2str(iph2
->dst
, iph2
->src
,
1341 msg
->sadb_msg_satype
,
1345 plog(LLV_INFO
, LOCATION
, NULL
,
1346 "IPsec-SA established: %s\n",
1347 sadbsecas2str(iph2
->dst
, iph2
->src
,
1348 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
,
1359 /* turn off the timer for calling pfkey_timeover() */
1360 SCHED_KILL(iph2
->sce
);
1363 iph2
->status
= PHASE2ST_ESTABLISHED
;
1365 if (iph2
->side
== INITIATOR
) {
1366 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1367 IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC
,
1368 CONSTSTR("Initiator, Quick-Mode"),
1371 IPSECSESSIONTRACEREVENT(iph2
->parent_session
,
1372 IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC
,
1373 CONSTSTR("Responder, Quick-Mode"),
1377 ike_session_ph2_established(iph2
);
1379 IPSECLOGASLMSG("IPSec Phase2 established (Initiated by %s).\n",
1380 (iph2
->side
== INITIATOR
)? "me" : "peer");
1383 gettimeofday(&iph2
->end
, NULL
);
1384 syslog(LOG_NOTICE
, "%s(%s): %8.6f",
1385 "phase2", "quick", timedelta(&iph2
->start
, &iph2
->end
));
1390 iph2
->ph1
->ph2cnt
++;
1392 /* turn off schedule */
1394 SCHED_KILL(iph2
->scr
);
1397 * since we are going to reuse the phase2 handler, we need to
1398 * remain it and refresh all the references between ph1 and ph2 to use.
1402 iph2
->sce
= sched_new(iph2
->approval
->lifetime
,
1403 isakmp_ph2expire_stub
, iph2
);
1405 plog(LLV_DEBUG
, LOCATION
, NULL
, "===\n");
1414 struct ph2handle
*iph2
;
1417 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
1418 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1420 u_int64_t lifebyte
= 0;
1421 u_int wsize
= 4; /* XXX static size of window */
1423 struct ph2natt natt
;
1426 if (iph2
->approval
== NULL
) {
1427 plog(LLV_ERROR
, LOCATION
, NULL
,
1428 "no approvaled SAs found.\n");
1431 if (iph2
->side
== INITIATOR
)
1432 proxy
= iph2
->ph1
->rmconf
->support_proxy
;
1433 else if (iph2
->sainfo
&& iph2
->sainfo
->id_i
)
1436 /* for mobile IPv6 */
1437 if (proxy
&& iph2
->src_id
&& iph2
->dst_id
&&
1438 ipsecdoi_transportmode(iph2
->approval
)) {
1446 for (pr
= iph2
->approval
->head
; pr
!= NULL
; pr
= pr
->next
) {
1447 /* validity check */
1448 satype
= ipsecdoi2pfkey_proto(pr
->proto_id
);
1450 plog(LLV_ERROR
, LOCATION
, NULL
,
1451 "invalid proto_id %d\n", pr
->proto_id
);
1454 else if (satype
== SADB_X_SATYPE_IPCOMP
) {
1455 /* no replay window for IPCOMP */
1458 #ifdef ENABLE_SAMODE_UNSPECIFIED
1459 mode
= IPSEC_MODE_ANY
;
1461 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
1463 plog(LLV_ERROR
, LOCATION
, NULL
,
1464 "invalid encmode %d\n", pr
->encmode
);
1469 /* set algorithm type and key length */
1470 e_keylen
= pr
->head
->encklen
;
1471 if (pfkey_convertfromipsecdoi(
1476 &a_type
, &a_keylen
, &flags
) < 0)
1480 lifebyte
= iph2
->approval
->lifebyte
* 1024,
1486 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_add\n");
1488 if (pr
->udp_encap
) {
1489 memset (&natt
, 0, sizeof (natt
));
1490 natt
.dport
= extract_port (iph2
->ph1
->remote
);
1491 flags
|= SADB_X_EXT_NATT
;
1492 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_ME
) {
1493 if (iph2
->ph1
->rmconf
->natt_keepalive
== TRUE
)
1494 flags
|= SADB_X_EXT_NATT_KEEPALIVE
;
1496 if (iph2
->ph1
->rmconf
->natt_multiple_user
== TRUE
&&
1497 mode
== IPSEC_MODE_TRANSPORT
&&
1498 dst
->ss_family
== AF_INET
) {
1499 flags
|= SADB_X_EXT_NATT_MULTIPLEUSERS
;
1501 if (iph2
->ph1
->natt_flags
& NAT_DETECTED_PEER
) {
1502 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1503 flags
|= SADB_X_EXT_NATT_DETECTED_PEER
;
1507 memset (&natt
, 0, sizeof (natt
));
1509 /* Remove port information, that SA doesn't use it */
1524 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1525 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1526 iph2
->seq
,natt
.dport
) < 0) {
1527 plog(LLV_ERROR
, LOCATION
, NULL
,
1528 "libipsec failed send add (%s)\n",
1533 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_add\n");
1535 /* Remove port information, it is not used without NAT-T */
1549 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1550 0, lifebyte
, iph2
->approval
->lifetime
, 0,
1551 iph2
->seq
, 0) < 0) {
1552 plog(LLV_ERROR
, LOCATION
, NULL
,
1553 "libipsec failed send add (%s)\n",
1557 #endif /* ENABLE_NATT */
1558 if (!lcconf
->pathinfo
[LC_PATHTYPE_BACKUPSA
])
1562 * It maybe good idea to call backupsa_to_file() after
1563 * racoon will receive the sadb_update messages.
1564 * But it is impossible because there is not key in the
1565 * information from the kernel.
1567 if (backupsa_to_file(satype
, mode
, (struct sockaddr
*)src
, (struct sockaddr
*)dst
,
1568 pr
->spi_p
, pr
->reqid_out
, 4,
1570 e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1571 0, iph2
->approval
->lifebyte
* 1024,
1572 iph2
->approval
->lifetime
, 0,
1574 plog(LLV_ERROR
, LOCATION
, NULL
,
1575 "backuped SA failed: %s\n",
1576 sadbsecas2str(src
, dst
,
1577 satype
, pr
->spi_p
, mode
));
1579 plog(LLV_DEBUG
, LOCATION
, NULL
,
1580 "backuped SA: %s\n",
1581 sadbsecas2str(src
, dst
,
1582 satype
, pr
->spi_p
, mode
));
1592 struct sadb_msg
*msg
;
1594 struct sockaddr_storage
*src
, *dst
;
1595 struct ph2handle
*iph2
;
1598 /* ignore this message because of local test mode. */
1604 || mhp
[SADB_EXT_SA
] == NULL
1605 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1606 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
1607 plog(LLV_ERROR
, LOCATION
, NULL
,
1608 "inappropriate sadb add message passed.\n");
1611 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1612 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1613 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1614 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1616 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1618 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1620 /* the message has to be processed or not ? */
1621 if (msg
->sadb_msg_pid
!= getpid()) {
1622 plog(LLV_DEBUG
, LOCATION
, NULL
,
1623 "%s message is not interesting "
1624 "because pid %d is not mine.\n",
1625 s_pfkey_type(msg
->sadb_msg_type
),
1630 iph2
= getph2byseq(msg
->sadb_msg_seq
);
1632 plog(LLV_DEBUG
, LOCATION
, NULL
,
1633 "seq %d of %s message not interesting.\n",
1635 s_pfkey_type(msg
->sadb_msg_type
));
1640 * NOTE don't update any status of phase2 handle
1641 * because they must be updated by SADB_UPDATE message
1644 plog(LLV_INFO
, LOCATION
, NULL
,
1645 "IPsec-SA established: %s\n",
1646 sadbsecas2str(iph2
->src
, iph2
->dst
,
1647 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, sa_mode
));
1649 ike_session_cleanup_other_established_ph2s(iph2
->parent_session
, iph2
);
1651 #ifdef ENABLE_VPNCONTROL_PORT
1655 if (iph2
->dst
->ss_family
== AF_INET
)
1656 address
= ((struct sockaddr_in
*)iph2
->dst
)->sin_addr
.s_addr
;
1659 vpncontrol_notify_phase_change(0, FROM_LOCAL
, NULL
, iph2
);
1663 plog(LLV_DEBUG
, LOCATION
, NULL
, "===\n");
1671 struct sadb_msg
*msg
;
1673 struct sockaddr_storage
*src
, *dst
;
1674 struct ph2handle
*iph2
;
1675 u_int proto_id
, sa_mode
;
1679 || mhp
[SADB_EXT_SA
] == NULL
1680 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1681 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
1682 || (mhp
[SADB_EXT_LIFETIME_HARD
] != NULL
1683 && mhp
[SADB_EXT_LIFETIME_SOFT
] != NULL
)) {
1684 plog(LLV_ERROR
, LOCATION
, NULL
,
1685 "inappropriate sadb expire message passed.\n");
1688 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1689 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
1690 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1691 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1693 sa_mode
= mhp
[SADB_X_EXT_SA2
] == NULL
1695 : (ALIGNED_CAST(struct sadb_x_sa2
*)mhp
[SADB_X_EXT_SA2
])->sadb_x_sa2_mode
;
1697 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
1698 if (proto_id
== ~0) {
1699 plog(LLV_ERROR
, LOCATION
, NULL
,
1700 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
1704 plog(LLV_INFO
, LOCATION
, NULL
,
1705 "IPsec-SA expired: %s\n",
1706 sadbsecas2str(src
, dst
,
1707 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, sa_mode
));
1709 iph2
= getph2bysaidx(src
, dst
, proto_id
, sa
->sadb_sa_spi
);
1712 * Ignore it because two expire messages are come up.
1713 * phase2 handler has been deleted already when 2nd message
1716 plog(LLV_DEBUG
, LOCATION
, NULL
,
1717 "no such a SA found: %s\n",
1718 sadbsecas2str(src
, dst
,
1719 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
,
1723 if (iph2
->is_dying
|| iph2
->status
!= PHASE2ST_ESTABLISHED
) {
1725 * If the status is not equal to PHASE2ST_ESTABLISHED,
1726 * racoon ignores this expire message. There are two reason.
1727 * One is that the phase 2 probably starts because there is
1728 * a potential that racoon receives the acquire message
1729 * without receiving a expire message. Another is that racoon
1730 * may receive the multiple expire messages from the kernel.
1732 plog(LLV_WARNING
, LOCATION
, NULL
,
1733 "the expire message is received "
1734 "but the handler is dying or has not been established.\n");
1738 /* turn off the timer for calling isakmp_ph2expire() */
1739 SCHED_KILL(iph2
->sce
);
1741 iph2
->status
= PHASE2ST_EXPIRED
;
1743 /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
1744 /* allocate buffer for status management of pfkey message */
1745 if (iph2
->side
== INITIATOR
&&
1746 !ike_session_has_other_established_ph2(iph2
->parent_session
, iph2
) &&
1747 !ike_session_drop_rekey(iph2
->parent_session
, IKE_SESSION_REKEY_TYPE_PH2
)) {
1751 /* update status for re-use */
1752 iph2
->status
= PHASE2ST_STATUS2
;
1754 /* start isakmp initiation by using ident exchange */
1755 if (isakmp_post_acquire(iph2
) < 0) {
1756 plog(LLV_ERROR
, LOCATION
, iph2
->dst
,
1757 "failed to begin ipsec sa "
1758 "re-negotiation.\n");
1769 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1770 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't
1771 * manage IPsec SA, so delete the list */
1783 struct sadb_msg
*msg
;
1784 struct sadb_x_policy
*xpl
;
1785 struct secpolicy
*sp_out
= NULL
, *sp_in
= NULL
;
1786 #define MAXNESTEDSA 5 /* XXX */
1787 struct ph2handle
*iph2
[MAXNESTEDSA
];
1788 struct sockaddr_storage
*src
, *dst
;
1789 int n
; /* # of phase 2 handler */
1791 /* ignore this message because of local test mode. */
1797 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
1798 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
1799 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
1800 plog(LLV_ERROR
, LOCATION
, NULL
,
1801 "inappropriate sadb acquire message passed.\n");
1804 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1805 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
1806 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1807 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1809 /* ignore if type is not IPSEC_POLICY_IPSEC */
1810 if (xpl
->sadb_x_policy_type
!= IPSEC_POLICY_IPSEC
) {
1811 plog(LLV_DEBUG
, LOCATION
, NULL
,
1812 "ignore ACQUIRE message. type is not IPsec.\n");
1816 /* ignore it if src is multicast address */
1818 struct sockaddr_storage
*sa
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
1820 if ((sa
->ss_family
== AF_INET
1821 && IN_MULTICAST(ntohl(((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
)))
1823 || (sa
->ss_family
== AF_INET6
1824 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6
*)sa
)->sin6_addr
))
1827 plog(LLV_DEBUG
, LOCATION
, NULL
,
1828 "ignore due to multicast address: %s.\n",
1829 saddrwop2str((struct sockaddr
*)sa
));
1834 /* ignore, if we do not listen on source address */
1837 * - if we'll contact peer from address we do not listen -
1838 * we will be unable to complete negotiation;
1839 * - if we'll negotiate using address we're listening -
1840 * remote peer will send packets to address different
1841 * than one in the policy, so kernel will drop them;
1842 * => therefore this acquire is not for us! --Aidas
1844 // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1845 struct sockaddr_storage
*sa
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
1848 for (p
= lcconf
->myaddrs
; p
; p
= p
->next
) {
1849 if (!cmpsaddrwop(p
->addr
, sa
)) {
1856 plog(LLV_DEBUG
, LOCATION
, NULL
,
1857 "ignore because do not listen on source address : %s.\n",
1858 saddrwop2str((struct sockaddr
*)sa
));
1864 * If there is a phase 2 handler against the policy identifier in
1865 * the acquire message, and if
1866 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1867 * should ignore such a acquire message because the phase 2
1868 * is just negotiating.
1869 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1870 * has to process such a acquire message because racoon may
1871 * have lost the expire message.
1873 iph2
[0] = getph2byid(src
, dst
, xpl
->sadb_x_policy_id
);
1874 if (iph2
[0] != NULL
) {
1875 if (iph2
[0]->status
< PHASE2ST_ESTABLISHED
) {
1876 plog(LLV_DEBUG
, LOCATION
, NULL
,
1877 "ignore the acquire because ph2 found\n");
1880 if (iph2
[0]->status
== PHASE2ST_EXPIRED
)
1885 /* search for proper policyindex */
1886 sp_out
= getspbyspid(xpl
->sadb_x_policy_id
);
1887 if (sp_out
== NULL
) {
1888 plog(LLV_ERROR
, LOCATION
, NULL
, "no policy found: id:%d.\n",
1889 xpl
->sadb_x_policy_id
);
1892 plog(LLV_DEBUG
, LOCATION
, NULL
,
1893 "suitable outbound SP found: %s.\n", spidx2str(&sp_out
->spidx
));
1895 /* get inbound policy */
1897 struct policyindex spidx
;
1899 spidx
.dir
= IPSEC_DIR_INBOUND
;
1900 memcpy(&spidx
.src
, &sp_out
->spidx
.dst
, sizeof(spidx
.src
));
1901 memcpy(&spidx
.dst
, &sp_out
->spidx
.src
, sizeof(spidx
.dst
));
1902 spidx
.prefs
= sp_out
->spidx
.prefd
;
1903 spidx
.prefd
= sp_out
->spidx
.prefs
;
1904 spidx
.ul_proto
= sp_out
->spidx
.ul_proto
;
1906 sp_in
= getsp(&spidx
);
1908 plog(LLV_DEBUG
, LOCATION
, NULL
,
1909 "suitable inbound SP found: %s.\n",
1910 spidx2str(&sp_in
->spidx
));
1912 plog(LLV_NOTIFY
, LOCATION
, NULL
,
1913 "no in-bound policy found: %s\n",
1918 memset(iph2
, 0, MAXNESTEDSA
);
1922 /* allocate a phase 2 */
1924 if (iph2
[n
] == NULL
) {
1925 plog(LLV_ERROR
, LOCATION
, NULL
,
1926 "failed to allocate phase2 entry.\n");
1929 iph2
[n
]->side
= INITIATOR
;
1930 iph2
[n
]->spid
= xpl
->sadb_x_policy_id
;
1931 iph2
[n
]->satype
= msg
->sadb_msg_satype
;
1932 iph2
[n
]->seq
= msg
->sadb_msg_seq
;
1933 iph2
[n
]->status
= PHASE2ST_STATUS2
;
1935 /* set end addresses of SA */
1936 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1937 iph2
[n
]->dst
= dupsaddr(ALIGNED_CAST(struct sockaddr
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]));
1938 if (iph2
[n
]->dst
== NULL
) {
1942 iph2
[n
]->src
= dupsaddr(ALIGNED_CAST(struct sockaddr
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]));
1943 if (iph2
[n
]->src
== NULL
) {
1948 plog(LLV_DEBUG
, LOCATION
, NULL
,
1949 "new acquire %s\n", spidx2str(&sp_out
->spidx
));
1953 vchar_t
*idsrc
, *iddst
;
1955 idsrc
= ipsecdoi_sockaddr2id(&sp_out
->spidx
.src
,
1956 sp_out
->spidx
.prefs
, sp_out
->spidx
.ul_proto
);
1957 if (idsrc
== NULL
) {
1958 plog(LLV_ERROR
, LOCATION
, NULL
,
1959 "failed to get ID for %s\n",
1960 spidx2str(&sp_out
->spidx
));
1964 iddst
= ipsecdoi_sockaddr2id(&sp_out
->spidx
.dst
,
1965 sp_out
->spidx
.prefd
, sp_out
->spidx
.ul_proto
);
1966 if (iddst
== NULL
) {
1967 plog(LLV_ERROR
, LOCATION
, NULL
,
1968 "failed to get ID for %s\n",
1969 spidx2str(&sp_out
->spidx
));
1974 iph2
[n
]->sainfo
= getsainfo(idsrc
, iddst
, NULL
, 0);
1977 if (iph2
[n
]->sainfo
== NULL
) {
1978 plog(LLV_ERROR
, LOCATION
, NULL
,
1979 "failed to get sainfo.\n");
1982 /* XXX should use the algorithm list from register message */
1984 if (link_sainfo_to_ph2(iph2
[n
]->sainfo
) != 0) {
1985 plog(LLV_ERROR
, LOCATION
, NULL
,
1986 "failed to link sainfo\n");
1987 iph2
[n
]->sainfo
= NULL
;
1993 if (set_proposal_from_policy(iph2
[n
], sp_out
, sp_in
) < 0) {
1994 plog(LLV_ERROR
, LOCATION
, NULL
,
1995 "failed to create saprop.\n");
2001 /* start isakmp initiation by using ident exchange */
2002 /* XXX should be looped if there are multiple phase 2 handler. */
2003 if (isakmp_post_acquire(iph2
[n
]) < 0) {
2004 plog(LLV_ERROR
, LOCATION
, NULL
,
2005 "failed to begin ipsec sa negotiation.\n");
2009 #if !TARGET_OS_EMBEDDED
2010 if ( lcconf
->vt
== NULL
){
2011 if (!(lcconf
->vt
= vproc_transaction_begin(NULL
)))
2012 plog(LLV_ERROR
, LOCATION
, NULL
,
2013 "vproc_transaction_begin returns NULL.\n");
2022 unbindph12(iph2
[n
]);
2035 struct sadb_msg
*msg
;
2037 struct sockaddr_storage
*src
, *dst
;
2038 struct ph2handle
*iph2
= NULL
;
2041 /* ignore this message because of local test mode. */
2047 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2048 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
) {
2049 plog(LLV_ERROR
, LOCATION
, NULL
,
2050 "inappropriate sadb delete message passed.\n");
2053 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2054 sa
= ALIGNED_CAST(struct sadb_sa
*)mhp
[SADB_EXT_SA
];
2055 src
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_SRC
]);
2056 dst
= ALIGNED_CAST(struct sockaddr_storage
*)PFKEY_ADDR_SADDR(mhp
[SADB_EXT_ADDRESS_DST
]);
2058 /* the message has to be processed or not ? */
2059 if (msg
->sadb_msg_pid
== getpid()) {
2060 plog(LLV_DEBUG
, LOCATION
, NULL
,
2061 "%s message is not interesting "
2062 "because the message was originated by me.\n",
2063 s_pfkey_type(msg
->sadb_msg_type
));
2067 proto_id
= pfkey2ipsecdoi_proto(msg
->sadb_msg_satype
);
2068 if (proto_id
== ~0) {
2069 plog(LLV_ERROR
, LOCATION
, NULL
,
2070 "invalid proto_id %d\n", msg
->sadb_msg_satype
);
2074 plog(LLV_DEBUG2
, LOCATION
, NULL
, "SADB delete message: proto-id %d\n", proto_id
);
2075 plog(LLV_DEBUG2
, LOCATION
, NULL
, "src: %s\n", saddr2str((struct sockaddr
*)src
));
2076 plog(LLV_DEBUG2
, LOCATION
, NULL
, "dst: %s\n", saddr2str((struct sockaddr
*)dst
));
2079 deleteallph2(src
, dst
, proto_id
);
2080 deleteallph1(src
, dst
);
2084 iph2
= getph2bysaidx(src
, dst
, proto_id
, sa
->sadb_sa_spi
);
2087 plog(LLV_ERROR
, LOCATION
, NULL
,
2088 "no iph2 found: %s\n",
2089 sadbsecas2str(src
, dst
, msg
->sadb_msg_satype
,
2090 sa
->sadb_sa_spi
, IPSEC_MODE_ANY
));
2094 plog(LLV_ERROR
, LOCATION
, NULL
,
2095 "pfkey DELETE received: %s\n",
2096 sadbsecas2str(iph2
->src
, iph2
->dst
,
2097 msg
->sadb_msg_satype
, sa
->sadb_sa_spi
, IPSEC_MODE_ANY
));
2099 /* send delete information */
2100 if (iph2
->status
== PHASE2ST_ESTABLISHED
)
2101 isakmp_info_send_d2(iph2
);
2103 ike_session_cleanup_ph1s_by_ph2(iph2
);
2115 /* ignore this message because of local test mode. */
2120 if (mhp
[0] == NULL
) {
2121 plog(LLV_ERROR
, LOCATION
, NULL
,
2122 "inappropriate sadb flush message passed.\n");
2133 getsadbpolicy(policy0
, policylen0
, type
, iph2
)
2135 int *policylen0
, type
;
2136 struct ph2handle
*iph2
;
2138 struct policyindex
*spidx
= iph2
->spidx_gen
;
2139 struct sadb_x_policy
*xpl
;
2140 struct sadb_x_ipsecrequest
*xisr
;
2147 /* get policy buffer size */
2148 policylen
= sizeof(struct sadb_x_policy
);
2149 if (type
!= SADB_X_SPDDELETE
) {
2150 for (pr
= iph2
->approval
->head
; pr
; pr
= pr
->next
) {
2151 xisrlen
= sizeof(*xisr
);
2152 if (pr
->encmode
== IPSECDOI_ATTR_ENC_MODE_TUNNEL
) {
2153 xisrlen
+= (sysdep_sa_len((struct sockaddr
*)iph2
->src
)
2154 + sysdep_sa_len((struct sockaddr
*)iph2
->dst
));
2157 policylen
+= PFKEY_ALIGN8(xisrlen
);
2161 /* make policy structure */
2162 policy
= racoon_malloc(policylen
);
2164 plog(LLV_ERROR
, LOCATION
, NULL
,
2165 "buffer allocation failed.\n");
2169 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)policy
;
2170 xpl
->sadb_x_policy_len
= PFKEY_UNIT64(policylen
);
2171 xpl
->sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
2172 xpl
->sadb_x_policy_type
= IPSEC_POLICY_IPSEC
;
2173 xpl
->sadb_x_policy_dir
= spidx
->dir
;
2174 xpl
->sadb_x_policy_id
= 0;
2175 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2176 xpl
->sadb_x_policy_priority
= PRIORITY_DEFAULT
;
2179 /* no need to append policy information any more if type is SPDDELETE */
2180 if (type
== SADB_X_SPDDELETE
)
2183 xisr
= (struct sadb_x_ipsecrequest
*)(xpl
+ 1);
2185 for (pr
= iph2
->approval
->head
; pr
; pr
= pr
->next
) {
2187 satype
= doi2ipproto(pr
->proto_id
);
2189 plog(LLV_ERROR
, LOCATION
, NULL
,
2190 "invalid proto_id %d\n", pr
->proto_id
);
2193 mode
= ipsecdoi2pfkey_mode(pr
->encmode
);
2195 plog(LLV_ERROR
, LOCATION
, NULL
,
2196 "invalid encmode %d\n", pr
->encmode
);
2201 * the policy level cannot be unique because the policy
2202 * is defined later than SA, so req_id cannot be bound to SA.
2204 xisr
->sadb_x_ipsecrequest_proto
= satype
;
2205 xisr
->sadb_x_ipsecrequest_mode
= mode
;
2206 xisr
->sadb_x_ipsecrequest_level
= IPSEC_LEVEL_REQUIRE
;
2207 xisr
->sadb_x_ipsecrequest_reqid
= 0;
2208 p
= (caddr_t
)(xisr
+ 1);
2210 xisrlen
= sizeof(*xisr
);
2212 if (pr
->encmode
== IPSECDOI_ATTR_ENC_MODE_TUNNEL
) {
2213 int src_len
, dst_len
;
2215 src_len
= sysdep_sa_len((struct sockaddr
*)iph2
->src
);
2216 dst_len
= sysdep_sa_len((struct sockaddr
*)iph2
->dst
);
2217 xisrlen
+= src_len
+ dst_len
;
2219 memcpy(p
, iph2
->src
, src_len
);
2222 memcpy(p
, iph2
->dst
, dst_len
);
2226 xisr
->sadb_x_ipsecrequest_len
= PFKEY_ALIGN8(xisrlen
);
2231 *policylen0
= policylen
;
2237 racoon_free(policy
);
2243 pk_sendspdupdate2(iph2
)
2244 struct ph2handle
*iph2
;
2246 struct policyindex
*spidx
= iph2
->spidx_gen
;
2247 caddr_t policy
= NULL
;
2249 u_int64_t ltime
, vtime
;
2251 ltime
= iph2
->approval
->lifetime
;
2254 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDUPDATE
, iph2
)) {
2255 plog(LLV_ERROR
, LOCATION
, NULL
,
2256 "getting sadb policy failed.\n");
2260 if (pfkey_send_spdupdate2(
2268 policy
, policylen
, 0) < 0) {
2269 plog(LLV_ERROR
, LOCATION
, NULL
,
2270 "libipsec failed send spdupdate2 (%s)\n",
2274 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_spdupdate2\n");
2278 racoon_free(policy
);
2284 pk_recvspdupdate(mhp
)
2287 struct sadb_address
*saddr
, *daddr
;
2288 struct sadb_x_policy
*xpl
;
2289 struct policyindex spidx
;
2290 struct secpolicy
*sp
;
2294 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2295 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2296 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2297 plog(LLV_ERROR
, LOCATION
, NULL
,
2298 "inappropriate sadb spdupdate message passed.\n");
2301 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2302 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2303 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2305 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2306 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2309 saddr
->sadb_address_prefixlen
,
2310 daddr
->sadb_address_prefixlen
,
2311 saddr
->sadb_address_proto
,
2312 xpl
->sadb_x_policy_priority
,
2315 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2318 saddr
->sadb_address_prefixlen
,
2319 daddr
->sadb_address_prefixlen
,
2320 saddr
->sadb_address_proto
,
2326 plog(LLV_ERROR
, LOCATION
, NULL
,
2327 "such policy does not already exist: \"%s\"\n",
2334 if (addnewsp(mhp
) < 0)
2341 * this function has to be used by responder side.
2344 pk_sendspdadd2(iph2
)
2345 struct ph2handle
*iph2
;
2347 struct policyindex
*spidx
= iph2
->spidx_gen
;
2348 caddr_t policy
= NULL
;
2350 u_int64_t ltime
, vtime
;
2352 ltime
= iph2
->approval
->lifetime
;
2355 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDADD
, iph2
)) {
2356 plog(LLV_ERROR
, LOCATION
, NULL
,
2357 "getting sadb policy failed.\n");
2361 if (pfkey_send_spdadd2(
2369 policy
, policylen
, 0) < 0) {
2370 plog(LLV_ERROR
, LOCATION
, NULL
,
2371 "libipsec failed send spdadd2 (%s)\n",
2375 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_spdadd2\n");
2379 racoon_free(policy
);
2388 struct sadb_address
*saddr
, *daddr
;
2389 struct sadb_x_policy
*xpl
;
2390 struct policyindex spidx
;
2391 struct secpolicy
*sp
;
2395 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2396 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2397 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2398 plog(LLV_ERROR
, LOCATION
, NULL
,
2399 "inappropriate sadb spdadd message passed.\n");
2402 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2403 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2404 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2406 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2407 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2410 saddr
->sadb_address_prefixlen
,
2411 daddr
->sadb_address_prefixlen
,
2412 saddr
->sadb_address_proto
,
2413 xpl
->sadb_x_policy_priority
,
2416 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2419 saddr
->sadb_address_prefixlen
,
2420 daddr
->sadb_address_prefixlen
,
2421 saddr
->sadb_address_proto
,
2427 plog(LLV_ERROR
, LOCATION
, NULL
,
2428 "such policy already exists. "
2429 "anyway replace it: %s\n",
2435 if (addnewsp(mhp
) < 0)
2442 * this function has to be used by responder side.
2445 pk_sendspddelete(iph2
)
2446 struct ph2handle
*iph2
;
2448 struct policyindex
*spidx
= iph2
->spidx_gen
;
2449 caddr_t policy
= NULL
;
2452 if (getsadbpolicy(&policy
, &policylen
, SADB_X_SPDDELETE
, iph2
)) {
2453 plog(LLV_ERROR
, LOCATION
, NULL
,
2454 "getting sadb policy failed.\n");
2458 if (pfkey_send_spddelete(
2465 policy
, policylen
, 0) < 0) {
2466 plog(LLV_ERROR
, LOCATION
, NULL
,
2467 "libipsec failed send spddelete (%s)\n",
2471 plog(LLV_DEBUG
, LOCATION
, NULL
, "call pfkey_send_spddelete\n");
2475 racoon_free(policy
);
2481 pk_recvspddelete(mhp
)
2484 struct sadb_address
*saddr
, *daddr
;
2485 struct sadb_x_policy
*xpl
;
2486 struct policyindex spidx
;
2487 struct secpolicy
*sp
;
2491 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2492 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2493 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2494 plog(LLV_ERROR
, LOCATION
, NULL
,
2495 "inappropriate sadb spddelete message passed.\n");
2498 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2499 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2500 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2502 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2503 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2506 saddr
->sadb_address_prefixlen
,
2507 daddr
->sadb_address_prefixlen
,
2508 saddr
->sadb_address_proto
,
2509 xpl
->sadb_x_policy_priority
,
2512 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2515 saddr
->sadb_address_prefixlen
,
2516 daddr
->sadb_address_prefixlen
,
2517 saddr
->sadb_address_proto
,
2523 plog(LLV_ERROR
, LOCATION
, NULL
,
2524 "no policy found: %s\n",
2529 purgephXbyspid(xpl
->sadb_x_policy_id
, true);
2538 pk_recvspdexpire(mhp
)
2541 struct sadb_address
*saddr
, *daddr
;
2542 struct sadb_x_policy
*xpl
;
2543 struct policyindex spidx
;
2544 struct secpolicy
*sp
;
2548 || mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2549 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2550 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2551 plog(LLV_ERROR
, LOCATION
, NULL
,
2552 "inappropriate sadb spdexpire message passed.\n");
2555 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2556 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2557 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2559 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2560 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2563 saddr
->sadb_address_prefixlen
,
2564 daddr
->sadb_address_prefixlen
,
2565 saddr
->sadb_address_proto
,
2566 xpl
->sadb_x_policy_priority
,
2569 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2572 saddr
->sadb_address_prefixlen
,
2573 daddr
->sadb_address_prefixlen
,
2574 saddr
->sadb_address_proto
,
2580 plog(LLV_ERROR
, LOCATION
, NULL
,
2581 "no policy found: %s\n",
2586 purgephXbyspid(xpl
->sadb_x_policy_id
, false);
2599 if (mhp
[0] == NULL
) {
2600 plog(LLV_ERROR
, LOCATION
, NULL
,
2601 "inappropriate sadb spdget message passed.\n");
2612 struct sadb_msg
*msg
;
2613 struct sadb_address
*saddr
, *daddr
;
2614 struct sadb_x_policy
*xpl
;
2615 struct policyindex spidx
;
2616 struct secpolicy
*sp
;
2619 if (mhp
[0] == NULL
) {
2620 plog(LLV_ERROR
, LOCATION
, NULL
,
2621 "inappropriate sadb spddump message passed.\n");
2624 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2626 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
];
2627 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2628 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2630 if (saddr
== NULL
|| daddr
== NULL
|| xpl
== NULL
) {
2631 plog(LLV_ERROR
, LOCATION
, NULL
,
2632 "inappropriate sadb spddump message passed.\n");
2636 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2637 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2640 saddr
->sadb_address_prefixlen
,
2641 daddr
->sadb_address_prefixlen
,
2642 saddr
->sadb_address_proto
,
2643 xpl
->sadb_x_policy_priority
,
2646 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
2649 saddr
->sadb_address_prefixlen
,
2650 daddr
->sadb_address_prefixlen
,
2651 saddr
->sadb_address_proto
,
2657 plog(LLV_ERROR
, LOCATION
, NULL
,
2658 "such policy already exists. "
2659 "anyway replace it: %s\n",
2665 if (addnewsp(mhp
) < 0)
2672 pk_recvspdflush(mhp
)
2676 if (mhp
[0] == NULL
) {
2677 plog(LLV_ERROR
, LOCATION
, NULL
,
2678 "inappropriate sadb spdflush message passed.\n");
2690 * send error against acquire message to kenrel.
2693 pk_sendeacquire(iph2
)
2694 struct ph2handle
*iph2
;
2696 struct sadb_msg
*newmsg
;
2699 len
= sizeof(struct sadb_msg
);
2700 newmsg
= racoon_calloc(1, len
);
2701 if (newmsg
== NULL
) {
2702 plog(LLV_ERROR
, LOCATION
, NULL
,
2703 "failed to get buffer to send acquire.\n");
2707 memset(newmsg
, 0, len
);
2708 newmsg
->sadb_msg_version
= PF_KEY_V2
;
2709 newmsg
->sadb_msg_type
= SADB_ACQUIRE
;
2710 newmsg
->sadb_msg_errno
= ENOENT
; /* XXX */
2711 newmsg
->sadb_msg_satype
= iph2
->satype
;
2712 newmsg
->sadb_msg_len
= PFKEY_UNIT64(len
);
2713 newmsg
->sadb_msg_reserved
= 0;
2714 newmsg
->sadb_msg_seq
= iph2
->seq
;
2715 newmsg
->sadb_msg_pid
= (u_int32_t
)getpid();
2718 len
= pfkey_send(lcconf
->sock_pfkey
, newmsg
, len
);
2720 racoon_free(newmsg
);
2726 pk_sendget_inbound_sastats(ike_session_t
*session
)
2728 u_int32_t max_stats
;
2732 plog(LLV_DEBUG
, LOCATION
, NULL
, "invalid args in %s \n", __FUNCTION__
);
2736 session
->traffic_monitor
.num_in_curr_req
= 0;
2737 bzero(session
->traffic_monitor
.in_curr_req
, sizeof(session
->traffic_monitor
.in_curr_req
));
2738 max_stats
= (sizeof(session
->traffic_monitor
.in_curr_req
) / sizeof(session
->traffic_monitor
.in_curr_req
[0]));
2741 if ((session
->traffic_monitor
.num_in_curr_req
= ike_session_get_sas_for_stats(session
,
2744 session
->traffic_monitor
.in_curr_req
,
2746 u_int64_t session_ids
[] = {(u_int64_t
)session
, 0};
2748 plog(LLV_DEBUG
, LOCATION
, NULL
, "about to call %s\n", __FUNCTION__
);
2750 if (pfkey_send_getsastats(lcconf
->sock_pfkey
,
2755 session
->traffic_monitor
.in_curr_req
,
2756 session
->traffic_monitor
.num_in_curr_req
) < 0) {
2759 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s successful\n", __FUNCTION__
);
2761 return session
->traffic_monitor
.num_in_curr_req
;
2767 pk_sendget_outbound_sastats(ike_session_t
*session
)
2769 u_int32_t max_stats
;
2773 plog(LLV_DEBUG
, LOCATION
, NULL
, "invalid args in %s \n", __FUNCTION__
);
2777 session
->traffic_monitor
.num_out_curr_req
= 0;
2778 bzero(session
->traffic_monitor
.out_curr_req
, sizeof(session
->traffic_monitor
.out_curr_req
));
2779 max_stats
= (sizeof(session
->traffic_monitor
.out_curr_req
) / sizeof(session
->traffic_monitor
.out_curr_req
[0]));
2782 if ((session
->traffic_monitor
.num_out_curr_req
= ike_session_get_sas_for_stats(session
,
2785 session
->traffic_monitor
.out_curr_req
,
2787 u_int64_t session_ids
[] = {(u_int64_t
)session
, 0};
2789 plog(LLV_DEBUG
, LOCATION
, NULL
, "about to call %s\n", __FUNCTION__
);
2791 if (pfkey_send_getsastats(lcconf
->sock_pfkey
,
2796 session
->traffic_monitor
.out_curr_req
,
2797 session
->traffic_monitor
.num_out_curr_req
) < 0) {
2800 plog(LLV_DEBUG
, LOCATION
, NULL
, "%s successful\n", __FUNCTION__
);
2802 return session
->traffic_monitor
.num_out_curr_req
;
2808 * receive GETSPDSTAT from kernel.
2811 pk_recvgetsastat(mhp
)
2814 struct sadb_msg
*msg
;
2815 struct sadb_session_id
*session_id
;
2816 struct sadb_sastat
*stat_resp
;
2817 ike_session_t
*session
;
2819 /* validity check */
2820 if (mhp
[0] == NULL
||
2821 mhp
[SADB_EXT_SESSION_ID
] == NULL
||
2822 mhp
[SADB_EXT_SASTAT
] == NULL
) {
2823 plog(LLV_ERROR
, LOCATION
, NULL
,
2824 "inappropriate sadb getsastat response.\n");
2827 msg
= ALIGNED_CAST(struct sadb_msg
*)mhp
[0]; // Wcast-align fix (void*) - mhp contains pointers to structs in an aligned buffer
2828 session_id
= ALIGNED_CAST(struct sadb_session_id
*)mhp
[SADB_EXT_SESSION_ID
];
2829 stat_resp
= ALIGNED_CAST(struct sadb_sastat
*)mhp
[SADB_EXT_SASTAT
];
2831 /* the message has to be processed or not ? */
2832 if (msg
->sadb_msg_pid
!= getpid()) {
2833 plog(LLV_DEBUG
, LOCATION
, NULL
,
2834 "%s message is not interesting "
2835 "because pid %d is not mine.\n",
2836 s_pfkey_type(msg
->sadb_msg_type
),
2840 if (!session_id
->sadb_session_id_v
[0]) {
2841 plog(LLV_DEBUG
, LOCATION
, NULL
,
2842 "%s message is bad "
2843 "because session-id[0] is invalid.\n",
2844 s_pfkey_type(msg
->sadb_msg_type
));
2847 session
= ALIGNED_CAST(__typeof__(session
))session_id
->sadb_session_id_v
[0];
2849 if (!stat_resp
->sadb_sastat_list_len
) {
2850 plog(LLV_DEBUG
, LOCATION
, NULL
,
2851 "%s message is bad "
2852 "because it has no sastats.\n",
2853 s_pfkey_type(msg
->sadb_msg_type
));
2857 ike_session_update_traffic_idle_status(session
,
2858 stat_resp
->sadb_sastat_dir
,
2859 (struct sastat
*)(stat_resp
+ 1),
2860 stat_resp
->sadb_sastat_list_len
);
2865 * check if the algorithm is supported or not.
2870 pk_checkalg(class, calg
, keylen
)
2871 int class, calg
, keylen
;
2875 struct sadb_alg alg0
;
2877 switch (algclass2doi(class)) {
2878 case IPSECDOI_PROTO_IPSEC_ESP
:
2879 sup
= SADB_EXT_SUPPORTED_ENCRYPT
;
2881 case IPSECDOI_ATTR_AUTH
:
2882 sup
= SADB_EXT_SUPPORTED_AUTH
;
2884 case IPSECDOI_PROTO_IPCOMP
:
2885 //plog(LLV_DEBUG, LOCATION, NULL,
2886 // "compression algorithm can not be checked "
2887 // "because sadb message doesn't support it.\n");
2890 plog(LLV_ERROR
, LOCATION
, NULL
,
2891 "invalid algorithm class.\n");
2894 alg
= ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg
));
2899 if (ipsec_get_keylen(sup
, alg
, &alg0
)) {
2900 plog(LLV_ERROR
, LOCATION
, NULL
,
2901 "%s.\n", ipsec_strerror());
2904 keylen
= alg0
.sadb_alg_minbits
;
2907 error
= ipsec_check_keylen(sup
, alg
, keylen
);
2909 plog(LLV_ERROR
, LOCATION
, NULL
,
2910 "%s.\n", ipsec_strerror());
2916 * differences with pfkey_recv() in libipsec/pfkey.c:
2917 * - never performs busy wait loop.
2918 * - returns NULL and set *lenp to negative on fatal failures
2919 * - returns NULL and set *lenp to non-negative on non-fatal failures
2920 * - returns non-NULL on success
2922 static struct sadb_msg
*
2927 struct sadb_msg
*newmsg
;
2929 socklen_t optlen
= sizeof(reallen
);
2931 if (getsockopt(so
, SOL_SOCKET
, SO_NREAD
, &reallen
, &optlen
) < 0)
2932 return NULL
; /*fatal*/
2937 if ((newmsg
= racoon_calloc(1, reallen
)) == NULL
)
2940 while ((*lenp
= recv(so
, (caddr_t
)newmsg
, reallen
, 0)) < 0) {
2943 plog(LLV_ERROR
, LOCATION
, NULL
,
2944 "failed to recv pfkey message: %s\n", strerror(errno
));
2948 racoon_free(newmsg
);
2949 return NULL
; /*fatal*/
2950 } else if (*lenp
!= reallen
|| *lenp
< sizeof(struct sadb_msg
)) {
2951 racoon_free(newmsg
);
2962 return eay_random();
2969 struct secpolicy
*new;
2970 struct sadb_address
*saddr
, *daddr
;
2971 struct sadb_x_policy
*xpl
;
2974 if (mhp
[SADB_EXT_ADDRESS_SRC
] == NULL
2975 || mhp
[SADB_EXT_ADDRESS_DST
] == NULL
2976 || mhp
[SADB_X_EXT_POLICY
] == NULL
) {
2977 plog(LLV_ERROR
, LOCATION
, NULL
,
2978 "inappropriate sadb spd management message passed.\n");
2982 saddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_SRC
]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2983 daddr
= ALIGNED_CAST(struct sadb_address
*)mhp
[SADB_EXT_ADDRESS_DST
];
2984 xpl
= ALIGNED_CAST(struct sadb_x_policy
*)mhp
[SADB_X_EXT_POLICY
];
2988 plog(LLV_ERROR
, LOCATION
, NULL
,
2989 "failed to allocate buffer\n");
2993 new->spidx
.dir
= xpl
->sadb_x_policy_dir
;
2994 new->id
= xpl
->sadb_x_policy_id
;
2995 new->policy
= xpl
->sadb_x_policy_type
;
2999 switch (xpl
->sadb_x_policy_type
) {
3000 case IPSEC_POLICY_DISCARD
:
3001 case IPSEC_POLICY_GENERATE
:
3002 case IPSEC_POLICY_NONE
:
3003 case IPSEC_POLICY_ENTRUST
:
3004 case IPSEC_POLICY_BYPASS
:
3007 case IPSEC_POLICY_IPSEC
:
3010 struct sadb_x_ipsecrequest
*xisr
;
3011 struct ipsecrequest
**p_isr
= &new->req
;
3013 /* validity check */
3014 if (PFKEY_EXTLEN(xpl
) < sizeof(*xpl
)) {
3015 plog(LLV_ERROR
, LOCATION
, NULL
,
3016 "invalid msg length.\n");
3020 tlen
= PFKEY_EXTLEN(xpl
) - sizeof(*xpl
);
3021 xisr
= (struct sadb_x_ipsecrequest
*)(xpl
+ 1);
3026 if (xisr
->sadb_x_ipsecrequest_len
< sizeof(*xisr
)) {
3027 plog(LLV_ERROR
, LOCATION
, NULL
,
3028 "invalid msg length.\n");
3032 /* allocate request buffer */
3033 *p_isr
= newipsecreq();
3034 if (*p_isr
== NULL
) {
3035 plog(LLV_ERROR
, LOCATION
, NULL
,
3036 "failed to get new ipsecreq.\n");
3041 (*p_isr
)->next
= NULL
;
3043 switch (xisr
->sadb_x_ipsecrequest_proto
) {
3046 case IPPROTO_IPCOMP
:
3049 plog(LLV_ERROR
, LOCATION
, NULL
,
3050 "invalid proto type: %u\n",
3051 xisr
->sadb_x_ipsecrequest_proto
);
3054 (*p_isr
)->saidx
.proto
= xisr
->sadb_x_ipsecrequest_proto
;
3056 switch (xisr
->sadb_x_ipsecrequest_mode
) {
3057 case IPSEC_MODE_TRANSPORT
:
3058 case IPSEC_MODE_TUNNEL
:
3060 case IPSEC_MODE_ANY
:
3062 plog(LLV_ERROR
, LOCATION
, NULL
,
3063 "invalid mode: %u\n",
3064 xisr
->sadb_x_ipsecrequest_mode
);
3067 (*p_isr
)->saidx
.mode
= xisr
->sadb_x_ipsecrequest_mode
;
3069 switch (xisr
->sadb_x_ipsecrequest_level
) {
3070 case IPSEC_LEVEL_DEFAULT
:
3071 case IPSEC_LEVEL_USE
:
3072 case IPSEC_LEVEL_REQUIRE
:
3074 case IPSEC_LEVEL_UNIQUE
:
3075 (*p_isr
)->saidx
.reqid
=
3076 xisr
->sadb_x_ipsecrequest_reqid
;
3080 plog(LLV_ERROR
, LOCATION
, NULL
,
3081 "invalid level: %u\n",
3082 xisr
->sadb_x_ipsecrequest_level
);
3085 (*p_isr
)->level
= xisr
->sadb_x_ipsecrequest_level
;
3087 /* set IP addresses if there */
3088 if (xisr
->sadb_x_ipsecrequest_len
> sizeof(*xisr
)) {
3089 struct sockaddr
*paddr
;
3091 paddr
= (struct sockaddr
*)(xisr
+ 1);
3092 bcopy(paddr
, &(*p_isr
)->saidx
.src
,
3093 sysdep_sa_len(paddr
));
3095 paddr
= (struct sockaddr
*)((caddr_t
)paddr
3096 + sysdep_sa_len(paddr
));
3097 bcopy(paddr
, &(*p_isr
)->saidx
.dst
,
3098 sysdep_sa_len(paddr
));
3103 /* initialization for the next. */
3104 p_isr
= &(*p_isr
)->next
;
3105 tlen
-= xisr
->sadb_x_ipsecrequest_len
;
3107 /* validity check */
3109 plog(LLV_ERROR
, LOCATION
, NULL
,
3110 "becoming tlen < 0\n");
3113 xisr
= ALIGNED_CAST(struct sadb_x_ipsecrequest
*)((caddr_t
)xisr
3114 + xisr
->sadb_x_ipsecrequest_len
);
3119 plog(LLV_ERROR
, LOCATION
, NULL
,
3120 "invalid policy type.\n");
3124 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3125 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
3128 saddr
->sadb_address_prefixlen
,
3129 daddr
->sadb_address_prefixlen
,
3130 saddr
->sadb_address_proto
,
3131 xpl
->sadb_x_policy_priority
,
3134 KEY_SETSECSPIDX(xpl
->sadb_x_policy_dir
,
3137 saddr
->sadb_address_prefixlen
,
3138 daddr
->sadb_address_prefixlen
,
3139 saddr
->sadb_address_proto
,
3148 /* proto/mode/src->dst spi */
3150 sadbsecas2str(src
, dst
, proto
, spi
, mode
)
3151 struct sockaddr_storage
*src
, *dst
;
3156 static char buf
[256];
3157 u_int doi_proto
, doi_mode
= 0;
3161 doi_proto
= pfkey2ipsecdoi_proto(proto
);
3162 if (doi_proto
== ~0)
3165 doi_mode
= pfkey2ipsecdoi_mode(mode
);
3170 blen
= sizeof(buf
) - 1;
3173 i
= snprintf(p
, blen
, "%s%s%s ",
3174 s_ipsecdoi_proto(doi_proto
),
3176 mode
? s_ipsecdoi_encmode(doi_mode
) : "");
3177 if (i
< 0 || i
>= blen
)
3182 i
= snprintf(p
, blen
, "%s->", saddr2str((struct sockaddr
*)src
));
3183 if (i
< 0 || i
>= blen
)
3188 i
= snprintf(p
, blen
, "%s ", saddr2str((struct sockaddr
*)dst
));
3189 if (i
< 0 || i
>= blen
)
3195 snprintf(p
, blen
, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi
),
3196 (unsigned long)ntohl(spi
));