pfkey.c revision 0a1907d434839af6a9cb6329bbde60b237bf53dc
10a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*	$NetBSD: pfkey.c,v 1.18.4.5 2008/03/05 22:14:24 mgrooms Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* $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.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
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.
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
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>
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef ANDROID_CHANGES
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/sysctl.h>
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#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
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic 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
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#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 */
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_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;
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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{
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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		}
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
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);
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (s >= 0)
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		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
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		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
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* called from scheduler */
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_timeover_stub(p)
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *p;
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pfkey_timeover((struct ph2handle *)p);
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpfkey_timeover(iph2)
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL,
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"%s give up to get IPsec-SA due to time up to wait.\n",
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddrwop2str(iph2->dst));
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->sce);
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* If initiator side, send error to kernel by SADB_ACQUIRE. */
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->side == INITIATOR)
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pk_sendeacquire(iph2);
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unbindph12(iph2);
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
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;
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proxy = 0;
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->side == INITIATOR) {
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp = iph2->proposal;
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proxy = iph2->ph1->rmconf->support_proxy;
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp = iph2->approval;
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2->sainfo && iph2->sainfo->id_i)
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			proxy = 1;
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* for mobile IPv6 */
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proxy && iph2->src_id && iph2->dst_id &&
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    ipsecdoi_transportmode(pp)) {
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = iph2->src_id;
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dst = iph2->dst_id;
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		src = iph2->src;
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		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
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX should we do a copy of src/dst for each pr ?
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (! pr->udp_encap) {
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Remove port information, that SA doesn't use it */
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(src, 0);
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(dst, 0);
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		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
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_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;
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || 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",
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				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",
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			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");
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			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;
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	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
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->side == INITIATOR)
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proxy = iph2->ph1->rmconf->support_proxy;
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (iph2->sainfo && iph2->sainfo->id_i)
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proxy = 1;
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
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;
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.l_addtime = iph2->approval->lifetime;
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.seq = iph2->seq;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.wsize = 4;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* for mobile IPv6 */
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proxy && iph2->src_id && iph2->dst_id &&
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    ipsecdoi_transportmode(iph2->approval)) {
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.dst = iph2->src_id;
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.src = iph2->dst_id;
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.dst = iph2->src;
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		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,
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.a_type, &sa_args.a_keylen,
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&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;
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_dport = extract_port (iph2->ph1->local);
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			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
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Remove port information, that SA doesn't use it */
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(sa_args.src, 0);
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(sa_args.dst, 0);
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#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
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * It maybe good idea to call backupsa_to_file() after
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * racoon will receive the sadb_update messages.
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * But it is impossible because there is not key in the
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * information from the kernel.
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* change some things before backing up */
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.wsize = 4;
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = iph2->approval->lifebyte * 1024;
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (backupsa_to_file(&sa_args) < 0) {
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"backuped SA failed: %s\n",
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(sa_args.src, sa_args.dst,
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa_args.satype, sa_args.spi, sa_args.mode));
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"backuped SA: %s\n",
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(sa_args.src, sa_args.dst,
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.satype, sa_args.spi, sa_args.mode));
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvupdate(mhp)
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id, encmode, sa_mode;
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int incomplete = 0;
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb update message passed.\n");
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid != getpid()) {
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because pid %d is not mine.\n",
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_pid);
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2byseq(msg->sadb_msg_seq);
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seq %d of %s message not interesting.\n",
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_seq,
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status != PHASE2ST_ADDSA) {
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"status mismatch (db:%d msg:%d)\n",
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->status, PHASE2ST_ADDSA);
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check to complete all keys ? */
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (proto_id == ~0) {
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", msg->sadb_msg_satype);
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		encmode = pfkey2ipsecdoi_mode(sa_mode);
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (encmode == ~0) {
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", sa_mode);
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->proto_id == proto_id
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 && pr->spi == sa->sadb_sa_spi) {
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr->ok = 1;
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfkey UPDATE succeeded: %s\n",
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(iph2->dst, iph2->src,
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    msg->sadb_msg_satype,
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa->sadb_sa_spi,
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa_mode));
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"IPsec-SA established: %s\n",
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(iph2->dst, iph2->src,
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					msg->sadb_msg_satype, sa->sadb_sa_spi,
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sa_mode));
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->ok == 0)
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			incomplete = 1;
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (incomplete)
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off the timer for calling pfkey_timeover() */
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->sce);
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update status */
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_ESTABLISHED;
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph2->end, NULL);
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2", "quick", timedelta(&iph2->start, &iph2->end));
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* count up */
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->ph1->ph2cnt++;
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->scr);
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Force the update of ph2's ports, as there is at least one
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * situation where they'll mismatch with ph1's values
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	set_port(iph2->src, extract_port(iph2->ph1->local));
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	set_port(iph2->dst, extract_port(iph2->ph1->remote));
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * since we are going to reuse the phase2 handler, we need to
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * remain it and refresh all the references between ph1 and ph2 to use.
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unbindph12(iph2);
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->sce = sched_new(iph2->approval->lifetime,
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    isakmp_ph2expire_stub, iph2);
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set outbound SA
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendadd(iph2)
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proxy = 0;
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct pfkey_send_sa_args sa_args;
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->approval == NULL) {
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no approvaled SAs found.\n");
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->side == INITIATOR)
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proxy = iph2->ph1->rmconf->support_proxy;
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (iph2->sainfo && iph2->sainfo->id_i)
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proxy = 1;
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* fill in some needed for pfkey_send_update2 */
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset (&sa_args, 0, sizeof (sa_args));
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.so = lcconf->sock_pfkey;
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.l_addtime = iph2->approval->lifetime;
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.seq = iph2->seq;
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_args.wsize = 4;
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* for mobile IPv6 */
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proxy && iph2->src_id && iph2->dst_id &&
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    ipsecdoi_transportmode(iph2->approval)) {
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.src = iph2->src_id;
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.dst = iph2->dst_id;
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.src = iph2->src;
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.dst = iph2->dst;
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.satype = ipsecdoi2pfkey_proto(pr->proto_id);
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.satype == ~0) {
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else if (sa_args.satype == SADB_X_SATYPE_IPCOMP) {
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* no replay window for IPCOMP */
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.wsize = 0;
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_SAMODE_UNSPECIFIED
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = IPSEC_MODE_ANY;
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.mode = ipsecdoi2pfkey_mode(pr->encmode);
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa_args.mode == ~0) {
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set algorithm type and key length */
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.e_keylen = pr->head->encklen;
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_convertfromipsecdoi(
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->proto_id,
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->trns_id,
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->head->authtype,
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.e_type, &sa_args.e_keylen,
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.a_type, &sa_args.a_keylen,
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				&sa_args.flags) < 0)
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = iph2->approval->lifebyte * 1024,
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.l_bytes = 0;
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*iph2->approval->sctx.ctx_str) {
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxdoi = iph2->approval->sctx.ctx_doi;
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxalg = iph2->approval->sctx.ctx_alg;
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstrlen = iph2->approval->sctx.ctx_strlen;
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.ctxstr = iph2->approval->sctx.ctx_str;
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2 "
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "(NAT flavor)\n");
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->udp_encap) {
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_sport = extract_port(iph2->ph1->local);
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_oa = NULL; // FIXME: Here comes OA!!!
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef SADB_X_EXT_NAT_T_FRAG
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Remove port information, that SA doesn't use it */
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(sa_args.src, 0);
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			set_port(sa_args.dst, 0);
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Remove port information, it is not used without NAT-T */
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(sa_args.src, 0);
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_port(sa_args.dst, 0);
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* more info to fill in */
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.spi = pr->spi_p;
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.reqid = pr->reqid_out;
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa_args.keymat = pr->keymat_p->v;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add2\n");
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pfkey_send_add2(&sa_args) < 0) {
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"libipsec failed send add (%s)\n",
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ipsec_strerror());
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * It maybe good idea to call backupsa_to_file() after
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * racoon will receive the sadb_update messages.
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * But it is impossible because there is not key in the
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * information from the kernel.
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (backupsa_to_file(&sa_args) < 0) {
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"backuped SA failed: %s\n",
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sadbsecas2str(sa_args.src, sa_args.dst,
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa_args.satype, sa_args.spi, sa_args.mode));
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"backuped SA: %s\n",
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(sa_args.src, sa_args.dst,
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa_args.satype, sa_args.spi, sa_args.mode));
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvadd(mhp)
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int sa_mode;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb add message passed.\n");
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid != getpid()) {
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because pid %d is not mine.\n",
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type),
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_pid);
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2byseq(msg->sadb_msg_seq);
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"seq %d of %s message not interesting.\n",
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_seq,
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE don't update any status of phase2 handle
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because they must be updated by SADB_UPDATE message
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"IPsec-SA established: %s\n",
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sadbsecas2str(iph2->src, iph2->dst,
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvexpire(mhp)
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id, sa_mode;
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	  && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb expire message passed.\n");
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_mode = mhp[SADB_X_EXT_SA2] == NULL
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		? IPSEC_MODE_ANY
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		: ((struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == ~0) {
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proto_id %d\n", msg->sadb_msg_satype);
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"IPsec-SA expired: %s\n",
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sadbsecas2str(src, dst,
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Ignore it because two expire messages are come up.
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * phase2 handler has been deleted already when 2nd message
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * is received.
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no such a SA found: %s\n",
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(src, dst,
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    msg->sadb_msg_satype, sa->sadb_sa_spi,
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    sa_mode));
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status != PHASE2ST_ESTABLISHED) {
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * If the status is not equal to PHASE2ST_ESTABLISHED,
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * racoon ignores this expire message.  There are two reason.
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * One is that the phase 2 probably starts because there is
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * a potential that racoon receives the acquire message
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * without receiving a expire message.  Another is that racoon
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * may receive the multiple expire messages from the kernel.
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the expire message is received "
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"but the handler has not been established.\n");
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off the timer for calling isakmp_ph2expire() */
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	SCHED_KILL(iph2->sce);
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_EXPIRED;
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* INITIATOR, begin phase 2 exchange. */
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate buffer for status management of pfkey message */
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->side == INITIATOR) {
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		initph2(iph2);
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* update status for re-use */
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2->status = PHASE2ST_STATUS2;
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* start isakmp initiation by using ident exchange */
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_post_acquire(iph2) < 0) {
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph2->dst,
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to begin ipsec sa "
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"re-negotication.\n");
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			unbindph12(iph2);
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*NOTREACHED*/
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* RESPONDER always delete ph2handle, keep silent.  RESPONDER doesn't
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * manage IPsec SA, so delete the list */
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unbindph12(iph2);
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvacquire(mhp)
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp_out = NULL, *sp_in = NULL;
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define MAXNESTEDSA	5	/* XXX */
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2[MAXNESTEDSA];
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int n;	/* # of phase 2 handler */
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int remoteid=0;
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_sec_ctx *m_sec_ctx;
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb acquire message passed.\n");
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx != NULL) {
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n",
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_doi);
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "security context algorithm: %u\n",
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_alg);
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context length: %u\n",
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     m_sec_ctx->sadb_x_ctx_len);
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL, "security context: %s\n",
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)));
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore if type is not IPSEC_POLICY_IPSEC */
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore ACQUIRE message. type is not IPsec.\n");
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore it if src is multicast address */
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((sa->sa_family == AF_INET
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	  && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || (sa->sa_family == AF_INET6
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	  && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	) {
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ignore due to multicast address: %s.\n",
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddrwop2str(sa));
17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    	/* ignore, if we do not listen on source address */
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* reasons behind:
17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * - if we'll contact peer from address we do not listen -
17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 *   we will be unable to complete negotiation;
17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * - if we'll negotiate using address we're listening -
17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 *   remote peer will send packets to address different
17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 *   than one in the policy, so kernel will drop them;
17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * => therefore this acquire is not for us! --Aidas
17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct myaddrs *p;
17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int do_listen = 0;
17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (p = lcconf->myaddrs; p; p = p->next) {
17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!cmpsaddrwop(p->addr, sa)) {
17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				do_listen = 1;
17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!do_listen) {
17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ignore because do not listen on source address : %s.\n",
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				saddrwop2str(sa));
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * If there is a phase 2 handler against the policy identifier in
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * the acquire message, and if
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *    1. its state is less than PHASE2ST_ESTABLISHED, then racoon
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       should ignore such a acquire message because the phase 2
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       is just negotiating.
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *    2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       has to prcesss such a acquire message because racoon may
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *       lost the expire message.
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2[0] != NULL) {
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ignore the acquire because ph2 found\n");
17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2[0]->status == PHASE2ST_EXPIRED)
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2[0] = NULL;
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* search for proper policyindex */
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_out = getspbyspid(xpl->sadb_x_policy_id);
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp_out == NULL) {
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_id);
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get inbound policy */
17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(&spidx, 0, sizeof(spidx));
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.dir = IPSEC_DIR_INBOUND;
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefs = sp_out->spidx.prefd;
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.prefd = sp_out->spidx.prefs;
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spidx.ul_proto = sp_out->spidx.ul_proto;
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx) {
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = m_sec_ctx->sadb_x_ctx_doi;
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = m_sec_ctx->sadb_x_ctx_alg;
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = m_sec_ctx->sadb_x_ctx_len;
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str,
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		      ((char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)),
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		      spidx.sec_ctx.ctx_strlen);
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp_in = getsp(&spidx);
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp_in) {
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"suitable inbound SP found: %s.\n",
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp_in->spidx));
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_NOTIFY, LOCATION, NULL,
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no in-bound policy found: %s\n",
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(iph2, 0, MAXNESTEDSA);
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	n = 0;
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate a phase 2 */
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n] = newph2();
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2[n] == NULL) {
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate phase2 entry.\n");
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->side = INITIATOR;
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->spid = xpl->sadb_x_policy_id;
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->satype = msg->sadb_msg_satype;
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->seq = msg->sadb_msg_seq;
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->status = PHASE2ST_STATUS2;
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set end addresses of SA */
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->dst = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2[n]->dst == NULL) {
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->src = dupsaddr(PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2[n]->src == NULL) {
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"new acquire %s\n", spidx2str(&sp_out->spidx));
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get sainfo */
18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *idsrc, *iddst;
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	idsrc = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.src,
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sp_out->spidx.prefs, sp_out->spidx.ul_proto);
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (idsrc == NULL) {
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp_out->spidx));
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iddst = ipsecdoi_sockaddr2id((struct sockaddr *)&sp_out->spidx.dst,
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sp_out->spidx.prefd, sp_out->spidx.ul_proto);
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iddst == NULL) {
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp_out->spidx));
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(idsrc);
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct remoteconf *conf;
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		conf = getrmconf(iph2[n]->dst);
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (conf != NULL)
18600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remoteid=conf->ph1id;
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else{
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "Warning: no valid rmconf !\n");
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remoteid=0;
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2[n]->sainfo = getsainfo(idsrc, iddst, NULL, remoteid);
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(idsrc);
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(iddst);
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2[n]->sainfo == NULL) {
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get sainfo.\n");
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX should use the algorithm list from register message */
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"selected sainfo: %s\n", sainfo2str(iph2[n]->sainfo));
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to create saprop.\n");
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (m_sec_ctx) {
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		set_secctx_in_proposal(iph2[n], spidx);
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	insph2(iph2[n]);
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start isakmp initiation by using ident exchange */
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX should be looped if there are multiple phase 2 handler. */
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_post_acquire(iph2[n]) < 0) {
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to begin ipsec sa negotication.\n");
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (n >= 0) {
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		unbindph12(iph2[n]);
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2[n]);
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2[n]);
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2[n] = NULL;
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n--;
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvdelete(mhp)
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_sa *sa;
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2 = NULL;
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int proto_id;
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_SA] == NULL
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb delete message passed.\n");
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the message has to be processed or not ? */
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (msg->sadb_msg_pid == getpid()) {
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s message is not interesting "
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because the message was originated by me.\n",
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_pfkey_type(msg->sadb_msg_type));
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == ~0) {
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proto_id %d\n", msg->sadb_msg_satype);
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ignore */
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no iph2 found: %s\n",
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sadbsecas2str(src, dst, msg->sadb_msg_satype,
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->sadb_sa_spi, IPSEC_MODE_ANY));
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL,
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"pfkey DELETE received: %s\n",
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sadbsecas2str(iph2->src, iph2->dst,
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send delete information */
19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ESTABLISHED)
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_info_send_d2(iph2);
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unbindph12(iph2);
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remph2(iph2);
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delph2(iph2);
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvflush(mhp)
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore this message because of local test mode. */
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (f_local)
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb flush message passed.\n");
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushph2();
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetsadbpolicy(policy0, policylen0, type, iph2)
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *policy0;
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *policylen0, type;
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_ipsecrequest *xisr;
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto **pr_rlist;
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int rlist_len = 0;
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy, p;
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen;
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int xisrlen;
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int satype, mode;
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ctxlen = 0;
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get policy buffer size */
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	policylen = sizeof(struct sadb_x_policy);
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (type != SADB_X_SPDDELETE) {
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = iph2->approval->head; pr; pr = pr->next) {
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisrlen = sizeof(*xisr);
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				xisrlen += (sysdep_sa_len(iph2->src)
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				          + sysdep_sa_len(iph2->dst));
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policylen += PFKEY_ALIGN8(xisrlen);
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*spidx->sec_ctx.ctx_str) {
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctxlen = sizeof(struct sadb_x_sec_ctx)
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ PFKEY_ALIGN8(spidx->sec_ctx.ctx_strlen);
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		policylen += ctxlen;
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make policy structure */
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	policy = racoon_malloc(policylen);
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset((void*)policy, 0xcd, policylen);
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!policy) {
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"buffer allocation failed.\n");
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)policy;
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_dir = spidx->dir;
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_id = 0;
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len++;
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*spidx->sec_ctx.ctx_str) {
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *p;
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (struct sadb_x_sec_ctx *)(xpl + len);
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(p, 0, ctxlen);
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_sec_len = PFKEY_UNIT64(ctxlen);
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_len = spidx->sec_ctx.ctx_strlen;
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_doi = spidx->sec_ctx.ctx_doi;
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->sadb_x_ctx_alg = spidx->sec_ctx.ctx_alg;
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(p + 1,spidx->sec_ctx.ctx_str,spidx->sec_ctx.ctx_strlen);
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len += ctxlen;
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no need to append policy information any more if type is SPDDELETE */
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (type == SADB_X_SPDDELETE)
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xisr = (struct sadb_x_ipsecrequest *)(xpl + len);
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* The order of things is reversed for use in add policy messages */
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr; pr = pr->next) rlist_len++;
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr_rlist = racoon_malloc((rlist_len+1)*sizeof(struct saproto*));
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!pr_rlist) {
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"buffer allocation failed.\n");
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr_rlist[rlist_len--] = NULL;
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = iph2->approval->head; pr; pr = pr->next) pr_rlist[rlist_len--] = pr;
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rlist_len = 0;
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr = pr_rlist[rlist_len++]; pr; pr = pr_rlist[rlist_len++]) {
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		satype = doi2ipproto(pr->proto_id);
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (satype == ~0) {
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proto_id %d\n", pr->proto_id);
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode = ipsecdoi2pfkey_mode(pr->encmode);
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (mode == ~0) {
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid encmode %d\n", pr->encmode);
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * the policy level cannot be unique because the policy
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * is defined later than SA, so req_id cannot be bound to SA.
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_proto = satype;
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_mode = mode;
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph2->proposal->head->reqid_in > 0){
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_reqid = iph2->proposal->head->reqid_in;
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}else{
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr->sadb_x_ipsecrequest_reqid = 0;
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (caddr_t)(xisr + 1);
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisrlen = sizeof(*xisr);
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int src_len, dst_len;
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			src_len = sysdep_sa_len(iph2->src);
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dst_len = sysdep_sa_len(iph2->dst);
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisrlen += src_len + dst_len;
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(p, iph2->src, src_len);
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += src_len;
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(p, iph2->dst, dst_len);
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += dst_len;
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr = (struct sadb_x_ipsecrequest *)p;
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(pr_rlist);
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*policy0 = policy;
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*policylen0 = policylen;
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr_rlist) racoon_free(pr_rlist);
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspdupdate2(iph2)
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen = 0;
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t ltime, vtime;
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ltime = iph2->approval->lifetime;
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vtime = 0;
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spdupdate2(
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ltime, vtime,
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spdupdate2 (%s)\n",
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdupdate(mhp)
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 	struct sadb_lifetime *lt;
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 	u_int64_t created;
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdupdate message passed.\n");
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such policy does not already exist: \"%s\"\n",
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (addnewsp(mhp) < 0)
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function has to be used by responder side.
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspdadd2(iph2)
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen = 0;
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t ltime, vtime;
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ltime = iph2->approval->lifetime;
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vtime = 0;
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spdadd2(
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ltime, vtime,
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spdadd2 (%s)\n",
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdadd(mhp)
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdadd message passed.\n");
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp != NULL) {
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such policy already exists. "
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"anyway replace it: %s\n",
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (addnewsp(mhp) < 0)
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function has to be used by responder side.
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendspddelete(iph2)
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex *spidx = (struct policyindex *)iph2->spidx_gen;
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t policy = NULL;
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int policylen;
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"getting sadb policy failed.\n");
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pfkey_send_spddelete(
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			lcconf->sock_pfkey,
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->src,
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefs,
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&spidx->dst,
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->prefd,
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx->ul_proto,
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			policy, policylen, 0) < 0) {
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"libipsec failed send spddelete (%s)\n",
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipsec_strerror());
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (policy)
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(policy);
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddelete(mhp)
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddelete message passed.\n");
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found: %s\n",
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remsp(sp);
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delsp(sp);
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdexpire(mhp)
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdexpire message passed.\n");
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found: %s\n",
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	remsp(sp);
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	delsp(sp);
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdget(mhp)
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdget message passed.\n");
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspddump(mhp)
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *msg;
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct policyindex spidx;
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddump message passed.\n");
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	msg = (struct sadb_msg *)mhp[0];
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (saddr == NULL || daddr == NULL || xpl == NULL) {
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spddump message passed.\n");
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&spidx);
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spidx.sec_ctx.ctx_str, ctx + 1, ctx->sadb_x_ctx_len);
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getsp(&spidx);
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp != NULL) {
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such policy already exists. "
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"anyway replace it: %s\n",
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&spidx));
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remsp(sp);
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delsp(sp);
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (addnewsp(mhp) < 0)
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recvspdflush(mhp)
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[0] == NULL) {
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spdflush message passed.\n");
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsp();
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * send error against acquire message to kenrel.
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_sendeacquire(iph2)
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg *newmsg;
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = sizeof(struct sadb_msg);
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg = racoon_calloc(1, len);
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newmsg == NULL) {
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer to send acquire.\n");
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(newmsg, 0, len);
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_version = PF_KEY_V2;
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_type = SADB_ACQUIRE;
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_errno = ENOENT;	/* XXX */
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_satype = iph2->satype;
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_len = PFKEY_UNIT64(len);
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_reserved = 0;
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_seq = iph2->seq;
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newmsg->sadb_msg_pid = (u_int32_t)getpid();
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send message */
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(newmsg);
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check if the algorithm is supported or not.
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT	 0: ok
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: ng
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_checkalg(class, calg, keylen)
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int class, calg, keylen;
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sup, error;
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int alg;
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_alg alg0;
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (algclass2doi(class)) {
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sup = SADB_EXT_SUPPORTED_ENCRYPT;
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH:
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sup = SADB_EXT_SUPPORTED_AUTH;
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"compression algorithm can not be checked "
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"because sadb message doesn't support it.\n");
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid algorithm class.\n");
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (alg == ~0)
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (keylen == 0) {
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ipsec_get_keylen(sup, alg, &alg0)) {
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"%s.\n", ipsec_strerror());
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		keylen = alg0.sadb_alg_minbits;
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = ipsec_check_keylen(sup, alg, keylen);
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error)
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"%s.\n", ipsec_strerror());
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * differences with pfkey_recv() in libipsec/pfkey.c:
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - never performs busy wait loop.
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns NULL and set *lenp to negative on fatal failures
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns NULL and set *lenp to non-negative on non-fatal failures
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - returns non-NULL on success
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct sadb_msg *
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_recv(so, lenp)
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so;
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *lenp;
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_msg buf, *newmsg;
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int reallen;
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int retry = 0;
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = -1;
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	do
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    plog(LLV_DEBUG, LOCATION, NULL, "pk_recv: retry[%d] recv() \n", retry );
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    *lenp = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT);
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    retry++;
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (*lenp < 0 && errno == EAGAIN && retry < 3);
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0)
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else if (*lenp < sizeof(buf))
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((newmsg = racoon_calloc(1, reallen)) == NULL)
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = recv(so, (caddr_t)newmsg, reallen, MSG_PEEK);
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0) {
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else if (*lenp != reallen) {
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*lenp = recv(so, (caddr_t)newmsg, reallen, 0);
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*lenp < 0) {
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;	/*fatal*/
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else if (*lenp != reallen) {
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(newmsg);
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newmsg;
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* see handler.h */
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangu_int32_t
28620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangpk_getseq()
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return eay_random();
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangaddnewsp(mhp)
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t *mhp;
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *new = NULL;
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_address *saddr, *daddr;
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_x_policy *xpl;
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sadb_lifetime *lt;
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int64_t created;
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* sanity check */
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || mhp[SADB_X_EXT_POLICY] == NULL) {
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"inappropriate sadb spd management message passed.\n");
28830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
28900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	lt = (struct sadb_lifetime*)mhp[SADB_EXT_LIFETIME_HARD];
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(lt != NULL)
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = lt->sadb_lifetime_addtime;
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		created = 0;
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* bsd skips over per-socket policies because there will be no
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * src and dst extensions in spddump messages. On Linux the only
29030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * way to achieve the same is check for policy id.
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xpl->sadb_x_policy_id % 8 >= 3) return 0;
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = newsp();
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate buffer\n");
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->spidx.dir = xpl->sadb_x_policy_dir;
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->id = xpl->sadb_x_policy_id;
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->policy = xpl->sadb_x_policy_type;
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new->req = NULL;
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check policy */
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (xpl->sadb_x_policy_type) {
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_DISCARD:
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_NONE:
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_ENTRUST:
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_BYPASS:
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_POLICY_IPSEC:
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int tlen;
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_ipsecrequest *xisr;
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ipsecrequest **p_isr = &new->req;
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid msg length.\n");
29380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
29390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (tlen > 0) {
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* length check */
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid msg length.\n");
29500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* allocate request buffer */
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p_isr = newipsecreq();
29550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (*p_isr == NULL) {
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to get new ipsecreq.\n");
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set values */
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->next = NULL;
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_proto) {
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_ESP:
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_AH:
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPPROTO_IPCOMP:
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid proto type: %u\n",
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_proto);
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_mode) {
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_TRANSPORT:
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_TUNNEL:
29800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_MODE_ANY:
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid mode: %u\n",
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_mode);
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (xisr->sadb_x_ipsecrequest_level) {
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_DEFAULT:
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_USE:
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_REQUIRE:
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSEC_LEVEL_UNIQUE:
29960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(*p_isr)->saidx.reqid =
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_reqid;
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid level: %u\n",
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					xisr->sadb_x_ipsecrequest_level);
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto bad;
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set IP addresses if there */
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				struct sockaddr *paddr;
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (struct sockaddr *)(xisr + 1);
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bcopy(paddr, &(*p_isr)->saidx.src,
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sysdep_sa_len(paddr));
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (struct sockaddr *)((caddr_t)paddr
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							+ sysdep_sa_len(paddr));
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bcopy(paddr, &(*p_isr)->saidx.dst,
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sysdep_sa_len(paddr));
30200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(*p_isr)->sp = new;
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* initialization for the next. */
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p_isr = &(*p_isr)->next;
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= xisr->sadb_x_ipsecrequest_len;
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validity check */
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tlen < 0) {
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"becoming tlen < 0\n");
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			                 + xisr->sadb_x_ipsecrequest_len);
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid policy type.\n");
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PFKEY_POLICY_PRIORITY
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xpl->sadb_x_policy_priority,
30530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&new->spidx);
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr + 1,
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr + 1,
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_prefixlen,
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			daddr->sadb_address_prefixlen,
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr->sadb_address_proto,
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			created,
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			&new->spidx);
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
30670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mhp[SADB_X_EXT_SEC_CTX] != NULL) {
30680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sadb_x_sec_ctx *ctx;
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX];
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_alg = ctx->sadb_x_ctx_alg;
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_doi = ctx->sadb_x_ctx_doi;
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new->spidx.sec_ctx.ctx_strlen = ctx->sadb_x_ctx_len;
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->spidx.sec_ctx.ctx_str,ctx + 1,ctx->sadb_x_ctx_len);
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	inssp(new);
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbad:
30820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new != NULL) {
30830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new->req != NULL)
30840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(new->req);
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(new);
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* proto/mode/src->dst spi */
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangconst char *
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsadbsecas2str(src, dst, proto, spi, mode)
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *src, *dst;
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t spi;
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int mode;
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[256];
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int doi_proto, doi_mode = 0;
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *p;
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int blen, i;
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	doi_proto = pfkey2ipsecdoi_proto(proto);
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (doi_proto == ~0)
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mode) {
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		doi_mode = pfkey2ipsecdoi_mode(mode);
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (doi_mode == ~0)
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen = sizeof(buf) - 1;
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = buf;
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s%s%s ",
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_proto(doi_proto),
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode ? "/" : "",
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		mode ? s_ipsecdoi_encmode(doi_mode) : "");
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s->", saddr2str(src));
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	i = snprintf(p, blen, "%s ", saddr2str(dst));
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i < 0 || i >= blen)
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p += i;
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	blen -= i;
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spi) {
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (unsigned long)ntohl(spi));
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buf;
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3143