proposal.c revision 0a1907d434839af6a9cb6329bbde60b237bf53dc
10a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*	$NetBSD: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* $Id: proposal.c,v 1.13.4.2 2008/07/22 13:25:42 vanhu 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 <sys/param.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/queue.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include PATH_IPSEC_H
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h"
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "pfkey.h"
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "algorithm.h"
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "proposal.h"
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sainfo.h"
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h"
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h"
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "nattraversal.h"
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic uint g_nextreqid = 1;
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%%
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modules for ipsec sa spec
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct saprop *
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnewsaprop()
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *new;
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = racoon_calloc(1, sizeof(*new));
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL)
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct saproto *
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnewsaproto()
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *new;
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = racoon_calloc(1, sizeof(*new));
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL)
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* set saprop to last part of the prop tree */
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanginssaprop(head, new)
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop **head;
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *new;
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *p;
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*head == NULL) {
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*head = new;
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = *head; p->next; p = p->next)
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		;
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p->next = new;
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* set saproto to the end of the proto tree in saprop */
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanginssaproto(pp, new)
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *new;
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *p;
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pp->head; p && p->next; p = p->next)
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		;
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp->head = new;
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->next = new;
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* set saproto to the top of the proto tree in saprop */
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanginssaprotorev(pp, new)
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang      struct saprop *pp;
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang      struct saproto *new;
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang      new->next = pp->head;
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang      pp->head = new;
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang      return;
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct satrns *
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangnewsatrns()
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *new;
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = racoon_calloc(1, sizeof(*new));
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL)
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* set saproto to last part of the proto tree in saprop */
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanginssatrns(pr, new)
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *new;
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (tr = pr->head; tr && tr->next; tr = tr->next)
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		;
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tr == NULL)
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pr->head = new;
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tr->next = new;
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * take a single match between saprop.  allocate a new proposal and return it
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * for future use (like picking single proposal from a bundle).
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	pp1: peer's proposal.
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	pp2: my proposal.
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: In the case of initiator, must be ensured that there is no
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification of the proposal by calling cmp_aproppair_i() before
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function.
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * XXX cannot understand the comment!
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct saprop *
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpsaprop_alloc(ph1, pp1, pp2, side)
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *ph1;
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp1, *pp2;
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int side;
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *newpp = NULL;
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr1, *pr2, *newpr = NULL;
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr1, *tr2, *newtr;
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int ordermatters = 0;
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int npr1, npr2;
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int spisizematch;
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp = newsaprop();
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newpp == NULL) {
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate saprop.\n");
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->prop_no = pp1->prop_no;
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* see proposal.h about lifetime/key length and PFS selection. */
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check time/bytes lifetime and PFS */
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (ph1->rmconf->pcheck_level) {
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_OBEY:
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifetime = pp1->lifetime;
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifebyte = pp1->lifebyte;
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->pfs_group = pp1->pfs_group;
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_STRICT:
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifetime > pp2->lifetime) {
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"long lifetime proposed: "
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(int)pp2->lifetime, (int)pp1->lifetime);
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifebyte > pp2->lifebyte) {
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"long lifebyte proposed: "
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp2->lifebyte, pp1->lifebyte);
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifetime = pp1->lifetime;
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifebyte = pp1->lifebyte;
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    prop_pfs_check:
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp2->pfs_group != 0 && pp1->pfs_group != pp2->pfs_group) {
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfs group mismatched: "
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp2->pfs_group, pp1->pfs_group);
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->pfs_group = pp1->pfs_group;
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_CLAIM:
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* lifetime */
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifetime <= pp2->lifetime) {
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->lifetime = pp1->lifetime;
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->lifetime = pp2->lifetime;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC;
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_NOTIFY, LOCATION, NULL,
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"use own lifetime: "
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(int)pp2->lifetime, (int)pp1->lifetime);
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* lifebyte */
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifebyte > pp2->lifebyte) {
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->lifebyte = pp2->lifebyte;
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC;
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_NOTIFY, LOCATION, NULL,
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"use own lifebyte: "
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp2->lifebyte, pp1->lifebyte);
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifebyte = pp1->lifebyte;
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    		goto prop_pfs_check;
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_EXACT:
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifetime != pp2->lifetime) {
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"lifetime mismatched: "
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(int)pp2->lifetime, (int)pp1->lifetime);
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->lifebyte != pp2->lifebyte) {
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"lifebyte mismatched: "
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp2->lifebyte, pp1->lifebyte);
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->pfs_group != pp2->pfs_group) {
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pfs group mismatched: "
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp2->pfs_group, pp1->pfs_group);
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifetime = pp1->lifetime;
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->lifebyte = pp1->lifebyte;
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpp->pfs_group = pp1->pfs_group;
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid pcheck_level why?.\n");
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check the security_context properties.
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * It is possible for one side to have a security context
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * and the other side doesn't. If so, this is an error.
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*pp1->sctx.ctx_str && !(*pp2->sctx.ctx_str)) {
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "My proposal missing security context\n");
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!(*pp1->sctx.ctx_str) && *pp2->sctx.ctx_str) {
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     "Peer is missing security context\n");
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*pp1->sctx.ctx_str && *pp2->sctx.ctx_str) {
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->sctx.ctx_doi == pp2->sctx.ctx_doi)
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->sctx.ctx_doi = pp1->sctx.ctx_doi;
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else {
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "sec doi mismatched: my:%d peer:%d\n",
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     pp2->sctx.ctx_doi, pp1->sctx.ctx_doi);
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     goto err;
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp1->sctx.ctx_alg == pp2->sctx.ctx_alg)
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->sctx.ctx_alg = pp1->sctx.ctx_alg;
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else {
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "sec alg mismatched: my:%d peer:%d\n",
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     pp2->sctx.ctx_alg, pp1->sctx.ctx_alg);
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((pp1->sctx.ctx_strlen != pp2->sctx.ctx_strlen) ||
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     memcmp(pp1->sctx.ctx_str, pp2->sctx.ctx_str,
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		     pp1->sctx.ctx_strlen) != 0) {
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "sec ctx string mismatched: my:%s peer:%s\n",
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     pp2->sctx.ctx_str, pp1->sctx.ctx_str);
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpp->sctx.ctx_strlen = pp1->sctx.ctx_strlen;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(newpp->sctx.ctx_str, pp1->sctx.ctx_str,
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp1->sctx.ctx_strlen);
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	npr1 = npr2 = 0;
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr1 = pp1->head; pr1; pr1 = pr1->next)
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		npr1++;
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pr2 = pp2->head; pr2; pr2 = pr2->next)
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		npr2++;
3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (npr1 != npr2)
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check protocol order */
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr1 = pp1->head;
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr2 = pp2->head;
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (1) {
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!ordermatters) {
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * XXX does not work if we have multiple proposals
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * with the same proto_id
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (side) {
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case RESPONDER:
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (!pr2)
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (pr1 = pp1->head; pr1; pr1 = pr1->next) {
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (pr1->proto_id == pr2->proto_id)
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case INITIATOR:
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (!pr1)
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					break;
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (pr2 = pp2->head; pr2; pr2 = pr2->next) {
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (pr2->proto_id == pr1->proto_id)
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!pr1 || !pr2)
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr1->proto_id != pr2->proto_id) {
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proto_id mismatched: "
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%s peer:%s\n",
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_proto(pr2->proto_id),
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_proto(pr1->proto_id));
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spisizematch = 0;
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr1->spisize == pr2->spisize)
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spisizematch = 1;
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else if (pr1->proto_id == IPSECDOI_PROTO_IPCOMP) {
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * draft-shacham-ippcp-rfc2393bis-05.txt:
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * need to accept 16bit and 32bit SPI (CPI) for IPComp.
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr1->spisize == sizeof(u_int16_t) &&
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pr2->spisize == sizeof(u_int32_t)) {
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				spisizematch = 1;
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else if (pr2->spisize == sizeof(u_int16_t) &&
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 pr1->spisize == sizeof(u_int32_t)) {
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				spisizematch = 1;
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (spisizematch) {
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "IPComp SPI size promoted "
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "from 16bit to 32bit\n");
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!spisizematch) {
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"spisize mismatched: "
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%d peer:%d\n",
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(int)pr2->spisize, (int)pr1->spisize);
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((ph1->natt_flags & NAT_DETECTED) &&
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    natt_udp_encap (pr2->encmode))
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n",
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     s_ipsecdoi_encmode(pr2->encmode),
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff));
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr2->encmode -= ph1->natt_options->mode_udp_diff;
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr2->udp_encap = 1;
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((ph1->natt_flags & NAT_DETECTED) &&
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    natt_udp_encap (pr1->encmode))
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     s_ipsecdoi_encmode(pr1->encmode),
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     pr1->encmode,
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff),
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     pr1->encmode - ph1->natt_options->mode_udp_diff);
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr1->encmode -= ph1->natt_options->mode_udp_diff;
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr1->udp_encap = 1;
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr1->encmode != pr2->encmode) {
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"encmode mismatched: "
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my:%s peer:%s\n",
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_encmode(pr2->encmode),
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_encmode(pr1->encmode));
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (tr1 = pr1->head; tr1; tr1 = tr1->next) {
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (tr2 = pr2->head; tr2; tr2 = tr2->next) {
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (cmpsatrns(pr1->proto_id, tr1, tr2, ph1->rmconf->pcheck_level) == 0)
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto found;
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    found:
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr = newsaproto();
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newpr == NULL) {
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to allocate saproto.\n");
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->proto_id = pr1->proto_id;
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->spisize = pr1->spisize;
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->encmode = pr1->encmode;
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->spi = pr2->spi;		/* copy my SPI */
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->spi_p = pr1->spi;	/* copy peer's SPI */
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->reqid_in = pr2->reqid_in;
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->reqid_out = pr2->reqid_out;
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->udp_encap = pr1->udp_encap | pr2->udp_encap;
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtr = newsatrns();
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newtr == NULL) {
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to allocate satrns.\n");
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(newpr);
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtr->trns_no = tr1->trns_no;
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtr->trns_id = tr1->trns_id;
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtr->encklen = tr1->encklen;
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtr->authtype = tr1->authtype;
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inssatrns(newpr, newtr);
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inssaproto(newpp, newpr);
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pr1 = pr1->next;
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pr2 = pr2->next;
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX should check if we have visited all items or not */
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ordermatters) {
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (side) {
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case RESPONDER:
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!pr2)
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr1 = NULL;
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case INITIATOR:
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!pr1)
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr2 = NULL;
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* should be matched all protocols in a proposal */
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr1 != NULL || pr2 != NULL)
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newpp;
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(newpp);
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* take a single match between saprop.  returns 0 if pp1 equals to pp2. */
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpsaprop(pp1, pp2)
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp1, *pp2;
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp1->pfs_group != pp2->pfs_group) {
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pfs_group mismatch. mine:%d peer:%d\n",
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp1->pfs_group, pp2->pfs_group);
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* FALLTHRU */
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp1->lifetime > pp2->lifetime) {
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"less lifetime proposed. mine:%d peer:%d\n",
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(int)pp1->lifetime, (int)pp2->lifetime);
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* FALLTHRU */
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp1->lifebyte > pp2->lifebyte) {
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"less lifebyte proposed. mine:%d peer:%d\n",
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp1->lifebyte, pp2->lifebyte);
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* FALLTHRU */
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * take a single match between satrns.  returns 0 if tr1 equals to tr2.
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * tr1: peer's satrns
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * tr2: my satrns
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpsatrns(proto_id, tr1, tr2, check_level)
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct satrns *tr1, *tr2;
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int check_level;
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tr1->trns_id != tr2->trns_id) {
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"trns_id mismatched: "
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"my:%s peer:%s\n",
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_trns(proto_id, tr2->trns_id),
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_trns(proto_id, tr1->trns_id));
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tr1->authtype != tr2->authtype) {
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"authtype mismatched: "
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"my:%s peer:%s\n",
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr2->authtype),
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr1->authtype));
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check key length regarding checkmode
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * XXX Shall we send some kind of notify message when key length rejected ?
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(check_level){
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_OBEY:
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_STRICT:
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* FALLTHROUGH */
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_CLAIM:
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr1->encklen < tr2->encklen) {
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "low key length proposed, "
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "mine:%d peer:%d.\n",
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr2->encklen, tr1->encklen);
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 1;
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case PROP_CHECK_EXACT:
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr1->encklen != tr2->encklen) {
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "key length mismatched, "
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "mine:%d peer:%d.\n",
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 tr2->encklen, tr1->encklen);
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 1;
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_satrnsbysainfo(pr, sainfo)
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sainfo *sainfo;
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sainfoalg *a, *b;
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *newtr;
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t;
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (pr->proto_id) {
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sainfo->algs[algclass_ipsec_auth] == NULL) {
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"no auth algorithm found\n");
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		t = 1;
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (a = sainfo->algs[algclass_ipsec_auth]; a; a = a->next) {
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (a->alg == IPSECDOI_ATTR_AUTH_NONE)
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				continue;
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* allocate satrns */
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr = newsatrns();
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (newtr == NULL) {
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate satrns.\n");
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->trns_no = t++;
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg);
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->authtype = a->alg;
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			inssatrns(pr, newtr);
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sainfo->algs[algclass_ipsec_enc] == NULL) {
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"no encryption algorithm found\n");
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		t = 1;
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) {
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) {
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* allocate satrns */
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtr = newsatrns();
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (newtr == NULL) {
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"failed to allocate satrns.\n");
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto err;
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtr->trns_no = t++;
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtr->trns_id = a->alg;
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtr->encklen = a->encklen;
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtr->authtype = b->alg;
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				inssatrns(pr, newtr);
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sainfo->algs[algclass_ipsec_comp] == NULL) {
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"no ipcomp algorithm found\n");
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		t = 1;
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (a = sainfo->algs[algclass_ipsec_comp]; a; a = a->next) {
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* allocate satrns */
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr = newsatrns();
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (newtr == NULL) {
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate satrns.\n");
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->trns_no = t++;
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->trns_id = a->alg;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr->authtype = IPSECDOI_ATTR_AUTH_NONE; /*no auth*/
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			inssatrns(pr, newtr);
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unknown proto_id (%d).\n", pr->proto_id);
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no proposal found */
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr->head == NULL) {
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "no algorithms found.\n");
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsatrns(pr->head);
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct saprop *
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangaproppair2saprop(p0)
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p0;
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *t;
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *newpp;
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *newpr;
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *newtr;
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *spi;
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p0 == NULL)
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* allocate ipsec a sa proposal */
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp = newsaprop();
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newpp == NULL) {
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate saprop.\n");
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->prop_no = p0->prop->p_no;
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* lifetime & lifebyte must be updated later */
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = p0; p; p = p->next) {
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* allocate ipsec sa protocol */
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr = newsaproto();
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newpr == NULL) {
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to allocate saproto.\n");
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check spi size */
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX should be handled isakmp cookie */
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sizeof(newpr->spi) < p->prop->spi_size) {
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid spi size %d.\n", p->prop->spi_size);
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(newpr);
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX SPI bits are left-filled, for use with IPComp.
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we should be switching to variable-length spi field...
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->proto_id = p->prop->proto_id;
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->spisize = p->prop->spi_size;
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(&newpr->spi, 0, sizeof(newpr->spi));
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi = (u_int8_t *)&newpr->spi;
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi += sizeof(newpr->spi);
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi -= p->prop->spi_size;
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(spi, p->prop + 1, p->prop->spi_size);
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->reqid_in = 0;
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->reqid_out = 0;
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (t = p; t; t = t->tnext) {
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"prop#=%d prot-id=%s spi-size=%d "
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"#trns=%d trns#=%d trns-id=%s\n",
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t->prop->p_no,
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_proto(t->prop->proto_id),
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t->prop->spi_size, t->prop->num_t,
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t->trns->t_no,
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_ipsecdoi_trns(t->prop->proto_id,
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t->trns->t_id));
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* allocate ipsec sa transform */
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtr = newsatrns();
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (newtr == NULL) {
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate satrns.\n");
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(newpr);
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ipsecdoi_t2satrns(t->trns,
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    newpp, newpr, newtr) < 0) {
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				flushsaprop(newpp);
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(newtr);
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(newpr);
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			inssatrns(newpr, newtr);
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * If the peer does not specify encryption mode, use
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * transport mode by default.  This is to conform to
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * draft-shacham-ippcp-rfc2393bis-08.txt (explicitly specifies
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * that unspecified == transport), as well as RFC2407
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * (unspecified == implementation dependent default).
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newpr->encmode == 0)
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS;
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inssaproto(newpp, newpr);
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newpp;
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(newpp);
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangflushsaprop(head)
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *head;
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *p, *save;
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = head; p != NULL; p = save) {
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		save = p->next;
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flushsaproto(p->head);
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p);
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangflushsaproto(head)
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *head;
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *p, *save;
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = head; p != NULL; p = save) {
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		save = p->next;
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flushsatrns(p->head);
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(p->keymat);
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(p->keymat_p);
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p);
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangflushsatrns(head)
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *head;
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *p, *save;
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = head; p != NULL; p = save) {
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		save = p->next;
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(p);
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * print multiple proposals
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprintsaprop(pri, pp)
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int pri;
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp;
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *p;
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp == NULL) {
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL, "(null)");
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pp; p; p = p->next) {
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printsaprop0(pri, p);
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * print one proposal.
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprintsaprop0(pri, pp)
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pri;
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp;
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saproto *p;
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp == NULL)
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pp->head; p; p = p->next) {
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printsaproto(pri, p);
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprintsaproto(pri, pr)
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int pri;
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saproto *pr;
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr == NULL)
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(pri, LOCATION, NULL,
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		" (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx "
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"encmode=%s reqid=%d:%d)\n",
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_proto(pr->proto_id),
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(int)pr->spisize,
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(unsigned long)ntohl(pr->spi),
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(unsigned long)ntohl(pr->spi_p),
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_attr_v(IPSECDOI_ATTR_ENC_MODE, pr->encmode),
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(int)pr->reqid_in, (int)pr->reqid_out);
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (tr = pr->head; tr; tr = tr->next) {
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		printsatrns(pri, pr->proto_id, tr);
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprintsatrns(pri, proto_id, tr)
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int pri;
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const int proto_id;
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct satrns *tr;
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tr == NULL)
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL,
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"  (trns_id=%s authtype=%s)\n",
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_trns(proto_id, tr->trns_id),
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype));
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL,
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"  (trns_id=%s encklen=%d authtype=%s)\n",
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_trns(proto_id, tr->trns_id),
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr->encklen,
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype));
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL,
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"  (trns_id=%s)\n",
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_trns(proto_id, tr->trns_id));
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(pri, LOCATION, NULL,
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"(unknown proto_id %d)\n", proto_id);
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprint_proppair0(pri, p, level)
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pri;
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int level;
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char spc[21];
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(spc, ' ', sizeof(spc));
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spc[sizeof(spc) - 1] = '\0';
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (level < 20) {
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spc[level] = '\0';
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(pri, LOCATION, NULL,
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"%s%p: next=%p tnext=%p\n", spc, p, p->next, p->tnext);
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p->next)
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair0(pri, p->next, level + 1);
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p->tnext)
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair0(pri, p->tnext, level + 1);
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangprint_proppair(pri, p)
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int pri;
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	print_proppair0(pri, p, 1);
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_proposal_from_policy(iph2, sp_main, sp_sub)
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp_main, *sp_sub;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *newpp;
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecrequest *req;
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int encmodesv = IPSECDOI_ATTR_ENC_MODE_TRNS; /* use only when complex_bundle */
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp = newsaprop();
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newpp == NULL) {
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate saprop.\n");
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->prop_no = 1;
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->lifetime = iph2->sainfo->lifetime;
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->lifebyte = iph2->sainfo->lifebyte;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newpp->pfs_group = iph2->sainfo->pfs_group;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (lcconf->complex_bundle)
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto skip1;
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * decide the encryption mode of this SA bundle.
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * the mode becomes tunnel mode when there is even one policy
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * of tunnel mode in the SPD.  otherwise the mode becomes
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * transport mode.
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (req = sp_main->req; req; req = req->next) {
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (req->saidx.mode == IPSEC_MODE_TUNNEL) {
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			encmodesv = pfkey2ipsecdoi_mode(req->saidx.mode);
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED))
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				encmodesv += iph2->ph1->natt_options->mode_udp_diff;
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    skip1:
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (req = sp_main->req; req; req = req->next) {
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct saproto *newpr;
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		caddr_t paddr = NULL;
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * check if SA bundle ?
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * nested SAs negotiation is NOT supported.
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 *       me +--- SA1 ---+ peer1
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 *       me +--- SA2 --------------+ peer2
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (req->saidx.src.ss_family && req->saidx.dst.ss_family) {
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (req->saidx.src.ss_len && req->saidx.dst.ss_len) {
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* check the end of ip addresses of SA */
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->side == INITIATOR)
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (caddr_t)&req->saidx.dst;
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				paddr = (caddr_t)&req->saidx.src;
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* allocate ipsec sa protocol */
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr = newsaproto();
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newpr == NULL) {
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to allocate saproto.\n");
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newpr->proto_id = ipproto2doi(req->saidx.proto);
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newpr->proto_id == IPSECDOI_PROTO_IPCOMP)
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->spisize = 2;
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->spisize = 4;
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (lcconf->complex_bundle) {
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode);
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED))
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newpr->encmode +=
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    iph2->ph1->natt_options->mode_udp_diff;
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->encmode = encmodesv;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2->side == INITIATOR)
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->reqid_out = req->saidx.reqid;
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->reqid_in = req->saidx.reqid;
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get algorithms.\n");
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(newpr);
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set new saproto */
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inssaprotorev(newpp, newpr);
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get reqid_in from inbound policy */
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp_sub) {
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct saproto *pr;
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		req = sp_sub->req;
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pr = newpp->head;
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (req && pr) {
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->side == INITIATOR)
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->reqid_in = req->saidx.reqid;
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pr->reqid_out = req->saidx.reqid;
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr = pr->next;
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			req = req->next;
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pr || req) {
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_NOTIFY, LOCATION, NULL,
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"There is a difference "
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"between the in/out bound policies in SPD.\n");
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->proposal = newpp;
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printsaprop0(LLV_DEBUG, newpp);
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(newpp);
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * generate a policy from peer's proposal.
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function unconditionally choices first proposal in SA payload
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * passed by peer.
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_proposal_from_proposal(iph2)
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        struct saprop *newpp = NULL, *pp0, *pp_peer = NULL;
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *newpr = NULL, *pr;
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * make my proposal according as the client proposal.
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * XXX assumed there is only one proposal even if it's the SA bundle.
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        for (i = 0; i < MAXPROPPAIRLEN; i++) {
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                if (pair[i] == NULL)
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                        continue;
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp_peer != NULL)
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			flushsaprop(pp_peer);
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp_peer = aproppair2saprop(pair[i]);
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp_peer == NULL)
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp0 = newsaprop();
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp0 == NULL) {
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to allocate saprop.\n");
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp0->prop_no = 1;
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp0->lifetime = iph2->sainfo->lifetime;
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp0->lifebyte = iph2->sainfo->lifebyte;
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pp0->pfs_group = iph2->sainfo->pfs_group;
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*pp_peer->sctx.ctx_str) {
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp0->sctx.ctx_doi = pp_peer->sctx.ctx_doi;
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp0->sctx.ctx_alg = pp_peer->sctx.ctx_alg;
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp0->sctx.ctx_strlen = pp_peer->sctx.ctx_strlen;
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(pp0->sctx.ctx_str, pp_peer->sctx.ctx_str,
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			       pp_peer->sctx.ctx_strlen);
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp_peer->next != NULL) {
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"pp_peer is inconsistency, ignore it.\n");
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp_peer->head; pr; pr = pr->next)
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct remoteconf *conf;
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr = newsaproto();
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (newpr == NULL)
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate saproto.\n");
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(pp0);
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->proto_id = pr->proto_id;
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->spisize = pr->spisize;
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->encmode = pr->encmode;
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->spi = 0;
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->spi_p = pr->spi;     /* copy peer's SPI */
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->reqid_in = 0;
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newpr->reqid_out = 0;
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			conf = getrmconf(iph2->dst);
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (conf != NULL &&
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				conf->gen_policy == GENERATE_POLICY_UNIQUE){
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newpr->reqid_in = g_nextreqid ;
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newpr->reqid_out = g_nextreqid ++;
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 * XXX there is a (very limited)
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 * risk of reusing the same reqid
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 * as another SP entry for the same peer
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 */
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if(g_nextreqid >= IPSEC_MANUAL_REQID_MAX)
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					g_nextreqid = 1;
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}else{
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newpr->reqid_in = 0;
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newpr->reqid_out = 0;
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0)
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			{
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to get algorithms.\n");
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(newpr);
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(pp0);
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			inssaproto(pp0, newpr);
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		inssaprop(&newpp, pp0);
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        }
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "make a proposal from peer's:\n");
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	printsaprop0(LLV_DEBUG, newpp);
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->proposal = newpp;
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error && newpp)
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flushsaprop(newpp);
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pp_peer)
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flushsaprop(pp_peer);
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair)
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair(pair);
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1295