1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: ipsec_doi.c,v 1.23.4.10 2009/06/19 07:32:52 tteras Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: ipsec_doi.c,v 1.55 2006/08/17 09:20:41 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.
8c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
20c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
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#include <netdb.h>
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if TIME_WITH_SYS_TIME
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h>
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if HAVE_SYS_TIME_H
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <sys/time.h>
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# else
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <time.h>
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "cfparse_proto.h"
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h"
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h"
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "algorithm.h"
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sainfo.h"
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "proposal.h"
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h"
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gcmalloc.h"
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "nattraversal.h"
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
86c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID
87c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int switch_authmethod(int);
88c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <iconv.h>
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gssapi.h"
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_ICONV_2ND_CONST
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define __iconv_const const
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define __iconv_const
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
100c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint verbose_proposal_check = 1;
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
102c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic vchar_t *get_ph1approval __P((struct ph1handle *, struct prop_pair **));
103c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct isakmpsa *get_ph1approvalx __P((struct prop_pair *,
104c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *, struct isakmpsa *, int));
105c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic void print_ph1mismatched __P((struct prop_pair *, struct isakmpsa *));
106c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *));
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cmp_aproppair_i __P((struct prop_pair *, struct prop_pair *));
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *get_ph2approval __P((struct ph2handle *,
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **));
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *get_ph2approvalx __P((struct ph2handle *,
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *));
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic void free_proppair0 __P((struct prop_pair *));
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int get_transform
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct isakmp_pl_p *, struct prop_pair **, int *));
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int32_t ipsecdoi_set_ld __P((vchar_t *));
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_doi __P((u_int32_t));
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_situation __P((u_int32_t));
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_prot_main __P((int));
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_prot_quick __P((int));
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_protocol[]) __P((int)) = {
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_prot_main,	/* IPSECDOI_TYPE_PH1 */
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_prot_quick,	/* IPSECDOI_TYPE_PH2 */
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_spi_size __P((int, int));
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_isakmp __P((int));
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_ah __P((int));
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_esp __P((int));
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_ipcomp __P((int));
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_transform[]) __P((int)) = {
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	0,
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_isakmp,	/* IPSECDOI_PROTO_ISAKMP */
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_ah,		/* IPSECDOI_PROTO_IPSEC_AH */
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_esp,		/* IPSECDOI_PROTO_IPSEC_ESP */
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_ipcomp,	/* IPSECDOI_PROTO_IPCOMP */
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_isakmp __P((struct isakmp_pl_t *));
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ah __P((struct isakmp_pl_t *));
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_esp __P((struct isakmp_pl_t *));
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ipsec __P((int, struct isakmp_pl_t *));
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ipcomp __P((struct isakmp_pl_t *));
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_attributes[]) __P((struct isakmp_pl_t *)) = {
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	0,
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_isakmp,	/* IPSECDOI_PROTO_ISAKMP */
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_ah,		/* IPSECDOI_PROTO_IPSEC_AH */
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_esp,		/* IPSECDOI_PROTO_IPSEC_ESP */
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_ipcomp,	/* IPSECDOI_PROTO_IPCOMP */
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1prop __P((struct isakmpsa *, caddr_t));
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1trns __P((struct isakmpsa *, caddr_t));
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1attr __P((struct isakmpsa *, caddr_t));
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *setph2proposal0 __P((const struct ph2handle *,
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *, const struct saproto *));
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
161c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic vchar_t *getidval __P((int, vchar_t *));
162c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
163c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef HAVE_GSSAPI
164c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct isakmpsa *fixup_initiator_sa __P((struct isakmpsa *,
165c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *));
166c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 1 SA payload.
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make new SA payload to be replyed not including general header.
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the pointer to one of isakmpsa in proposal is set into iph1->approval.
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive: the pointer to new buffer of SA payload.
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *		  network byte order.
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	NULL	: error occurd.
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkph1proposal(sa, iph1)
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa;
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;		/* new SA payload approved. */
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
187c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	pair = get_proppair(sa, IPSECDOI_TYPE_PH1);
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and get one SA for use */
192c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	newsa = get_ph1approval(iph1, pair);
193c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL)
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->sa_ret = newsa;
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
201c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return 0;
202f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
203f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * acceptable check for remote configuration.
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return a new SA payload to be reply to peer.
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *
209c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehget_ph1approval(iph1, pair)
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;
214c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *sa, tsa;
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *s, *p;
216c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int prophlen;
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->approval) {
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delisakmpsa(iph1->approval);
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->approval = NULL;
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i] == NULL)
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (s = pair[i]; s; s = s->next) {
228c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			prophlen =
229c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    sizeof(struct isakmp_pl_p) + s->prop->spi_size;
230c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare proposal and select one */
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (p = s; p; p = p->tnext) {
233c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if ((sa = get_ph1approvalx(p,
234c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    iph1->rmconf->proposal, &tsa,
235c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    iph1->rmconf->pcheck_level)) != NULL)
236c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					goto found;
237c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
238c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
239c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
241c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/*
242c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * if there is no suitable proposal, racoon complains about all of
243c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 * mismatched items in those proposal.
244c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	 */
245c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (verbose_proposal_check) {
246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		for (i = 0; i < MAXPROPPAIRLEN; i++) {
247c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (pair[i] == NULL)
248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				continue;
249c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			for (s = pair[i]; s; s = s->next) {
250c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				prophlen = sizeof(struct isakmp_pl_p)
251c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						+ s->prop->spi_size;
252c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				for (p = s; p; p = p->tnext) {
253c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					print_ph1mismatched(p,
254c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						iph1->rmconf->proposal);
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "no suitable proposal found.\n");
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfound:
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "an acceptable proposal found.\n");
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check DH group settings */
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->dhgrp) {
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->dhgrp->prime && sa->dhgrp->gen1) {
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it's ok */
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto saok;
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid DH parameter found, use default.\n");
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oakley_dhgrp_free(sa->dhgrp);
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa->dhgrp=NULL;
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) {
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa->dhgrp = NULL;
280c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		racoon_free(sa);
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsaok:
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->gssid != NULL)
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n",
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)sa->gssid->l, sa->gssid->v);
289c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph1-> side == INITIATOR) {
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->proposal->gssid != NULL)
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->gi_i = vdup(iph1->rmconf->proposal->gssid);
292c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (tsa.gssid != NULL)
293c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph1->gi_r = vdup(tsa.gssid);
294c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->approval = fixup_initiator_sa(sa, &tsa);
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
296c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (tsa.gssid != NULL) {
297c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			iph1->gi_r = vdup(tsa.gssid);
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->gi_i = gssapi_get_id(iph1);
299c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (sa->gssid == NULL && iph1->gi_i != NULL)
300c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sa->gssid = vdup(iph1->gi_i);
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
302c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->approval = sa;
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->gi_i != NULL)
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n",
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)iph1->gi_i->l, iph1->gi_i->v);
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->gi_r != NULL)
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n",
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)iph1->gi_r->l, iph1->gi_r->v);
310c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
311c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->approval = sa;
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
313c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if(iph1->approval) {
314c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n",
315c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    s_oakley_attr_method(iph1->approval->authmethod));
316c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
318c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	newsa = get_sabyproppair(p, iph1);
319c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (newsa == NULL){
320c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delisakmpsa(iph1->approval);
321c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->approval = NULL;
322c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare peer's single proposal and all of my proposal.
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * and select one if suiatable.
330c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * p       : one of peer's proposal.
331c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * proposal: my proposals.
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
333c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic struct isakmpsa *
334c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehget_ph1approvalx(p, proposal, sap, check_level)
335c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct prop_pair *p;
336c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *proposal, *sap;
337c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int check_level;
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
339c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmp_pl_p *prop = p->prop;
340c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmp_pl_t *trns = p->trns;
341c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa sa, *s, *tsap;
342c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int authmethod;
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
344c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
345c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh       		"prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n",
346c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		prop->p_no, s_ipsecdoi_proto(prop->proto_id),
347c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		prop->spi_size, prop->num_t);
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
349c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
350c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		"trns#=%d, trns-id=%s\n",
351c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		trns->t_no,
352c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		s_ipsecdoi_trns(prop->proto_id, trns->t_id));
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
354c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	tsap = sap != NULL ? sap : &sa;
355c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
356c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	memset(tsap, 0, sizeof(*tsap));
357c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (t2isakmpsa(trns, tsap) < 0)
358c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return NULL;
359c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	for (s = proposal; s != NULL; s = s->next) {
360c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID
361c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = switch_authmethod(s->authmethod);
362c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
363c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = s->authmethod;
364c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
365c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "Compared: DB:Peer\n");
366c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "(lifetime = %ld:%ld)\n",
367c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			(long)s->lifetime, (long)tsap->lifetime);
368c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "(lifebyte = %zu:%zu)\n",
369c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->lifebyte, tsap->lifebyte);
370c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "enctype = %s:%s\n",
371c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
372c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->enctype),
373c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
374c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					tsap->enctype));
375c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "(encklen = %d:%d)\n",
376c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->encklen, tsap->encklen);
377c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "hashtype = %s:%s\n",
378c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
379c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->hashtype),
380c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
381c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					tsap->hashtype));
382c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "authmethod = %s:%s\n",
383c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
384c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->authmethod),
385c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
386c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					tsap->authmethod));
387c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL, "dh_group = %s:%s\n",
388c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
389c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->dh_group),
390c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
391c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					tsap->dh_group));
392c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if 0
393c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* XXX to be considered ? */
394c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (tsap->lifebyte > s->lifebyte) ;
395c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
396c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/*
397c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * if responder side and peer's key length in proposal
398c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * is bigger than mine, it might be accepted.
399c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 */
400c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if(tsap->enctype == s->enctype &&
401c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    tsap->authmethod == authmethod &&
402c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    tsap->hashtype == s->hashtype &&
403c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    tsap->dh_group == s->dh_group &&
404c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    tsap->encklen == s->encklen) {
405c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			switch(check_level) {
406c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case PROP_CHECK_OBEY:
407c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto found;
408c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
409c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case PROP_CHECK_STRICT:
411c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if ((tsap->lifetime > s->lifetime) ||
412c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    (tsap->lifebyte > s->lifebyte))
413c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					continue;
414c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto found;
415c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
416c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
417c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case PROP_CHECK_CLAIM:
418c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (tsap->lifetime < s->lifetime)
419c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->lifetime = tsap->lifetime;
420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (tsap->lifebyte < s->lifebyte)
421c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->lifebyte = tsap->lifebyte;
422c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto found;
423c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
424c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
425c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case PROP_CHECK_EXACT:
426c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if ((tsap->lifetime != s->lifetime) ||
427c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    (tsap->lifebyte != s->lifebyte))
428c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					continue;
429c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto found;
430c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
431c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
432c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			default:
433c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
434c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    "Unexpected proposal_check value\n");
435c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				continue;
436c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
437c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
438c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
441c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehfound:
442c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (tsap->dhgrp != NULL){
443c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		oakley_dhgrp_free(tsap->dhgrp);
444c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		tsap->dhgrp = NULL;
445c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
447c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if ((s = dupisakmpsa(s)) != NULL) {
448c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		switch(check_level) {
449c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case PROP_CHECK_OBEY:
450c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->lifetime = tsap->lifetime;
451c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->lifebyte = tsap->lifebyte;
452c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
453c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
454c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case PROP_CHECK_STRICT:
455c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->lifetime = tsap->lifetime;
456c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			s->lifebyte = tsap->lifebyte;
457c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
458c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
459c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case PROP_CHECK_CLAIM:
460c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (tsap->lifetime < s->lifetime)
461c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->lifetime = tsap->lifetime;
462c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (tsap->lifebyte < s->lifebyte)
463c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->lifebyte = tsap->lifebyte;
464c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
465c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
466c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		default:
467c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			break;
468c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
469c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
470c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return s;
471c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
472c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
473c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*
474c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * print all of items in peer's proposal which are mismatched to my proposal.
475c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * p       : one of peer's proposal.
476c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh * proposal: my proposals.
477c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh */
478c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic void
479c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehprint_ph1mismatched(p, proposal)
480c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct prop_pair *p;
481c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *proposal;
482c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
483c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa sa, *s;
484c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
485c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	memset(&sa, 0, sizeof(sa));
486c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (t2isakmpsa(p->trns, &sa) < 0)
487c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return;
488c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	for (s = proposal; s ; s = s->next) {
489c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (sa.enctype != s->enctype) {
490c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
491c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"rejected enctype: "
492c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
493c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"%s:%s\n",
494c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->prop_no, s->trns_no,
495c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				p->prop->p_no, p->trns->t_no,
496c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
497c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->enctype),
498c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG,
499c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa.enctype));
500c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
501c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (sa.authmethod != s->authmethod) {
502c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
503c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"rejected authmethod: "
504c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
505c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"%s:%s\n",
506c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->prop_no, s->trns_no,
507c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				p->prop->p_no, p->trns->t_no,
508c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
509c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->authmethod),
510c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD,
511c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa.authmethod));
512c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
513c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (sa.hashtype != s->hashtype) {
514c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
515c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"rejected hashtype: "
516c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
517c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"%s:%s\n",
518c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->prop_no, s->trns_no,
519c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				p->prop->p_no, p->trns->t_no,
520c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
521c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->hashtype),
522c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG,
523c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa.hashtype));
524c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
525c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (sa.dh_group != s->dh_group) {
526c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
527c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"rejected dh_group: "
528c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"DB(prop#%d:trns#%d):Peer(prop#%d:trns#%d) = "
529c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"%s:%s\n",
530c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s->prop_no, s->trns_no,
531c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				p->prop->p_no, p->trns->t_no,
532c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
533c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					s->dh_group),
534c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC,
535c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa.dh_group));
536c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
537c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
538c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
539c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (sa.dhgrp != NULL){
540c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		oakley_dhgrp_free(sa.dhgrp);
541c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		sa.dhgrp=NULL;
542c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get ISAKMP data attributes
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
549c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeht2isakmpsa(trns, sa)
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d, *prev;
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int life_t;
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int keylen = 0;
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *val = NULL;
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len, tlen;
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *p;
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(*trns);
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prev = (struct isakmp_data *)NULL;
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)(trns + 1);
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* default */
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT;
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->lifebyte = 0;
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!sa->dhgrp)
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr(type), flag,
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr_v(type, ntohs(d->lorv)));
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get variable-sized item */
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {	/*TV*/
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = 2;
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = (u_char *)&d->lorv;
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {	/*TLV*/
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = ntohs(d->lorv);
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = (u_char *)(d + 1);
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			val = vmalloc(len);
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!val)
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(val->v, p, len);
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->enctype = (u_int16_t)ntohs(d->lorv);
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->hashtype = (u_int16_t)ntohs(d->lorv);
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->authmethod = ntohs(d->lorv);
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dh_group = (u_int16_t)ntohs(d->lorv);
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = (int)ntohs(d->lorv);
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (type == OAKLEY_ATTR_GRP_TYPE_MODP)
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->type = type;
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->prime = val;
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(val);
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag)
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = ntohs(d->lorv);
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = 0;
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (len > 4)
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(&sa->dhgrp->gen1, d + 1, len);
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = ntohl(sa->dhgrp->gen1);
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(val);
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag)
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = ntohs(d->lorv);
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = 0;
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (len > 4)
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(&sa->dhgrp->gen2, d + 1, len);
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = ntohl(sa->dhgrp->gen2);
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->curve_a = val;
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->curve_b = val;
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = (int)ntohs(d->lorv);
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (type) {
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_SEC:
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_KB:
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = type;
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT;
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!prev
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) !=
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					OAKLEY_ATTR_SA_LD_TYPE) {
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "life duration must follow ltype\n");
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (life_t) {
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->lifetime = ipsecdoi_set_ld(val);
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (sa->lifetime == 0) {
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto err;
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->lifebyte = ipsecdoi_set_ld(val);
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (sa->lifebyte == 0) {
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto err;
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type: %d\n", life_t);
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (len % 8 != 0) {
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"keylen %d: not multiple of 8\n",
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					len);
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->encklen = (u_int16_t)len;
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			keylen++;
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* unsupported */
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->order = val;
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GSS_ID:
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int error = -1;
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iconv_t cd = (iconv_t) -1;
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			size_t srcleft, dstleft, rv;
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			__iconv_const char *src;
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *dst;
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Older verions of racoon just placed the
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * ISO-Latin-1 string on the wire directly.
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Check to see if we are configured to be
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * compatible with this behavior.
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if ((sa->gssid = vmalloc(len)) == NULL) {
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to allocate memory\n");
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(sa->gssid->v, d + 1, len);
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "received old-style gss "
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "id '%.*s' (len %zu)\n",
773c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				    (int)sa->gssid->l, sa->gssid->v,
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa->gssid->l);
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				error = 0;
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * For Windows 2000 compatibility, we expect
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * the GSS ID attribute on the wire to be
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * encoded in UTF-16LE.  Internally, we work
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * in ISO-Latin-1.  Therefore, we should need
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * 1/2 the specified length, which should always
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * be a multiple of 2 octets.
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			cd = iconv_open("latin1", "utf-16le");
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (cd == (iconv_t) -1) {
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "unable to initialize utf-16le -> latin1 "
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "conversion descriptor: %s\n",
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((sa->gssid = vmalloc(len / 2)) == NULL) {
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "failed to allocate memory\n");
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			src = (__iconv_const char *)(d + 1);
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			srcleft = len;
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dst = sa->gssid->v;
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dstleft = len / 2;
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
808c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			rv = iconv(cd, (__iconv_const char **)&src, &srcleft,
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   &dst, &dstleft);
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (rv != 0) {
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rv == -1) {
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "unable to convert GSS ID from "
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "utf-16le -> latin1: %s\n",
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    strerror(errno));
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				} else {
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "%zd character%s in GSS ID cannot "
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "be represented in latin1\n",
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    rv, rv == 1 ? "" : "s");
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* XXX dstleft should always be 0; assert it? */
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->gssid->l = (len / 2) - dstleft;
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "received gss id '%.*s' (len %zu)\n",
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (int)sa->gssid->l, sa->gssid->v, sa->gssid->l);
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			error = 0;
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (cd != (iconv_t)-1)
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(void)iconv_close(cd);
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((error != 0) && (sa->gssid != NULL)) {
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(sa->gssid);
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->gssid = NULL;
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_GSSAPI */
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prev = d;
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d));
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + ntohs(d->lorv));
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d) + ntohs(d->lorv));
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* key length must not be specified on some algorithms */
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (keylen) {
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->enctype == OAKLEY_ATTR_ENC_ALG_DES
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_IDEA_H
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || sa->enctype == OAKLEY_ATTR_ENC_ALG_IDEA
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || sa->enctype == OAKLEY_ATTR_ENC_ALG_3DES) {
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"keylen must not be specified "
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"for encryption algorithm %d\n",
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->enctype);
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 2 SA payload and select single proposal.
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make new SA payload to be replyed not including general header.
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by responder only.
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: succeed.
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: error occured.
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_selectph2proposal(iph2)
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret;
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
896c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and select a proposal. */
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = get_ph2approval(iph2, pair);
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret == NULL)
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make a SA to be replayed. */
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* SPI must be updated later. */
908c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->sa_ret = get_sabyproppair(ret, iph2->ph1);
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair0(ret);
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa_ret == NULL)
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 2 SA payload returned from responder.
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by initiator only.
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: valid.
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: invalid.
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkph2proposal(iph2)
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **rpair = NULL, **spair = NULL;
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i, n, num;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa_ret = NULL;
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair of SA sent. */
934c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	spair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair == NULL) {
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get prop pair.\n");
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX should check the number of transform */
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair of SA replayed */
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rpair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2);
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair == NULL) {
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get prop pair.\n");
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check proposal is only one ? */
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	n = 0;
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	num = 0;
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (rpair[i]) {
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			n = i;
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			num++;
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num == 0) {
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no proposal received.\n");
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num != 1) {
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"some proposals received.\n");
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair[n] == NULL) {
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proposal number:%d received.\n", i);
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
975c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair[n]->tnext != NULL) {
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"multi transforms replyed.\n");
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cmp_aproppair_i(rpair[n], spair[n])) {
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"proposal mismathed.\n");
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * check and select a proposal.
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * ensure that there is no modification of the proposal by
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * cmp_aproppair_i()
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = get_ph2approval(iph2, rpair);
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make a SA to be replayed. */
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_ret = iph2->sa_ret;
1000c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->sa_ret = get_sabyproppair(p, iph2->ph1);
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair0(p);
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa_ret == NULL)
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair)
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair(rpair);
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair)
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair(spair);
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa_ret)
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(sa_ret);
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare two prop_pair which is assumed to have same proposal number.
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the case of bundle or single SA, NOT multi transforms.
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * a: a proposal that is multi protocols and single transform, usually replyed.
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * b: a proposal that is multi protocols and multi transform, usually sent.
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: this function is for initiator.
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: equal
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	1: not equal
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * XXX cannot understand the comment!
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmp_aproppair_i(a, b)
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *a, *b;
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q, *r;
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = a, q = b; p && q; p = p->next, q = q->next) {
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (r = q; r; r = r->tnext) {
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare trns */
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->trns->t_no == r->trns->t_no)
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!r) {
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* no suitable transform found */
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"no suitable transform found.\n");
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare prop */
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->p_no != r->prop->p_no) {
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%d mismatched, "
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"expected #%d.\n",
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				r->prop->p_no, p->prop->p_no);
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->proto_id != r->prop->proto_id) {
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proto_id mismathed: my:%d peer:%d\n",
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				r->prop->proto_id, p->prop->proto_id);
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->spi_size != r->prop->spi_size) {
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid spi size: %d.\n",
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p->prop->spi_size);
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check #of transforms */
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->num_t != 1) {
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"#of transform is %d, "
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"but expected 1.\n", p->prop->num_t);
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->trns->t_id != r->trns->t_id) {
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"transform number has been modified.\n");
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->trns->reserved != r->trns->reserved) {
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"reserved field should be zero.\n");
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare attribute */
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = ntohs(r->trns->h.len) - sizeof(*p->trns);
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (memcmp(p->trns + 1, r->trns + 1, len) != 0) {
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attribute has been modified.\n");
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((p && !q) || (!p && q)) {
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* # of protocols mismatched */
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"#of protocols mismatched.\n");
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * acceptable check for policy configuration.
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return a new SA payload to be reply to peer.
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_ph2approval(iph2, pair)
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret;
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->approval = NULL;
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin compare proposals.\n");
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i] == NULL)
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pair[%d]: %p\n", i, pair[i]);
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair(LLV_DEBUG, pair[i]);;
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare proposal and select one */
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = get_ph2approvalx(iph2, pair[i]);
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != NULL) {
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* found */
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ret;
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "no suitable policy found.\n");
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare my proposal and peers just one proposal.
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set a approval.
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_ph2approvalx(iph2, pp)
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pp;
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret = NULL;
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pr0, *pr = NULL;
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *q1, *q2;
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr0 = aproppair2saprop(pp);
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr0 == NULL)
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (q1 = pr0; q1; q1 = q1->next) {
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (q2 = iph2->proposal; q2; q2 = q2->next) {
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"peer's single bundle:\n");
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			printsaprop0(LLV_DEBUG, q1);
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my single bundle:\n");
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			printsaprop0(LLV_DEBUG, q2);
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr = cmpsaprop_alloc(iph2->ph1, q1, q2, iph2->side);
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr != NULL)
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto found;
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"not matched\n");
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no proposal matching */
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(pr0);
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfound:
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(pr0);
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "matched\n");
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->approval = pr;
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *sp;
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *x;
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *n = NULL;
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = NULL;
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pp; p; p = p->next) {
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * find a proposal with matching proto_id.
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we have analyzed validity already, in cmpsaprop_alloc().
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (sp = pr->head; sp; sp = sp->next) {
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sp->proto_id == p->prop->proto_id)
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!sp)
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sp->head->next)
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;	/* XXX */
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (x = p; x; x = x->tnext)
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sp->head->trns_no == x->trns->t_no)
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!x)
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;	/* XXX */
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n = racoon_calloc(1, sizeof(struct prop_pair));
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (n == NULL) {
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get buffer.\n");
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n->prop = x->prop;
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n->trns = x->trns;
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* need to preserve the order */
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (x = ret; x && x->next; x = x->next)
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			;
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (x && x->prop == n->prop) {
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (/*nothing*/; x && x->tnext; x = x->tnext)
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				;
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x->tnext = n;
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (x)
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x->next = n;
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret = n;
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* #of transforms should be updated ? */
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfree_proppair(pair)
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair0(pair[i]);
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pair[i] = NULL;
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(pair);
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic void
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfree_proppair0(pair)
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pair;
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q, *r, *s;
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = pair;
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (p) {
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		q = p->next;
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r = p;
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (r) {
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s = r->tnext;
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(r);
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r = s;
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = q;
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get proposal pairs from SA payload.
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * tiny check for proposal payload.
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1285c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct prop_pair **
1286c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehget_proppair(sa, mode)
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa;
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int mode;
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair = NULL;
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int num_p = 0;			/* number of proposal for use */
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v;
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "total SA len=%zu\n", sa->l);
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plogdump(LLV_DEBUG, sa->v, sa->l);
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check SA payload size */
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->l < sizeof(*sab)) {
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid SA length = %zu.\n", sa->l);
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check DOI */
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (check_doi(ntohl(sab->doi)) < 0)
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check SITUATION */
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (check_situation(ntohl(sab->sit)) < 0)
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair));
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL) {
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1321a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
1322a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley	memset(pair, 0, MAXPROPPAIRLEN * sizeof(*pair));
1323a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(pair, 0, sizeof(pair));
1325a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (caddr_t)(sab + 1);
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sa->l - sizeof(*sab);
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proplen;
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pbuf = NULL;
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *pa;
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen);
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pbuf == NULL)
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pa = (struct isakmp_parse_t *)pbuf->v;
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa->type != ISAKMP_NPTYPE_NONE;
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa++) {
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check the value of next payload */
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pa->type != ISAKMP_NPTYPE_P) {
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Invalid payload type=%u\n", pa->type);
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)pa->ptr;
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proplen = pa->len;
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"proposal #%u len=%d\n", prop->p_no, proplen);
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (proplen == 0) {
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proposal with length %d\n", proplen);
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check Protocol ID */
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!check_protocol[mode]) {
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported mode %d\n", mode);
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_protocol[mode](prop->proto_id) < 0)
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check SPI length when IKE. */
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_spi_size(prop->proto_id, prop->spi_size) < 0)
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get transform */
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (get_transform(prop, pair, &num_p) < 0) {
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(pbuf);
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = NULL;
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int notrans, nprop;
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q;
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check for proposals with no transforms */
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!pair[i])
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "pair %d:\n", i);
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair(LLV_DEBUG, pair[i]);
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		notrans = nprop = 0;
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (p = pair[i]; p; p = p->next) {
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->trns == NULL) {
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				notrans++;
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (q = p; q; q = q->tnext)
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				nprop++;
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX at this moment, we cannot accept proposal group
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with multiple proposals.  this should be fixed.
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i]->next) {
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%u ignored "
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"(multiple proposal not supported)\n",
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[i]->prop->p_no);
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			notrans++;
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (notrans) {
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (p = pair[i]; p; p = q) {
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				q = p->next;
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(p);
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pair[i] = NULL;
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			num_p--;
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%u: %d transform\n",
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[i]->prop->p_no, nprop);
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* bark if no proposal is found. */
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num_p <= 0) {
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no Proposal found.\n");
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pair;
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbad:
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair != NULL)
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(pair);
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform payload.
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive: return the pointer to the payload of valid transform.
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0	: No valid transform found.
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_transform(prop, pair, num_p)
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *num_p;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen; /* total length of all transform in a proposal */
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trnslen;
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pbuf = NULL;
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *pa;
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p = NULL, *q;
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int num_t;
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size;
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(prop->h.len)
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		- (sizeof(struct isakmp_pl_p) + prop->spi_size);
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, tlen);
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pbuf == NULL)
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and get transform for use */
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	num_t = 0;
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pa = (struct isakmp_parse_t *)pbuf->v;
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa->type != ISAKMP_NPTYPE_NONE;
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa++) {
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		num_t++;
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check the value of next payload */
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pa->type != ISAKMP_NPTYPE_T) {
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Invalid payload type=%u\n", pa->type);
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)pa->ptr;
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = pa->len;
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"transform #%u len=%u\n", trns->t_no, trnslen);
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check transform ID */
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (prop->proto_id >= ARRAYLEN(check_transform)) {
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (prop->proto_id >= ARRAYLEN(check_attributes)) {
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!check_transform[prop->proto_id]
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || !check_attributes[prop->proto_id]) {
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_transform[prop->proto_id](trns->t_id) < 0)
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check data attributes */
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_attributes[prop->proto_id](trns) != 0)
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = racoon_calloc(1, sizeof(*p));
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p == NULL) {
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get buffer.\n");
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->prop = prop;
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->trns = trns;
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* need to preserve the order */
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (q = pair[prop->p_no]; q && q->next; q = q->next)
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			;
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (q && q->prop == p->prop) {
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (/*nothing*/; q && q->tnext; q = q->tnext)
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				;
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			q->tnext = p;
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (q)
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				q->next = p;
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[prop->p_no] = p;
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(*num_p)++;
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(pbuf);
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make a new SA payload from prop_pair.
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: this function make spi value clear.
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
1567c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehget_sabyproppair(pair, iph1)
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pair;
1569c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ph1handle *iph1;
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newtlen;
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_p = NULL;
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int prophlen, trnslen;
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newtlen = sizeof(struct ipsecdoi_sa_b);
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair; p; p = p->next) {
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += sizeof(struct isakmp_pl_p);
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += p->prop->spi_size;
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += ntohs(p->trns->h.len);
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newsa = vmalloc(newtlen);
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL) {
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n");
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = newsa->v;
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct isakmp_gen *)bp)->len = htons(newtlen);
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update some of values in SA header */
1595c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	((struct ipsecdoi_sa_b *)bp)->doi = htonl(iph1->rmconf->doitype);
1596c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	((struct ipsecdoi_sa_b *)bp)->sit = htonl(iph1->rmconf->sittype);
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp += sizeof(struct ipsecdoi_sa_b);
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair; p; p = p->next) {
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prophlen = sizeof(struct isakmp_pl_p)
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ p->prop->spi_size;
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = ntohs(p->trns->h.len);
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_p)
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_p = ISAKMP_NPTYPE_P;
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create proposal */
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(bp, p->prop, prophlen);
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE;
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen);
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->num_t = 1;
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np_p = &((struct isakmp_pl_p *)bp)->h.np;
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(bp + sizeof(struct isakmp_pl_p), 0, p->prop->spi_size);
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bp += prophlen;
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create transform */
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(bp, p->trns, trnslen);
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE;
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_t *)bp)->h.len = htons(trnslen);
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bp += trnslen;
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * update responder's spi
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_updatespi(iph2)
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair, *p;
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *spi;
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2);
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i])
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i == MAXPROPPAIRLEN || pair[i]->tnext) {
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* multiple transform must be filtered by selectph2proposal.*/
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp = iph2->approval;
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair[i]; p; p = p->next) {
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * find a proposal/transform with matching proto_id/t_id.
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we have analyzed validity already, in cmpsaprop_alloc().
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->prop->proto_id == pr->proto_id &&
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    p->trns->t_id == pr->head->trns_id) {
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!pr)
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX SPI bits are left-filled, for use with IPComp.
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we should be switching to variable-length spi field...
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi = (u_int8_t *)&pr->spi;
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi += sizeof(pr->spi);
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi -= pr->spisize;
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy((caddr_t)p->prop + sizeof(*p->prop), spi, pr->spisize);
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make a new SA payload from prop_pair.
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_sabysaprop(pp0, sa0)
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp0;
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa0;
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair = NULL;
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa = NULL;
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newtlen;
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_p = NULL;
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p = NULL;
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
17020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
17030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int prophlen, trnslen;
17040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
17050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
17060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
17080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = get_proppair(sa0, IPSECDOI_TYPE_PH2);
17090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
17100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
17110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newtlen = sizeof(struct ipsecdoi_sa_b);
17130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pp = pp0; pp; pp = pp->next) {
17140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[pp->prop_no] == NULL)
17160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
17170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
17190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtlen += (sizeof(struct isakmp_pl_p)
17200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ pr->spisize);
17210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (tr = pr->head; tr; tr = tr->next) {
17230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (p = pair[pp->prop_no]; p; p = p->tnext) {
17240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (tr->trns_no == p->trns->t_no)
17250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
17260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
17270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (p == NULL)
17280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
17290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtlen += ntohs(p->trns->h.len);
17310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
17320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newsa = vmalloc(newtlen);
17360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL) {
17370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n");
17380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
17390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = newsa->v;
17410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* some of values of SA must be updated in the out of this function */
17430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct isakmp_gen *)bp)->len = htons(newtlen);
17440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp += sizeof(struct ipsecdoi_sa_b);
17450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
17470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pp = pp0; pp; pp = pp->next) {
17480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
17500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			prophlen = sizeof(struct isakmp_pl_p)
17510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					+ p->prop->spi_size;
17520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (tr = pr->head; tr; tr = tr->next) {
17540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (p = pair[pp->prop_no]; p; p = p->tnext) {
17550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (tr->trns_no == p->trns->t_no)
17560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
17570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
17580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (p == NULL)
17590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
17600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				trnslen = ntohs(p->trns->h.len);
17620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (np_p)
17640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					*np_p = ISAKMP_NPTYPE_P;
17650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* create proposal */
17670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(bp, p->prop, prophlen);
17690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE;
17700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen);
17710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->num_t = 1;
17720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				np_p = &((struct isakmp_pl_p *)bp)->h.np;
17730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bp += prophlen;
17740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* create transform */
17760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(bp, p->trns, trnslen);
17770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE;
17780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_t *)bp)->h.len = htons(trnslen);
17790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bp += trnslen;
17800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
17810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
17850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
17860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair != NULL)
17870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(pair);
17880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
17900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newsa != NULL) {
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(newsa);
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newsa = NULL;
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * If some error happens then return 0.  Although 0 means that lifetime is zero,
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * such a value should not be accepted.
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Also 0 of lifebyte should not be included in a packet although 0 means not
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * to care of it.
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int32_t
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_set_ld(buf)
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t ld;
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == 0)
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (buf->l) {
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 2:
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ld = ntohs(*(u_int16_t *)buf->v);
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 4:
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ld = ntohl(*(u_int32_t *)buf->v);
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"length %zu of life duration "
18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"isn't supported.\n", buf->l);
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ld;
18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check DOI
18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_doi(doi)
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t doi;
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (doi) {
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_DOI:
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid value of DOI 0x%08x.\n", doi);
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check situation
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_situation(sit)
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t sit;
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (sit) {
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_IDENTITY_ONLY:
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_SECRECY:
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_INTEGRITY:
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"situation 0x%08x unsupported yet.\n", sit);
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid situation 0x%08x.\n", sit);
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check protocol id in main mode
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_prot_main(proto_id)
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_ISAKMP:
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Illegal protocol id=%u.\n", proto_id);
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check protocol id in quick mode
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_prot_quick(proto_id)
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid protocol id %d.\n", proto_id);
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_spi_size(proto_id, size)
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id, size;
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_ISAKMP:
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 0) {
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* WARNING */
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"SPI size isn't zero, but IKE proposal.\n");
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 4) {
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid SPI size=%d for IPSEC proposal.\n",
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size);
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 2 && size != 4) {
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid SPI size=%d for IPCOMP proposal.\n",
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size);
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ??? */
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in ISAKMP.
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_isakmp(t_id)
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_KEY_IKE:
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in proto_id=%u.\n",
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			t_id, IPSECDOI_KEY_IKE);
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in AH.
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_ah(t_id)
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_MD5:
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA:
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA256:
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA384:
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA512:
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_DES:
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"not support transform-id=%u in AH.\n", t_id);
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in AH.\n", t_id);
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in ESP.
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_esp(t_id)
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES:
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3DES:
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_NULL:
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC5:
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAST:
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_BLOWFISH:
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_AES:
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_TWOFISH:
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAMELLIA:
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV32:
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV64:
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_IDEA:
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3IDEA:
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC4:
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"not support transform-id=%u in ESP.\n", t_id);
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in ESP.\n", t_id);
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in IPCOMP.
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_ipcomp(t_id)
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_OUI:
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_DEFLATE:
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_LZS:
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in IPCOMP.\n", t_id);
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check data attributes in IKE.
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_isakmp(trns)
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr(type), flag,
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr_v(type, lorv));
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * some of the attributes must be encoded in TV.
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * see RFC2409 Appendix A "Attribute Classes".
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag) {	/* TLV*/
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"oakley attribute %d must be TV.\n",
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					type);
20980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
20990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check for TLV.  length must be specified. */
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!flag && lorv == 0) {	/*TLV*/
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length %d for TLV attribute %d.\n",
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lorv, type);
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_encdef_ok(lorv)) {
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalied encryption algorithm=%d.\n",
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_hashdef_ok(lorv)) {
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalied hash algorithm=%d.\n",
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
2137c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if 0 /* Clashes with OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB */
2138f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
2141c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"auth method %s isn't supported.\n",
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					s_oakley_attr_method(lorv));
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid auth method %d.\n",
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid DH group %d.\n",
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_GRP_TYPE_MODP:
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"unsupported DH group type %d.\n",
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* sanity checks? */
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_SEC:
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_KB:
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* should check the value */
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GSS_ID:
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check data attributes in IPSEC AH/ESP.
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ah(trns)
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_AH, trns);
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_esp(trns)
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_ESP, trns);
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ipsec(proto_id, trns)
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type = 0;
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrseen[16];	/* XXX magic number */
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attrseen, 0, sizeof(attrseen));
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr(type), flag,
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(type, lorv));
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (type < sizeof(attrseen)/sizeof(attrseen[0]))
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrseen[type]++;
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when ENC_MODE.\n");
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TRNS:
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "UDP encapsulation requested\n");
23190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid encryption mode=%u.\n",
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when AUTH.\n");
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_HMAC_MD5:
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (proto_id == IPSECDOI_PROTO_IPSEC_AH &&
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    trns->t_id != IPSECDOI_AH_MD5) {
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangahmismatch:
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"auth algorithm %u conflicts "
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"with transform %u.\n",
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						lorv, trns->t_id);
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (trns->t_id != IPSECDOI_AH_SHA)
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						goto ahmismatch;
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA256)
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 						goto ahmismatch;
2358c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh 				}
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA384)
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 						goto ahmismatch;
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				}
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA512)
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					goto ahmismatch;
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				}
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_DES_MAC:
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_KPDK:
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"auth algorithm %u isn't supported.\n",
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid auth algorithm=%u.\n",
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when LD_TYPE.\n");
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"life duration was in TLV.\n");
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (lorv == 0) {
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid length of LD\n");
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when GRP_DESC.\n");
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid group description=%u.\n",
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when KEY_LENGTH.\n");
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SECCTX:
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"SECCTX must be in TLV.\n");
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPSEC_AH &&
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"attr AUTH must be present for AH.\n");
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPSEC_ESP &&
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    trns->t_id == IPSECDOI_ESP_NULL &&
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "attr AUTH must be present for ESP NULL encryption.\n");
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ipcomp(trns)
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type = 0;
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrseen[16];	/* XXX magic number */
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attrseen, 0, sizeof(attrseen));
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%d, flag=0x%04x, lorv=0x%04x\n",
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type, flag, lorv);
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (type < sizeof(attrseen)/sizeof(attrseen[0]))
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrseen[type]++;
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when ENC_MODE.\n");
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TRNS:
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "UDP encapsulation requested\n");
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid encryption mode=%u.\n",
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when LD_TYPE.\n");
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"life duration was in TLV.\n");
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (lorv == 0) {
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid length of LD\n");
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when GRP_DESC.\n");
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid group description=%u.\n",
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attr type=%u.\n", type);
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
26060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
26070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
26280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPCOMP &&
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"attr AUTH must be present for AH.\n", type);
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% */
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create phase1 proposal from remote configuration.
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header of SA payload
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
2645c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehipsecdoi_setph1proposal(props)
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *props;
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *mysa;
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sablen;
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* count total size of SA minus isakmp general header */
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not including isakmp general header of SA payload */
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sablen = sizeof(struct ipsecdoi_sa_b);
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sablen += setph1prop(props, NULL);
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mysa = vmalloc(sablen);
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mysa == NULL) {
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate my sa buffer\n");
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create SA payload */
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not including isakmp general header */
2665c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(props->rmconf->doitype);
2666c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(props->rmconf->sittype);
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)setph1prop(props, mysa->v + sizeof(struct ipsecdoi_sa_b));
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return mysa;
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1prop(props, buf)
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *props;
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop = NULL;
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *s = NULL;
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proplen, trnslen;
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_t; /* pointer next trns type in previous header */
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trns_num;
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proplen = sizeof(*prop);
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create proposal */
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)p;
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->h.np = ISAKMP_NPTYPE_NONE;
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->p_no = props->prop_no;
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->proto_id = IPSECDOI_PROTO_ISAKMP;
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = 0;
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += sizeof(*prop);
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np_t = NULL;
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trns_num = 0;
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (s = props; s != NULL; s = s->next) {
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_t)
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_t = ISAKMP_NPTYPE_T;
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = setph1trns(s, p);
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proplen += trnslen;
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* save buffer to pre-next payload */
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			np_t = &((struct isakmp_pl_t *)p)->h.np;
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += trnslen;
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* count up transform length */
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			trns_num++;
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update proposal length */
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->h.len = htons(proplen);
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->num_t = trns_num;
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return proplen;
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1trns(sa, buf)
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns = NULL;
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trnslen, attrlen;
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnslen = sizeof(*trns);
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create transform */
27360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)p;
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.np  = ISAKMP_NPTYPE_NONE;
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_no  = sa->trns_no;
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_id  = IPSECDOI_KEY_IKE;
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += sizeof(*trns);
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attrlen = setph1attr(sa, p);
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnslen += attrlen;
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += attrlen;
27470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.len = htons(trnslen);
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return trnslen;
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1attr(sa, buf)
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrlen = 0;
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->lifetime) {
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t lifetime = htonl((u_int32_t)sa->lifetime);
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data)
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct isakmp_data);
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->lifetime > 0xffff)
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(lifetime);
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						OAKLEY_ATTR_SA_LD_TYPE_SEC);
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sa->lifetime > 0xffff) {
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
2774c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						(caddr_t)&lifetime,
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						sizeof(lifetime));
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sa->lifetime);
27790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
27800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->lifebyte) {
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte);
2785c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data)
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct isakmp_data);
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->lifebyte > 0xffff)
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(lifebyte);
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						OAKLEY_ATTR_SA_LD_TYPE_KB);
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sa->lifebyte > 0xffff) {
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&lifebyte,
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sizeof(lifebyte));
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sa->lifebyte);
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->enctype) {
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_ENC_ALG, sa->enctype);
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->encklen) {
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_KEY_LEN, sa->encklen);
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->authmethod) {
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int authmethod;
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2817c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID
2818c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = switch_authmethod(sa->authmethod);
2819c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#else
2820c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = sa->authmethod;
2821c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_AUTH_METHOD, authmethod);
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->hashtype) {
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_HASH_ALG, sa->hashtype);
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (sa->dh_group) {
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP768:
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP1024:
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP1536:
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP2048:
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP3072:
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP4096:
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP6144:
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP8192:
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't attach group type for known groups */
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_DESC,
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dh_group);
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_EC2N155:
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_EC2N185:
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't attach group type for known groups */
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_TYPE,
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				OAKLEY_ATTR_GRP_TYPE_EC2N);
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0:
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
28620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    sa->gssid != NULL) {
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Older versions of racoon just placed the ISO-Latin-1
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * string on the wire directly.  Check to see if we are
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * configured to be compatible with this behavior.  Otherwise,
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we encode the GSS ID as UTF-16LE for Windows 2000
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * compatibility, which requires twice the number of octets.
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (lcconf->gss_id_enc == LC_GSSENC_LATIN1)
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sa->gssid->l;
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sa->gssid->l * 2;
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, "
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l,
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    sa->gssid->v);
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID,
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(caddr_t)sa->gssid->v,
28830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sa->gssid->l);
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t dstleft = sa->gssid->l * 2;
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t srcleft = sa->gssid->l;
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				const char *src = (const char *)sa->gssid->v;
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				char *odst, *dst = racoon_malloc(dstleft);
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iconv_t cd;
28900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t rv;
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				cd = iconv_open("utf-16le", "latin1");
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (cd == (iconv_t) -1) {
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "unable to initialize "
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "latin1 -> utf-16le "
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "converstion descriptor: %s\n",
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    strerror(errno));
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					attrlen -= sa->gssid->l * 2;
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto gssid_done;
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				odst = dst;
2903c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				rv = iconv(cd, (__iconv_const char **)&src,
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    &srcleft, &dst, &dstleft);
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rv != 0) {
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (rv == -1) {
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						plog(LLV_ERROR, LOCATION, NULL,
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "unable to convert GSS ID "
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "from latin1 -> utf-16le: "
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "%s\n", strerror(errno));
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					} else {
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						/* should never happen */
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						plog(LLV_ERROR, LOCATION, NULL,
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "%zd character%s in GSS ID "
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "cannot be represented "
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "in utf-16le\n",
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    rv, rv == 1 ? "" : "s");
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					}
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(void) iconv_close(cd);
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					attrlen -= sa->gssid->l * 2;
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto gssid_done;
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(void) iconv_close(cd);
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* XXX Check srcleft and dstleft? */
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID,
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					odst, sa->gssid->l * 2);
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(odst);
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang gssid_done:
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_GSSAPI */
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return attrlen;
29380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
29390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *
29410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph2proposal0(iph2, pp, pr)
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct ph2handle *iph2;
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp;
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saproto *pr;
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *p;
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
29500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrlen;
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t trnsoff;
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t x0, x;
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_t; /* pointer next trns type in previous header */
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_int8_t *spi;
29550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int truectxlen = 0;
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = vmalloc(sizeof(*prop) + sizeof(pr->spi));
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal */
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop = (struct isakmp_pl_p *)p->v;
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->h.np = ISAKMP_NPTYPE_NONE;
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->p_no = pp->prop_no;
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->proto_id = pr->proto_id;
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->num_t = 1;
29690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spi = (const u_int8_t *)&pr->spi;
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (pr->proto_id) {
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * draft-shacham-ippcp-rfc2393bis-05.txt:
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * construct 16bit SPI (CPI).
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX we may need to provide a configuration option to
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * generate 32bit SPI.  otherwise we cannot interoeprate
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with nodes that uses 32bit SPI, in case we are initiator.
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
29800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = sizeof(u_int16_t);
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi += sizeof(pr->spi) - sizeof(u_int16_t);
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->l -= sizeof(pr->spi);
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->l += sizeof(u_int16_t);
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = sizeof(pr->spi);
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(prop + 1, spi, prop->spi_size);
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create transform */
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnsoff = sizeof(*prop) + prop->spi_size;
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np_t = NULL;
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (tr = pr->head; tr; tr = tr->next) {
2996c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (pr->proto_id) {
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_ESP:
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * don't build a null encryption
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * with no authentication transform.
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->trns_id == IPSECDOI_ESP_NULL &&
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    tr->authtype == IPSECDOI_ATTR_AUTH_NONE)
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				continue;
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_t) {
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_t = ISAKMP_NPTYPE_T;
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			prop->num_t++;
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get attribute length */
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen = 0;
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifetime) {
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data)
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(struct isakmp_data);
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifetime > 0xffff)
30200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(u_int32_t);
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) {
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data)
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(struct isakmp_data);
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifebyte > 0xffff)
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(u_int32_t);
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);	/* enc mode */
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr->encklen)
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
30310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (pr->proto_id) {
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_ESP:
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* non authentication mode ? */
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE)
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(struct isakmp_data);
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_AH:
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype == IPSECDOI_ATTR_AUTH_NONE) {
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"no authentication algorithm found "
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"but protocol is AH.\n");
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(p);
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPCOMP:
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid protocol: %d\n", pr->proto_id);
30530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(p);
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group))
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ctx_str is defined as char ctx_str[MAX_CTXSTR_SIZ].
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * The string may be smaller than MAX_CTXSTR_SIZ.
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*pp->sctx.ctx_str) {
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			truectxlen = sizeof(struct security_ctx) -
30660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     (MAX_CTXSTR_SIZE - pp->sctx.ctx_strlen);
30670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data) + truectxlen;
30680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = vrealloc(p, p->l + sizeof(*trns) + attrlen);
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p == NULL)
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)p->v;
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set transform's values */
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)(p->v + trnsoff);
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.np  = ISAKMP_NPTYPE_NONE;
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_no  = tr->trns_no;
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_id  = tr->trns_id;
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set attributes */
30830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		x = x0 = p->v + trnsoff + sizeof(*trns);
30840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifetime) {
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE,
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						IPSECDOI_ATTR_SA_LD_TYPE_SEC);
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifetime > 0xffff) {
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int32_t v = htonl((u_int32_t)pp->lifetime);
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD,
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&v, sizeof(v));
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD,
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							pp->lifetime);
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) {
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE,
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						IPSECDOI_ATTR_SA_LD_TYPE_KB);
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifebyte > 0xffff) {
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int32_t v = htonl((u_int32_t)pp->lifebyte);
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD,
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&v, sizeof(v));
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD,
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							pp->lifebyte);
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		x = isakmp_set_attr_l(x, IPSECDOI_ATTR_ENC_MODE, pr->encmode);
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr->encklen)
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_KEY_LENGTH, tr->encklen);
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* mandatory check has done above. */
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP && tr->authtype != IPSECDOI_ATTR_AUTH_NONE)
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || pr->proto_id == IPSECDOI_PROTO_IPSEC_AH)
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_AUTH, tr->authtype);
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group))
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_GRP_DESC,
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph2->sainfo->pfs_group);
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*pp->sctx.ctx_str) {
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct security_ctx secctx;
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			secctx = pp->sctx;
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			secctx.ctx_strlen = htons(pp->sctx.ctx_strlen);
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SECCTX,
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					     (caddr_t)&secctx, truectxlen);
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* update length of this transform. */
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)(p->v + trnsoff);
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.len = htons(sizeof(*trns) + attrlen);
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* save buffer to pre-next payload */
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np_t = &trns->h.np;
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnsoff += (sizeof(*trns) + attrlen);
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (np_t == NULL) {
31450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no suitable proposal was created.\n");
31470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update length of this protocol. */
31510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->h.len = htons(p->l);
31520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return p;
31540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
31570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create phase2 proposal from policy configuration.
31580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header of SA payload.
31590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by initiator only.
31600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
31610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setph2proposal(iph2)
31630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
31640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *proposal, *a;
31660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *b = NULL;
31670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *q;
31680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_sa_b *sab;
31690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
31700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t propoff;	/* for previous field of type of next payload. */
31710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proposal = iph2->proposal;
31730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->sa = vmalloc(sizeof(*sab));
31750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa == NULL) {
31760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate my sa buffer\n");
31780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create SA payload */
31820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab = (struct ipsecdoi_sa_b *)iph2->sa->v;
31830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab->doi = htonl(IPSEC_DOI);
31840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab->sit = htonl(IPSECDOI_SIT_IDENTITY_ONLY);	/* XXX configurable ? */
31850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop = NULL;
31870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	propoff = 0;
31880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (a = proposal; a; a = a->next) {
31890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (b = a->head; b; b = b->next) {
31900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
31910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->ph1->natt_flags & NAT_DETECTED) {
31920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  int udp_diff = iph2->ph1->natt_options->mode_udp_diff;
31930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  plog (LLV_INFO, LOCATION, NULL,
31940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"NAT detected -> UDP encapsulation "
31950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"(ENC_MODE %d->%d).\n",
31960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b->encmode,
31970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b->encmode+udp_diff);
31980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  /* Tunnel -> UDP-Tunnel, Transport -> UDP_Transport */
31990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  b->encmode += udp_diff;
32000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  b->udp_encap = 1;
32010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
32030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			q = setph2proposal0(iph2, a, b);
32050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (q == NULL) {
32060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				VPTRINIT(iph2->sa);
32070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
32080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->sa = vrealloc(iph2->sa, iph2->sa->l + q->l);
32110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->sa == NULL) {
32120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
32130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate my sa buffer\n");
32140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (q)
32150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					vfree(q);
32160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
32170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(iph2->sa->v + iph2->sa->l - q->l, q->v, q->l);
32190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (propoff != 0) {
32200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop = (struct isakmp_pl_p *)(iph2->sa->v +
32210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					propoff);
32220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->h.np = ISAKMP_NPTYPE_P;
32230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
32240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			propoff = iph2->sa->l - q->l;
32250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(q);
32270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
32310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
32340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return 1 if all of the given protocols are transport mode.
32350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
32360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_transportmode(pp)
32380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
32390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr = NULL;
32410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (; pp; pp = pp->next) {
32430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
3244c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS)
32450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return 0;
32460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 1;
32500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_get_defaultlifetime()
32540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
32560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkalgtypes(proto_id, enc, auth, comp)
32600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id, enc, auth, comp;
32610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define TMPALGTYPE2STR(n) s_algtype(algclass_ipsec_##n, n)
32630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
32640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
32650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc == 0 || comp != 0) {
32660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ESP enc=%s auth=%s comp=%s.\n",
32690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
32760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc != 0 || auth == 0 || comp != 0) {
32770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"AH enc=%s auth=%s comp=%s.\n",
32800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
32870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc != 0 || auth != 0 || comp == 0) {
32880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"IPcomp enc=%s auth=%s comp=%s.\n",
32910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
32980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
32990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid ipsec protocol %d\n", proto_id);
33000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
33010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef TMPALGTYPE2STR
33030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
33040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipproto2doi(proto)
33080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
33090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
33110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_AH:
33120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_AH;
33130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_ESP:
33140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_ESP;
33150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_IPCOMP:
33160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPCOMP;
33170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;	/* XXX */
33190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdoi2ipproto(proto)
33230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
33240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
33260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
33270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_AH;
33280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
33290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_ESP;
33300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
33310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_IPCOMP;
33320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;	/* XXX */
33340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
33370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Check if a subnet id is valid for comparison
33380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * with an address id ( address length mask )
33390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * and compare them
33400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return value
33410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  0 for match
33420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  1 for mismatch
33430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
33440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_subnetisaddr_v4( subnet, address )
33470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *subnet;
33480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *address;
33490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct in_addr *mask;
33510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (address->l != sizeof(struct in_addr))
33530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (subnet->l != (sizeof(struct in_addr)*2))
33560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr));
33590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mask->s_addr!=0xffffffff)
33610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return memcmp(subnet->v,address->v,address->l);
33640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
33670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_subnetisaddr_v6( subnet, address )
33700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *subnet;
33710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *address;
33720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct in6_addr *mask;
33740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
33750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (address->l != sizeof(struct in6_addr))
33770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (subnet->l != (sizeof(struct in6_addr)*2))
33800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr));
33830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i=0; i<16; i++)
33850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(mask->s6_addr[i]!=0xff)
33860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 1;
33870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return memcmp(subnet->v,address->v,address->l);
33890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
33920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
33940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Check and Compare two IDs
33950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - specify 0 for exact if wildcards are allowed
33960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return value
33970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  0 for match
33980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  1 for misatch
33990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * = -1 for integrity error
34000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
34010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
34030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_chkcmpids( idt, ids, exact )
34040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *idt; /* id cmp target */
34050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *ids; /* id cmp source */
34060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int exact;
34070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
34080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_bt;
34090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_bs;
34100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t ident_t;
34110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t ident_s;
34120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
34130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* handle wildcard IDs */
34150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (idt == NULL || ids == NULL)
34170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
34180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( !exact )
34190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
34200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
34210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : values matched (ANONYMOUS)\n" );
34220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
34230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
34250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
34260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
34270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : value mismatch (ANONYMOUS)\n" );
34280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
34290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make sure the ids are of the same type */
34330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_bt = (struct ipsecdoi_id_b *) idt->v;
34350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_bs = (struct ipsecdoi_id_b *) ids->v;
34360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_t.v = idt->v + sizeof(*id_bt);
34380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_t.l = idt->l - sizeof(*id_bt);
34390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_s.v = ids->v + sizeof(*id_bs);
34400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_s.l = ids->l - sizeof(*id_bs);
34410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (id_bs->type != id_bt->type)
34430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
34440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
34450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * special exception for comparing
34460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 * address to subnet id types when
34470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 * the netmask is address length
34480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 */
34490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&&
34510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) {
34520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s);
34530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&&
34570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) {
34580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t);
34590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&&
34640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
34650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s);
34660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&&
34700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) {
34710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t);
34720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"check and compare ids : id type mismatch %s != %s\n",
34770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_bs->type),
34780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_bt->type));
34790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
34810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(id_bs->proto_id != id_bt->proto_id){
34840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"check and compare ids : proto_id mismatch %d != %d\n",
34860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_bs->proto_id, id_bt->proto_id);
34870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
34890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* compare the ID data. */
34920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_bt->type) {
34940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	        case IPSECDOI_ID_DER_ASN1_DN:
34950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        	case IPSECDOI_ID_DER_ASN1_GN:
34960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare asn1 ids */
34970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = eay_cmp_asn1dn(&ident_t, &ident_s);
34980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR:
35010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
35020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != sizeof(struct in_addr))||
35030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != sizeof(struct in_addr)))
35040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
35050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
35080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_RANGE:
35090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
35100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != (sizeof(struct in_addr)*2))||
35110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != (sizeof(struct in_addr)*2)))
35120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
35130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
35160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR:
35170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
35180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != sizeof(struct in6_addr))||
35190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != sizeof(struct in6_addr)))
35200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
35210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
35240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_RANGE:
35250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
35260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != (sizeof(struct in6_addr)*2))||
35270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != (sizeof(struct in6_addr)*2)))
35280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
35290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
35310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_FQDN:
35320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_USER_FQDN:
35330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_KEY_ID:
35340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
35350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
35370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
35380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Unhandled id type %i specified for comparison\n",
35390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				id_bt->type);
35400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
35410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* validate matching data and length */
35440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident_t.l == ident_s.l)
35450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		result = memcmp(ident_t.v,ident_s.v,ident_t.l);
35460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
35470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		result = 1;
35480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpid_result:
35500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* debug level output */
35520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(loglevel >= LLV_DEBUG) {
35530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *idstrt = ipsecdoi_id2str(idt);
35540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *idstrs = ipsecdoi_id2str(ids);
35550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!result)
35570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 		plog(LLV_DEBUG, LOCATION, NULL,
35580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : values matched (%s)\n",
35590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 s_ipsecdoi_ident(id_bs->type) );
35600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
35610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			plog(LLV_DEBUG, LOCATION, NULL,
35620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : value mismatch (%s)\n",
35630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 s_ipsecdoi_ident(id_bs->type));
35640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt );
35660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs );
35670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(idstrs);
35690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(idstrt);
35700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* return result */
35730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if( !result )
35740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
35750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
35760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
35770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpid_invalid:
35790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* id integrity error */
35810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n",
35820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(id_bs->type));
35830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l );
35840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l );
35850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
35870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
35880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
35900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check the following:
35910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - In main mode with pre-shared key, only address type can be used.
35920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if proper type for phase 1 ?
35930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if phase 1 ID payload conformed RFC2407 4.6.2.
35940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *   (proto, port) must be (0, 0), (udp, 500) or (udp, [specified]).
35950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if ID payload sent from peer is equal to the ID expected by me.
35960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
35970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * both of "id" and "id_p" should be ID payload without general header,
35980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
35990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
36000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkid1(iph1)
36010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
36020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
36030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_b;
3604c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr *sa;
3605c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	caddr_t sa1, sa2;
36060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->id_p == NULL) {
36080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid iph1 passed id_p == NULL\n");
36100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_INTERNAL_ERROR;
36110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->id_p->l < sizeof(*id_b)) {
36130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
36140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid value passed as \"ident\" (len=%lu)\n",
36150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(u_long)iph1->id_p->l);
36160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
36170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
36200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3621c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifndef ANDROID_PATCHED
36220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* In main mode with pre-shared key, only address type can be used. */
36230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->etype == ISAKMP_ETYPE_IDENT &&
36240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) {
36250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 if (id_b->type != IPSECDOI_ID_IPV4_ADDR
36260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		  && id_b->type != IPSECDOI_ID_IPV6_ADDR) {
36270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
36280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Expecting IP address type in main mode, "
36290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"but %s.\n", s_ipsecdoi_ident(id_b->type));
36300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
36310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
36320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3633c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
36340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if proper type for phase 1 ? */
36360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
36370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
36380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
36390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
36400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
36410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
36420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such ID type %s is not proper.\n",
36430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_b->type));
36440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
36450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if phase 1 ID payload conformed RFC2407 4.6.2. */
36480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (id_b->type == IPSECDOI_ID_IPV4_ADDR ||
36490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    id_b->type == IPSECDOI_ID_IPV6_ADDR) {
36500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) {
36520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
36530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"protocol ID and Port mismatched. "
36540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proto_id:%d port:%d\n",
36550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				id_b->proto_id, ntohs(id_b->port));
36560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
36570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else if (id_b->proto_id == IPPROTO_UDP) {
36590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
36600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * copmaring with expecting port.
36610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * always permit if port is equal to PORT_ISAKMP
36620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
36630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ntohs(id_b->port) != PORT_ISAKMP) {
36640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int16_t port;
36650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				port = extract_port(iph1->remote);
36670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ntohs(id_b->port) != port) {
36680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_WARNING, LOCATION, NULL,
36690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"port %d expected, but %d\n",
36700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						port, ntohs(id_b->port));
36710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					/*FALLTHROUGH*/
36720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
36730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
36740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
36750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3677c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* compare with the ID if specified. */
3678c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (genlist_next(iph1->rmconf->idvl_p, 0)) {
3679c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		vchar_t *ident0 = NULL;
3680c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		vchar_t ident;
3681c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct idspec *id;
3682c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct genlist_entry *gpb;
3683c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3684c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		for (id = genlist_next (iph1->rmconf->idvl_p, &gpb); id; id = genlist_next (0, &gpb)) {
3685c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* check the type of both IDs */
3686c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (id->idtype != doi2idtype(id_b->type))
3687c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				continue;  /* ID type mismatch */
3688c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (id->id == 0)
3689c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				goto matched;
3690c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3691c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			/* compare defined ID with the ID sent by peer. */
3692c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (ident0 != NULL)
3693c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				vfree(ident0);
3694c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ident0 = getidval(id->idtype, id->id);
3695c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3696c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			switch (id->idtype) {
3697c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case IDTYPE_ASN1DN:
3698c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				ident.v = iph1->id_p->v + sizeof(*id_b);
3699c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				ident.l = iph1->id_p->l - sizeof(*id_b);
3700c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (eay_cmp_asn1dn(ident0, &ident) == 0)
3701c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					goto matched;
3702c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
3703c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			case IDTYPE_ADDRESS:
3704c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sa = (struct sockaddr *)ident0->v;
3705c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				sa2 = (caddr_t)(id_b + 1);
3706c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				switch (sa->sa_family) {
3707c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				case AF_INET:
3708c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in_addr))
3709c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						continue;  /* ID value mismatch */
3710c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa1 = (caddr_t)&((struct sockaddr_in *)sa)->sin_addr;
3711c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					if (memcmp(sa1, sa2, sizeof(struct in_addr)) == 0)
3712c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						goto matched;
3713c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					break;
3714c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef INET6
3715c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				case AF_INET6:
3716c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					if (iph1->id_p->l - sizeof(*id_b) != sizeof(struct in6_addr))
3717c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						continue;  /* ID value mismatch */
3718c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sa1 = (caddr_t)&((struct sockaddr_in6 *)sa)->sin6_addr;
3719c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					if (memcmp(sa1, sa2, sizeof(struct in6_addr)) == 0)
3720c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh						goto matched;
3721c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					break;
3722c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
3723c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				default:
3724c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					break;
3725c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				}
3726c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
3727c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			default:
3728c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				if (memcmp(ident0->v, id_b + 1, ident0->l) == 0)
3729c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					goto matched;
3730c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				break;
3731c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			}
3732c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
3733c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (ident0 != NULL) {
3734c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			vfree(ident0);
3735c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ident0 = NULL;
3736c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		}
3737c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_WARNING, LOCATION, NULL, "No ID match.\n");
3738c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph1->rmconf->verify_identifier)
3739c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
3740c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehmatched: /* ID value match */
3741c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (ident0 != NULL)
3742c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			vfree(ident0);
3743c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
37440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
37460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
37470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
37490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create ID payload for phase 1 and set into iph1->id.
37500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header.
37510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
37520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
37530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
37540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setid1(iph1)
37550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
37560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
37570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
37580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b id_b;
37590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ident = NULL;
37600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *ipid = NULL;
37610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* init */
37630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b.proto_id = 0;
37640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b.port = 0;
37650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident = NULL;
37660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (iph1->rmconf->idvtype) {
37680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_FQDN:
37690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_FQDN;
3770c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
37710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
37720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_USERFQDN:
37730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_USER_FQDN;
3774c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
37750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
37760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_KEYID:
37770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_KEY_ID;
3778c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
37790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
37800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ASN1DN:
37810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_DER_ASN1_DN;
37820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->idv) {
37830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* XXX it must be encoded to asn1dn. */
37840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ident = vdup(iph1->rmconf->idv);
37850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
37860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (oakley_getmycert(iph1) < 0) {
37870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
37880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to get own CERT.\n");
37890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
37900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3791c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ident = eay_get_x509asn1subjectname(&iph1->cert->cert);
37920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
37930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
37940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ADDRESS:
37950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
37960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * if the value of the id type was set by the configuration
37970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * file, then use it.  otherwise the value is get from local
37980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ip address by using ike negotiation.
37990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
38000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->idv)
38010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipid = (struct sockaddr *)iph1->rmconf->idv->v;
38020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
38030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
38040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
38050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int l;
38060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		caddr_t p;
38070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ipid == NULL)
38090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipid = iph1->local;
38100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* use IP address */
38120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ipid->sa_family) {
38130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
38140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_b.type = IPSECDOI_ID_IPV4_ADDR;
38150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = sizeof(struct in_addr);
38160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (caddr_t)&((struct sockaddr_in *)ipid)->sin_addr;
38170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
38180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
38190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
38200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_b.type = IPSECDOI_ID_IPV6_ADDR;
38210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = sizeof(struct in6_addr);
38220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (caddr_t)&((struct sockaddr_in6 *)ipid)->sin6_addr;
38230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
38240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
38250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
38260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
38270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid address family.\n");
38280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
38290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.proto_id = IPPROTO_UDP;
38310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.port = htons(PORT_ISAKMP);
38320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ident = vmalloc(l);
38330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!ident) {
38340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
38350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get ID buffer.\n");
3836c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return 0;
38370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(ident->v, p, ident->l);
38390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
38400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
38410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ident) {
38420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
38430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
3844c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return 0;
38450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
38460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(sizeof(id_b) + ident->l);
38480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret == NULL) {
38490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
38500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
38510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
38520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
38530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(ret->v, &id_b, sizeof(id_b));
38550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(ret->v + sizeof(id_b), ident->v, ident->l);
38560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->id = ret;
38580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
38600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"use ID type of %s\n", s_ipsecdoi_ident(id_b.type));
38610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident)
38620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ident);
38630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
38640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
38660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident)
38670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ident);
38680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "failed get my ID\n");
38690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
38700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
38710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3872c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic vchar_t *
3873c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehgetidval(type, val)
3874c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int type;
3875c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *val;
3876c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
3877c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	vchar_t *new = NULL;
3878c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3879c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (val)
3880c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		new = vdup(val);
3881c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	else if (lcconf->ident[type])
3882c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		new = vdup(lcconf->ident[type]);
3883c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3884c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return new;
3885c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
3886c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
38870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* it's only called by cfparse.y. */
38880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
38890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_identifier(vpp, type, value)
38900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **vpp, *value;
38910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
38920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
38930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC);
38940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
38950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
38970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_identifier_qual(vpp, type, value, qual)
38980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **vpp, *value;
38990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
39000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int qual;
39010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
39020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new = NULL;
39030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* simply return if value is null. */
39050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!value){
39060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( type == IDTYPE_FQDN || type == IDTYPE_USERFQDN){
39070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
39080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "No %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn");
39090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
39120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (type) {
39150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_FQDN:
39160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_USERFQDN:
39170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(value->l <= 1){
39180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
39190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn");
39200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* length is adjusted since QUOTEDSTRING teminates NULL. */
39230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new = vmalloc(value->l - 1);
39240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL)
39250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->v, value->v, new->l);
39270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
39280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_KEYID:
3929c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/*
39300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * If no qualifier is specified: IDQUAL_UNSPEC. It means
3931c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		 * to use a file for backward compatibility sake.
39320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
39330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch(qual) {
39340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_FILE:
39350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_UNSPEC: {
39360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			FILE *fp;
39370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char b[512];
39380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int tlen, len;
39390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			fp = fopen(value->v, "r");
39410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (fp == NULL) {
39420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
39430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"can not open %s\n", value->v);
39440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
39450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
39460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen = 0;
39470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while ((len = fread(b, 1, sizeof(b), fp)) != 0) {
39480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				new = vrealloc(new, tlen + len);
39490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (!new) {
39500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					fclose(fp);
39510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
39520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
39530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(new->v + tlen, b, len);
39540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				tlen += len;
39550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
39560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
39570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_TAG:
39600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = vmalloc(value->l - 1);
39610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (new == NULL) {
39620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
39630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"can not allocate memory");
39640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
39650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
39660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(new->v, value->v, new->l);
39670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
39680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
39700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
39710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unknown qualifier");
39720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3975c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
39760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ADDRESS: {
39770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *sa;
39780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* length is adjusted since QUOTEDSTRING teminates NULL. */
39800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (value->l == 0)
39810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
39820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = str2saddr(value->v, NULL);
39840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa == NULL) {
39850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
39860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid ip address %s\n", value->v);
39870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new = vmalloc(sysdep_sa_len(sa));
39910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL) {
39920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(sa);
39930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
39940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->v, sa, new->l);
39960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(sa);
39970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
39980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ASN1DN:
40000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (value->v[0] == '~')
40010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Hex-encoded ASN1 strings */
40020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = eay_hex2asn1dn(value->v + 1, - 1);
40030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
40040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* DN encoded strings */
40050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = eay_str2asn1dn(value->v, value->l - 1);
40060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL)
40080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
40090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (loglevel >= LLV_DEBUG) {
40110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME *xn;
40120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO *bio;
40130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			unsigned char *ptr = (unsigned char *) new->v, *buf;
40140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			size_t len;
4015a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
4016a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley			char *bio_contents;
4017a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
40180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char save;
4019a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
40200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l);
40220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bio = BIO_new(BIO_s_mem());
4023c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
40240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_print_ex(bio, xn, 0, 0);
4025a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#if defined(ANDROID_CHANGES)
4026a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley			BIO_write(bio, "\x00", 1);
4027a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley			BIO_get_mem_data(bio, &bio_contents);
4028a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley			plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", bio_contents);
4029a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#else
40300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BIO_get_mem_data(bio, &ptr);
40310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			save = ptr[len];
40320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ptr[len] = 0;
40330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr);
40340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ptr[len] = save;
4035a029281fff6b28b379bd69602f8f5649f0a2740dAdam Langley#endif
40360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_free(xn);
40370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO_free(bio);
40380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
40390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
40410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*vpp = new;
40440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
40460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
40470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
40490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create ID payload for phase 2, and set into iph2->id and id_p.  There are
40500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header.
40510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is for initiator.  responder will get to copy from payload.
40520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * responder ID type is always address type.
40530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
40540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
40550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
40560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setid2(iph2)
40570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
40580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
40590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
40600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check there is phase 2 handler ? */
40620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getspbyspid(iph2->spid);
40630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
40640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
40650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found for spid:%u.\n", iph2->spid);
40660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
40670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4069c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src,
4070c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh					sp->spidx.prefs, sp->spidx.ul_proto);
40710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id == NULL) {
40720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
40730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
40740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp->spidx));
40750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
40760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "use local ID type %s\n",
40780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type));
40790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* remote side */
4081c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst,
40820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sp->spidx.prefd, sp->spidx.ul_proto);
40830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id_p == NULL) {
40840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
40850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
40860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp->spidx));
40870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		VPTRINIT(iph2->id);
40880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
40890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
40910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"use remote ID type %s\n",
40920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id_p->v)->type));
40930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
40950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
40960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
40980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set address type of ID.
40990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING general header.
41000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
41010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
41020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto)
41030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *saddr;
41040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int prefixlen;
41050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int ul_proto;
41060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
41070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new;
41080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type, len1, len2;
41090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t sa;
41100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
41110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
41130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Q. When type is SUBNET, is it allowed to be ::1/128.
41140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * A. Yes. (consensus at bake-off)
41150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
41160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (saddr->sa_family) {
41170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
41180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in_addr);
4119c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (prefixlen == (sizeof(struct in_addr) << 3)) {
41200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV4_ADDR;
41210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = 0;
41220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
41230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV4_ADDR_SUBNET;
41240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = sizeof(struct in_addr);
41250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
41260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr;
41270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port = ((struct sockaddr_in *)(saddr))->sin_port;
41280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
41290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
41300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
41310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in6_addr);
4132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (prefixlen == (sizeof(struct in6_addr) << 3)) {
41330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV6_ADDR;
41340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = 0;
41350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
41360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV6_ADDR_SUBNET;
41370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = sizeof(struct in6_addr);
41380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
41390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr;
41400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port = ((struct sockaddr_in6 *)(saddr))->sin6_port;
41410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
41420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
41430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
41440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
41450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d.\n", saddr->sa_family);
41460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
41470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get ID buffer */
41500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2);
41510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
41520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
41530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
41540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
41550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(new->v, 0, new->l);
41580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set the part of header. */
41600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->type = type;
41610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set ul_proto and port */
41630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
41640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card
41650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 means port number of 0.  Instead of 0, we use IPSEC_*_ANY.
41660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
41670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->proto_id =
41680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto;
41690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->port =
41700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port == IPSEC_PORT_ANY ? 0 : port;
41710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(new->v + sizeof(struct ipsecdoi_id_b), sa, len1);
41720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set address */
41740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set prefix */
41760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len2) {
4177c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		u_char *p = (unsigned char *) new->v +
41780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct ipsecdoi_id_b) + len1;
41790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int bits = prefixlen;
41800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (bits >= 8) {
41820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p++ = 0xff;
41830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bits -= 8;
41840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
41850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (bits > 0)
41870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p = ~((1 << (8 - bits)) - 1);
41880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
41910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
41920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
41940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_sockrange2id(laddr, haddr, ul_proto)
41950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *laddr, *haddr;
41960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int ul_proto;
41970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
41980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new;
41990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type, len1, len2;
42000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
42010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (laddr->sa_family != haddr->sa_family) {
42030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n");
42040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    return NULL;
42050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
42060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (laddr->sa_family) {
42080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
42090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    type = IPSECDOI_ID_IPV4_ADDR_RANGE;
42100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    len1 = sizeof(struct in_addr);
42110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    len2 = sizeof(struct in_addr);
42120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    break;
42130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
42140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
42150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = IPSECDOI_ID_IPV6_ADDR_RANGE;
42160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in6_addr);
42170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len2 = sizeof(struct in6_addr);
42180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
42210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
42220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d.\n", laddr->sa_family);
42230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
42240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
42250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get ID buffer */
42270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2);
42280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
42290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
42300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
42310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
42320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
42330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(new->v, 0, new->l);
42350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set the part of header. */
42360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->type = type;
42370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set ul_proto and port */
42390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
42400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card
42410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 means port number of 0.  Instead of 0, we use IPSEC_*_ANY.
42420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
42430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->proto_id =
42440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto;
42450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)(laddr))->sin_port;
42460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->port =
42470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port == IPSEC_PORT_ANY ? 0 : port;
4248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	memcpy(new->v + sizeof(struct ipsecdoi_id_b),
4249c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	       (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr,
42500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       len1);
4251c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1,
42520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr,
42530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       len2);
42540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
42550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
42560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
42590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create sockaddr structure from ID payload (buf).
42600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * buffers (saddr, prefixlen, ul_proto) must be allocated.
42610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
42620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
42630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
42640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto)
42650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
42660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *saddr;
42670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *prefixlen;
42680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t *ul_proto;
42690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4270c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)buf->v;
42710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int plen = 0;
42720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
42740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * When a ID payload of subnet type with a IP address of full bit
42750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * masked, it has to be processed as host address.
42760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * e.g. below 2 type are same.
42770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *      type = ipv6 subnet, data = 2001::1/128
42780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *      type = ipv6 address, data = 2001::1
42790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
42800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
42810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
42820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
42830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
42840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_len = sizeof(struct sockaddr_in);
42850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_family = AF_INET;
42870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct sockaddr_in *)saddr)->sin_port =
42880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(id_b->port == 0
42890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_PORT_ANY
42900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->port);		/* see sockaddr2id() */
42910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&((struct sockaddr_in *)saddr)->sin_addr,
42920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf->v + sizeof(*id_b), sizeof(struct in_addr));
42930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
42950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
42960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
42970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
42980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_len = sizeof(struct sockaddr_in6);
42990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_family = AF_INET6;
43010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct sockaddr_in6 *)saddr)->sin6_port =
43020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(id_b->port == 0
43030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_PORT_ANY
43040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->port);		/* see sockaddr2id() */
43050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr,
43060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf->v + sizeof(*id_b), sizeof(struct in6_addr));
43070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
43100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
43110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported ID type %d\n", id_b->type);
43120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
43130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
43140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get prefix length */
43160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
43170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
43180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = sizeof(struct in_addr) << 3;
43190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
43220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = sizeof(struct in6_addr) << 3;
43230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
43260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
43280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
43300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_char *p;
43310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int max;
43320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int alen = sizeof(struct in_addr);
43330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (id_b->type) {
43350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
43360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in_addr);
43370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
43380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
43400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in6_addr);
43410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
43420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check */
43460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf->l < alen)
43470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ISAKMP_INTERNAL_ERROR;
43480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get subnet mask length */
43500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = 0;
43510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		max = alen <<3;
43520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (unsigned char *) buf->v
43540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct ipsecdoi_id_b)
43550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ alen;
43560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (; *p == 0xff; p++) {
43580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += 8;
43590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (plen >= max)
43600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
43610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (plen < max) {
43640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int l = 0;
43650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_char b = ~(*p);
43660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (b) {
43680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b >>= 1;
43690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				l++;
43700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
43710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = 8 - l;
43730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += l;
43740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
43760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
43780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*prefixlen = plen;
43800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*ul_proto = id_b->proto_id == 0
43810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_ULPROTO_ANY
43820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->proto_id;	/* see sockaddr2id() */
43830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
43850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
43860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
43880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make printable string from ID payload except of general header.
43890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
43900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
43910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_id2str(id)
43920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *id;
43930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
43940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define BUFLEN 512
43950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * ret = NULL;
43960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
43970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *dat;
43980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[BUFLEN];
43990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v;
4400c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr_storage saddr_storage;
4401c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr        *saddr;
4402c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr_in     *saddr_in;
4403c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct sockaddr_in6    *saddr_in6;
44040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int plen = 0;
44050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4406c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	saddr     = (struct sockaddr *)&saddr_storage;
4407c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	saddr_in  = (struct sockaddr_in *)&saddr_storage;
4408c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	saddr_in6 = (struct sockaddr_in6 *)&saddr_storage;
4409c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4410c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
44110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
44120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
44130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
44140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
44150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4417c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_len = sizeof(struct sockaddr_in);
44180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4419c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_family = AF_INET;
4420c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4421c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in->sin_port = IPSEC_PORT_ANY;
4422c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		memcpy(&saddr_in->sin_addr,
44230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b), sizeof(struct in_addr));
44240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
44260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
44270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
44280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
44290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4431c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_len = sizeof(struct sockaddr_in6);
44320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4433c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_family = AF_INET6;
4434c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4435c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in6->sin6_port = IPSEC_PORT_ANY;
4436c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		memcpy(&saddr_in6->sin6_addr,
44370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b), sizeof(struct in6_addr));
4438c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in6->sin6_scope_id =
4439c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			(IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
4440051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
4441051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				: 0);
44420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
44440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
44450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
44470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
44480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
44490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
44500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4451c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s", saddrwop2str(saddr));
44520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
44550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
44560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
44570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
44580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
44590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_char *p;
44600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int max;
44610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int alen = sizeof(struct in_addr);
44620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (id_b->type) {
44640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
44650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in_addr);
44660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
44670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
44680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
44690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in6_addr);
44700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
44710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
44720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
44730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check */
44750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (id->l < alen) {
44760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = 0;
44770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
44780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
44790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get subnet mask length */
44810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = 0;
44820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		max = alen <<3;
44830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (unsigned char *) id->v
44850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct ipsecdoi_id_b)
44860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ alen;
44870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (; *p == 0xff; p++) {
44890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += 8;
44900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (plen >= max)
44910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
44920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
44930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (plen < max) {
44950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int l = 0;
44960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_char b = ~(*p);
44970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (b) {
44990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b >>= 1;
45000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				l++;
45010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
45020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = 8 - l;
45040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += l;
45050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
45060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4507c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(saddr), plen);
45080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
45090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
45120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4513c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
45140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4516c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_len = sizeof(struct sockaddr_in);
45170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4518c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_family = AF_INET;
4519c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in->sin_port = IPSEC_PORT_ANY;
4520c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		memcpy(&saddr_in->sin_addr,
45210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b) + sizeof(struct in_addr),
45220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct in_addr));
45230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4524c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
4525c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
45260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
45290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
4530c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4531c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(saddr));
45320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4534c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_len = sizeof(struct sockaddr_in6);
45350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4536c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr->sa_family = AF_INET6;
4537c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in6->sin6_port = IPSEC_PORT_ANY;
4538c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		memcpy(&saddr_in6->sin6_addr,
45390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b) + sizeof(struct in6_addr),
45400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct in6_addr));
4541c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		saddr_in6->sin6_scope_id =
4542c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			(IN6_IS_ADDR_LINKLOCAL(&saddr_in6->sin6_addr)
4543051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
4544051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				: 0);
45450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4546c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len += snprintf( buf + len, BUFLEN - len, "%s", saddrwop2str(saddr));
4547c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
45480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
45500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_FQDN:
45520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_USER_FQDN:
45530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = id->l - sizeof(*id_b);
45540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len > BUFLEN)
45550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BUFLEN;
45560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(buf, id->v + sizeof(*id_b), len);
45570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_DN:
45600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_GN:
45610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
45620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME *xn = NULL;
45630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dat = id->v + sizeof(*id_b);
45650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = id->l - sizeof(*id_b);
45660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) {
45680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO *bio = BIO_new(BIO_s_mem());
45690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_print_ex(bio, xn, 0, 0);
45700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BIO_get_mem_data(bio, &dat);
45710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (len > BUFLEN)
45720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = BUFLEN;
45730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(buf,dat,len);
45740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO_free(bio);
45750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_free(xn);
45760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
45770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
45780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unable to extract asn1dn from id\n");
45790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = sprintf(buf, "<ASN1-DN>");
45810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
45820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
45850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* currently unhandled id types */
45870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_KEY_ID:
45880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sprintf( buf, "<KEY-ID>");
45890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
45900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
45920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
45930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unknown ID type %d\n", id_b->type);
45940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
45950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!len)
45970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sprintf( buf, "<?>");
45980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = racoon_malloc(len+1);
46000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret != NULL) {
46010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(ret,buf,len);
46020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret[len]=0;
46030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
46040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
46060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
46070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
46090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set IPsec data attributes into a proposal.
46100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: MUST called per a transform.
46110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
46120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
46130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_t2satrns(t, pp, pr, tr)
46140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *t;
46150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
46160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
46170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
46180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
46190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d, *prev;
46200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
46210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
46220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int life_t;
46230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
46240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->trns_no = t->t_no;
46260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->trns_id = t->t_id;
46270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(t->h.len) - sizeof(*t);
46290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prev = (struct isakmp_data *)NULL;
46300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)(t + 1);
46310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* default */
46330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT;
46340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
46350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp->lifebyte = 0;
46360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->authtype = IPSECDOI_ATTR_AUTH_NONE;
46370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
46390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
46410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
46420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
46440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
46450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr(type), flag,
46460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(type, ntohs(d->lorv)));
46470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
46490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
46500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
46510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = ntohs(d->lorv);
46520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (type) {
46530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
46540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
46550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = type;
46560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
46570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
46580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, NULL,
46590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life duration type. "
46600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"use default\n");
46610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT;
46620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
46630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
46660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
46670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (prev == NULL
46680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) !=
46690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					IPSECDOI_ATTR_SA_LD_TYPE) {
46700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "life duration must follow ltype\n");
46720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
46730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    {
46760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int32_t t;
46770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vchar_t *ld_buf = NULL;
46780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
46800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
46810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ld_buf = vmalloc(sizeof(d->lorv));
46820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ld_buf == NULL) {
46830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to get LD buffer.\n");
46850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(ld_buf->v, &d->lorv, sizeof(d->lorv));
46880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
46890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
46900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
46910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ld_buf = vmalloc(len);
46920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ld_buf == NULL) {
46930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to get LD buffer.\n");
46950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(ld_buf->v, d + 1, len);
46980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (life_t) {
47000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
47010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t = ipsecdoi_set_ld(ld_buf);
47020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
47030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (t == 0) {
47040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
47050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
47060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
47070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
47080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* lifetime must be equal in a proposal. */
47090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (pp->lifetime == IPSECDOI_ATTR_SA_LD_SEC_DEFAULT)
47100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pp->lifetime = t;
47110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else if (pp->lifetime != t) {
47120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
47130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"lifetime mismatched "
47140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"in a proposal, "
47150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"prev:%ld curr:%u.\n",
47160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						(long)pp->lifetime, t);
47170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
47180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
47190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
47200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
47210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t = ipsecdoi_set_ld(ld_buf);
47220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
47230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (t == 0) {
47240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
47250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
47260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
47270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
47280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* lifebyte must be equal in a proposal. */
47290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (pp->lifebyte == 0)
47300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pp->lifebyte = t;
47310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else if (pp->lifebyte != t) {
47320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
47330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"lifebyte mismatched "
47340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"in a proposal, "
47350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"prev:%d curr:%u.\n",
47360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						pp->lifebyte, t);
47370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
47380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
47390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
47400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
47410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
47420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
47430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type: %d\n", life_t);
47440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
47450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
47460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    }
47470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
47500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
47510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * RFC2407: 4.5 IPSEC Security Association Attributes
47520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   Specifies the Oakley Group to be used in a PFS QM
47530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   negotiation.  For a list of supported values, see
47540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   Appendix A of [IKE].
47550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
47560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->pfs_group == 0)
47570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp->pfs_group = (u_int16_t)ntohs(d->lorv);
47580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else if (pp->pfs_group != (u_int16_t)ntohs(d->lorv)) {
47590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
47600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"pfs_group mismatched "
47610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a proposal.\n");
47620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
47630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
47640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
47670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->encmode &&
47680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pr->encmode != (u_int16_t)ntohs(d->lorv)) {
47690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
47700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"multiple encmode exist "
47710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a transform.\n");
47720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
47730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
47740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr->encmode = (u_int16_t)ntohs(d->lorv);
47750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
47780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) {
47790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
47800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"multiple authtype exist "
47810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a transform.\n");
47820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
47830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
47840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr->authtype = (u_int16_t)ntohs(d->lorv);
47850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
47880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->proto_id != IPSECDOI_PROTO_IPSEC_ESP) {
47890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
47900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"key length defined but not ESP");
47910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
47920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
47930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr->encklen = ntohs(d->lorv);
47940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
47960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SECCTX:
47970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
47980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
47990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&pp->sctx, d + 1, len);
48000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp->sctx.ctx_strlen = ntohs(pp->sctx.ctx_strlen);
48010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
48020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
48030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
48040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
48050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
48060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
48070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
48080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
48090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
48100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
48110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prev = d;
48120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
48130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
48140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d));
48150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
48160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + ntohs(d->lorv));
48170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d + sizeof(*d) + ntohs(d->lorv));
48180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
48190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
48200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
48210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
48220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
48230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
48240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
48250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
48260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
48270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_authalg2trnsid(alg)
48280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int alg;
48290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
48300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (alg) {
48310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_HMAC_MD5:
48320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_MD5;
48330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
48340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA;
48350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
48360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA256;
48370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
48380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA384;
48390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
48400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA512;
48410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_DES_MAC:
48420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_DES;
48430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_KPDK:
48440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_MD5;	/* XXX */
48450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
48460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
48470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid authentication algorithm:%d\n", alg);
48480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
48490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
48500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
48510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4852c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef HAVE_GSSAPI
4853c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstruct isakmpsa *
4854c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehfixup_initiator_sa(match, received)
4855c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct isakmpsa *match, *received;
4856c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
4857c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (received->gssid != NULL)
4858c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		match->gssid = vdup(received->gssid);
4859c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4860c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return match;
4861c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
4862c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
4863c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
48640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int rm_idtype2doi[] = {
48650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	255,				/* IDTYPE_UNDEFINED, 0 */
48660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_FQDN,		/* IDTYPE_FQDN, 1 */
48670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_USER_FQDN,		/* IDTYPE_USERFQDN, 2 */
48680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_KEY_ID,		/* IDTYPE_KEYID, 3 */
4869c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	255,    /*			   IDTYPE_ADDRESS, 4
48700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * it expands into 4 types by another function. */
48710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_DER_ASN1_DN,	/* IDTYPE_ASN1DN, 5 */
48720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
48730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
48740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
48750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert idtype to DOI value.
48760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT	255  : NG
48770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	other: converted.
48780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
48790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
48800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangidtype2doi(idtype)
48810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int idtype;
48820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
48830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ARRAYLEN(rm_idtype2doi) > idtype)
48840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return rm_idtype2doi[idtype];
48850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 255;
48860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
48870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
48880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
48890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdoi2idtype(doi)
48900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int doi;
48910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
48920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(doi) {
48930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_FQDN:
48940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_FQDN);
48950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_USER_FQDN:
48960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_USERFQDN);
48970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_KEY_ID:
48980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_KEYID);
48990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_DN:
49000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ASN1DN);
49010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
49020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
49030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
49040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
49050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ADDRESS);
49060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
49070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
49080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Inproper idtype:%s in this function.\n",
49090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(doi));
49100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ADDRESS);	/* XXX */
49110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
49120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
49130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4914c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4915c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ENABLE_HYBRID
4916c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int
4917c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehswitch_authmethod(authmethod)
4918c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	int authmethod;
4919c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh{
4920c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	switch(authmethod) {
4921c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
4922c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
4923c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4924c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
4925c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I;
4926c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4927c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
4928c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
4929c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4930c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
4931c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
4932c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4933c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* Those are not implemented */
4934c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
4935c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I;
4936c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4937c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
4938c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I;
4939c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4940c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
4941c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		authmethod = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I;
4942c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4943c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	default:
4944c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		break;
4945c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
4946c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
4947c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return authmethod;
4948c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh}
4949c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
4950