xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/pfkey.c (revision 2980e352a13e8f0b545a366830c411e7a542ada8)
1 /*	$NetBSD: pfkey.c,v 1.29 2008/07/14 05:45:15 tteras Exp $	*/
2 
3 /* $Id: pfkey.c,v 1.29 2008/07/14 05:45:15 tteras Exp $ */
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "config.h"
35 
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <netdb.h>
40 #include <errno.h>
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 
48 #ifdef ENABLE_NATT
49 # ifdef __linux__
50 #  include <linux/udp.h>
51 # endif
52 # if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
53   (defined(__APPLE__) && defined(__MACH__))
54 #  include <netinet/udp.h>
55 # endif
56 #endif
57 
58 #include <sys/types.h>
59 #include <sys/param.h>
60 #include <sys/socket.h>
61 #include <sys/queue.h>
62 #include <sys/sysctl.h>
63 
64 #include <net/route.h>
65 #include <net/pfkeyv2.h>
66 
67 #include <netinet/in.h>
68 #include PATH_IPSEC_H
69 #include <fcntl.h>
70 
71 #include "libpfkey.h"
72 
73 #include "var.h"
74 #include "misc.h"
75 #include "vmbuf.h"
76 #include "plog.h"
77 #include "sockmisc.h"
78 #include "debug.h"
79 
80 #include "schedule.h"
81 #include "localconf.h"
82 #include "remoteconf.h"
83 #include "handler.h"
84 #include "policy.h"
85 #include "proposal.h"
86 #include "isakmp_var.h"
87 #include "isakmp.h"
88 #include "isakmp_inf.h"
89 #include "ipsec_doi.h"
90 #include "oakley.h"
91 #include "pfkey.h"
92 #include "algorithm.h"
93 #include "sainfo.h"
94 #include "admin.h"
95 #include "evt.h"
96 #include "privsep.h"
97 #include "strnames.h"
98 #include "backupsa.h"
99 #include "gcmalloc.h"
100 #include "nattraversal.h"
101 #include "crypto_openssl.h"
102 #include "grabmyaddr.h"
103 
104 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
105 #define SADB_X_EALG_AESCBC  SADB_X_EALG_RIJNDAELCBC
106 #endif
107 
108 /* prototype */
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));
115 
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 struct sadb_msg *pk_recv __P((int, int *));
132 
133 static int (*pkrecvf[]) __P((caddr_t *)) = {
134 NULL,
135 pk_recvgetspi,
136 pk_recvupdate,
137 pk_recvadd,
138 pk_recvdelete,
139 NULL,	/* SADB_GET */
140 pk_recvacquire,
141 NULL,	/* SABD_REGISTER */
142 pk_recvexpire,
143 pk_recvflush,
144 NULL,	/* SADB_DUMP */
145 NULL,	/* SADB_X_PROMISC */
146 NULL,	/* SADB_X_PCHANGE */
147 pk_recvspdupdate,
148 pk_recvspdadd,
149 pk_recvspddelete,
150 pk_recvspdget,
151 NULL,	/* SADB_X_SPDACQUIRE */
152 pk_recvspddump,
153 pk_recvspdflush,
154 NULL,	/* SADB_X_SPDSETIDX */
155 pk_recvspdexpire,
156 NULL,	/* SADB_X_SPDDELETE2 */
157 NULL,	/* SADB_X_NAT_T_NEW_MAPPING */
158 NULL,	/* SADB_X_MIGRATE */
159 #if (SADB_MAX > 24)
160 #error "SADB extra message?"
161 #endif
162 };
163 
164 static int addnewsp __P((caddr_t *));
165 
166 /* cope with old kame headers - ugly */
167 #ifndef SADB_X_AALG_MD5
168 #define SADB_X_AALG_MD5		SADB_AALG_MD5
169 #endif
170 #ifndef SADB_X_AALG_SHA
171 #define SADB_X_AALG_SHA		SADB_AALG_SHA
172 #endif
173 #ifndef SADB_X_AALG_NULL
174 #define SADB_X_AALG_NULL	SADB_AALG_NULL
175 #endif
176 
177 #ifndef SADB_X_EALG_BLOWFISHCBC
178 #define SADB_X_EALG_BLOWFISHCBC	SADB_EALG_BLOWFISHCBC
179 #endif
180 #ifndef SADB_X_EALG_CAST128CBC
181 #define SADB_X_EALG_CAST128CBC	SADB_EALG_CAST128CBC
182 #endif
183 #ifndef SADB_X_EALG_RC5CBC
184 #ifdef SADB_EALG_RC5CBC
185 #define SADB_X_EALG_RC5CBC	SADB_EALG_RC5CBC
186 #endif
187 #endif
188 
189 /*
190  * PF_KEY packet handler
191  *	0: success
192  *	-1: fail
193  */
194 int
195 pfkey_handler()
196 {
197 	struct sadb_msg *msg;
198 	int len;
199 	caddr_t mhp[SADB_EXT_MAX + 1];
200 	int error = -1;
201 
202 	/* receive pfkey message. */
203 	len = 0;
204 	msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
205 	if (msg == NULL) {
206 		if (len < 0) {
207 			plog(LLV_ERROR, LOCATION, NULL,
208 				"failed to recv from pfkey (%s)\n",
209 				strerror(errno));
210 			goto end;
211 		} else {
212 			/* short message - msg not ready */
213 			return 0;
214 		}
215 	}
216 
217 	plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
218 		s_pfkey_type(msg->sadb_msg_type));
219 	plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
220 
221 	/* validity check */
222 	if (msg->sadb_msg_errno) {
223 		int pri;
224 
225 		/* when SPD is empty, treat the state as no error. */
226 		if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
227 		    msg->sadb_msg_errno == ENOENT)
228 			pri = LLV_DEBUG;
229 		else
230 			pri = LLV_ERROR;
231 
232 		plog(pri, LOCATION, NULL,
233 			"pfkey %s failed: %s\n",
234 			s_pfkey_type(msg->sadb_msg_type),
235 			strerror(msg->sadb_msg_errno));
236 
237 		goto end;
238 	}
239 
240 	/* check pfkey message. */
241 	if (pfkey_align(msg, mhp)) {
242 		plog(LLV_ERROR, LOCATION, NULL,
243 			"libipsec failed pfkey align (%s)\n",
244 			ipsec_strerror());
245 		goto end;
246 	}
247 	if (pfkey_check(mhp)) {
248 		plog(LLV_ERROR, LOCATION, NULL,
249 			"libipsec failed pfkey check (%s)\n",
250 			ipsec_strerror());
251 		goto end;
252 	}
253 	msg = (struct sadb_msg *)mhp[0];
254 
255 	/* safety check */
256 	if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
257 		plog(LLV_ERROR, LOCATION, NULL,
258 			"unknown PF_KEY message type=%u\n",
259 			msg->sadb_msg_type);
260 		goto end;
261 	}
262 
263 	if (pkrecvf[msg->sadb_msg_type] == NULL) {
264 		plog(LLV_INFO, LOCATION, NULL,
265 			"unsupported PF_KEY message %s\n",
266 			s_pfkey_type(msg->sadb_msg_type));
267 		goto end;
268 	}
269 
270 	if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
271 		goto end;
272 
273 	error = 0;
274 end:
275 	if (msg)
276 		racoon_free(msg);
277 	return(error);
278 }
279 
280 /*
281  * dump SADB
282  */
283 vchar_t *
284 pfkey_dump_sadb(satype)
285 	int satype;
286 {
287 	int s = -1;
288 	vchar_t *buf = NULL;
289 	pid_t pid = getpid();
290 	struct sadb_msg *msg = NULL;
291 	size_t bl, ml;
292 	int len;
293 
294 	if ((s = privsep_pfkey_open()) < 0) {
295 		plog(LLV_ERROR, LOCATION, NULL,
296 			"libipsec failed pfkey open: %s\n",
297 			ipsec_strerror());
298 		return NULL;
299 	}
300 
301 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
302 	if (pfkey_send_dump(s, satype) < 0) {
303 		plog(LLV_ERROR, LOCATION, NULL,
304 			"libipsec failed dump: %s\n", ipsec_strerror());
305 		goto fail;
306 	}
307 
308 	while (1) {
309 		if (msg)
310 			racoon_free(msg);
311 		msg = pk_recv(s, &len);
312 		if (msg == NULL) {
313 			if (len < 0)
314 				goto done;
315 			else
316 				continue;
317 		}
318 
319 		if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid)
320 		{
321 		    plog(LLV_DEBUG, LOCATION, NULL,
322 			 "discarding non-sadb dump msg %p, our pid=%i\n", msg, pid);
323 		    plog(LLV_DEBUG, LOCATION, NULL,
324 			 "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid);
325 		    continue;
326 		}
327 
328 
329 		ml = msg->sadb_msg_len << 3;
330 		bl = buf ? buf->l : 0;
331 		buf = vrealloc(buf, bl + ml);
332 		if (buf == NULL) {
333 			plog(LLV_ERROR, LOCATION, NULL,
334 				"failed to reallocate buffer to dump.\n");
335 			goto fail;
336 		}
337 		memcpy(buf->v + bl, msg, ml);
338 
339 		if (msg->sadb_msg_seq == 0)
340 			break;
341 	}
342 	goto done;
343 
344 fail:
345 	if (buf)
346 		vfree(buf);
347 	buf = NULL;
348 done:
349 	if (msg)
350 		racoon_free(msg);
351 	if (s >= 0)
352 		privsep_pfkey_close(s);
353 	return buf;
354 }
355 
356 #ifdef ENABLE_ADMINPORT
357 /*
358  * flush SADB
359  */
360 void
361 pfkey_flush_sadb(proto)
362 	u_int proto;
363 {
364 	int satype;
365 
366 	/* convert to SADB_SATYPE */
367 	if ((satype = admin2pfkey_proto(proto)) < 0)
368 		return;
369 
370 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
371 	if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
372 		plog(LLV_ERROR, LOCATION, NULL,
373 			"libipsec failed send flush (%s)\n", ipsec_strerror());
374 		return;
375 	}
376 
377 	return;
378 }
379 #endif
380 
381 /*
382  * These are the SATYPEs that we manage.  We register to get
383  * PF_KEY messages related to these SATYPEs, and we also use
384  * this list to determine which SATYPEs to delete SAs for when
385  * we receive an INITIAL-CONTACT.
386  */
387 const struct pfkey_satype pfkey_satypes[] = {
388 	{ SADB_SATYPE_AH,	"AH" },
389 	{ SADB_SATYPE_ESP,	"ESP" },
390 	{ SADB_X_SATYPE_IPCOMP,	"IPCOMP" },
391 };
392 const int pfkey_nsatypes =
393     sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
394 
395 /*
396  * PF_KEY initialization
397  */
398 int
399 pfkey_init()
400 {
401 	int i, reg_fail;
402 
403 	if ((lcconf->sock_pfkey = privsep_pfkey_open()) < 0) {
404 		plog(LLV_ERROR, LOCATION, NULL,
405 			"libipsec failed pfkey open (%s)\n", ipsec_strerror());
406 		return -1;
407 	}
408 	if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1)
409 		plog(LLV_WARNING, LOCATION, NULL,
410 		    "failed to set the pfkey socket to NONBLOCK\n");
411 
412 	for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
413 		plog(LLV_DEBUG, LOCATION, NULL,
414 		    "call pfkey_send_register for %s\n",
415 		    pfkey_satypes[i].ps_name);
416 		if (pfkey_send_register(lcconf->sock_pfkey,
417 					pfkey_satypes[i].ps_satype) < 0 ||
418 		    pfkey_recv_register(lcconf->sock_pfkey) < 0) {
419 			plog(LLV_WARNING, LOCATION, NULL,
420 			    "failed to register %s (%s)\n",
421 			    pfkey_satypes[i].ps_name,
422 			    ipsec_strerror());
423 			reg_fail++;
424 		}
425 	}
426 
427 	if (reg_fail == pfkey_nsatypes) {
428 		plog(LLV_ERROR, LOCATION, NULL,
429 			"failed to regist any protocol.\n");
430 		pfkey_close(lcconf->sock_pfkey);
431 		return -1;
432 	}
433 
434 	initsp();
435 
436 	if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
437 		plog(LLV_ERROR, LOCATION, NULL,
438 			"libipsec sending spddump failed: %s\n",
439 			ipsec_strerror());
440 		pfkey_close(lcconf->sock_pfkey);
441 		return -1;
442 	}
443 #if 0
444 	if (pfkey_promisc_toggle(1) < 0) {
445 		pfkey_close(lcconf->sock_pfkey);
446 		return -1;
447 	}
448 #endif
449 	return 0;
450 }
451 
452 int
453 pfkey_reload()
454 {
455 	flushsp();
456 
457 	if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
458 		plog(LLV_ERROR, LOCATION, NULL,
459 			"libipsec sending spddump failed: %s\n",
460 			ipsec_strerror());
461 		return -1;
462 	}
463 
464 	return 0;
465 }
466 
467 /* %%% for conversion */
468 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
469 static u_int
470 ipsecdoi2pfkey_aalg(hashtype)
471 	u_int hashtype;
472 {
473 	switch (hashtype) {
474 	case IPSECDOI_ATTR_AUTH_HMAC_MD5:
475 		return SADB_AALG_MD5HMAC;
476 	case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
477 		return SADB_AALG_SHA1HMAC;
478 	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
479 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
480 		return SADB_X_AALG_SHA2_256;
481 #else
482 		return SADB_X_AALG_SHA2_256HMAC;
483 #endif
484 	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
485 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
486 		return SADB_X_AALG_SHA2_384;
487 #else
488 		return SADB_X_AALG_SHA2_384HMAC;
489 #endif
490 	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
491 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
492 		return SADB_X_AALG_SHA2_512;
493 #else
494 		return SADB_X_AALG_SHA2_512HMAC;
495 #endif
496 	case IPSECDOI_ATTR_AUTH_KPDK:		/* need special care */
497 		return SADB_AALG_NONE;
498 
499 	/* not supported */
500 	case IPSECDOI_ATTR_AUTH_DES_MAC:
501 		plog(LLV_ERROR, LOCATION, NULL,
502 			"Not supported hash type: %u\n", hashtype);
503 		return ~0;
504 
505 	case 0: /* reserved */
506 	default:
507 		return SADB_AALG_NONE;
508 
509 		plog(LLV_ERROR, LOCATION, NULL,
510 			"Invalid hash type: %u\n", hashtype);
511 		return ~0;
512 	}
513 	/*NOTREACHED*/
514 }
515 
516 /* IPSECDOI_ESP -> SADB_EALG */
517 static u_int
518 ipsecdoi2pfkey_ealg(t_id)
519 	u_int t_id;
520 {
521 	switch (t_id) {
522 	case IPSECDOI_ESP_DES_IV64:		/* sa_flags |= SADB_X_EXT_OLD */
523 		return SADB_EALG_DESCBC;
524 	case IPSECDOI_ESP_DES:
525 		return SADB_EALG_DESCBC;
526 	case IPSECDOI_ESP_3DES:
527 		return SADB_EALG_3DESCBC;
528 #ifdef SADB_X_EALG_RC5CBC
529 	case IPSECDOI_ESP_RC5:
530 		return SADB_X_EALG_RC5CBC;
531 #endif
532 	case IPSECDOI_ESP_CAST:
533 		return SADB_X_EALG_CAST128CBC;
534 	case IPSECDOI_ESP_BLOWFISH:
535 		return SADB_X_EALG_BLOWFISHCBC;
536 	case IPSECDOI_ESP_DES_IV32:	/* flags |= (SADB_X_EXT_OLD|
537 							SADB_X_EXT_IV4B)*/
538 		return SADB_EALG_DESCBC;
539 	case IPSECDOI_ESP_NULL:
540 		return SADB_EALG_NULL;
541 #ifdef SADB_X_EALG_AESCBC
542 	case IPSECDOI_ESP_AES:
543 		return SADB_X_EALG_AESCBC;
544 #endif
545 #ifdef SADB_X_EALG_TWOFISHCBC
546 	case IPSECDOI_ESP_TWOFISH:
547 		return SADB_X_EALG_TWOFISHCBC;
548 #endif
549 #ifdef SADB_X_EALG_CAMELLIACBC
550 	case IPSECDOI_ESP_CAMELLIA:
551 		return SADB_X_EALG_CAMELLIACBC;
552 #endif
553 
554 	/* not supported */
555 	case IPSECDOI_ESP_3IDEA:
556 	case IPSECDOI_ESP_IDEA:
557 	case IPSECDOI_ESP_RC4:
558 		plog(LLV_ERROR, LOCATION, NULL,
559 			"Not supported transform: %u\n", t_id);
560 		return ~0;
561 
562 	case 0: /* reserved */
563 	default:
564 		plog(LLV_ERROR, LOCATION, NULL,
565 			"Invalid transform id: %u\n", t_id);
566 		return ~0;
567 	}
568 	/*NOTREACHED*/
569 }
570 
571 /* IPCOMP -> SADB_CALG */
572 static u_int
573 ipsecdoi2pfkey_calg(t_id)
574 	u_int t_id;
575 {
576 	switch (t_id) {
577 	case IPSECDOI_IPCOMP_OUI:
578 		return SADB_X_CALG_OUI;
579 	case IPSECDOI_IPCOMP_DEFLATE:
580 		return SADB_X_CALG_DEFLATE;
581 	case IPSECDOI_IPCOMP_LZS:
582 		return SADB_X_CALG_LZS;
583 
584 	case 0: /* reserved */
585 	default:
586 		plog(LLV_ERROR, LOCATION, NULL,
587 			"Invalid transform id: %u\n", t_id);
588 		return ~0;
589 	}
590 	/*NOTREACHED*/
591 }
592 
593 /* IPSECDOI_PROTO -> SADB_SATYPE */
594 u_int
595 ipsecdoi2pfkey_proto(proto)
596 	u_int proto;
597 {
598 	switch (proto) {
599 	case IPSECDOI_PROTO_IPSEC_AH:
600 		return SADB_SATYPE_AH;
601 	case IPSECDOI_PROTO_IPSEC_ESP:
602 		return SADB_SATYPE_ESP;
603 	case IPSECDOI_PROTO_IPCOMP:
604 		return SADB_X_SATYPE_IPCOMP;
605 
606 	default:
607 		plog(LLV_ERROR, LOCATION, NULL,
608 			"Invalid ipsec_doi proto: %u\n", proto);
609 		return ~0;
610 	}
611 	/*NOTREACHED*/
612 }
613 
614 static u_int
615 ipsecdoi2pfkey_alg(algclass, type)
616 	u_int algclass, type;
617 {
618 	switch (algclass) {
619 	case IPSECDOI_ATTR_AUTH:
620 		return ipsecdoi2pfkey_aalg(type);
621 	case IPSECDOI_PROTO_IPSEC_ESP:
622 		return ipsecdoi2pfkey_ealg(type);
623 	case IPSECDOI_PROTO_IPCOMP:
624 		return ipsecdoi2pfkey_calg(type);
625 	default:
626 		plog(LLV_ERROR, LOCATION, NULL,
627 			"Invalid ipsec_doi algclass: %u\n", algclass);
628 		return ~0;
629 	}
630 	/*NOTREACHED*/
631 }
632 
633 /* SADB_SATYPE -> IPSECDOI_PROTO */
634 u_int
635 pfkey2ipsecdoi_proto(satype)
636 	u_int satype;
637 {
638 	switch (satype) {
639 	case SADB_SATYPE_AH:
640 		return IPSECDOI_PROTO_IPSEC_AH;
641 	case SADB_SATYPE_ESP:
642 		return IPSECDOI_PROTO_IPSEC_ESP;
643 	case SADB_X_SATYPE_IPCOMP:
644 		return IPSECDOI_PROTO_IPCOMP;
645 
646 	default:
647 		plog(LLV_ERROR, LOCATION, NULL,
648 			"Invalid pfkey proto: %u\n", satype);
649 		return ~0;
650 	}
651 	/*NOTREACHED*/
652 }
653 
654 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
655 u_int
656 ipsecdoi2pfkey_mode(mode)
657 	u_int mode;
658 {
659 	switch (mode) {
660 	case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
661 #ifdef ENABLE_NATT
662 	case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
663 	case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
664 #endif
665 		return IPSEC_MODE_TUNNEL;
666 	case IPSECDOI_ATTR_ENC_MODE_TRNS:
667 #ifdef ENABLE_NATT
668 	case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
669 	case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
670 #endif
671 		return IPSEC_MODE_TRANSPORT;
672 	default:
673 		plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
674 		return ~0;
675 	}
676 	/*NOTREACHED*/
677 }
678 
679 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
680 u_int
681 pfkey2ipsecdoi_mode(mode)
682 	u_int mode;
683 {
684 	switch (mode) {
685 	case IPSEC_MODE_TUNNEL:
686 		return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
687 	case IPSEC_MODE_TRANSPORT:
688 		return IPSECDOI_ATTR_ENC_MODE_TRNS;
689 	case IPSEC_MODE_ANY:
690 		return IPSECDOI_ATTR_ENC_MODE_ANY;
691 	default:
692 		plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
693 		return ~0;
694 	}
695 	/*NOTREACHED*/
696 }
697 
698 /* default key length for encryption algorithm */
699 static u_int
700 keylen_aalg(hashtype)
701 	u_int hashtype;
702 {
703 	int res;
704 
705 	if (hashtype == 0)
706 		return SADB_AALG_NONE;
707 
708 	res = alg_ipsec_hmacdef_hashlen(hashtype);
709 	if (res == -1) {
710 		plog(LLV_ERROR, LOCATION, NULL,
711 			"invalid hmac algorithm %u.\n", hashtype);
712 		return ~0;
713 	}
714 	return res;
715 }
716 
717 /* default key length for encryption algorithm */
718 static u_int
719 keylen_ealg(enctype, encklen)
720 	u_int enctype;
721 	int encklen;
722 {
723 	int res;
724 
725 	res = alg_ipsec_encdef_keylen(enctype, encklen);
726 	if (res == -1) {
727 		plog(LLV_ERROR, LOCATION, NULL,
728 			"invalid encryption algorithm %u.\n", enctype);
729 		return ~0;
730 	}
731 	return res;
732 }
733 
734 int
735 pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
736 		e_type, e_keylen, a_type, a_keylen, flags)
737 	u_int proto_id;
738 	u_int t_id;
739 	u_int hashtype;
740 	u_int *e_type;
741 	u_int *e_keylen;
742 	u_int *a_type;
743 	u_int *a_keylen;
744 	u_int *flags;
745 {
746 	*flags = 0;
747 	switch (proto_id) {
748 	case IPSECDOI_PROTO_IPSEC_ESP:
749 		if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
750 			goto bad;
751 		if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
752 			goto bad;
753 		*e_keylen >>= 3;
754 
755 		if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
756 			goto bad;
757 		if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
758 			goto bad;
759 		*a_keylen >>= 3;
760 
761 		if (*e_type == SADB_EALG_NONE) {
762 			plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
763 			goto bad;
764 		}
765 		break;
766 
767 	case IPSECDOI_PROTO_IPSEC_AH:
768 		if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
769 			goto bad;
770 		if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
771 			goto bad;
772 		*a_keylen >>= 3;
773 
774 		if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
775 		 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
776 			/* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
777 			*a_type = SADB_X_AALG_MD5;
778 			*flags |= SADB_X_EXT_OLD;
779 		}
780 		*e_type = SADB_EALG_NONE;
781 		*e_keylen = 0;
782 		if (*a_type == SADB_AALG_NONE) {
783 			plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
784 			goto bad;
785 		}
786 		break;
787 
788 	case IPSECDOI_PROTO_IPCOMP:
789 		if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
790 			goto bad;
791 		*e_keylen = 0;
792 
793 		*flags = SADB_X_EXT_RAWCPI;
794 
795 		*a_type = SADB_AALG_NONE;
796 		*a_keylen = 0;
797 		if (*e_type == SADB_X_CALG_NONE) {
798 			plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
799 			goto bad;
800 		}
801 		break;
802 
803 	default:
804 		plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
805 		goto bad;
806 	}
807 
808 	return 0;
809 
810     bad:
811 	errno = EINVAL;
812 	return -1;
813 }
814 
815 /* called from scheduler */
816 void
817 pfkey_timeover_stub(p)
818 	void *p;
819 {
820 
821 	pfkey_timeover((struct ph2handle *)p);
822 }
823 
824 void
825 pfkey_timeover(iph2)
826 	struct ph2handle *iph2;
827 {
828 	plog(LLV_ERROR, LOCATION, NULL,
829 		"%s give up to get IPsec-SA due to time up to wait.\n",
830 		saddrwop2str(iph2->dst));
831 	SCHED_KILL(iph2->sce);
832 
833 	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
834 	if (iph2->side == INITIATOR)
835 		pk_sendeacquire(iph2);
836 
837 	unbindph12(iph2);
838 	remph2(iph2);
839 	delph2(iph2);
840 
841 	return;
842 }
843 
844 /*%%%*/
845 /* send getspi message per ipsec protocol per remote address */
846 /*
847  * the local address and remote address in ph1handle are dealed
848  * with destination address and source address respectively.
849  * Because SPI is decided by responder.
850  */
851 int
852 pk_sendgetspi(iph2)
853 	struct ph2handle *iph2;
854 {
855 	struct sockaddr *src = NULL, *dst = NULL;
856 	u_int satype, mode;
857 	struct saprop *pp;
858 	struct saproto *pr;
859 	u_int32_t minspi, maxspi;
860 	int proxy = 0;
861 
862 	if (iph2->side == INITIATOR) {
863 		pp = iph2->proposal;
864 		proxy = iph2->ph1->rmconf->support_proxy;
865 	} else {
866 		pp = iph2->approval;
867 		if (iph2->sainfo && iph2->sainfo->id_i)
868 			proxy = 1;
869 	}
870 
871 	/* for mobile IPv6 */
872 	if (proxy && iph2->src_id && iph2->dst_id &&
873 	    ipsecdoi_transportmode(pp)) {
874 		src = iph2->src_id;
875 		dst = iph2->dst_id;
876 	} else {
877 		src = iph2->src;
878 		dst = iph2->dst;
879 	}
880 
881 	for (pr = pp->head; pr != NULL; pr = pr->next) {
882 
883 		/* validity check */
884 		satype = ipsecdoi2pfkey_proto(pr->proto_id);
885 		if (satype == ~0) {
886 			plog(LLV_ERROR, LOCATION, NULL,
887 				"invalid proto_id %d\n", pr->proto_id);
888 			return -1;
889 		}
890 		/* this works around a bug in Linux kernel where it allocates 4 byte
891 		   spi's for IPCOMP */
892 		else if (satype == SADB_X_SATYPE_IPCOMP) {
893 			minspi = 0x100;
894 			maxspi = 0xffff;
895 		}
896 		else {
897 			minspi = 0;
898 			maxspi = 0;
899 		}
900 		mode = ipsecdoi2pfkey_mode(pr->encmode);
901 		if (mode == ~0) {
902 			plog(LLV_ERROR, LOCATION, NULL,
903 				"invalid encmode %d\n", pr->encmode);
904 			return -1;
905 		}
906 
907 #ifdef ENABLE_NATT
908 		/* XXX should we do a copy of src/dst for each pr ?
909 		 */
910 		if (! pr->udp_encap) {
911 			/* Remove port information, that SA doesn't use it */
912 			set_port(src, 0);
913 			set_port(dst, 0);
914 		}
915 #endif
916 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
917 		if (pfkey_send_getspi(
918 				lcconf->sock_pfkey,
919 				satype,
920 				mode,
921 				dst,			/* src of SA */
922 				src,			/* dst of SA */
923 				minspi, maxspi,
924 				pr->reqid_in, iph2->seq) < 0) {
925 			plog(LLV_ERROR, LOCATION, NULL,
926 				"ipseclib failed send getspi (%s)\n",
927 				ipsec_strerror());
928 			return -1;
929 		}
930 		plog(LLV_DEBUG, LOCATION, NULL,
931 			"pfkey GETSPI sent: %s\n",
932 			sadbsecas2str(dst, src, satype, 0, mode));
933 	}
934 
935 	return 0;
936 }
937 
938 /*
939  * receive GETSPI from kernel.
940  */
941 static int
942 pk_recvgetspi(mhp)
943 	caddr_t *mhp;
944 {
945 	struct sadb_msg *msg;
946 	struct sadb_sa *sa;
947 	struct ph2handle *iph2;
948 	struct sockaddr *dst;
949 	int proto_id;
950 	int allspiok, notfound;
951 	struct saprop *pp;
952 	struct saproto *pr;
953 
954 	/* validity check */
955 	if (mhp[SADB_EXT_SA] == NULL
956 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
957 		plog(LLV_ERROR, LOCATION, NULL,
958 			"inappropriate sadb getspi message passed.\n");
959 		return -1;
960 	}
961 	msg = (struct sadb_msg *)mhp[0];
962 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
963 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
964 
965 	/* the message has to be processed or not ? */
966 	if (msg->sadb_msg_pid != getpid()) {
967 		plog(LLV_DEBUG, LOCATION, NULL,
968 			"%s message is not interesting "
969 			"because pid %d is not mine.\n",
970 			s_pfkey_type(msg->sadb_msg_type),
971 			msg->sadb_msg_pid);
972 		return -1;
973 	}
974 
975 	iph2 = getph2byseq(msg->sadb_msg_seq);
976 	if (iph2 == NULL) {
977 		plog(LLV_DEBUG, LOCATION, NULL,
978 			"seq %d of %s message not interesting.\n",
979 			msg->sadb_msg_seq,
980 			s_pfkey_type(msg->sadb_msg_type));
981 		return -1;
982 	}
983 
984 	if (iph2->status != PHASE2ST_GETSPISENT) {
985 		plog(LLV_ERROR, LOCATION, NULL,
986 			"status mismatch (db:%d msg:%d)\n",
987 			iph2->status, PHASE2ST_GETSPISENT);
988 		return -1;
989 	}
990 
991 	/* set SPI, and check to get all spi whether or not */
992 	allspiok = 1;
993 	notfound = 1;
994 	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
995 	pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
996 
997 	for (pr = pp->head; pr != NULL; pr = pr->next) {
998 		if (pr->proto_id == proto_id && pr->spi == 0) {
999 			pr->spi = sa->sadb_sa_spi;
1000 			notfound = 0;
1001 			plog(LLV_DEBUG, LOCATION, NULL,
1002 				"pfkey GETSPI succeeded: %s\n",
1003 				sadbsecas2str(iph2->dst, iph2->src,
1004 				    msg->sadb_msg_satype,
1005 				    sa->sadb_sa_spi,
1006 				    ipsecdoi2pfkey_mode(pr->encmode)));
1007 		}
1008 		if (pr->spi == 0)
1009 			allspiok = 0;	/* not get all spi */
1010 	}
1011 
1012 	if (notfound) {
1013 		plog(LLV_ERROR, LOCATION, NULL,
1014 			"get spi for unknown address %s\n",
1015 			saddrwop2str(iph2->dst));
1016 		return -1;
1017 	}
1018 
1019 	if (allspiok) {
1020 		/* update status */
1021 		iph2->status = PHASE2ST_GETSPIDONE;
1022 		if (isakmp_post_getspi(iph2) < 0) {
1023 			plog(LLV_ERROR, LOCATION, NULL,
1024 				"failed to start post getspi.\n");
1025 			unbindph12(iph2);
1026 			remph2(iph2);
1027 			delph2(iph2);
1028 			iph2 = NULL;
1029 			return -1;
1030 		}
1031 	}
1032 
1033 	return 0;
1034 }
1035 
1036 /*
1037  * set inbound SA
1038  */
1039 int
1040 pk_sendupdate(iph2)
1041 	struct ph2handle *iph2;
1042 {
1043 	struct saproto *pr;
1044 	struct pfkey_send_sa_args sa_args;
1045 	int proxy = 0;
1046 
1047 	/* sanity check */
1048 	if (iph2->approval == NULL) {
1049 		plog(LLV_ERROR, LOCATION, NULL,
1050 			"no approvaled SAs found.\n");
1051 	}
1052 
1053 	if (iph2->side == INITIATOR)
1054 		proxy = iph2->ph1->rmconf->support_proxy;
1055 	else if (iph2->sainfo && iph2->sainfo->id_i)
1056 		proxy = 1;
1057 
1058 	/* fill in some needed for pfkey_send_update2 */
1059 	memset (&sa_args, 0, sizeof (sa_args));
1060 	sa_args.so = lcconf->sock_pfkey;
1061 	if (iph2->lifetime_secs)
1062 		sa_args.l_addtime = iph2->lifetime_secs;
1063 	else
1064 		sa_args.l_addtime = iph2->approval->lifetime;
1065 	sa_args.seq = iph2->seq;
1066 	sa_args.wsize = 4;
1067 
1068 	/* for mobile IPv6 */
1069 	if (proxy && iph2->src_id && iph2->dst_id &&
1070 	    ipsecdoi_transportmode(iph2->approval)) {
1071 		sa_args.dst = iph2->src_id;
1072 		sa_args.src = iph2->dst_id;
1073 	} else {
1074 		sa_args.dst = iph2->src;
1075 		sa_args.src = iph2->dst;
1076 	}
1077 
1078 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1079 		/* validity check */
1080 		sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1081 		if (sa_args.satype == ~0) {
1082 			plog(LLV_ERROR, LOCATION, NULL,
1083 				"invalid proto_id %d\n", pr->proto_id);
1084 			return -1;
1085 		}
1086 		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1087 			/* IPCOMP has no replay window */
1088 			sa_args.wsize = 0;
1089 		}
1090 #ifdef ENABLE_SAMODE_UNSPECIFIED
1091 		sa_args.mode = IPSEC_MODE_ANY;
1092 #else
1093 		sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1094 		if (sa_args.mode == ~0) {
1095 			plog(LLV_ERROR, LOCATION, NULL,
1096 				"invalid encmode %d\n", pr->encmode);
1097 			return -1;
1098 		}
1099 #endif
1100 		/* set algorithm type and key length */
1101 		sa_args.e_keylen = pr->head->encklen;
1102 		if (pfkey_convertfromipsecdoi(
1103 				pr->proto_id,
1104 				pr->head->trns_id,
1105 				pr->head->authtype,
1106 				&sa_args.e_type, &sa_args.e_keylen,
1107 				&sa_args.a_type, &sa_args.a_keylen,
1108 				&sa_args.flags) < 0)
1109 			return -1;
1110 
1111 #if 0
1112 		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1113 #else
1114 		sa_args.l_bytes = 0;
1115 #endif
1116 
1117 #ifdef HAVE_SECCTX
1118 		if (*iph2->approval->sctx.ctx_str) {
1119 			sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1120 			sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1121 			sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1122 			sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1123 		}
1124 #endif /* HAVE_SECCTX */
1125 
1126 #ifdef ENABLE_NATT
1127 		if (pr->udp_encap) {
1128 			sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
1129 			sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
1130 			sa_args.l_natt_dport = extract_port (iph2->ph1->local);
1131 			sa_args.l_natt_oa = iph2->natoa_src;
1132 #ifdef SADB_X_EXT_NAT_T_FRAG
1133 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1134 #endif
1135 		} else {
1136 			/* Remove port information, that SA doesn't use it */
1137 			set_port(sa_args.src, 0);
1138 			set_port(sa_args.dst, 0);
1139 		}
1140 
1141 #endif
1142 		/* more info to fill in */
1143 		sa_args.spi = pr->spi;
1144 		sa_args.reqid = pr->reqid_in;
1145 		sa_args.keymat = pr->keymat->v;
1146 
1147 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n");
1148 		if (pfkey_send_update2(&sa_args) < 0) {
1149 			plog(LLV_ERROR, LOCATION, NULL,
1150 				"libipsec failed send update (%s)\n",
1151 				ipsec_strerror());
1152 			return -1;
1153 		}
1154 
1155 		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1156 			continue;
1157 
1158 		/*
1159 		 * It maybe good idea to call backupsa_to_file() after
1160 		 * racoon will receive the sadb_update messages.
1161 		 * But it is impossible because there is not key in the
1162 		 * information from the kernel.
1163 		 */
1164 
1165 		/* change some things before backing up */
1166 		sa_args.wsize = 4;
1167 		sa_args.l_bytes = iph2->approval->lifebyte * 1024;
1168 
1169 		if (backupsa_to_file(&sa_args) < 0) {
1170 			plog(LLV_ERROR, LOCATION, NULL,
1171 				"backuped SA failed: %s\n",
1172 				sadbsecas2str(sa_args.src, sa_args.dst,
1173 				sa_args.satype, sa_args.spi, sa_args.mode));
1174 		}
1175 		plog(LLV_DEBUG, LOCATION, NULL,
1176 			"backuped SA: %s\n",
1177 			sadbsecas2str(sa_args.src, sa_args.dst,
1178 			sa_args.satype, sa_args.spi, sa_args.mode));
1179 	}
1180 
1181 	return 0;
1182 }
1183 
1184 static int
1185 pk_recvupdate(mhp)
1186 	caddr_t *mhp;
1187 {
1188 	struct sadb_msg *msg;
1189 	struct sadb_sa *sa;
1190 	struct sockaddr *src, *dst;
1191 	struct ph2handle *iph2;
1192 	u_int proto_id, encmode, sa_mode;
1193 	int incomplete = 0;
1194 	struct saproto *pr;
1195 
1196 	/* ignore this message because of local test mode. */
1197 	if (f_local)
1198 		return 0;
1199 
1200 	/* sanity check */
1201 	if (mhp[0] == NULL
1202 	 || mhp[SADB_EXT_SA] == NULL
1203 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1204 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1205 		plog(LLV_ERROR, LOCATION, NULL,
1206 			"inappropriate sadb update message passed.\n");
1207 		return -1;
1208 	}
1209 	msg = (struct sadb_msg *)mhp[0];
1210 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1211 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1212 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1213 
1214 	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1215 		? IPSEC_MODE_ANY
1216 		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1217 
1218 	/* the message has to be processed or not ? */
1219 	if (msg->sadb_msg_pid != getpid()) {
1220 		plog(LLV_DEBUG, LOCATION, NULL,
1221 			"%s message is not interesting "
1222 			"because pid %d is not mine.\n",
1223 			s_pfkey_type(msg->sadb_msg_type),
1224 			msg->sadb_msg_pid);
1225 		return -1;
1226 	}
1227 
1228 	iph2 = getph2byseq(msg->sadb_msg_seq);
1229 	if (iph2 == NULL) {
1230 		plog(LLV_DEBUG, LOCATION, NULL,
1231 			"seq %d of %s message not interesting.\n",
1232 			msg->sadb_msg_seq,
1233 			s_pfkey_type(msg->sadb_msg_type));
1234 		return -1;
1235 	}
1236 
1237 	if (iph2->status != PHASE2ST_ADDSA) {
1238 		plog(LLV_ERROR, LOCATION, NULL,
1239 			"status mismatch (db:%d msg:%d)\n",
1240 			iph2->status, PHASE2ST_ADDSA);
1241 		return -1;
1242 	}
1243 
1244 	/* check to complete all keys ? */
1245 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1246 		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1247 		if (proto_id == ~0) {
1248 			plog(LLV_ERROR, LOCATION, NULL,
1249 				"invalid proto_id %d\n", msg->sadb_msg_satype);
1250 			return -1;
1251 		}
1252 		encmode = pfkey2ipsecdoi_mode(sa_mode);
1253 		if (encmode == ~0) {
1254 			plog(LLV_ERROR, LOCATION, NULL,
1255 				"invalid encmode %d\n", sa_mode);
1256 			return -1;
1257 		}
1258 
1259 		if (pr->proto_id == proto_id
1260 		 && pr->spi == sa->sadb_sa_spi) {
1261 			pr->ok = 1;
1262 			plog(LLV_DEBUG, LOCATION, NULL,
1263 				"pfkey UPDATE succeeded: %s\n",
1264 				sadbsecas2str(iph2->dst, iph2->src,
1265 				    msg->sadb_msg_satype,
1266 				    sa->sadb_sa_spi,
1267 				    sa_mode));
1268 
1269 			plog(LLV_INFO, LOCATION, NULL,
1270 				"IPsec-SA established: %s\n",
1271 				sadbsecas2str(iph2->dst, iph2->src,
1272 					msg->sadb_msg_satype, sa->sadb_sa_spi,
1273 					sa_mode));
1274 		}
1275 
1276 		if (pr->ok == 0)
1277 			incomplete = 1;
1278 	}
1279 
1280 	if (incomplete)
1281 		return 0;
1282 
1283 	/* turn off the timer for calling pfkey_timeover() */
1284 	SCHED_KILL(iph2->sce);
1285 
1286 	/* update status */
1287 	iph2->status = PHASE2ST_ESTABLISHED;
1288 	evt_phase2(iph2, EVT_PHASE2_UP, NULL);
1289 
1290 #ifdef ENABLE_STATS
1291 	gettimeofday(&iph2->end, NULL);
1292 	syslog(LOG_NOTICE, "%s(%s): %8.6f",
1293 		"phase2", "quick", timedelta(&iph2->start, &iph2->end));
1294 #endif
1295 
1296 	/* count up */
1297 	iph2->ph1->ph2cnt++;
1298 
1299 	/* turn off schedule */
1300 	SCHED_KILL(iph2->scr);
1301 
1302 	/* Force the update of ph2's ports, as there is at least one
1303 	 * situation where they'll mismatch with ph1's values
1304 	 */
1305 
1306 #ifdef ENABLE_NATT
1307 	set_port(iph2->src, extract_port(iph2->ph1->local));
1308 	set_port(iph2->dst, extract_port(iph2->ph1->remote));
1309 #endif
1310 
1311 	/*
1312 	 * since we are going to reuse the phase2 handler, we need to
1313 	 * remain it and refresh all the references between ph1 and ph2 to use.
1314 	 */
1315 	unbindph12(iph2);
1316 
1317 	iph2->sce = sched_new(iph2->approval->lifetime,
1318 	    isakmp_ph2expire_stub, iph2);
1319 
1320 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1321 	return 0;
1322 }
1323 
1324 /*
1325  * set outbound SA
1326  */
1327 int
1328 pk_sendadd(iph2)
1329 	struct ph2handle *iph2;
1330 {
1331 	struct saproto *pr;
1332 	int proxy = 0;
1333 	struct pfkey_send_sa_args sa_args;
1334 
1335 	/* sanity check */
1336 	if (iph2->approval == NULL) {
1337 		plog(LLV_ERROR, LOCATION, NULL,
1338 			"no approvaled SAs found.\n");
1339 		return -1;
1340 	}
1341 
1342 	if (iph2->side == INITIATOR)
1343 		proxy = iph2->ph1->rmconf->support_proxy;
1344 	else if (iph2->sainfo && iph2->sainfo->id_i)
1345 		proxy = 1;
1346 
1347 	/* fill in some needed for pfkey_send_update2 */
1348 	memset (&sa_args, 0, sizeof (sa_args));
1349 	sa_args.so = lcconf->sock_pfkey;
1350 	if (iph2->lifetime_secs)
1351 		sa_args.l_addtime = iph2->lifetime_secs;
1352 	else
1353 		sa_args.l_addtime = iph2->approval->lifetime;
1354 	sa_args.seq = iph2->seq;
1355 	sa_args.wsize = 4;
1356 
1357 	/* for mobile IPv6 */
1358 	if (proxy && iph2->src_id && iph2->dst_id &&
1359 	    ipsecdoi_transportmode(iph2->approval)) {
1360 		sa_args.src = iph2->src_id;
1361 		sa_args.dst = iph2->dst_id;
1362 	} else {
1363 		sa_args.src = iph2->src;
1364 		sa_args.dst = iph2->dst;
1365 	}
1366 
1367 	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1368 		/* validity check */
1369 		sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
1370 		if (sa_args.satype == ~0) {
1371 			plog(LLV_ERROR, LOCATION, NULL,
1372 				"invalid proto_id %d\n", pr->proto_id);
1373 			return -1;
1374 		}
1375 		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
1376 			/* no replay window for IPCOMP */
1377 			sa_args.wsize = 0;
1378 		}
1379 #ifdef ENABLE_SAMODE_UNSPECIFIED
1380 		sa_args.mode = IPSEC_MODE_ANY;
1381 #else
1382 		sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
1383 		if (sa_args.mode == ~0) {
1384 			plog(LLV_ERROR, LOCATION, NULL,
1385 				"invalid encmode %d\n", pr->encmode);
1386 			return -1;
1387 		}
1388 #endif
1389 
1390 		/* set algorithm type and key length */
1391 		sa_args.e_keylen = pr->head->encklen;
1392 		if (pfkey_convertfromipsecdoi(
1393 				pr->proto_id,
1394 				pr->head->trns_id,
1395 				pr->head->authtype,
1396 				&sa_args.e_type, &sa_args.e_keylen,
1397 				&sa_args.a_type, &sa_args.a_keylen,
1398 				&sa_args.flags) < 0)
1399 			return -1;
1400 
1401 #if 0
1402 		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
1403 #else
1404 		sa_args.l_bytes = 0;
1405 #endif
1406 
1407 #ifdef HAVE_SECCTX
1408 		if (*iph2->approval->sctx.ctx_str) {
1409 			sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
1410 			sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
1411 			sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
1412 			sa_args.ctxstr = iph2->approval->sctx.ctx_str;
1413 		}
1414 #endif /* HAVE_SECCTX */
1415 
1416 #ifdef ENABLE_NATT
1417 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
1418 		    "(NAT flavor)\n");
1419 
1420 		if (pr->udp_encap) {
1421 			sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
1422 			sa_args.l_natt_sport = extract_port(iph2->ph1->local);
1423 			sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
1424 			sa_args.l_natt_oa = iph2->natoa_dst;
1425 #ifdef SADB_X_EXT_NAT_T_FRAG
1426 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
1427 #endif
1428 		} else {
1429 			/* Remove port information, that SA doesn't use it */
1430 			set_port(sa_args.src, 0);
1431 			set_port(sa_args.dst, 0);
1432 		}
1433 
1434 #else
1435 		/* Remove port information, it is not used without NAT-T */
1436 		set_port(sa_args.src, 0);
1437 		set_port(sa_args.dst, 0);
1438 #endif
1439 
1440 		/* more info to fill in */
1441 		sa_args.spi = pr->spi_p;
1442 		sa_args.reqid = pr->reqid_out;
1443 		sa_args.keymat = pr->keymat_p->v;
1444 
1445 		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
1446 		if (pfkey_send_add2(&sa_args) < 0) {
1447 			plog(LLV_ERROR, LOCATION, NULL,
1448 				"libipsec failed send add (%s)\n",
1449 				ipsec_strerror());
1450 			return -1;
1451 		}
1452 
1453 		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1454 			continue;
1455 
1456 		/*
1457 		 * It maybe good idea to call backupsa_to_file() after
1458 		 * racoon will receive the sadb_update messages.
1459 		 * But it is impossible because there is not key in the
1460 		 * information from the kernel.
1461 		 */
1462 		if (backupsa_to_file(&sa_args) < 0) {
1463 			plog(LLV_ERROR, LOCATION, NULL,
1464 				"backuped SA failed: %s\n",
1465 				sadbsecas2str(sa_args.src, sa_args.dst,
1466 				sa_args.satype, sa_args.spi, sa_args.mode));
1467 		}
1468 		plog(LLV_DEBUG, LOCATION, NULL,
1469 			"backuped SA: %s\n",
1470 			sadbsecas2str(sa_args.src, sa_args.dst,
1471 			sa_args.satype, sa_args.spi, sa_args.mode));
1472 	}
1473 	return 0;
1474 }
1475 
1476 static int
1477 pk_recvadd(mhp)
1478 	caddr_t *mhp;
1479 {
1480 	struct sadb_msg *msg;
1481 	struct sadb_sa *sa;
1482 	struct sockaddr *src, *dst;
1483 	struct ph2handle *iph2;
1484 	u_int sa_mode;
1485 
1486 	/* ignore this message because of local test mode. */
1487 	if (f_local)
1488 		return 0;
1489 
1490 	/* sanity check */
1491 	if (mhp[0] == NULL
1492 	 || mhp[SADB_EXT_SA] == NULL
1493 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1494 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1495 		plog(LLV_ERROR, LOCATION, NULL,
1496 			"inappropriate sadb add message passed.\n");
1497 		return -1;
1498 	}
1499 	msg = (struct sadb_msg *)mhp[0];
1500 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1501 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1502 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1503 
1504 	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1505 		? IPSEC_MODE_ANY
1506 		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1507 
1508 	/* the message has to be processed or not ? */
1509 	if (msg->sadb_msg_pid != getpid()) {
1510 		plog(LLV_DEBUG, LOCATION, NULL,
1511 			"%s message is not interesting "
1512 			"because pid %d is not mine.\n",
1513 			s_pfkey_type(msg->sadb_msg_type),
1514 			msg->sadb_msg_pid);
1515 		return -1;
1516 	}
1517 
1518 	iph2 = getph2byseq(msg->sadb_msg_seq);
1519 	if (iph2 == NULL) {
1520 		plog(LLV_DEBUG, LOCATION, NULL,
1521 			"seq %d of %s message not interesting.\n",
1522 			msg->sadb_msg_seq,
1523 			s_pfkey_type(msg->sadb_msg_type));
1524 		return -1;
1525 	}
1526 
1527 	/*
1528 	 * NOTE don't update any status of phase2 handle
1529 	 * because they must be updated by SADB_UPDATE message
1530 	 */
1531 
1532 	plog(LLV_INFO, LOCATION, NULL,
1533 		"IPsec-SA established: %s\n",
1534 		sadbsecas2str(iph2->src, iph2->dst,
1535 			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1536 
1537 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1538 	return 0;
1539 }
1540 
1541 static int
1542 pk_recvexpire(mhp)
1543 	caddr_t *mhp;
1544 {
1545 	struct sadb_msg *msg;
1546 	struct sadb_sa *sa;
1547 	struct sockaddr *src, *dst;
1548 	struct ph2handle *iph2;
1549 	u_int proto_id, sa_mode;
1550 
1551 	/* sanity check */
1552 	if (mhp[0] == NULL
1553 	 || mhp[SADB_EXT_SA] == NULL
1554 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1555 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1556 	 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1557 	  && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1558 		plog(LLV_ERROR, LOCATION, NULL,
1559 			"inappropriate sadb expire message passed.\n");
1560 		return -1;
1561 	}
1562 	msg = (struct sadb_msg *)mhp[0];
1563 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1564 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1565 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1566 
1567 	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1568 		? IPSEC_MODE_ANY
1569 		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1570 
1571 	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1572 	if (proto_id == ~0) {
1573 		plog(LLV_ERROR, LOCATION, NULL,
1574 			"invalid proto_id %d\n", msg->sadb_msg_satype);
1575 		return -1;
1576 	}
1577 
1578 	plog(LLV_INFO, LOCATION, NULL,
1579 		"IPsec-SA expired: %s\n",
1580 		sadbsecas2str(src, dst,
1581 			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1582 
1583 	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1584 	if (iph2 == NULL) {
1585 		/*
1586 		 * Ignore it because two expire messages are come up.
1587 		 * phase2 handler has been deleted already when 2nd message
1588 		 * is received.
1589 		 */
1590 		plog(LLV_DEBUG, LOCATION, NULL,
1591 			"no such a SA found: %s\n",
1592 			sadbsecas2str(src, dst,
1593 			    msg->sadb_msg_satype, sa->sadb_sa_spi,
1594 			    sa_mode));
1595 		return 0;
1596 	}
1597 	if (iph2->status != PHASE2ST_ESTABLISHED) {
1598 		/*
1599 		 * If the status is not equal to PHASE2ST_ESTABLISHED,
1600 		 * racoon ignores this expire message.  There are two reason.
1601 		 * One is that the phase 2 probably starts because there is
1602 		 * a potential that racoon receives the acquire message
1603 		 * without receiving a expire message.  Another is that racoon
1604 		 * may receive the multiple expire messages from the kernel.
1605 		 */
1606 		plog(LLV_WARNING, LOCATION, NULL,
1607 			"the expire message is received "
1608 			"but the handler has not been established.\n");
1609 		return 0;
1610 	}
1611 
1612 	/* turn off the timer for calling isakmp_ph2expire() */
1613 	SCHED_KILL(iph2->sce);
1614 
1615 	iph2->status = PHASE2ST_EXPIRED;
1616 
1617 	/* INITIATOR, begin phase 2 exchange. */
1618 	/* allocate buffer for status management of pfkey message */
1619 	if (iph2->side == INITIATOR) {
1620 
1621 		initph2(iph2);
1622 
1623 		/* update status for re-use */
1624 		iph2->status = PHASE2ST_STATUS2;
1625 
1626 		/* start isakmp initiation by using ident exchange */
1627 		if (isakmp_post_acquire(iph2) < 0) {
1628 			plog(LLV_ERROR, LOCATION, iph2->dst,
1629 				"failed to begin ipsec sa "
1630 				"re-negotication.\n");
1631 			unbindph12(iph2);
1632 			remph2(iph2);
1633 			delph2(iph2);
1634 			return -1;
1635 		}
1636 
1637 		return 0;
1638 		/*NOTREACHED*/
1639 	}
1640 
1641 	/* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1642 	/* RESPONDER always delete ph2handle, keep silent.  RESPONDER doesn't
1643 	 * manage IPsec SA, so delete the list */
1644 	unbindph12(iph2);
1645 	remph2(iph2);
1646 	delph2(iph2);
1647 
1648 	return 0;
1649 }
1650 
1651 static int
1652 pk_recvacquire(mhp)
1653 	caddr_t *mhp;
1654 {
1655 	struct sadb_msg *msg;
1656 	struct sadb_x_policy *xpl;
1657 	struct secpolicy *sp_out = NULL, *sp_in = NULL;
1658 #define MAXNESTEDSA	5	/* XXX */
1659 	struct ph2handle *iph2[MAXNESTEDSA];
1660 	struct sockaddr *src, *dst;
1661 	int n;	/* # of phase 2 handler */
1662 #ifdef HAVE_SECCTX
1663 	struct sadb_x_sec_ctx *m_sec_ctx;
1664 #endif /* HAVE_SECCTX */
1665 	struct policyindex spidx;
1666 
1667 
1668 	/* ignore this message because of local test mode. */
1669 	if (f_local)
1670 		return 0;
1671 
1672 	/* sanity check */
1673 	if (mhp[0] == NULL
1674 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1675 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1676 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
1677 		plog(LLV_ERROR, LOCATION, NULL,
1678 			"inappropriate sadb acquire message passed.\n");
1679 		return -1;
1680 	}
1681 	msg = (struct sadb_msg *)mhp[0];
1682 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1683 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1684 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1685 
1686 #ifdef HAVE_SECCTX
1687 	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
1688 
1689 	if (m_sec_ctx != NULL) {
1690 		plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
1691 		     m_sec_ctx->sadb_x_ctx_doi);
1692 		plog(LLV_INFO, LOCATION, NULL,
1693 		     "security context algorithm: %u\n",
1694 		     m_sec_ctx->sadb_x_ctx_alg);
1695 		plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
1696 		     m_sec_ctx->sadb_x_ctx_len);
1697 		plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
1698 		     ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
1699 	}
1700 #endif /* HAVE_SECCTX */
1701 
1702 	/* ignore if type is not IPSEC_POLICY_IPSEC */
1703 	if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1704 		plog(LLV_DEBUG, LOCATION, NULL,
1705 			"ignore ACQUIRE message. type is not IPsec.\n");
1706 		return 0;
1707 	}
1708 
1709 	/* ignore it if src is multicast address */
1710     {
1711 	struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1712 
1713 	if ((sa->sa_family == AF_INET
1714 	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
1715 #ifdef INET6
1716 	 || (sa->sa_family == AF_INET6
1717 	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
1718 #endif
1719 	) {
1720 		plog(LLV_DEBUG, LOCATION, NULL,
1721 			"ignore due to multicast address: %s.\n",
1722 			saddrwop2str(sa));
1723 		return 0;
1724 	}
1725     }
1726 
1727     	/* ignore, if we do not listen on source address */
1728 	{
1729 		/* reasons behind:
1730 		 * - if we'll contact peer from address we do not listen -
1731 		 *   we will be unable to complete negotiation;
1732 		 * - if we'll negotiate using address we're listening -
1733 		 *   remote peer will send packets to address different
1734 		 *   than one in the policy, so kernel will drop them;
1735 		 * => therefore this acquire is not for us! --Aidas
1736 		 */
1737 		struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1738 		struct myaddrs *p;
1739 		int do_listen = 0;
1740 		for (p = lcconf->myaddrs; p; p = p->next) {
1741 			if (!cmpsaddrwop(p->addr, sa)) {
1742 				do_listen = 1;
1743 				break;
1744 			}
1745 		}
1746 
1747 		if (!do_listen) {
1748 			plog(LLV_DEBUG, LOCATION, NULL,
1749 				"ignore because do not listen on source address : %s.\n",
1750 				saddrwop2str(sa));
1751 			return 0;
1752 		}
1753 	}
1754 
1755 	/*
1756 	 * If there is a phase 2 handler against the policy identifier in
1757 	 * the acquire message, and if
1758 	 *    1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1759 	 *       should ignore such a acquire message because the phase 2
1760 	 *       is just negotiating.
1761 	 *    2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1762 	 *       has to prcesss such a acquire message because racoon may
1763 	 *       lost the expire message.
1764 	 */
1765 	iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
1766 	if (iph2[0] != NULL) {
1767 		if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
1768 			plog(LLV_DEBUG, LOCATION, NULL,
1769 				"ignore the acquire because ph2 found\n");
1770 			return -1;
1771 		}
1772 		if (iph2[0]->status == PHASE2ST_EXPIRED)
1773 			iph2[0] = NULL;
1774 		/*FALLTHROUGH*/
1775 	}
1776 
1777 	/* search for proper policyindex */
1778 	sp_out = getspbyspid(xpl->sadb_x_policy_id);
1779 	if (sp_out == NULL) {
1780 		plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1781 			xpl->sadb_x_policy_id);
1782 		return -1;
1783 	}
1784 	plog(LLV_DEBUG, LOCATION, NULL,
1785 		"suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1786 
1787 	/* get inbound policy */
1788     {
1789 
1790 	memset(&spidx, 0, sizeof(spidx));
1791 	spidx.dir = IPSEC_DIR_INBOUND;
1792 	memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1793 	memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1794 	spidx.prefs = sp_out->spidx.prefd;
1795 	spidx.prefd = sp_out->spidx.prefs;
1796 	spidx.ul_proto = sp_out->spidx.ul_proto;
1797 
1798 #ifdef HAVE_SECCTX
1799 	if (m_sec_ctx) {
1800 		spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
1801 		spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
1802 		spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
1803 		memcpy(spidx.sec_ctx.ctx_str,
1804 		      ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
1805 		      spidx.sec_ctx.ctx_strlen);
1806 	}
1807 #endif /* HAVE_SECCTX */
1808 
1809 	sp_in = getsp(&spidx);
1810 	if (sp_in) {
1811 		plog(LLV_DEBUG, LOCATION, NULL,
1812 			"suitable inbound SP found: %s.\n",
1813 			spidx2str(&sp_in->spidx));
1814 	} else {
1815 		plog(LLV_NOTIFY, LOCATION, NULL,
1816 			"no in-bound policy found: %s\n",
1817 			spidx2str(&spidx));
1818 	}
1819     }
1820 
1821 	memset(iph2, 0, MAXNESTEDSA);
1822 
1823 	n = 0;
1824 
1825 	/* allocate a phase 2 */
1826 	iph2[n] = newph2();
1827 	if (iph2[n] == NULL) {
1828 		plog(LLV_ERROR, LOCATION, NULL,
1829 			"failed to allocate phase2 entry.\n");
1830 		return -1;
1831 	}
1832 	iph2[n]->side = INITIATOR;
1833 	iph2[n]->spid = xpl->sadb_x_policy_id;
1834 	iph2[n]->satype = msg->sadb_msg_satype;
1835 	iph2[n]->seq = msg->sadb_msg_seq;
1836 	iph2[n]->status = PHASE2ST_STATUS2;
1837 
1838 	/* set end addresses of SA */
1839 	iph2[n]->dst = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
1840 	if (iph2[n]->dst == NULL) {
1841 		delph2(iph2[n]);
1842 		return -1;
1843 	}
1844 	iph2[n]->src = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
1845 	if (iph2[n]->src == NULL) {
1846 		delph2(iph2[n]);
1847 		return -1;
1848 	}
1849 
1850 	if (isakmp_get_sainfo(iph2[n], sp_out, sp_in) < 0) {
1851 		delph2(iph2[n]);
1852 		return -1;
1853 	}
1854 
1855 
1856 #ifdef HAVE_SECCTX
1857 	if (m_sec_ctx) {
1858 		set_secctx_in_proposal(iph2[n], spidx);
1859 	}
1860 #endif /* HAVE_SECCTX */
1861 
1862 	insph2(iph2[n]);
1863 
1864 	/* start isakmp initiation by using ident exchange */
1865 	/* XXX should be looped if there are multiple phase 2 handler. */
1866 	if (isakmp_post_acquire(iph2[n]) < 0) {
1867 		plog(LLV_ERROR, LOCATION, NULL,
1868 			"failed to begin ipsec sa negotication.\n");
1869 		goto err;
1870 	}
1871 
1872 	return 0;
1873 
1874 err:
1875 	while (n >= 0) {
1876 		unbindph12(iph2[n]);
1877 		remph2(iph2[n]);
1878 		delph2(iph2[n]);
1879 		iph2[n] = NULL;
1880 		n--;
1881 	}
1882 	return -1;
1883 }
1884 
1885 static int
1886 pk_recvdelete(mhp)
1887 	caddr_t *mhp;
1888 {
1889 	struct sadb_msg *msg;
1890 	struct sadb_sa *sa;
1891 	struct sockaddr *src, *dst;
1892 	struct ph2handle *iph2 = NULL;
1893 	u_int proto_id;
1894 
1895 	/* ignore this message because of local test mode. */
1896 	if (f_local)
1897 		return 0;
1898 
1899 	/* sanity check */
1900 	if (mhp[0] == NULL
1901 	 || mhp[SADB_EXT_SA] == NULL
1902 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1903 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1904 		plog(LLV_ERROR, LOCATION, NULL,
1905 			"inappropriate sadb delete message passed.\n");
1906 		return -1;
1907 	}
1908 	msg = (struct sadb_msg *)mhp[0];
1909 	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1910 	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1911 	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1912 
1913 	/* the message has to be processed or not ? */
1914 	if (msg->sadb_msg_pid == getpid()) {
1915 		plog(LLV_DEBUG, LOCATION, NULL,
1916 			"%s message is not interesting "
1917 			"because the message was originated by me.\n",
1918 			s_pfkey_type(msg->sadb_msg_type));
1919 		return -1;
1920 	}
1921 
1922 	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1923 	if (proto_id == ~0) {
1924 		plog(LLV_ERROR, LOCATION, NULL,
1925 			"invalid proto_id %d\n", msg->sadb_msg_satype);
1926 		return -1;
1927 	}
1928 
1929 	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1930 	if (iph2 == NULL) {
1931 		/* ignore */
1932 		plog(LLV_ERROR, LOCATION, NULL,
1933 			"no iph2 found: %s\n",
1934 			sadbsecas2str(src, dst, msg->sadb_msg_satype,
1935 				sa->sadb_sa_spi, IPSEC_MODE_ANY));
1936 		return 0;
1937 	}
1938 
1939 	plog(LLV_ERROR, LOCATION, NULL,
1940 		"pfkey DELETE received: %s\n",
1941 		sadbsecas2str(iph2->src, iph2->dst,
1942 			msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
1943 
1944 	/* send delete information */
1945 	if (iph2->status == PHASE2ST_ESTABLISHED)
1946 		isakmp_info_send_d2(iph2);
1947 
1948 	unbindph12(iph2);
1949 	remph2(iph2);
1950 	delph2(iph2);
1951 
1952 	return 0;
1953 }
1954 
1955 static int
1956 pk_recvflush(mhp)
1957 	caddr_t *mhp;
1958 {
1959 	/* ignore this message because of local test mode. */
1960 	if (f_local)
1961 		return 0;
1962 
1963 	/* sanity check */
1964 	if (mhp[0] == NULL) {
1965 		plog(LLV_ERROR, LOCATION, NULL,
1966 			"inappropriate sadb flush message passed.\n");
1967 		return -1;
1968 	}
1969 
1970 	flushph2();
1971 
1972 	return 0;
1973 }
1974 
1975 static int
1976 getsadbpolicy(policy0, policylen0, type, iph2)
1977 	caddr_t *policy0;
1978 	int *policylen0, type;
1979 	struct ph2handle *iph2;
1980 {
1981 	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
1982 	struct sadb_x_policy *xpl;
1983 	struct sadb_x_ipsecrequest *xisr;
1984 	struct saproto *pr;
1985 	struct saproto **pr_rlist;
1986 	int rlist_len = 0;
1987 	caddr_t policy, p;
1988 	int policylen;
1989 	int xisrlen;
1990 	u_int satype, mode;
1991 	int len = 0;
1992 #ifdef HAVE_SECCTX
1993 	int ctxlen = 0;
1994 #endif /* HAVE_SECCTX */
1995 
1996 
1997 	/* get policy buffer size */
1998 	policylen = sizeof(struct sadb_x_policy);
1999 	if (type != SADB_X_SPDDELETE) {
2000 		for (pr = iph2->approval->head; pr; pr = pr->next) {
2001 			xisrlen = sizeof(*xisr);
2002 			if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2003 				xisrlen += (sysdep_sa_len(iph2->src)
2004 				          + sysdep_sa_len(iph2->dst));
2005 			}
2006 
2007 			policylen += PFKEY_ALIGN8(xisrlen);
2008 		}
2009 	}
2010 
2011 #ifdef HAVE_SECCTX
2012 	if (*spidx->sec_ctx.ctx_str) {
2013 		ctxlen = sizeof(struct sadb_x_sec_ctx)
2014 				+ PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
2015 		policylen += ctxlen;
2016 	}
2017 #endif /* HAVE_SECCTX */
2018 
2019 	/* make policy structure */
2020 	policy = racoon_malloc(policylen);
2021 	memset((void*)policy, 0xcd, policylen);
2022 	if (!policy) {
2023 		plog(LLV_ERROR, LOCATION, NULL,
2024 			"buffer allocation failed.\n");
2025 		return -1;
2026 	}
2027 
2028 	xpl = (struct sadb_x_policy *)policy;
2029 	xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2030 	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2031 	xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2032 	xpl->sadb_x_policy_dir = spidx->dir;
2033 	xpl->sadb_x_policy_id = 0;
2034 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2035 	xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2036 #endif
2037 	len++;
2038 
2039 #ifdef HAVE_SECCTX
2040 	if (*spidx->sec_ctx.ctx_str) {
2041 		struct sadb_x_sec_ctx *p;
2042 
2043 		p = (struct sadb_x_sec_ctx *)(xpl + len);
2044 		memset(p, 0, ctxlen);
2045 		p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
2046 		p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2047 		p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
2048 		p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
2049 		p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
2050 
2051 		memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
2052 		len += ctxlen;
2053 	}
2054 #endif /* HAVE_SECCTX */
2055 
2056 	/* no need to append policy information any more if type is SPDDELETE */
2057 	if (type == SADB_X_SPDDELETE)
2058 		goto end;
2059 
2060 	xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
2061 
2062 	/* The order of things is reversed for use in add policy messages */
2063 	for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
2064 	pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
2065 	if (!pr_rlist) {
2066 		plog(LLV_ERROR, LOCATION, NULL,
2067 			"buffer allocation failed.\n");
2068 		return -1;
2069 	}
2070 	pr_rlist[rlist_len--] = NULL;
2071 	for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
2072 	rlist_len = 0;
2073 
2074 	for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
2075 
2076 		satype = doi2ipproto(pr->proto_id);
2077 		if (satype == ~0) {
2078 			plog(LLV_ERROR, LOCATION, NULL,
2079 				"invalid proto_id %d\n", pr->proto_id);
2080 			goto err;
2081 		}
2082 		mode = ipsecdoi2pfkey_mode(pr->encmode);
2083 		if (mode == ~0) {
2084 			plog(LLV_ERROR, LOCATION, NULL,
2085 				"invalid encmode %d\n", pr->encmode);
2086 			goto err;
2087 		}
2088 
2089 		/*
2090 		 * the policy level cannot be unique because the policy
2091 		 * is defined later than SA, so req_id cannot be bound to SA.
2092 		 */
2093 		xisr->sadb_x_ipsecrequest_proto = satype;
2094 		xisr->sadb_x_ipsecrequest_mode = mode;
2095 		if(iph2->proposal->head->reqid_in > 0){
2096 			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
2097 			xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
2098 		}else{
2099 			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2100 			xisr->sadb_x_ipsecrequest_reqid = 0;
2101 		}
2102 		p = (caddr_t)(xisr + 1);
2103 
2104 		xisrlen = sizeof(*xisr);
2105 
2106 		if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2107 			int src_len, dst_len;
2108 
2109 			src_len = sysdep_sa_len(iph2->src);
2110 			dst_len = sysdep_sa_len(iph2->dst);
2111 			xisrlen += src_len + dst_len;
2112 
2113 			memcpy(p, iph2->src, src_len);
2114 			p += src_len;
2115 
2116 			memcpy(p, iph2->dst, dst_len);
2117 			p += dst_len;
2118 		}
2119 
2120 		xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2121 		xisr = (struct sadb_x_ipsecrequest *)p;
2122 
2123 	}
2124 	racoon_free(pr_rlist);
2125 
2126 end:
2127 	*policy0 = policy;
2128 	*policylen0 = policylen;
2129 
2130 	return 0;
2131 
2132 err:
2133 	if (policy)
2134 		racoon_free(policy);
2135 	if (pr_rlist) racoon_free(pr_rlist);
2136 
2137 	return -1;
2138 }
2139 
2140 int
2141 pk_sendspdupdate2(iph2)
2142 	struct ph2handle *iph2;
2143 {
2144 	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2145 	caddr_t policy = NULL;
2146 	int policylen = 0;
2147 	u_int64_t ltime, vtime;
2148 
2149 	ltime = iph2->approval->lifetime;
2150 	vtime = 0;
2151 
2152 	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2153 		plog(LLV_ERROR, LOCATION, NULL,
2154 			"getting sadb policy failed.\n");
2155 		return -1;
2156 	}
2157 
2158 	if (pfkey_send_spdupdate2(
2159 			lcconf->sock_pfkey,
2160 			(struct sockaddr *)&spidx->src,
2161 			spidx->prefs,
2162 			(struct sockaddr *)&spidx->dst,
2163 			spidx->prefd,
2164 			spidx->ul_proto,
2165 			ltime, vtime,
2166 			policy, policylen, 0) < 0) {
2167 		plog(LLV_ERROR, LOCATION, NULL,
2168 			"libipsec failed send spdupdate2 (%s)\n",
2169 			ipsec_strerror());
2170 		goto end;
2171 	}
2172 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
2173 
2174 end:
2175 	if (policy)
2176 		racoon_free(policy);
2177 
2178 	return 0;
2179 }
2180 
2181 static int
2182 pk_recvspdupdate(mhp)
2183 	caddr_t *mhp;
2184 {
2185 	struct sadb_address *saddr, *daddr;
2186 	struct sadb_x_policy *xpl;
2187  	struct sadb_lifetime *lt;
2188 	struct policyindex spidx;
2189 	struct secpolicy *sp;
2190  	u_int64_t created;
2191 
2192 	/* sanity check */
2193 	if (mhp[0] == NULL
2194 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2195 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2196 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
2197 		plog(LLV_ERROR, LOCATION, NULL,
2198 			"inappropriate sadb spdupdate message passed.\n");
2199 		return -1;
2200 	}
2201 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2202 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2203 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2204 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2205 	if(lt != NULL)
2206 		created = lt->sadb_lifetime_addtime;
2207 	else
2208 		created = 0;
2209 
2210 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2211 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2212 			saddr + 1,
2213 			daddr + 1,
2214 			saddr->sadb_address_prefixlen,
2215 			daddr->sadb_address_prefixlen,
2216 			saddr->sadb_address_proto,
2217 			xpl->sadb_x_policy_priority,
2218 			created,
2219 			&spidx);
2220 #else
2221 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2222 			saddr + 1,
2223 			daddr + 1,
2224 			saddr->sadb_address_prefixlen,
2225 			daddr->sadb_address_prefixlen,
2226 			saddr->sadb_address_proto,
2227 			created,
2228 			&spidx);
2229 #endif
2230 
2231 #ifdef HAVE_SECCTX
2232 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2233 		struct sadb_x_sec_ctx *ctx;
2234 
2235 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2236 		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2237 		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2238 		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2239 		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2240 	}
2241 #endif /* HAVE_SECCTX */
2242 
2243 	sp = getsp(&spidx);
2244 	if (sp == NULL) {
2245 		plog(LLV_ERROR, LOCATION, NULL,
2246 			"such policy does not already exist: \"%s\"\n",
2247 			spidx2str(&spidx));
2248 	} else {
2249 		remsp(sp);
2250 		delsp(sp);
2251 	}
2252 
2253 	if (addnewsp(mhp) < 0)
2254 		return -1;
2255 
2256 	return 0;
2257 }
2258 
2259 /*
2260  * this function has to be used by responder side.
2261  */
2262 int
2263 pk_sendspdadd2(iph2)
2264 	struct ph2handle *iph2;
2265 {
2266 	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2267 	caddr_t policy = NULL;
2268 	int policylen = 0;
2269 	u_int64_t ltime, vtime;
2270 
2271 	ltime = iph2->approval->lifetime;
2272 	vtime = 0;
2273 
2274 	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2275 		plog(LLV_ERROR, LOCATION, NULL,
2276 			"getting sadb policy failed.\n");
2277 		return -1;
2278 	}
2279 
2280 	if (pfkey_send_spdadd2(
2281 			lcconf->sock_pfkey,
2282 			(struct sockaddr *)&spidx->src,
2283 			spidx->prefs,
2284 			(struct sockaddr *)&spidx->dst,
2285 			spidx->prefd,
2286 			spidx->ul_proto,
2287 			ltime, vtime,
2288 			policy, policylen, 0) < 0) {
2289 		plog(LLV_ERROR, LOCATION, NULL,
2290 			"libipsec failed send spdadd2 (%s)\n",
2291 			ipsec_strerror());
2292 		goto end;
2293 	}
2294 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
2295 
2296 end:
2297 	if (policy)
2298 		racoon_free(policy);
2299 
2300 	return 0;
2301 }
2302 
2303 static int
2304 pk_recvspdadd(mhp)
2305 	caddr_t *mhp;
2306 {
2307 	struct sadb_address *saddr, *daddr;
2308 	struct sadb_x_policy *xpl;
2309 	struct sadb_lifetime *lt;
2310 	struct policyindex spidx;
2311 	struct secpolicy *sp;
2312 	u_int64_t created;
2313 
2314 	/* sanity check */
2315 	if (mhp[0] == NULL
2316 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2317 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2318 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
2319 		plog(LLV_ERROR, LOCATION, NULL,
2320 			"inappropriate sadb spdadd message passed.\n");
2321 		return -1;
2322 	}
2323 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2324 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2325 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2326 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2327 	if(lt != NULL)
2328 		created = lt->sadb_lifetime_addtime;
2329 	else
2330 		created = 0;
2331 
2332 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2333 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2334 			saddr + 1,
2335 			daddr + 1,
2336 			saddr->sadb_address_prefixlen,
2337 			daddr->sadb_address_prefixlen,
2338 			saddr->sadb_address_proto,
2339 			xpl->sadb_x_policy_priority,
2340 			created,
2341 			&spidx);
2342 #else
2343 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2344 			saddr + 1,
2345 			daddr + 1,
2346 			saddr->sadb_address_prefixlen,
2347 			daddr->sadb_address_prefixlen,
2348 			saddr->sadb_address_proto,
2349 			created,
2350 			&spidx);
2351 #endif
2352 
2353 #ifdef HAVE_SECCTX
2354 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2355 		struct sadb_x_sec_ctx *ctx;
2356 
2357 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2358 		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2359 		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2360 		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2361 		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2362 	}
2363 #endif /* HAVE_SECCTX */
2364 
2365 	sp = getsp(&spidx);
2366 	if (sp != NULL) {
2367 		plog(LLV_ERROR, LOCATION, NULL,
2368 			"such policy already exists. "
2369 			"anyway replace it: %s\n",
2370 			spidx2str(&spidx));
2371 		remsp(sp);
2372 		delsp(sp);
2373 	}
2374 
2375 	if (addnewsp(mhp) < 0)
2376 		return -1;
2377 
2378 	return 0;
2379 }
2380 
2381 /*
2382  * this function has to be used by responder side.
2383  */
2384 int
2385 pk_sendspddelete(iph2)
2386 	struct ph2handle *iph2;
2387 {
2388 	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
2389 	caddr_t policy = NULL;
2390 	int policylen;
2391 
2392 	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2393 		plog(LLV_ERROR, LOCATION, NULL,
2394 			"getting sadb policy failed.\n");
2395 		return -1;
2396 	}
2397 
2398 	if (pfkey_send_spddelete(
2399 			lcconf->sock_pfkey,
2400 			(struct sockaddr *)&spidx->src,
2401 			spidx->prefs,
2402 			(struct sockaddr *)&spidx->dst,
2403 			spidx->prefd,
2404 			spidx->ul_proto,
2405 			policy, policylen, 0) < 0) {
2406 		plog(LLV_ERROR, LOCATION, NULL,
2407 			"libipsec failed send spddelete (%s)\n",
2408 			ipsec_strerror());
2409 		goto end;
2410 	}
2411 	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2412 
2413 end:
2414 	if (policy)
2415 		racoon_free(policy);
2416 
2417 	return 0;
2418 }
2419 
2420 static int
2421 pk_recvspddelete(mhp)
2422 	caddr_t *mhp;
2423 {
2424 	struct sadb_address *saddr, *daddr;
2425 	struct sadb_x_policy *xpl;
2426 	struct sadb_lifetime *lt;
2427 	struct policyindex spidx;
2428 	struct secpolicy *sp;
2429 	u_int64_t created;
2430 
2431 	/* sanity check */
2432 	if (mhp[0] == NULL
2433 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2434 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2435 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
2436 		plog(LLV_ERROR, LOCATION, NULL,
2437 			"inappropriate sadb spddelete message passed.\n");
2438 		return -1;
2439 	}
2440 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2441 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2442 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2443 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2444 	if(lt != NULL)
2445 		created = lt->sadb_lifetime_addtime;
2446 	else
2447 		created = 0;
2448 
2449 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2450 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2451 			saddr + 1,
2452 			daddr + 1,
2453 			saddr->sadb_address_prefixlen,
2454 			daddr->sadb_address_prefixlen,
2455 			saddr->sadb_address_proto,
2456 			xpl->sadb_x_policy_priority,
2457 			created,
2458 			&spidx);
2459 #else
2460 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2461 			saddr + 1,
2462 			daddr + 1,
2463 			saddr->sadb_address_prefixlen,
2464 			daddr->sadb_address_prefixlen,
2465 			saddr->sadb_address_proto,
2466 			created,
2467 			&spidx);
2468 #endif
2469 
2470 #ifdef HAVE_SECCTX
2471 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2472 		struct sadb_x_sec_ctx *ctx;
2473 
2474 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2475 		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2476 		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2477 		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2478 		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2479 	}
2480 #endif /* HAVE_SECCTX */
2481 
2482 	sp = getsp(&spidx);
2483 	if (sp == NULL) {
2484 		plog(LLV_ERROR, LOCATION, NULL,
2485 			"no policy found: %s\n",
2486 			spidx2str(&spidx));
2487 		return -1;
2488 	}
2489 
2490 	remsp(sp);
2491 	delsp(sp);
2492 
2493 	return 0;
2494 }
2495 
2496 static int
2497 pk_recvspdexpire(mhp)
2498 	caddr_t *mhp;
2499 {
2500 	struct sadb_address *saddr, *daddr;
2501 	struct sadb_x_policy *xpl;
2502 	struct sadb_lifetime *lt;
2503 	struct policyindex spidx;
2504 	struct secpolicy *sp;
2505 	u_int64_t created;
2506 
2507 	/* sanity check */
2508 	if (mhp[0] == NULL
2509 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2510 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2511 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
2512 		plog(LLV_ERROR, LOCATION, NULL,
2513 			"inappropriate sadb spdexpire message passed.\n");
2514 		return -1;
2515 	}
2516 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2517 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2518 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2519 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2520 	if(lt != NULL)
2521 		created = lt->sadb_lifetime_addtime;
2522 	else
2523 		created = 0;
2524 
2525 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2526 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2527 			saddr + 1,
2528 			daddr + 1,
2529 			saddr->sadb_address_prefixlen,
2530 			daddr->sadb_address_prefixlen,
2531 			saddr->sadb_address_proto,
2532 			xpl->sadb_x_policy_priority,
2533 			created,
2534 			&spidx);
2535 #else
2536 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2537 			saddr + 1,
2538 			daddr + 1,
2539 			saddr->sadb_address_prefixlen,
2540 			daddr->sadb_address_prefixlen,
2541 			saddr->sadb_address_proto,
2542 			created,
2543 			&spidx);
2544 #endif
2545 
2546 #ifdef HAVE_SECCTX
2547 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2548 		struct sadb_x_sec_ctx *ctx;
2549 
2550 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2551 		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2552 		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2553 		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2554 		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2555 	}
2556 #endif /* HAVE_SECCTX */
2557 
2558 	sp = getsp(&spidx);
2559 	if (sp == NULL) {
2560 		plog(LLV_ERROR, LOCATION, NULL,
2561 			"no policy found: %s\n",
2562 			spidx2str(&spidx));
2563 		return -1;
2564 	}
2565 
2566 	remsp(sp);
2567 	delsp(sp);
2568 
2569 	return 0;
2570 }
2571 
2572 static int
2573 pk_recvspdget(mhp)
2574 	caddr_t *mhp;
2575 {
2576 	/* sanity check */
2577 	if (mhp[0] == NULL) {
2578 		plog(LLV_ERROR, LOCATION, NULL,
2579 			"inappropriate sadb spdget message passed.\n");
2580 		return -1;
2581 	}
2582 
2583 	return 0;
2584 }
2585 
2586 static int
2587 pk_recvspddump(mhp)
2588 	caddr_t *mhp;
2589 {
2590 	struct sadb_msg *msg;
2591 	struct sadb_address *saddr, *daddr;
2592 	struct sadb_x_policy *xpl;
2593 	struct sadb_lifetime *lt;
2594 	struct policyindex spidx;
2595 	struct secpolicy *sp;
2596 	u_int64_t created;
2597 
2598 	/* sanity check */
2599 	if (mhp[0] == NULL) {
2600 		plog(LLV_ERROR, LOCATION, NULL,
2601 			"inappropriate sadb spddump message passed.\n");
2602 		return -1;
2603 	}
2604 	msg = (struct sadb_msg *)mhp[0];
2605 
2606 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2607 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2608 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2609 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2610 	if(lt != NULL)
2611 		created = lt->sadb_lifetime_addtime;
2612 	else
2613 		created = 0;
2614 
2615 	if (saddr == NULL || daddr == NULL || xpl == NULL) {
2616 		plog(LLV_ERROR, LOCATION, NULL,
2617 			"inappropriate sadb spddump message passed.\n");
2618 		return -1;
2619 	}
2620 
2621 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2622 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2623 			saddr + 1,
2624 			daddr + 1,
2625 			saddr->sadb_address_prefixlen,
2626 			daddr->sadb_address_prefixlen,
2627 			saddr->sadb_address_proto,
2628 			xpl->sadb_x_policy_priority,
2629 			created,
2630 			&spidx);
2631 #else
2632 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2633 			saddr + 1,
2634 			daddr + 1,
2635 			saddr->sadb_address_prefixlen,
2636 			daddr->sadb_address_prefixlen,
2637 			saddr->sadb_address_proto,
2638 			created,
2639 			&spidx);
2640 #endif
2641 
2642 #ifdef HAVE_SECCTX
2643 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
2644 		struct sadb_x_sec_ctx *ctx;
2645 
2646 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
2647 		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
2648 		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
2649 		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
2650 		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
2651 	}
2652 #endif /* HAVE_SECCTX */
2653 
2654 	sp = getsp(&spidx);
2655 	if (sp != NULL) {
2656 		plog(LLV_ERROR, LOCATION, NULL,
2657 			"such policy already exists. "
2658 			"anyway replace it: %s\n",
2659 			spidx2str(&spidx));
2660 		remsp(sp);
2661 		delsp(sp);
2662 	}
2663 
2664 	if (addnewsp(mhp) < 0)
2665 		return -1;
2666 
2667 	return 0;
2668 }
2669 
2670 static int
2671 pk_recvspdflush(mhp)
2672 	caddr_t *mhp;
2673 {
2674 	/* sanity check */
2675 	if (mhp[0] == NULL) {
2676 		plog(LLV_ERROR, LOCATION, NULL,
2677 			"inappropriate sadb spdflush message passed.\n");
2678 		return -1;
2679 	}
2680 
2681 	flushsp();
2682 
2683 	return 0;
2684 }
2685 
2686 /*
2687  * send error against acquire message to kenrel.
2688  */
2689 int
2690 pk_sendeacquire(iph2)
2691 	struct ph2handle *iph2;
2692 {
2693 	struct sadb_msg *newmsg;
2694 	int len;
2695 
2696 	len = sizeof(struct sadb_msg);
2697 	newmsg = racoon_calloc(1, len);
2698 	if (newmsg == NULL) {
2699 		plog(LLV_ERROR, LOCATION, NULL,
2700 			"failed to get buffer to send acquire.\n");
2701 		return -1;
2702 	}
2703 
2704 	memset(newmsg, 0, len);
2705 	newmsg->sadb_msg_version = PF_KEY_V2;
2706 	newmsg->sadb_msg_type = SADB_ACQUIRE;
2707 	newmsg->sadb_msg_errno = ENOENT;	/* XXX */
2708 	newmsg->sadb_msg_satype = iph2->satype;
2709 	newmsg->sadb_msg_len = PFKEY_UNIT64(len);
2710 	newmsg->sadb_msg_reserved = 0;
2711 	newmsg->sadb_msg_seq = iph2->seq;
2712 	newmsg->sadb_msg_pid = (u_int32_t)getpid();
2713 
2714 	/* send message */
2715 	len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
2716 
2717 	racoon_free(newmsg);
2718 
2719 	return 0;
2720 }
2721 
2722 /*
2723  * check if the algorithm is supported or not.
2724  * OUT	 0: ok
2725  *	-1: ng
2726  */
2727 int
2728 pk_checkalg(class, calg, keylen)
2729 	int class, calg, keylen;
2730 {
2731 	int sup, error;
2732 	u_int alg;
2733 	struct sadb_alg alg0;
2734 
2735 	switch (algclass2doi(class)) {
2736 	case IPSECDOI_PROTO_IPSEC_ESP:
2737 		sup = SADB_EXT_SUPPORTED_ENCRYPT;
2738 		break;
2739 	case IPSECDOI_ATTR_AUTH:
2740 		sup = SADB_EXT_SUPPORTED_AUTH;
2741 		break;
2742 	case IPSECDOI_PROTO_IPCOMP:
2743 		plog(LLV_DEBUG, LOCATION, NULL,
2744 			"compression algorithm can not be checked "
2745 			"because sadb message doesn't support it.\n");
2746 		return 0;
2747 	default:
2748 		plog(LLV_ERROR, LOCATION, NULL,
2749 			"invalid algorithm class.\n");
2750 		return -1;
2751 	}
2752 	alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
2753 	if (alg == ~0)
2754 		return -1;
2755 
2756 	if (keylen == 0) {
2757 		if (ipsec_get_keylen(sup, alg, &alg0)) {
2758 			plog(LLV_ERROR, LOCATION, NULL,
2759 				"%s.\n", ipsec_strerror());
2760 			return -1;
2761 		}
2762 		keylen = alg0.sadb_alg_minbits;
2763 	}
2764 
2765 	error = ipsec_check_keylen(sup, alg, keylen);
2766 	if (error)
2767 		plog(LLV_ERROR, LOCATION, NULL,
2768 			"%s.\n", ipsec_strerror());
2769 
2770 	return error;
2771 }
2772 
2773 /*
2774  * differences with pfkey_recv() in libipsec/pfkey.c:
2775  * - never performs busy wait loop.
2776  * - returns NULL and set *lenp to negative on fatal failures
2777  * - returns NULL and set *lenp to non-negative on non-fatal failures
2778  * - returns non-NULL on success
2779  */
2780 static struct sadb_msg *
2781 pk_recv(so, lenp)
2782 	int so;
2783 	int *lenp;
2784 {
2785 	struct sadb_msg buf, *newmsg;
2786 	int reallen;
2787 	int retry = 0;
2788 
2789 	*lenp = -1;
2790 	do
2791 	{
2792 	    plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
2793 	    *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
2794 	    retry++;
2795 	}
2796 	while (*lenp < 0 && errno == EAGAIN && retry < 3);
2797 
2798 	if (*lenp < 0)
2799 		return NULL;	/*fatal*/
2800 
2801 	else if (*lenp < sizeof(buf))
2802 		return NULL;
2803 
2804 	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
2805 	if (reallen < sizeof(buf)) {
2806 		*lenp = -1;
2807 		errno = EIO;
2808 		return NULL;    /*fatal*/
2809 	}
2810 	if ((newmsg = racoon_calloc(1, reallen)) == NULL)
2811 		return NULL;
2812 
2813 	*lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
2814 	if (*lenp < 0) {
2815 		racoon_free(newmsg);
2816 		return NULL;	/*fatal*/
2817 	} else if (*lenp != reallen) {
2818 		racoon_free(newmsg);
2819 		return NULL;
2820 	}
2821 
2822 	*lenp = recv(so, (caddr_t)newmsg, reallen, 0);
2823 	if (*lenp < 0) {
2824 		racoon_free(newmsg);
2825 		return NULL;	/*fatal*/
2826 	} else if (*lenp != reallen) {
2827 		racoon_free(newmsg);
2828 		return NULL;
2829 	}
2830 
2831 	return newmsg;
2832 }
2833 
2834 /* see handler.h */
2835 u_int32_t
2836 pk_getseq()
2837 {
2838 	return eay_random();
2839 }
2840 
2841 static int
2842 addnewsp(mhp)
2843 	caddr_t *mhp;
2844 {
2845 	struct secpolicy *new = NULL;
2846 	struct sadb_address *saddr, *daddr;
2847 	struct sadb_x_policy *xpl;
2848 	struct sadb_lifetime *lt;
2849 	u_int64_t created;
2850 
2851 	/* sanity check */
2852 	if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
2853 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2854 	 || mhp[SADB_X_EXT_POLICY] == NULL) {
2855 		plog(LLV_ERROR, LOCATION, NULL,
2856 			"inappropriate sadb spd management message passed.\n");
2857 		goto bad;
2858 	}
2859 
2860 	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2861 	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2862 	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2863 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2864 	if(lt != NULL)
2865 		created = lt->sadb_lifetime_addtime;
2866 	else
2867 		created = 0;
2868 	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
2869 	if(lt != NULL)
2870 		created = lt->sadb_lifetime_addtime;
2871 	else
2872 		created = 0;
2873 
2874 #ifdef __linux__
2875 	/* bsd skips over per-socket policies because there will be no
2876 	 * src and dst extensions in spddump messages. On Linux the only
2877 	 * way to achieve the same is check for policy id.
2878 	 */
2879 	if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
2880 #endif
2881 
2882 	new = newsp();
2883 	if (new == NULL) {
2884 		plog(LLV_ERROR, LOCATION, NULL,
2885 			"failed to allocate buffer\n");
2886 		goto bad;
2887 	}
2888 
2889 	new->spidx.dir = xpl->sadb_x_policy_dir;
2890 	new->id = xpl->sadb_x_policy_id;
2891 	new->policy = xpl->sadb_x_policy_type;
2892 	new->req = NULL;
2893 
2894 	/* check policy */
2895 	switch (xpl->sadb_x_policy_type) {
2896 	case IPSEC_POLICY_DISCARD:
2897 	case IPSEC_POLICY_NONE:
2898 	case IPSEC_POLICY_ENTRUST:
2899 	case IPSEC_POLICY_BYPASS:
2900 		break;
2901 
2902 	case IPSEC_POLICY_IPSEC:
2903 	    {
2904 		int tlen;
2905 		struct sadb_x_ipsecrequest *xisr;
2906 		struct ipsecrequest **p_isr = &new->req;
2907 
2908 		/* validity check */
2909 		if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
2910 			plog(LLV_ERROR, LOCATION, NULL,
2911 				"invalid msg length.\n");
2912 			goto bad;
2913 		}
2914 
2915 		tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
2916 		xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
2917 
2918 		while (tlen > 0) {
2919 
2920 			/* length check */
2921 			if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
2922 				plog(LLV_ERROR, LOCATION, NULL,
2923 					"invalid msg length.\n");
2924 				goto bad;
2925 			}
2926 
2927 			/* allocate request buffer */
2928 			*p_isr = newipsecreq();
2929 			if (*p_isr == NULL) {
2930 				plog(LLV_ERROR, LOCATION, NULL,
2931 					"failed to get new ipsecreq.\n");
2932 				goto bad;
2933 			}
2934 
2935 			/* set values */
2936 			(*p_isr)->next = NULL;
2937 
2938 			switch (xisr->sadb_x_ipsecrequest_proto) {
2939 			case IPPROTO_ESP:
2940 			case IPPROTO_AH:
2941 			case IPPROTO_IPCOMP:
2942 				break;
2943 			default:
2944 				plog(LLV_ERROR, LOCATION, NULL,
2945 					"invalid proto type: %u\n",
2946 					xisr->sadb_x_ipsecrequest_proto);
2947 				goto bad;
2948 			}
2949 			(*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
2950 
2951 			switch (xisr->sadb_x_ipsecrequest_mode) {
2952 			case IPSEC_MODE_TRANSPORT:
2953 			case IPSEC_MODE_TUNNEL:
2954 				break;
2955 			case IPSEC_MODE_ANY:
2956 			default:
2957 				plog(LLV_ERROR, LOCATION, NULL,
2958 					"invalid mode: %u\n",
2959 					xisr->sadb_x_ipsecrequest_mode);
2960 				goto bad;
2961 			}
2962 			(*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
2963 
2964 			switch (xisr->sadb_x_ipsecrequest_level) {
2965 			case IPSEC_LEVEL_DEFAULT:
2966 			case IPSEC_LEVEL_USE:
2967 			case IPSEC_LEVEL_REQUIRE:
2968 				break;
2969 			case IPSEC_LEVEL_UNIQUE:
2970 				(*p_isr)->saidx.reqid =
2971 					xisr->sadb_x_ipsecrequest_reqid;
2972 				break;
2973 
2974 			default:
2975 				plog(LLV_ERROR, LOCATION, NULL,
2976 					"invalid level: %u\n",
2977 					xisr->sadb_x_ipsecrequest_level);
2978 				goto bad;
2979 			}
2980 			(*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
2981 
2982 			/* set IP addresses if there */
2983 			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
2984 				struct sockaddr *paddr;
2985 
2986 				paddr = (struct sockaddr *)(xisr + 1);
2987 				bcopy(paddr, &(*p_isr)->saidx.src,
2988 					sysdep_sa_len(paddr));
2989 
2990 				paddr = (struct sockaddr *)((caddr_t)paddr
2991 							+ sysdep_sa_len(paddr));
2992 				bcopy(paddr, &(*p_isr)->saidx.dst,
2993 					sysdep_sa_len(paddr));
2994 			}
2995 
2996 			(*p_isr)->sp = new;
2997 
2998 			/* initialization for the next. */
2999 			p_isr = &(*p_isr)->next;
3000 			tlen -= xisr->sadb_x_ipsecrequest_len;
3001 
3002 			/* validity check */
3003 			if (tlen < 0) {
3004 				plog(LLV_ERROR, LOCATION, NULL,
3005 					"becoming tlen < 0\n");
3006 			}
3007 
3008 			xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
3009 			                 + xisr->sadb_x_ipsecrequest_len);
3010 		}
3011 	    }
3012 		break;
3013 	default:
3014 		plog(LLV_ERROR, LOCATION, NULL,
3015 			"invalid policy type.\n");
3016 		goto bad;
3017 	}
3018 
3019 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3020 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3021 			saddr + 1,
3022 			daddr + 1,
3023 			saddr->sadb_address_prefixlen,
3024 			daddr->sadb_address_prefixlen,
3025 			saddr->sadb_address_proto,
3026 			xpl->sadb_x_policy_priority,
3027 			created,
3028 			&new->spidx);
3029 #else
3030 	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3031 			saddr + 1,
3032 			daddr + 1,
3033 			saddr->sadb_address_prefixlen,
3034 			daddr->sadb_address_prefixlen,
3035 			saddr->sadb_address_proto,
3036 			created,
3037 			&new->spidx);
3038 #endif
3039 
3040 #ifdef HAVE_SECCTX
3041 	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
3042 		struct sadb_x_sec_ctx *ctx;
3043 
3044 		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
3045 		new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
3046 		new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
3047 		new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
3048 		memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
3049 	}
3050 #endif /* HAVE_SECCTX */
3051 
3052 	inssp(new);
3053 
3054 	return 0;
3055 bad:
3056 	if (new != NULL) {
3057 		if (new->req != NULL)
3058 			racoon_free(new->req);
3059 		racoon_free(new);
3060 	}
3061 	return -1;
3062 }
3063 
3064 /* proto/mode/src->dst spi */
3065 const char *
3066 sadbsecas2str(src, dst, proto, spi, mode)
3067 	struct sockaddr *src, *dst;
3068 	int proto;
3069 	u_int32_t spi;
3070 	int mode;
3071 {
3072 	static char buf[256];
3073 	u_int doi_proto, doi_mode = 0;
3074 	char *p;
3075 	int blen, i;
3076 
3077 	doi_proto = pfkey2ipsecdoi_proto(proto);
3078 	if (doi_proto == ~0)
3079 		return NULL;
3080 	if (mode) {
3081 		doi_mode = pfkey2ipsecdoi_mode(mode);
3082 		if (doi_mode == ~0)
3083 			return NULL;
3084 	}
3085 
3086 	blen = sizeof(buf) - 1;
3087 	p = buf;
3088 
3089 	i = snprintf(p, blen, "%s%s%s ",
3090 		s_ipsecdoi_proto(doi_proto),
3091 		mode ? "/" : "",
3092 		mode ? s_ipsecdoi_encmode(doi_mode) : "");
3093 	if (i < 0 || i >= blen)
3094 		return NULL;
3095 	p += i;
3096 	blen -= i;
3097 
3098 	i = snprintf(p, blen, "%s->", saddr2str(src));
3099 	if (i < 0 || i >= blen)
3100 		return NULL;
3101 	p += i;
3102 	blen -= i;
3103 
3104 	i = snprintf(p, blen, "%s ", saddr2str(dst));
3105 	if (i < 0 || i >= blen)
3106 		return NULL;
3107 	p += i;
3108 	blen -= i;
3109 
3110 	if (spi) {
3111 		snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3112 		    (unsigned long)ntohl(spi));
3113 	}
3114 
3115 	return buf;
3116 }
3117