1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: pfkey.c,v 1.18.4.5 2008/03/05 22:14:24 mgrooms Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* $Id: pfkey.c,v 1.18.4.5 2008/03/05 22:14:24 mgrooms Exp $ */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
8c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
20c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_UNISTD_H
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h>
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/inet.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# ifdef __linux__
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <linux/udp.h>
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  (defined(__APPLE__) && defined(__MACH__))
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/udp.h>
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/queue.h>
62458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#ifndef ANDROID_CHANGES
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/sysctl.h>
64458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#endif
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <net/route.h>
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <net/pfkeyv2.h>
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include PATH_IPSEC_H
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <fcntl.h>
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "libpfkey.h"
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h"
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h"
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "proposal.h"
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_inf.h"
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h"
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "pfkey.h"
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "algorithm.h"
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sainfo.h"
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h"
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "privsep.h"
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h"
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "backupsa.h"
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "nattraversal.h"
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "grabmyaddr.h"
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_EALG_AESCBC  SADB_X_EALG_RIJNDAELCBC
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* prototype */
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int ipsecdoi2pfkey_aalg __P((u_int));
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int ipsecdoi2pfkey_ealg __P((u_int));
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int ipsecdoi2pfkey_calg __P((u_int));
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int ipsecdoi2pfkey_alg __P((u_int, u_int));
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int keylen_aalg __P((u_int));
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int keylen_ealg __P((u_int, int));
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvgetspi __P((caddr_t *));
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvupdate __P((caddr_t *));
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvadd __P((caddr_t *));
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvdelete __P((caddr_t *));
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvacquire __P((caddr_t *));
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvexpire __P((caddr_t *));
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvflush __P((caddr_t *));
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *));
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspdupdate __P((caddr_t *));
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspdadd __P((caddr_t *));
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspddelete __P((caddr_t *));
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspdexpire __P((caddr_t *));
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspdget __P((caddr_t *));
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspddump __P((caddr_t *));
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int pk_recvspdflush __P((caddr_t *));
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct sadb_msg *pk_recv __P((int, int *));
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*pkrecvf[]) __P((caddr_t *)) = {
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvgetspi,
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvupdate,
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvadd,
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvdelete,
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_GET */
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvacquire,
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SABD_REGISTER */
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvexpire,
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvflush,
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_DUMP */
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_PROMISC */
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_PCHANGE */
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdupdate,
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdadd,
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddelete,
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdget,
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_SPDACQUIRE */
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddump,
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdflush,
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_SPDSETIDX */
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdexpire,
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_SPDDELETE2 */
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_NAT_T_NEW_MAPPING */
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangNULL,	/* SADB_X_MIGRATE */
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (SADB_MAX > 24)
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#error "SADB extra message?"
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
165c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int addnewsp __P((caddr_t *));
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* cope with old kame headers - ugly */
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_AALG_MD5
169c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define SADB_X_AALG_MD5		SADB_AALG_MD5
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_AALG_SHA
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_AALG_SHA		SADB_AALG_SHA
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_AALG_NULL
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_AALG_NULL	SADB_AALG_NULL
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_EALG_BLOWFISHCBC
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_EALG_BLOWFISHCBC	SADB_EALG_BLOWFISHCBC
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_EALG_CAST128CBC
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_EALG_CAST128CBC	SADB_EALG_CAST128CBC
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef SADB_X_EALG_RC5CBC
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_EALG_RC5CBC
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define SADB_X_EALG_RC5CBC	SADB_EALG_RC5CBC
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * PF_KEY packet handler
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: success
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: fail
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
195c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehpfkey_handler()
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t mhp[SADB_EXT_MAX + 1];
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* receive pfkey message. */
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = 0;
205c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg == NULL) {
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len < 0) {
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to recv from pfkey (%s)\n",
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror(errno));
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* short message - msg not ready */
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
218c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_pfkey_type(msg->sadb_msg_type));
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* validity check */
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_errno) {
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int pri;
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* when SPD is empty, treat the state as no error. */
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    msg->sadb_msg_errno == ENOENT)
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pri = LLV_DEBUG;
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pri = LLV_ERROR;
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL,
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pfkey %s failed: %s\n",
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror(msg->sadb_msg_errno));
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check pfkey message. */
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_align(msg, mhp)) {
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed pfkey align (%s)\n",
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_check(mhp)) {
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed pfkey check (%s)\n",
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* safety check */
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unknown PF_KEY message type=%u\n",
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_type);
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pkrecvf[msg->sadb_msg_type] == NULL) {
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported PF_KEY message %s\n",
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
274c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	error = 0;
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg)
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(msg);
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return(error);
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * dump SADB
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_dump_sadb(satype)
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int satype;
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
288c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int s = -1;
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL;
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pid_t pid = getpid();
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg = NULL;
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t bl, ml;
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
295c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if ((s = privsep_pfkey_open()) < 0) {
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed pfkey open: %s\n",
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_dump(s, satype) < 0) {
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed dump: %s\n", ipsec_strerror());
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto fail;
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (1) {
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg)
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(msg);
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		msg = pk_recv(s, &len);
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg == NULL) {
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (len < 0)
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto done;
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				continue;
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg->sadb_msg_type != SADB_DUMP || msg->sadb_msg_pid != pid)
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    plog(LLV_DEBUG, LOCATION, NULL,
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "discarding non-sadb dump msg %p, our pid=%i\n", msg, pid);
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    plog(LLV_DEBUG, LOCATION, NULL,
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 "type %i, pid %i\n", msg->sadb_msg_type, msg->sadb_msg_pid);
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    continue;
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
328c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ml = msg->sadb_msg_len << 3;
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bl = buf ? buf->l : 0;
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		buf = vrealloc(buf, bl + ml);
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf == NULL) {
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to reallocate buffer to dump.\n");
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto fail;
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(buf->v + bl, msg, ml);
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (msg->sadb_msg_seq == 0)
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	goto done;
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfail:
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	buf = NULL;
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdone:
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg)
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(msg);
352c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (s >= 0)
353c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		privsep_pfkey_close(s);
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_ADMINPORT
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * flush SADB
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_flush_sadb(proto)
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto;
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int satype;
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* convert to SADB_SATYPE */
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((satype = admin2pfkey_proto(proto)) < 0)
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send flush (%s)\n", ipsec_strerror());
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * These are the SATYPEs that we manage.  We register to get
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * PF_KEY messages related to these SATYPEs, and we also use
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this list to determine which SATYPEs to delete SAs for when
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * we receive an INITIAL-CONTACT.
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst struct pfkey_satype pfkey_satypes[] = {
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{ SADB_SATYPE_AH,	"AH" },
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{ SADB_SATYPE_ESP,	"ESP" },
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{ SADB_X_SATYPE_IPCOMP,	"IPCOMP" },
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst int pfkey_nsatypes =
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * PF_KEY initialization
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_init()
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i, reg_fail;
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
404c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if ((lcconf->sock_pfkey = privsep_pfkey_open()) < 0) {
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed pfkey open (%s)\n", ipsec_strerror());
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (fcntl(lcconf->sock_pfkey, F_SETFL, O_NONBLOCK) == -1)
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "failed to set the pfkey socket to NONBLOCK\n");
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "call pfkey_send_register for %s\n",
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pfkey_satypes[i].ps_name);
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_send_register(lcconf->sock_pfkey,
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pfkey_satypes[i].ps_satype) < 0 ||
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pfkey_recv_register(lcconf->sock_pfkey) < 0) {
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "failed to register %s (%s)\n",
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pfkey_satypes[i].ps_name,
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ipsec_strerror());
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reg_fail++;
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (reg_fail == pfkey_nsatypes) {
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to regist any protocol.\n");
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pfkey_close(lcconf->sock_pfkey);
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	initsp();
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec sending spddump failed: %s\n",
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pfkey_close(lcconf->sock_pfkey);
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_promisc_toggle(1) < 0) {
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pfkey_close(lcconf->sock_pfkey);
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% for conversion */
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPSECDOI_ATTR_AUTH -> SADB_AALG */
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_aalg(hashtype)
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int hashtype;
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (hashtype) {
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_MD5:
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_AALG_MD5HMAC;
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_AALG_SHA1HMAC;
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_256;
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_256HMAC;
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_384;
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_384HMAC;
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_512;
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_AALG_SHA2_512HMAC;
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_KPDK:		/* need special care */
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_AALG_NONE;
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not supported */
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_DES_MAC:
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Not supported hash type: %u\n", hashtype);
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0: /* reserved */
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_AALG_NONE;
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid hash type: %u\n", hashtype);
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPSECDOI_ESP -> SADB_EALG */
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_ealg(t_id)
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int t_id;
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV64:		/* sa_flags |= SADB_X_EXT_OLD */
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_EALG_DESCBC;
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES:
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_EALG_DESCBC;
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3DES:
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_EALG_3DESCBC;
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EALG_RC5CBC
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC5:
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_RC5CBC;
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAST:
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_CAST128CBC;
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_BLOWFISH:
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_BLOWFISHCBC;
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV32:	/* flags |= (SADB_X_EXT_OLD|
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							SADB_X_EXT_IV4B)*/
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_EALG_DESCBC;
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_NULL:
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_EALG_NULL;
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EALG_AESCBC
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_AES:
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_AESCBC;
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EALG_TWOFISHCBC
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_TWOFISH:
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_TWOFISHCBC;
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EALG_CAMELLIACBC
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAMELLIA:
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_EALG_CAMELLIACBC;
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not supported */
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3IDEA:
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_IDEA:
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC4:
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Not supported transform: %u\n", t_id);
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0: /* reserved */
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid transform id: %u\n", t_id);
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPCOMP -> SADB_CALG */
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_calg(t_id)
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int t_id;
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_OUI:
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_CALG_OUI;
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_DEFLATE:
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_CALG_DEFLATE;
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_LZS:
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_CALG_LZS;
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0: /* reserved */
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid transform id: %u\n", t_id);
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPSECDOI_PROTO -> SADB_SATYPE */
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_proto(proto)
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto;
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_SATYPE_AH;
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_SATYPE_ESP;
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_X_SATYPE_IPCOMP;
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid ipsec_doi proto: %u\n", proto);
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_alg(algclass, type)
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int algclass, type;
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (algclass) {
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH:
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ipsecdoi2pfkey_aalg(type);
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ipsecdoi2pfkey_ealg(type);
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ipsecdoi2pfkey_calg(type);
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid ipsec_doi algclass: %u\n", algclass);
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* SADB_SATYPE -> IPSECDOI_PROTO */
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey2ipsecdoi_proto(satype)
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int satype;
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (satype) {
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case SADB_SATYPE_AH:
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_AH;
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case SADB_SATYPE_ESP:
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_ESP;
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case SADB_X_SATYPE_IPCOMP:
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPCOMP;
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid pfkey proto: %u\n", satype);
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi2pfkey_mode(mode)
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int mode;
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (mode) {
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSEC_MODE_TUNNEL;
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_TRNS:
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSEC_MODE_TRANSPORT;
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey2ipsecdoi_mode(mode)
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int mode;
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (mode) {
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_MODE_TUNNEL:
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_MODE_TRANSPORT:
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_ATTR_ENC_MODE_TRNS;
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_MODE_ANY:
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_ATTR_ENC_MODE_ANY;
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* default key length for encryption algorithm */
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangkeylen_aalg(hashtype)
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int hashtype;
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (hashtype == 0)
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return SADB_AALG_NONE;
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = alg_ipsec_hmacdef_hashlen(hashtype);
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res == -1) {
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid hmac algorithm %u.\n", hashtype);
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* default key length for encryption algorithm */
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangkeylen_ealg(enctype, encklen)
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int enctype;
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int encklen;
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = alg_ipsec_encdef_keylen(enctype, encklen);
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res == -1) {
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid encryption algorithm %u.\n", enctype);
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ~0;
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		e_type, e_keylen, a_type, a_keylen, flags)
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id;
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int t_id;
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int hashtype;
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int *e_type;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int *e_keylen;
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int *a_type;
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int *a_keylen;
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int *flags;
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*flags = 0;
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*e_keylen >>= 3;
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*a_keylen >>= 3;
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*e_type == SADB_EALG_NONE) {
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*a_keylen >>= 3;
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
760c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*a_type = SADB_X_AALG_MD5;
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*flags |= SADB_X_EXT_OLD;
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*e_type = SADB_EALG_NONE;
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*e_keylen = 0;
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*a_type == SADB_AALG_NONE) {
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*e_keylen = 0;
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*flags = SADB_X_EXT_RAWCPI;
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*a_type = SADB_AALG_NONE;
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*a_keylen = 0;
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*e_type == SADB_X_CALG_NONE) {
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    bad:
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	errno = EINVAL;
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
801c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* called from scheduler */
802c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
803c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehpfkey_timeover_stub(p)
804c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *p;
805c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
806c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
807c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	pfkey_timeover((struct ph2handle *)p);
808c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
809c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
810c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehvoid
811c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehpfkey_timeover(iph2)
812c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ph2handle *iph2;
813c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
814c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_ERROR, LOCATION, NULL,
815c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		"%s give up to get IPsec-SA due to time up to wait.\n",
816c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddrwop2str(iph2->dst));
817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->sce);
818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
819c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
820c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->side == INITIATOR)
821c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		pk_sendeacquire(iph2);
822c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
823c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	unbindph12(iph2);
824c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	remph2(iph2);
825c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	delph2(iph2);
826c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
827c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
828c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
829c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* send getspi message per ipsec protocol per remote address */
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the local address and remote address in ph1handle are dealed
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * with destination address and source address respectively.
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Because SPI is decided by responder.
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendgetspi(iph2)
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src = NULL, *dst = NULL;
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int satype, mode;
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t minspi, maxspi;
846c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int proxy = 0;
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
848c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->side == INITIATOR) {
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp = iph2->proposal;
850c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		proxy = iph2->ph1->rmconf->support_proxy;
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
852c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		pp = iph2->approval;
853c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph2->sainfo && iph2->sainfo->id_i)
854c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			proxy = 1;
855f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	}
856f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
857c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* for mobile IPv6 */
858c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (proxy && iph2->src_id && iph2->dst_id &&
859c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    ipsecdoi_transportmode(pp)) {
860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		src = iph2->src_id;
861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		dst = iph2->dst_id;
862c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	} else {
863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		src = iph2->src;
864c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		dst = iph2->dst;
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = pp->head; pr != NULL; pr = pr->next) {
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		satype = ipsecdoi2pfkey_proto(pr->proto_id);
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (satype == ~0) {
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* this works around a bug in Linux kernel where it allocates 4 byte
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		   spi's for IPCOMP */
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else if (satype == SADB_X_SATYPE_IPCOMP) {
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			minspi = 0x100;
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			maxspi = 0xffff;
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else {
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			minspi = 0;
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			maxspi = 0;
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode = ipsecdoi2pfkey_mode(pr->encmode);
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (mode == ~0) {
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
894c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* XXX should we do a copy of src/dst for each pr ?
895c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 */
896c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (! pr->udp_encap) {
897c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* Remove port information, that SA doesn't use it */
898c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(src, 0);
899c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(dst, 0);
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
903c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (pfkey_send_getspi(
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lcconf->sock_pfkey,
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				satype,
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				mode,
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				dst,			/* src of SA */
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				src,			/* dst of SA */
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				minspi, maxspi,
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->reqid_in, iph2->seq) < 0) {
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ipseclib failed send getspi (%s)\n",
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ipsec_strerror());
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pfkey GETSPI sent: %s\n",
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(dst, src, satype, 0, mode));
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * receive GETSPI from kernel.
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
928c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehpk_recvgetspi(mhp)
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
934c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr *dst;
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int allspiok, notfound;
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* validity check */
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_EXT_SA] == NULL
942c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb getspi message passed.\n");
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid != getpid()) {
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because pid %d is not mine.\n",
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_pid);
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2byseq(msg->sadb_msg_seq);
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seq %d of %s message not interesting.\n",
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_seq,
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status != PHASE2ST_GETSPISENT) {
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"status mismatch (db:%d msg:%d)\n",
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->status, PHASE2ST_GETSPISENT);
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set SPI, and check to get all spi whether or not */
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	allspiok = 1;
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	notfound = 1;
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = pp->head; pr != NULL; pr = pr->next) {
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->proto_id == proto_id && pr->spi == 0) {
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr->spi = sa->sadb_sa_spi;
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			notfound = 0;
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfkey GETSPI succeeded: %s\n",
989c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sadbsecas2str(iph2->dst, iph2->src,
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    msg->sadb_msg_satype,
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa->sadb_sa_spi,
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    ipsecdoi2pfkey_mode(pr->encmode)));
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->spi == 0)
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			allspiok = 0;	/* not get all spi */
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (notfound) {
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"get spi for unknown address %s\n",
1001c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			saddrwop2str(iph2->dst));
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (allspiok) {
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* update status */
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->status = PHASE2ST_GETSPIDONE;
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_post_getspi(iph2) < 0) {
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to start post getspi.\n");
1011c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			unbindph12(iph2);
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2 = NULL;
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set inbound SA
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendupdate(iph2)
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct pfkey_send_sa_args sa_args;
1031c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int proxy = 0;
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->approval == NULL) {
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no approvaled SAs found.\n");
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1039c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->side == INITIATOR)
1040c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		proxy = iph2->ph1->rmconf->support_proxy;
1041c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	else if (iph2->sainfo && iph2->sainfo->id_i)
1042c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		proxy = 1;
1043c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* fill in some needed for pfkey_send_update2 */
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset (&sa_args, 0, sizeof (sa_args));
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.so = lcconf->sock_pfkey;
1047c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sa_args.l_addtime = iph2->approval->lifetime;
1048c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sa_args.seq = iph2->seq;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.wsize = 4;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1051c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* for mobile IPv6 */
1052c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (proxy && iph2->src_id && iph2->dst_id &&
1053c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    ipsecdoi_transportmode(iph2->approval)) {
1054c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.dst = iph2->src_id;
1055c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.src = iph2->dst_id;
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
1057c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.dst = iph2->src;
1058c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.src = iph2->dst;
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.satype == ~0) {
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* IPCOMP has no replay window */
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.wsize = 0;
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_SAMODE_UNSPECIFIED
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = IPSEC_MODE_ANY;
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.mode == ~0) {
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set algorithm type and key length */
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.e_keylen = pr->head->encklen;
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_convertfromipsecdoi(
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->proto_id,
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->trns_id,
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->authtype,
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.e_type, &sa_args.e_keylen,
1090c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				&sa_args.a_type, &sa_args.a_keylen,
1091c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				&sa_args.flags) < 0)
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = 0;
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*iph2->approval->sctx.ctx_str) {
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstr = iph2->approval->sctx.ctx_str;
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->udp_encap) {
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
1112c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
1113c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sa_args.l_natt_dport = extract_port (iph2->ph1->local);
1114c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sa_args.l_natt_oa = NULL;  // FIXME: Here comes OA!!!
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EXT_NAT_T_FRAG
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1118c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		} else {
1119c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* Remove port information, that SA doesn't use it */
1120c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(sa_args.src, 0);
1121c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(sa_args.dst, 0);
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1123f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1124c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* more info to fill in */
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.spi = pr->spi;
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.reqid = pr->reqid_in;
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.keymat = pr->keymat->v;
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update2\n");
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_send_update2(&sa_args) < 0) {
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"libipsec failed send update (%s)\n",
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ipsec_strerror());
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1138837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#ifndef ANDROID_PATCHED
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * It maybe good idea to call backupsa_to_file() after
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * racoon will receive the sadb_update messages.
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * But it is impossible because there is not key in the
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * information from the kernel.
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
1148c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* change some things before backing up */
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.wsize = 4;
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = iph2->approval->lifebyte * 1024;
1152c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (backupsa_to_file(&sa_args) < 0) {
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"backuped SA failed: %s\n",
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(sa_args.src, sa_args.dst,
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa_args.satype, sa_args.spi, sa_args.mode));
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"backuped SA: %s\n",
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(sa_args.src, sa_args.dst,
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.satype, sa_args.spi, sa_args.mode));
1163837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#endif
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvupdate(mhp)
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id, encmode, sa_mode;
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int incomplete = 0;
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb update message passed.\n");
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid != getpid()) {
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because pid %d is not mine.\n",
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_pid);
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2byseq(msg->sadb_msg_seq);
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seq %d of %s message not interesting.\n",
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_seq,
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status != PHASE2ST_ADDSA) {
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"status mismatch (db:%d msg:%d)\n",
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->status, PHASE2ST_ADDSA);
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check to complete all keys ? */
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (proto_id == ~0) {
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", msg->sadb_msg_satype);
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		encmode = pfkey2ipsecdoi_mode(sa_mode);
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (encmode == ~0) {
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", sa_mode);
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->proto_id == proto_id
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 && pr->spi == sa->sadb_sa_spi) {
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr->ok = 1;
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfkey UPDATE succeeded: %s\n",
1249c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sadbsecas2str(iph2->dst, iph2->src,
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    msg->sadb_msg_satype,
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa->sadb_sa_spi,
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa_mode));
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"IPsec-SA established: %s\n",
1256c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sadbsecas2str(iph2->dst, iph2->src,
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg->sadb_msg_satype, sa->sadb_sa_spi,
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sa_mode));
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->ok == 0)
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			incomplete = 1;
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (incomplete)
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off the timer for calling pfkey_timeover() */
1269c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->sce);
1270c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update status */
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_ESTABLISHED;
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph2->end, NULL);
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2", "quick", timedelta(&iph2->start, &iph2->end));
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1280c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* count up */
1281c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->ph1->ph2cnt++;
1282c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
1284c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->scr);
1285c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1286c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* Force the update of ph2's ports, as there is at least one
1287c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * situation where they'll mismatch with ph1's values
1288c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 */
1289c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1290c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_NATT
1291c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	set_port(iph2->src, extract_port(iph2->ph1->local));
1292c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	set_port(iph2->dst, extract_port(iph2->ph1->remote));
1293c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * since we are going to reuse the phase2 handler, we need to
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * remain it and refresh all the references between ph1 and ph2 to use.
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1299c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	unbindph12(iph2);
1300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1301c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->sce = sched_new(iph2->approval->lifetime,
1302c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    isakmp_ph2expire_stub, iph2);
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set outbound SA
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendadd(iph2)
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
1316c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int proxy = 0;
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct pfkey_send_sa_args sa_args;
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->approval == NULL) {
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no approvaled SAs found.\n");
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1326c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->side == INITIATOR)
1327c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		proxy = iph2->ph1->rmconf->support_proxy;
1328c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	else if (iph2->sainfo && iph2->sainfo->id_i)
1329c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		proxy = 1;
1330c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* fill in some needed for pfkey_send_update2 */
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset (&sa_args, 0, sizeof (sa_args));
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.so = lcconf->sock_pfkey;
1334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sa_args.l_addtime = iph2->approval->lifetime;
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.seq = iph2->seq;
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.wsize = 4;
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1338c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* for mobile IPv6 */
1339c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (proxy && iph2->src_id && iph2->dst_id &&
1340c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    ipsecdoi_transportmode(iph2->approval)) {
1341c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.src = iph2->src_id;
1342c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.dst = iph2->dst_id;
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
1344c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.src = iph2->src;
1345c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa_args.dst = iph2->dst;
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.satype == ~0) {
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* no replay window for IPCOMP */
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.wsize = 0;
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_SAMODE_UNSPECIFIED
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = IPSEC_MODE_ANY;
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.mode == ~0) {
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set algorithm type and key length */
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.e_keylen = pr->head->encklen;
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_convertfromipsecdoi(
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->proto_id,
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->trns_id,
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->authtype,
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.e_type, &sa_args.e_keylen,
1378c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				&sa_args.a_type, &sa_args.a_keylen,
1379c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				&sa_args.flags) < 0)
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = 0;
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*iph2->approval->sctx.ctx_str) {
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstr = iph2->approval->sctx.ctx_str;
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "(NAT flavor)\n");
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->udp_encap) {
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_sport = extract_port(iph2->ph1->local);
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
1405c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sa_args.l_natt_oa = NULL; // FIXME: Here comes OA!!!
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EXT_NAT_T_FRAG
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1409c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		} else {
1410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* Remove port information, that SA doesn't use it */
1411c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(sa_args.src, 0);
1412c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			set_port(sa_args.dst, 0);
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1414c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1415c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
1416c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* Remove port information, it is not used without NAT-T */
1417c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		set_port(sa_args.src, 0);
1418c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		set_port(sa_args.dst, 0);
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* more info to fill in */
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.spi = pr->spi_p;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.reqid = pr->reqid_out;
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.keymat = pr->keymat_p->v;
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_send_add2(&sa_args) < 0) {
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"libipsec failed send add (%s)\n",
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ipsec_strerror());
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1434837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#ifndef ANDROID_PATCHED
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * It maybe good idea to call backupsa_to_file() after
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * racoon will receive the sadb_update messages.
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * But it is impossible because there is not key in the
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * information from the kernel.
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (backupsa_to_file(&sa_args) < 0) {
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"backuped SA failed: %s\n",
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(sa_args.src, sa_args.dst,
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa_args.satype, sa_args.spi, sa_args.mode));
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"backuped SA: %s\n",
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(sa_args.src, sa_args.dst,
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.satype, sa_args.spi, sa_args.mode));
1454837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#endif
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvadd(mhp)
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int sa_mode;
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb add message passed.\n");
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid != getpid()) {
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because pid %d is not mine.\n",
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_pid);
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2byseq(msg->sadb_msg_seq);
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seq %d of %s message not interesting.\n",
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_seq,
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE don't update any status of phase2 handle
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because they must be updated by SADB_UPDATE message
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"IPsec-SA established: %s\n",
1517c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sadbsecas2str(iph2->src, iph2->dst,
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvexpire(mhp)
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id, sa_mode;
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	  && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb expire message passed.\n");
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == ~0) {
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proto_id %d\n", msg->sadb_msg_satype);
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"IPsec-SA expired: %s\n",
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sadbsecas2str(src, dst,
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Ignore it because two expire messages are come up.
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * phase2 handler has been deleted already when 2nd message
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * is received.
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no such a SA found: %s\n",
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(src, dst,
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    msg->sadb_msg_satype, sa->sadb_sa_spi,
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    sa_mode));
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1580c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->status != PHASE2ST_ESTABLISHED) {
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
1582c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * If the status is not equal to PHASE2ST_ESTABLISHED,
1583c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * racoon ignores this expire message.  There are two reason.
1584c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * One is that the phase 2 probably starts because there is
1585c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * a potential that racoon receives the acquire message
1586c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * without receiving a expire message.  Another is that racoon
1587c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * may receive the multiple expire messages from the kernel.
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
1590c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"the expire message is received "
1591c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"but the handler has not been established.\n");
1592c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return 0;
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1595c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* turn off the timer for calling isakmp_ph2expire() */
1596c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->sce);
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1598c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->status = PHASE2ST_EXPIRED;
1599c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1600c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* INITIATOR, begin phase 2 exchange. */
1601c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* allocate buffer for status management of pfkey message */
1602c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2->side == INITIATOR) {
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1604f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		initph2(iph2);
1605c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1606c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* update status for re-use */
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->status = PHASE2ST_STATUS2;
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1609c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* start isakmp initiation by using ident exchange */
1610c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (isakmp_post_acquire(iph2) < 0) {
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph2->dst,
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to begin ipsec sa "
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"re-negotication.\n");
1614c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			unbindph12(iph2);
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
1621c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/*NOTREACHED*/
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1624c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1625c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* RESPONDER always delete ph2handle, keep silent.  RESPONDER doesn't
1626c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * manage IPsec SA, so delete the list */
1627c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	unbindph12(iph2);
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvacquire(mhp)
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp_out = NULL, *sp_in = NULL;
1641c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define MAXNESTEDSA	5	/* XXX */
1642c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ph2handle *iph2[MAXNESTEDSA];
1643c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr *src, *dst;
1644c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int n;	/* # of phase 2 handler */
1645c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int remoteid=0;
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_sec_ctx *m_sec_ctx;
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1651c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb acquire message passed.\n");
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1667c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1668c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx != NULL) {
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_doi);
1676c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_INFO, LOCATION, NULL,
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "security context algorithm: %u\n",
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_alg);
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_len);
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore if type is not IPSEC_POLICY_IPSEC */
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore ACQUIRE message. type is not IPsec.\n");
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1693c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* ignore it if src is multicast address */
1694c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    {
1695c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1697c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if ((sa->sa_family == AF_INET
1698c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
1700c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 || (sa->sa_family == AF_INET6
1701c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	) {
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
1705c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"ignore due to multicast address: %s.\n",
1706c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			saddrwop2str(sa));
17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1709c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    }
1710c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1711c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    	/* ignore, if we do not listen on source address */
1712c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	{
1713c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* reasons behind:
1714c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * - if we'll contact peer from address we do not listen -
1715c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 *   we will be unable to complete negotiation;
1716c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * - if we'll negotiate using address we're listening -
1717c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 *   remote peer will send packets to address different
1718c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 *   than one in the policy, so kernel will drop them;
1719c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * => therefore this acquire is not for us! --Aidas
1720c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 */
1721c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1722c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct myaddrs *p;
1723c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		int do_listen = 0;
1724c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		for (p = lcconf->myaddrs; p; p = p->next) {
1725c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (!cmpsaddrwop(p->addr, sa)) {
1726c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				do_listen = 1;
1727c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
1728c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
1729c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1731c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (!do_listen) {
1732c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_DEBUG, LOCATION, NULL,
1733c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"ignore because do not listen on source address : %s.\n",
1734c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				saddrwop2str(sa));
1735c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return 0;
1736c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If there is a phase 2 handler against the policy identifier in
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * the acquire message, and if
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *    1. its state is less than PHASE2ST_ESTABLISHED, then racoon
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       should ignore such a acquire message because the phase 2
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       is just negotiating.
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *    2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       has to prcesss such a acquire message because racoon may
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       lost the expire message.
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1749c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
1750c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2[0] != NULL) {
1751c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ignore the acquire because ph2 found\n");
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
1756c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph2[0]->status == PHASE2ST_EXPIRED)
1757c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph2[0] = NULL;
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1761c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* search for proper policyindex */
1762c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	sp_out = getspbyspid(xpl->sadb_x_policy_id);
1763c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (sp_out == NULL) {
1764c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1765c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			xpl->sadb_x_policy_id);
1766c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1768c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
1769c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		"suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get inbound policy */
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&spidx, 0, sizeof(spidx));
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_INBOUND;
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefs = sp_out->spidx.prefd;
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefd = sp_out->spidx.prefs;
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.ul_proto = sp_out->spidx.ul_proto;
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx) {
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str,
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		      ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		      spidx.sec_ctx.ctx_strlen);
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_in = getsp(&spidx);
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp_in) {
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"suitable inbound SP found: %s.\n",
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp_in->spidx));
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_NOTIFY, LOCATION, NULL,
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no in-bound policy found: %s\n",
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1805c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	memset(iph2, 0, MAXNESTEDSA);
1806c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1807c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	n = 0;
1808c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate a phase 2 */
1810c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n] = newph2();
1811c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2[n] == NULL) {
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate phase2 entry.\n");
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1816c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->side = INITIATOR;
1817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->spid = xpl->sadb_x_policy_id;
1818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->satype = msg->sadb_msg_satype;
1819c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->seq = msg->sadb_msg_seq;
1820c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->status = PHASE2ST_STATUS2;
1821c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1822c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* set end addresses of SA */
1823c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->dst = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
1824c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2[n]->dst == NULL) {
1825c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1828c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->src = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
1829c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2[n]->src == NULL) {
1830c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1834c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
1835c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		"new acquire %s\n", spidx2str(&sp_out->spidx));
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1837c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* get sainfo */
1838c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    {
1839c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *idsrc, *iddst;
1840c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1841c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
1842c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sp_out->spidx.prefs, sp_out->spidx.ul_proto);
1843c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (idsrc == NULL) {
1844c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
1845c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to get ID for %s\n",
1846c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx2str(&sp_out->spidx));
1847c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
1848c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
1849c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1850c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
1851c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sp_out->spidx.prefd, sp_out->spidx.ul_proto);
1852c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iddst == NULL) {
1853c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
1854c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to get ID for %s\n",
1855c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			spidx2str(&sp_out->spidx));
1856c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		vfree(idsrc);
1857c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
1858c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
1859c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	{
1861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct remoteconf *conf;
1862c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		conf = getrmconf(iph2[n]->dst);
1863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (conf != NULL)
1864c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			remoteid=conf->ph1id;
1865c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		else{
1866c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
1867c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			remoteid=0;
1868c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
1869c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1870c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2[n]->sainfo = getsainfo(idsrc, iddst, NULL, remoteid);
1871c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vfree(idsrc);
1872c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vfree(iddst);
1873c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph2[n]->sainfo == NULL) {
1874c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
1875c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to get sainfo.\n");
1876c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1878c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* XXX should use the algorithm list from register message */
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1880f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1881c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
1882c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		"selected sainfo: %s\n", sainfo2str(iph2[n]->sainfo));
1883c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    }
1884c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1885c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
1886c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
1887c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to create saprop.\n");
1888c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
1889c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
1890c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx) {
1893c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		set_secctx_in_proposal(iph2[n], spidx);
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1897c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	insph2(iph2[n]);
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start isakmp initiation by using ident exchange */
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX should be looped if there are multiple phase 2 handler. */
1901c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (isakmp_post_acquire(iph2[n]) < 0) {
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to begin ipsec sa negotication.\n");
1904c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		goto err;
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
1908c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1909c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeherr:
1910c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	while (n >= 0) {
1911c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		unbindph12(iph2[n]);
1912c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		remph2(iph2[n]);
1913c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2[n]);
1914c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph2[n] = NULL;
1915c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		n--;
1916c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1917c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return -1;
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvdelete(mhp)
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2 = NULL;
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id;
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb delete message passed.\n");
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid == getpid()) {
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because the message was originated by me.\n",
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == ~0) {
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proto_id %d\n", msg->sadb_msg_satype);
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ignore */
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no iph2 found: %s\n",
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(src, dst, msg->sadb_msg_satype,
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->sadb_sa_spi, IPSEC_MODE_ANY));
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL,
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"pfkey DELETE received: %s\n",
1976c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sadbsecas2str(iph2->src, iph2->dst,
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send delete information */
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ESTABLISHED)
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_info_send_d2(iph2);
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1983c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	unbindph12(iph2);
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvflush(mhp)
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb flush message passed.\n");
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushph2();
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetsadbpolicy(policy0, policylen0, type, iph2)
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *policy0;
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *policylen0, type;
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_ipsecrequest *xisr;
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto **pr_rlist;
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int rlist_len = 0;
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy, p;
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen;
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int xisrlen;
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int satype, mode;
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ctxlen = 0;
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get policy buffer size */
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	policylen = sizeof(struct sadb_x_policy);
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (type != SADB_X_SPDDELETE) {
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = iph2->approval->head; pr; pr = pr->next) {
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisrlen = sizeof(*xisr);
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2038c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				xisrlen += (sysdep_sa_len(iph2->src)
2039c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				          + sysdep_sa_len(iph2->dst));
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policylen += PFKEY_ALIGN8(xisrlen);
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*spidx->sec_ctx.ctx_str) {
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctxlen = sizeof(struct sadb_x_sec_ctx)
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		policylen += ctxlen;
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make policy structure */
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	policy = racoon_malloc(policylen);
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset((void*)policy, 0xcd, policylen);
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!policy) {
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"buffer allocation failed.\n");
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)policy;
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_dir = spidx->dir;
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_id = 0;
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len++;
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*spidx->sec_ctx.ctx_str) {
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *p;
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (struct sadb_x_sec_ctx *)(xpl + len);
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(p, 0, ctxlen);
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
2085c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len += ctxlen;
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no need to append policy information any more if type is SPDDELETE */
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (type == SADB_X_SPDDELETE)
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* The order of things is reversed for use in add policy messages */
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!pr_rlist) {
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"buffer allocation failed.\n");
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr_rlist[rlist_len--] = NULL;
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rlist_len = 0;
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		satype = doi2ipproto(pr->proto_id);
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (satype == ~0) {
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode = ipsecdoi2pfkey_mode(pr->encmode);
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (mode == ~0) {
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2124c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/*
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * the policy level cannot be unique because the policy
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * is defined later than SA, so req_id cannot be bound to SA.
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_proto = satype;
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_mode = mode;
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph2->proposal->head->reqid_in > 0){
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}else{
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_reqid = 0;
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (caddr_t)(xisr + 1);
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisrlen = sizeof(*xisr);
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int src_len, dst_len;
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2144c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			src_len = sysdep_sa_len(iph2->src);
2145c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			dst_len = sysdep_sa_len(iph2->dst);
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisrlen += src_len + dst_len;
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2148c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			memcpy(p, iph2->src, src_len);
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += src_len;
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2151c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			memcpy(p, iph2->dst, dst_len);
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += dst_len;
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr = (struct sadb_x_ipsecrequest *)p;
2157c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(pr_rlist);
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*policy0 = policy;
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*policylen0 = policylen;
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr_rlist) racoon_free(pr_rlist);
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspdupdate2(iph2)
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen = 0;
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t ltime, vtime;
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ltime = iph2->approval->lifetime;
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vtime = 0;
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spdupdate2(
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ltime, vtime,
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spdupdate2 (%s)\n",
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdupdate(mhp)
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
2222c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 	struct sadb_lifetime *lt;
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
2225c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 	u_int64_t created;
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdupdate message passed.\n");
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
2280c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
2281c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"such policy does not already exist: \"%s\"\n",
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2288c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (addnewsp(mhp) < 0)
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function has to be used by responder side.
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspdadd2(iph2)
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen = 0;
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t ltime, vtime;
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ltime = iph2->approval->lifetime;
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vtime = 0;
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spdadd2(
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ltime, vtime,
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spdadd2 (%s)\n",
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdadd(mhp)
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdadd message passed.\n");
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp != NULL) {
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such policy already exists. "
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"anyway replace it: %s\n",
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (addnewsp(mhp) < 0)
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function has to be used by responder side.
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspddelete(iph2)
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen;
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spddelete(
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spddelete (%s)\n",
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddelete(mhp)
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddelete message passed.\n");
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found: %s\n",
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remsp(sp);
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delsp(sp);
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdexpire(mhp)
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdexpire message passed.\n");
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found: %s\n",
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remsp(sp);
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delsp(sp);
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdget(mhp)
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdget message passed.\n");
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddump(mhp)
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddump message passed.\n");
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
2640c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (saddr == NULL || daddr == NULL || xpl == NULL) {
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddump message passed.\n");
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp != NULL) {
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such policy already exists. "
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"anyway replace it: %s\n",
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2699c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (addnewsp(mhp) < 0)
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdflush(mhp)
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdflush message passed.\n");
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsp();
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27219d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh#ifndef ANDROID_PATCHED
27229d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2724c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * send error against acquire message to kenrel.
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendeacquire(iph2)
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *newmsg;
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(struct sadb_msg);
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg = racoon_calloc(1, len);
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newmsg == NULL) {
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer to send acquire.\n");
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(newmsg, 0, len);
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_version = PF_KEY_V2;
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_type = SADB_ACQUIRE;
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_errno = ENOENT;	/* XXX */
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_satype = iph2->satype;
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_len = PFKEY_UNIT64(len);
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_reserved = 0;
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_seq = iph2->seq;
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_pid = (u_int32_t)getpid();
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send message */
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(newmsg);
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27599d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh#else
27609d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh
27619d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yehint pk_sendeacquire(struct ph2handle *iph2)
2762c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
2763c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	exit(1);
27649d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh}
27659d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh
27669d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh#endif
27679d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check if the algorithm is supported or not.
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT	 0: ok
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: ng
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_checkalg(class, calg, keylen)
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int class, calg, keylen;
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sup, error;
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int alg;
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_alg alg0;
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (algclass2doi(class)) {
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sup = SADB_EXT_SUPPORTED_ENCRYPT;
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH:
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sup = SADB_EXT_SUPPORTED_AUTH;
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
2790c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"compression algorithm can not be checked "
2791c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"because sadb message doesn't support it.\n");
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid algorithm class.\n");
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (alg == ~0)
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (keylen == 0) {
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ipsec_get_keylen(sup, alg, &alg0)) {
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"%s.\n", ipsec_strerror());
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		keylen = alg0.sadb_alg_minbits;
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = ipsec_check_keylen(sup, alg, keylen);
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error)
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s.\n", ipsec_strerror());
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * differences with pfkey_recv() in libipsec/pfkey.c:
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - never performs busy wait loop.
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns NULL and set *lenp to negative on fatal failures
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns NULL and set *lenp to non-negative on non-fatal failures
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns non-NULL on success
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct sadb_msg *
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recv(so, lenp)
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so;
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *lenp;
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg buf, *newmsg;
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int reallen;
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int retry = 0;
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = -1;
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	do
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    retry++;
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (*lenp < 0 && errno == EAGAIN && retry < 3);
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0)
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (*lenp < sizeof(buf))
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((newmsg = racoon_calloc(1, reallen)) == NULL)
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0) {
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else if (*lenp != reallen) {
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = recv(so, (caddr_t)newmsg, reallen, 0);
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0) {
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else if (*lenp != reallen) {
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newmsg;
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* see handler.h */
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
28770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_getseq()
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_random();
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
2883c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehaddnewsp(mhp)
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *new = NULL;
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
28900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spd management message passed.\n");
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
29030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* bsd skips over per-socket policies because there will be no
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * src and dst extensions in spddump messages. On Linux the only
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * way to achieve the same is check for policy id.
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = newsp();
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate buffer\n");
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->spidx.dir = xpl->sadb_x_policy_dir;
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->id = xpl->sadb_x_policy_id;
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->policy = xpl->sadb_x_policy_type;
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->req = NULL;
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check policy */
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (xpl->sadb_x_policy_type) {
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_DISCARD:
29380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_NONE:
29390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_ENTRUST:
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_BYPASS:
29410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_IPSEC:
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int tlen;
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_ipsecrequest *xisr;
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ipsecrequest **p_isr = &new->req;
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
29500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid msg length.\n");
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (tlen > 0) {
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* length check */
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid msg length.\n");
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* allocate request buffer */
29690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p_isr = newipsecreq();
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (*p_isr == NULL) {
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to get new ipsecreq.\n");
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set values */
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->next = NULL;
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_proto) {
29800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_ESP:
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_AH:
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_IPCOMP:
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid proto type: %u\n",
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_proto);
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_mode) {
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_TRANSPORT:
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_TUNNEL:
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_ANY:
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid mode: %u\n",
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_mode);
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_level) {
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_DEFAULT:
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_USE:
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_REQUIRE:
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_UNIQUE:
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(*p_isr)->saidx.reqid =
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_reqid;
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid level: %u\n",
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_level);
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
30200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set IP addresses if there */
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				struct sockaddr *paddr;
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (struct sockaddr *)(xisr + 1);
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bcopy(paddr, &(*p_isr)->saidx.src,
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sysdep_sa_len(paddr));
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (struct sockaddr *)((caddr_t)paddr
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							+ sysdep_sa_len(paddr));
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bcopy(paddr, &(*p_isr)->saidx.dst,
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sysdep_sa_len(paddr));
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->sp = new;
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* initialization for the next. */
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p_isr = &(*p_isr)->next;
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= xisr->sadb_x_ipsecrequest_len;
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validity check */
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tlen < 0) {
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"becoming tlen < 0\n");
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			                 + xisr->sadb_x_ipsecrequest_len);
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
30530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid policy type.\n");
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
30660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
30670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
30680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&new->spidx);
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&new->spidx);
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
30820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
30830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
30840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	inssp(new);
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbad:
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new != NULL) {
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new->req != NULL)
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(new->req);
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(new);
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* proto/mode/src->dst spi */
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsadbsecas2str(src, dst, proto, spi, mode)
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t spi;
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int mode;
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[256];
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int doi_proto, doi_mode = 0;
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int blen, i;
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	doi_proto = pfkey2ipsecdoi_proto(proto);
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (doi_proto == ~0)
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mode) {
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		doi_mode = pfkey2ipsecdoi_mode(mode);
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (doi_mode == ~0)
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen = sizeof(buf) - 1;
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = buf;
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s%s%s ",
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_proto(doi_proto),
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode ? "/" : "",
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode ? s_ipsecdoi_encmode(doi_mode) : "");
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s->", saddr2str(src));
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s ", saddr2str(dst));
31460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spi) {
31520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
31530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (unsigned long)ntohl(spi));
31540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
31570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3158