ipsec_doi.c revision f8a6a7636d53a5730c58ae041e4e09ae12e1657c
1f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/*	$NetBSD: ipsec_doi.c,v 1.46 2010/12/14 17:57:31 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.
8f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-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.
20f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-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
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <iconv.h>
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "gssapi.h"
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_ICONV_2ND_CONST
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define __iconv_const const
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define __iconv_const
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
97f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic vchar_t *get_ph1approval __P((struct ph1handle *, u_int32_t, u_int32_t,
98f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				     struct prop_pair **));
99f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int get_ph1approvalx __P((struct remoteconf *, void *));
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
101f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int t2isakmpsa __P((struct isakmp_pl_t *, struct isakmpsa *, u_int32_t));
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int cmp_aproppair_i __P((struct prop_pair *, struct prop_pair *));
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *get_ph2approval __P((struct ph2handle *,
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **));
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *get_ph2approvalx __P((struct ph2handle *,
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *));
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic void free_proppair0 __P((struct prop_pair *));
108f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic struct prop_pair ** get_proppair_and_doi_sit __P((vchar_t *, int,
109f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh							 u_int32_t *, u_int32_t *));
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int get_transform
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct isakmp_pl_p *, struct prop_pair **, int *));
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int32_t ipsecdoi_set_ld __P((vchar_t *));
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_doi __P((u_int32_t));
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_situation __P((u_int32_t));
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_prot_main __P((int));
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_prot_quick __P((int));
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_protocol[]) __P((int)) = {
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_prot_main,	/* IPSECDOI_TYPE_PH1 */
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_prot_quick,	/* IPSECDOI_TYPE_PH2 */
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_spi_size __P((int, int));
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_isakmp __P((int));
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_ah __P((int));
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_esp __P((int));
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_trns_ipcomp __P((int));
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_transform[]) __P((int)) = {
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	0,
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_isakmp,	/* IPSECDOI_PROTO_ISAKMP */
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_ah,		/* IPSECDOI_PROTO_IPSEC_AH */
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_esp,		/* IPSECDOI_PROTO_IPSEC_ESP */
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_trns_ipcomp,	/* IPSECDOI_PROTO_IPCOMP */
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_isakmp __P((struct isakmp_pl_t *));
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ah __P((struct isakmp_pl_t *));
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_esp __P((struct isakmp_pl_t *));
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ipsec __P((int, struct isakmp_pl_t *));
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int check_attr_ipcomp __P((struct isakmp_pl_t *));
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*check_attributes[]) __P((struct isakmp_pl_t *)) = {
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	0,
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_isakmp,	/* IPSECDOI_PROTO_ISAKMP */
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_ah,		/* IPSECDOI_PROTO_IPSEC_AH */
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_esp,		/* IPSECDOI_PROTO_IPSEC_ESP */
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	check_attr_ipcomp,	/* IPSECDOI_PROTO_IPCOMP */
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1prop __P((struct isakmpsa *, caddr_t));
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1trns __P((struct isakmpsa *, caddr_t));
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int setph1attr __P((struct isakmpsa *, caddr_t));
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *setph2proposal0 __P((const struct ph2handle *,
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *, const struct saproto *));
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
158f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstruct ph1approvalx_ctx {
159f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct prop_pair *p;
160f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmpsa *sa;
161f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh};
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 1 SA payload.
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make new SA payload to be replyed not including general header.
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the pointer to one of isakmpsa in proposal is set into iph1->approval.
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive: the pointer to new buffer of SA payload.
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *		  network byte order.
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	NULL	: error occurd.
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkph1proposal(sa, iph1)
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa;
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;		/* new SA payload approved. */
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
180f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t doitype, sittype;
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
183f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	pair = get_proppair_and_doi_sit(sa, IPSECDOI_TYPE_PH1,
184f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					&doitype, &sittype);
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and get one SA for use */
189f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	newsa = get_ph1approval(iph1, doitype, sittype, pair);
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL)
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->sa_ret = newsa;
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
199f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic void
200f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehprint_ph1proposal(pair, s)
201f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct prop_pair *pair;
202f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmpsa *s;
203f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
204f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmp_pl_p *prop = pair->prop;
205f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmp_pl_t *trns = pair->trns;
206f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
207f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
208f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "prop#=%d, prot-id=%s, spi-size=%d, #trns=%d\n",
209f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     prop->p_no, s_ipsecdoi_proto(prop->proto_id),
210f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     prop->spi_size, prop->num_t);
211f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
212f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "trns#=%d, trns-id=%s\n",
213f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     trns->t_no, s_ipsecdoi_trns(prop->proto_id, trns->t_id));
214f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
215f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  lifetime = %ld\n", (long) s->lifetime);
216f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
217f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  lifebyte = %zu\n", s->lifebyte);
218f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
219f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  enctype = %s\n",
220f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     s_oakley_attr_v(OAKLEY_ATTR_ENC_ALG, s->enctype));
221f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
222f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  encklen = %d\n", s->encklen);
223f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
224f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  hashtype = %s\n",
225f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     s_oakley_attr_v(OAKLEY_ATTR_HASH_ALG, s->hashtype));
226f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
227f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  authmethod = %s\n",
228f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     s_oakley_attr_v(OAKLEY_ATTR_AUTH_METHOD, s->authmethod));
229f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL,
230f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     "  dh_group = %s\n",
231f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     s_oakley_attr_v(OAKLEY_ATTR_GRP_DESC, s->dh_group));
232f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
233f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
234f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * acceptable check for remote configuration.
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return a new SA payload to be reply to peer.
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
239f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *
241f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehget_ph1approval(iph1, doitype, sittype, pair)
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
243f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t doitype, sittype;
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;
247f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct ph1approvalx_ctx ctx;
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *s, *p;
249f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct rmconfselector rmsel;
250f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmpsa *sa;
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
253f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	memset(&rmsel, 0, sizeof(rmsel));
254f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	rmsel.remote = iph1->remote;
255f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->approval) {
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delisakmpsa(iph1->approval);
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->approval = NULL;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i] == NULL)
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (s = pair[i]; s; s = s->next) {
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare proposal and select one */
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (p = s; p; p = p->tnext) {
267f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				struct isakmp_pl_p *prop = p->prop;
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
269f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				sa = newisakmpsa();
270f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				ctx.p = p;
271f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				ctx.sa = sa;
272f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				if (t2isakmpsa(p->trns, sa,
273f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					       iph1->vendorid_mask) < 0)
274f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					continue;
275f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				print_ph1proposal(p, sa);
276f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				if (iph1->rmconf != NULL) {
277f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					if (get_ph1approvalx(iph1->rmconf, &ctx))
278f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						goto found;
279f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				} else {
280f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					if (enumrmconf(&rmsel, get_ph1approvalx, &ctx))
281f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						goto found;
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
283f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				delisakmpsa(sa);
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
287f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "no suitable proposal found.\n");
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfound:
293f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	sa = ctx.sa;
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "an acceptable proposal found.\n");
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check DH group settings */
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->dhgrp) {
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->dhgrp->prime && sa->dhgrp->gen1) {
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it's ok */
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto saok;
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid DH parameter found, use default.\n");
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		oakley_dhgrp_free(sa->dhgrp);
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa->dhgrp=NULL;
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (oakley_setdhgroup(sa->dh_group, &sa->dhgrp) == -1) {
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa->dhgrp = NULL;
310f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		delisakmpsa(sa);
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsaok:
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->gssid != NULL)
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "gss id in new sa '%.*s'\n",
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)sa->gssid->l, sa->gssid->v);
319f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (iph1->side == INITIATOR) {
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->proposal->gssid != NULL)
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->gi_i = vdup(iph1->rmconf->proposal->gssid);
322f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (sa->gssid != NULL)
323f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			iph1->gi_r = vdup(sa->gssid);
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} else {
325f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (sa->gssid != NULL) {
326f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			iph1->gi_r = vdup(sa->gssid);
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->gi_i = gssapi_get_id(iph1);
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->gi_i != NULL)
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "GIi is %.*s\n",
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)iph1->gi_i->l, iph1->gi_i->v);
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->gi_r != NULL)
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "GIr is %.*s\n",
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (int)iph1->gi_r->l, iph1->gi_r->v);
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
337f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	plog(LLV_DEBUG, LOCATION, NULL, "agreed on %s auth.\n",
338f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	     s_oakley_attr_method(sa->authmethod));
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	newsa = get_sabyproppair(doitype, sittype, p);
341f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (newsa == NULL)
342f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		delisakmpsa(sa);
343f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	else
344f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph1->approval = sa;
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare peer's single proposal and all of my proposal.
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * and select one if suiatable.
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
353f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int
354f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehget_ph1approvalx(rmconf, ctx)
355f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct remoteconf *rmconf;
356f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	void *ctx;
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
358f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct ph1approvalx_ctx *pctx = (struct ph1approvalx_ctx *) ctx;
359f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmpsa *sa;
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
361f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	/* do the hard work */
362f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	sa = checkisakmpsa(rmconf->pcheck_level, pctx->sa, rmconf->proposal);
363f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (sa == NULL)
364f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		return 0;
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
366f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	/* duplicate and modify the found SA to match proposal */
367f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	sa = dupisakmpsa(sa);
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
369f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	switch (rmconf->pcheck_level) {
370f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	case PROP_CHECK_OBEY:
371f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		sa->lifetime = pctx->sa->lifetime;
372f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		sa->lifebyte = pctx->sa->lifebyte;
373f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		sa->encklen = pctx->sa->encklen;
374f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		break;
375f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	case PROP_CHECK_CLAIM:
376f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	case PROP_CHECK_STRICT:
377f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (pctx->sa->lifetime < sa->lifetime)
378f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			sa->lifetime = pctx->sa->lifetime;
379f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (pctx->sa->lifebyte < sa->lifebyte)
380f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			sa->lifebyte = pctx->sa->lifebyte;
381f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (pctx->sa->encklen > sa->encklen)
382f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			sa->encklen = pctx->sa->encklen;
383f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		break;
384f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	default:
385f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		break;
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
388f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	/* replace the proposal with our approval sa */
389f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	delisakmpsa(pctx->sa);
390f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	pctx->sa = sa;
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
392f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	return 1;
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get ISAKMP data attributes
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
399f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeht2isakmpsa(trns, sa, vendorid_mask)
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
402f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t vendorid_mask;
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d, *prev;
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int life_t;
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int keylen = 0;
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *val = NULL;
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len, tlen;
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_char *p;
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(*trns);
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prev = (struct isakmp_data *)NULL;
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)(trns + 1);
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* default */
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT;
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->lifebyte = 0;
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa->dhgrp = racoon_calloc(1, sizeof(struct dhgroup));
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!sa->dhgrp)
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr(type), flag,
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr_v(type, ntohs(d->lorv)));
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get variable-sized item */
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {	/*TV*/
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = 2;
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = (u_char *)&d->lorv;
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {	/*TLV*/
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = ntohs(d->lorv);
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = (u_char *)(d + 1);
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			val = vmalloc(len);
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!val)
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(val->v, p, len);
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->enctype = (u_int16_t)ntohs(d->lorv);
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->hashtype = (u_int16_t)ntohs(d->lorv);
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->authmethod = ntohs(d->lorv);
472f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#ifdef HAVE_GSSAPI
473f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB_REAL &&
474f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			    (vendorid_mask & VENDORID_GSSAPI_MASK))
475f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				sa->authmethod = OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB;
476f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#endif
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dh_group = (u_int16_t)ntohs(d->lorv);
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = (int)ntohs(d->lorv);
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (type == OAKLEY_ATTR_GRP_TYPE_MODP)
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->type = type;
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->prime = val;
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(val);
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag)
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = ntohs(d->lorv);
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = 0;
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (len > 4)
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(&sa->dhgrp->gen1, d + 1, len);
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen1 = ntohl(sa->dhgrp->gen1);
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(val);
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag)
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = ntohs(d->lorv);
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = 0;
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (len > 4)
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(&sa->dhgrp->gen2, d + 1, len);
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dhgrp->gen2 = ntohl(sa->dhgrp->gen2);
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->curve_a = val;
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->curve_b = val;
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = (int)ntohs(d->lorv);
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (type) {
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_SEC:
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_KB:
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = type;
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = OAKLEY_ATTR_SA_LD_TYPE_DEFAULT;
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!prev
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) !=
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					OAKLEY_ATTR_SA_LD_TYPE) {
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "life duration must follow ltype\n");
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (life_t) {
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->lifetime = ipsecdoi_set_ld(val);
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (sa->lifetime == 0) {
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto err;
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->lifebyte = ipsecdoi_set_ld(val);
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (sa->lifebyte == 0) {
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto err;
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(val);
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type: %d\n", life_t);
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (len % 8 != 0) {
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"keylen %d: not multiple of 8\n",
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					len);
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->encklen = (u_int16_t)len;
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			keylen++;
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* unsupported */
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->dhgrp->order = val;
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GSS_ID:
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int error = -1;
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iconv_t cd = (iconv_t) -1;
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			size_t srcleft, dstleft, rv;
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			__iconv_const char *src;
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *dst;
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Older verions of racoon just placed the
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * ISO-Latin-1 string on the wire directly.
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * Check to see if we are configured to be
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * compatible with this behavior.
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if ((sa->gssid = vmalloc(len)) == NULL) {
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to allocate memory\n");
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(sa->gssid->v, d + 1, len);
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "received old-style gss "
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "id '%.*s' (len %zu)\n",
629f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				    (int)sa->gssid->l, sa->gssid->v,
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    sa->gssid->l);
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				error = 0;
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * For Windows 2000 compatibility, we expect
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * the GSS ID attribute on the wire to be
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * encoded in UTF-16LE.  Internally, we work
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * in ISO-Latin-1.  Therefore, we should need
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * 1/2 the specified length, which should always
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * be a multiple of 2 octets.
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			cd = iconv_open("latin1", "utf-16le");
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (cd == (iconv_t) -1) {
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "unable to initialize utf-16le -> latin1 "
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "conversion descriptor: %s\n",
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    strerror(errno));
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((sa->gssid = vmalloc(len / 2)) == NULL) {
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "failed to allocate memory\n");
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			src = (__iconv_const char *)(d + 1);
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			srcleft = len;
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dst = sa->gssid->v;
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dstleft = len / 2;
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
664f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			rv = iconv(cd, (__iconv_const char **)&src, &srcleft,
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   &dst, &dstleft);
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (rv != 0) {
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rv == -1) {
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "unable to convert GSS ID from "
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "utf-16le -> latin1: %s\n",
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    strerror(errno));
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				} else {
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "%zd character%s in GSS ID cannot "
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "be represented in latin1\n",
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    rv, rv == 1 ? "" : "s");
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto out;
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* XXX dstleft should always be 0; assert it? */
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sa->gssid->l = (len / 2) - dstleft;
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "received gss id '%.*s' (len %zu)\n",
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (int)sa->gssid->l, sa->gssid->v, sa->gssid->l);
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			error = 0;
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (cd != (iconv_t)-1)
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(void)iconv_close(cd);
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((error != 0) && (sa->gssid != NULL)) {
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(sa->gssid);
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->gssid = NULL;
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_GSSAPI */
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prev = d;
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d));
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + ntohs(d->lorv));
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d) + ntohs(d->lorv));
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* key length must not be specified on some algorithms */
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (keylen) {
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->enctype == OAKLEY_ATTR_ENC_ALG_DES
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_OPENSSL_IDEA_H
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || sa->enctype == OAKLEY_ATTR_ENC_ALG_IDEA
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || sa->enctype == OAKLEY_ATTR_ENC_ALG_3DES) {
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"keylen must not be specified "
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"for encryption algorithm %d\n",
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->enctype);
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 2 SA payload and select single proposal.
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make new SA payload to be replyed not including general header.
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by responder only.
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: succeed.
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: error occured.
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_selectph2proposal(iph2)
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret;
750f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t doitype, sittype;
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
753f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	pair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2,
754f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					&doitype, &sittype);
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and select a proposal. */
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = get_ph2approval(iph2, pair);
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret == NULL)
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make a SA to be replayed. */
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* SPI must be updated later. */
766f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	iph2->sa_ret = get_sabyproppair(doitype, sittype, ret);
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair0(ret);
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa_ret == NULL)
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check phase 2 SA payload returned from responder.
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by initiator only.
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: valid.
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	-1: invalid.
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkph2proposal(iph2)
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **rpair = NULL, **spair = NULL;
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i, n, num;
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa_ret = NULL;
790f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t doitype, sittype;
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair of SA sent. */
793f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	spair = get_proppair_and_doi_sit(iph2->sa, IPSECDOI_TYPE_PH2,
794f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					 &doitype, &sittype);
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair == NULL) {
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get prop pair.\n");
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX should check the number of transform */
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair of SA replayed */
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rpair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2);
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair == NULL) {
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get prop pair.\n");
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check proposal is only one ? */
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	n = 0;
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	num = 0;
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (rpair[i]) {
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			n = i;
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			num++;
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num == 0) {
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no proposal received.\n");
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num != 1) {
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"some proposals received.\n");
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair[n] == NULL) {
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid proposal number:%d received.\n", i);
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
835f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair[n]->tnext != NULL) {
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"multi transforms replyed.\n");
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (cmp_aproppair_i(rpair[n], spair[n])) {
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"proposal mismathed.\n");
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * check and select a proposal.
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * ensure that there is no modification of the proposal by
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * cmp_aproppair_i()
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = get_ph2approval(iph2, rpair);
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make a SA to be replayed. */
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sa_ret = iph2->sa_ret;
860f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	iph2->sa_ret = get_sabyproppair(doitype, sittype, p);
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair0(p);
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa_ret == NULL)
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rpair)
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair(rpair);
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (spair)
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair(spair);
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa_ret)
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(sa_ret);
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare two prop_pair which is assumed to have same proposal number.
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * the case of bundle or single SA, NOT multi transforms.
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * a: a proposal that is multi protocols and single transform, usually replyed.
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * b: a proposal that is multi protocols and multi transform, usually sent.
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: this function is for initiator.
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0: equal
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	1: not equal
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * XXX cannot understand the comment!
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmp_aproppair_i(a, b)
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *a, *b;
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q, *r;
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len;
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = a, q = b; p && q; p = p->next, q = q->next) {
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (r = q; r; r = r->tnext) {
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare trns */
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->trns->t_no == r->trns->t_no)
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!r) {
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* no suitable transform found */
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"no suitable transform found.\n");
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare prop */
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->p_no != r->prop->p_no) {
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%d mismatched, "
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"expected #%d.\n",
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				r->prop->p_no, p->prop->p_no);
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->proto_id != r->prop->proto_id) {
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proto_id mismathed: my:%d peer:%d\n",
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				r->prop->proto_id, p->prop->proto_id);
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->spi_size != r->prop->spi_size) {
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid spi size: %d.\n",
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p->prop->spi_size);
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check #of transforms */
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->prop->num_t != 1) {
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"#of transform is %d, "
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"but expected 1.\n", p->prop->num_t);
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->trns->t_id != r->trns->t_id) {
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"transform number has been modified.\n");
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p->trns->reserved != r->trns->reserved) {
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"reserved field should be zero.\n");
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare attribute */
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = ntohs(r->trns->h.len) - sizeof(*p->trns);
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (memcmp(p->trns + 1, r->trns + 1, len) != 0) {
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attribute has been modified.\n");
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((p && !q) || (!p && q)) {
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* # of protocols mismatched */
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"#of protocols mismatched.\n");
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * acceptable check for policy configuration.
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return a new SA payload to be reply to peer.
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_ph2approval(iph2, pair)
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret;
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->approval = NULL;
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin compare proposals.\n");
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i] == NULL)
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"pair[%d]: %p\n", i, pair[i]);
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair(LLV_DEBUG, pair[i]);;
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* compare proposal and select one */
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret = get_ph2approvalx(iph2, pair[i]);
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ret != NULL) {
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* found */
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ret;
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "no suitable policy found.\n");
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * compare my proposal and peers just one proposal.
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set a approval.
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct prop_pair *
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_ph2approvalx(iph2, pp)
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pp;
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *ret = NULL;
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pr0, *pr = NULL;
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *q1, *q2;
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pr0 = aproppair2saprop(pp);
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pr0 == NULL)
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (q1 = pr0; q1; q1 = q1->next) {
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (q2 = iph2->proposal; q2; q2 = q2->next) {
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"peer's single bundle:\n");
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			printsaprop0(LLV_DEBUG, q1);
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"my single bundle:\n");
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			printsaprop0(LLV_DEBUG, q2);
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr = cmpsaprop_alloc(iph2->ph1, q1, q2, iph2->side);
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr != NULL)
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto found;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"not matched\n");
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* no proposal matching */
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(pr0);
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfound:
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	flushsaprop(pr0);
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "matched\n");
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->approval = pr;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *sp;
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *x;
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *n = NULL;
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = NULL;
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pp; p; p = p->next) {
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * find a proposal with matching proto_id.
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we have analyzed validity already, in cmpsaprop_alloc().
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (sp = pr->head; sp; sp = sp->next) {
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sp->proto_id == p->prop->proto_id)
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!sp)
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sp->head->next)
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;	/* XXX */
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (x = p; x; x = x->tnext)
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sp->head->trns_no == x->trns->t_no)
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!x)
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;	/* XXX */
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n = racoon_calloc(1, sizeof(struct prop_pair));
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (n == NULL) {
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get buffer.\n");
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n->prop = x->prop;
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		n->trns = x->trns;
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* need to preserve the order */
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (x = ret; x && x->next; x = x->next)
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			;
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (x && x->prop == n->prop) {
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (/*nothing*/; x && x->tnext; x = x->tnext)
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				;
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x->tnext = n;
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (x)
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x->next = n;
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ret = n;
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* #of transforms should be updated ? */
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfree_proppair(pair)
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free_proppair0(pair[i]);
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		pair[i] = NULL;
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(pair);
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic void
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfree_proppair0(pair)
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pair;
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q, *r, *s;
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = pair;
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (p) {
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		q = p->next;
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		r = p;
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (r) {
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s = r->tnext;
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(r);
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			r = s;
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = q;
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get proposal pairs from SA payload.
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * tiny check for proposal payload.
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
1145f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic struct prop_pair **
1146f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehget_proppair_and_doi_sit(sa, mode, doitype, sittype)
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa;
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int mode;
1149f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t *doitype, *sittype;
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair = NULL;
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int num_p = 0;			/* number of proposal for use */
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_sa_b *sab = (struct ipsecdoi_sa_b *)sa->v;
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "total SA len=%zu\n", sa->l);
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plogdump(LLV_DEBUG, sa->v, sa->l);
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check SA payload size */
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->l < sizeof(*sab)) {
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid SA length = %zu.\n", sa->l);
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check DOI */
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (check_doi(ntohl(sab->doi)) < 0)
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
1171f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (doitype != NULL)
1172f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		*doitype = ntohl(sab->doi);
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check SITUATION */
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (check_situation(ntohl(sab->sit)) < 0)
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
1177f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (sittype != NULL)
1178f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		*sittype = ntohl(sab->sit);
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = racoon_calloc(1, MAXPROPPAIRLEN * sizeof(*pair));
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL) {
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get buffer.\n");
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(pair, 0, sizeof(pair));
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (caddr_t)(sab + 1);
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sa->l - sizeof(*sab);
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proplen;
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pbuf = NULL;
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *pa;
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_P, (struct isakmp_gen *)bp, tlen);
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pbuf == NULL)
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pa = (struct isakmp_parse_t *)pbuf->v;
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa->type != ISAKMP_NPTYPE_NONE;
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa++) {
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check the value of next payload */
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pa->type != ISAKMP_NPTYPE_P) {
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Invalid payload type=%u\n", pa->type);
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)pa->ptr;
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proplen = pa->len;
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"proposal #%u len=%d\n", prop->p_no, proplen);
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (proplen == 0) {
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid proposal with length %d\n", proplen);
12210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check Protocol ID */
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!check_protocol[mode]) {
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported mode %d\n", mode);
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_protocol[mode](prop->proto_id) < 0)
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check SPI length when IKE. */
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_spi_size(prop->proto_id, prop->spi_size) < 0)
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get transform */
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (get_transform(prop, pair, &num_p) < 0) {
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto bad;
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(pbuf);
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = NULL;
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int notrans, nprop;
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p, *q;
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check for proposals with no transforms */
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!pair[i])
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "pair %d:\n", i);
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		print_proppair(LLV_DEBUG, pair[i]);
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		notrans = nprop = 0;
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (p = pair[i]; p; p = p->next) {
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->trns == NULL) {
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				notrans++;
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (q = p; q; q = q->tnext)
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				nprop++;
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX at this moment, we cannot accept proposal group
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with multiple proposals.  this should be fixed.
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i]->next) {
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%u ignored "
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"(multiple proposal not supported)\n",
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[i]->prop->p_no);
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			notrans++;
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (notrans) {
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (p = pair[i]; p; p = q) {
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				q = p->next;
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(p);
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pair[i] = NULL;
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			num_p--;
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proposal #%u: %d transform\n",
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[i]->prop->p_no, nprop);
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* bark if no proposal is found. */
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (num_p <= 0) {
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no Proposal found.\n");
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto bad;
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return pair;
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangbad:
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair != NULL)
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(pair);
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return NULL;
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1314f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstruct prop_pair **
1315f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehget_proppair(sa, mode)
1316f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	vchar_t *sa;
1317f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	int mode;
1318f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
1319f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	return get_proppair_and_doi_sit(sa, mode, NULL, NULL);
1320f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
1321f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1322f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform payload.
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT:
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	positive: return the pointer to the payload of valid transform.
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	0	: No valid transform found.
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_transform(prop, pair, num_p)
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair;
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int *num_p;
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen; /* total length of all transform in a proposal */
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trnslen;
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pbuf = NULL;
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_parse_t *pa;
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p = NULL, *q;
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int num_t;
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = (caddr_t)prop + sizeof(struct isakmp_pl_p) + prop->spi_size;
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(prop->h.len)
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		- (sizeof(struct isakmp_pl_p) + prop->spi_size);
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pbuf = isakmp_parsewoh(ISAKMP_NPTYPE_T, (struct isakmp_gen *)bp, tlen);
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pbuf == NULL)
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check and get transform for use */
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	num_t = 0;
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pa = (struct isakmp_parse_t *)pbuf->v;
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa->type != ISAKMP_NPTYPE_NONE;
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	     pa++) {
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		num_t++;
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check the value of next payload */
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pa->type != ISAKMP_NPTYPE_T) {
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Invalid payload type=%u\n", pa->type);
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)pa->ptr;
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = pa->len;
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"transform #%u len=%u\n", trns->t_no, trnslen);
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check transform ID */
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (prop->proto_id >= ARRAYLEN(check_transform)) {
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (prop->proto_id >= ARRAYLEN(check_attributes)) {
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!check_transform[prop->proto_id]
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || !check_attributes[prop->proto_id]) {
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unsupported proto_id %u\n",
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->proto_id);
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_transform[prop->proto_id](trns->t_id) < 0)
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check data attributes */
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (check_attributes[prop->proto_id](trns) != 0)
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = racoon_calloc(1, sizeof(*p));
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p == NULL) {
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get buffer.\n");
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(pbuf);
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->prop = prop;
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->trns = trns;
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* need to preserve the order */
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (q = pair[prop->p_no]; q && q->next; q = q->next)
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			;
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (q && q->prop == p->prop) {
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (/*nothing*/; q && q->tnext; q = q->tnext)
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				;
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			q->tnext = p;
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (q)
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				q->next = p;
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else {
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pair[prop->p_no] = p;
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(*num_p)++;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(pbuf);
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make a new SA payload from prop_pair.
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: this function make spi value clear.
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
1437f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehget_sabyproppair(doitype, sittype, pair)
1438f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t doitype, sittype;
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *pair;
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa;
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newtlen;
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_p = NULL;
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p;
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int prophlen, trnslen;
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newtlen = sizeof(struct ipsecdoi_sa_b);
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair; p; p = p->next) {
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += sizeof(struct isakmp_pl_p);
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += p->prop->spi_size;
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		newtlen += ntohs(p->trns->h.len);
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newsa = vmalloc(newtlen);
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL) {
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n");
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = newsa->v;
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct isakmp_gen *)bp)->len = htons(newtlen);
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update some of values in SA header */
1465f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	((struct ipsecdoi_sa_b *)bp)->doi = htonl(doitype);
1466f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	((struct ipsecdoi_sa_b *)bp)->sit = htonl(sittype);
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp += sizeof(struct ipsecdoi_sa_b);
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
14700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair; p; p = p->next) {
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prophlen = sizeof(struct isakmp_pl_p)
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ p->prop->spi_size;
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = ntohs(p->trns->h.len);
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_p)
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_p = ISAKMP_NPTYPE_P;
14770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create proposal */
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(bp, p->prop, prophlen);
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen);
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_p *)bp)->num_t = 1;
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np_p = &((struct isakmp_pl_p *)bp)->h.np;
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(bp + sizeof(struct isakmp_pl_p), 0, p->prop->spi_size);
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bp += prophlen;
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create transform */
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(bp, p->trns, trnslen);
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE;
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct isakmp_pl_t *)bp)->h.len = htons(trnslen);
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		bp += trnslen;
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * update responder's spi
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_updatespi(iph2)
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair, *p;
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *spi;
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = get_proppair(iph2->sa_ret, IPSECDOI_TYPE_PH2);
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
15140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
15150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < MAXPROPPAIRLEN; i++) {
15160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[i])
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (i == MAXPROPPAIRLEN || pair[i]->tnext) {
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* multiple transform must be filtered by selectph2proposal.*/
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp = iph2->approval;
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (p = pair[i]; p; p = p->next) {
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * find a proposal/transform with matching proto_id/t_id.
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we have analyzed validity already, in cmpsaprop_alloc().
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (p->prop->proto_id == pr->proto_id &&
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    p->trns->t_id == pr->head->trns_id) {
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!pr)
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto end;
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX SPI bits are left-filled, for use with IPComp.
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we should be switching to variable-length spi field...
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi = (u_int8_t *)&pr->spi;
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi += sizeof(pr->spi);
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi -= pr->spisize;
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy((caddr_t)p->prop + sizeof(*p->prop), spi, pr->spisize);
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	free_proppair(pair);
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make a new SA payload from prop_pair.
15590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangget_sabysaprop(pp0, sa0)
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp0;
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *sa0;
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair **pair = NULL;
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *newsa = NULL;
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int newtlen;
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_p = NULL;
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct prop_pair *p = NULL;
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int prophlen, trnslen;
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t bp;
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get proposal pair */
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pair = get_proppair(sa0, IPSECDOI_TYPE_PH2);
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair == NULL)
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
15810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newtlen = sizeof(struct ipsecdoi_sa_b);
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pp = pp0; pp; pp = pp->next) {
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pair[pp->prop_no] == NULL)
15860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
15870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newtlen += (sizeof(struct isakmp_pl_p)
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ pr->spisize);
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (tr = pr->head; tr; tr = tr->next) {
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (p = pair[pp->prop_no]; p; p = p->tnext) {
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (tr->trns_no == p->trns->t_no)
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (p == NULL)
15980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
15990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				newtlen += ntohs(p->trns->h.len);
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	newsa = vmalloc(newtlen);
16060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (newsa == NULL) {
16070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "failed to get newsa.\n");
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp = newsa->v;
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* some of values of SA must be updated in the out of this function */
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct isakmp_gen *)bp)->len = htons(newtlen);
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bp += sizeof(struct ipsecdoi_sa_b);
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal payloads */
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (pp = pp0; pp; pp = pp->next) {
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			prophlen = sizeof(struct isakmp_pl_p)
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					+ p->prop->spi_size;
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			for (tr = pr->head; tr; tr = tr->next) {
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				for (p = pair[pp->prop_no]; p; p = p->tnext) {
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (tr->trns_no == p->trns->t_no)
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						break;
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (p == NULL)
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto out;
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				trnslen = ntohs(p->trns->h.len);
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (np_p)
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					*np_p = ISAKMP_NPTYPE_P;
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* create proposal */
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(bp, p->prop, prophlen);
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->h.np = ISAKMP_NPTYPE_NONE;
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->h.len = htons(prophlen + trnslen);
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_p *)bp)->num_t = 1;
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				np_p = &((struct isakmp_pl_p *)bp)->h.np;
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bp += prophlen;
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* create transform */
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(bp, p->trns, trnslen);
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_t *)bp)->h.np = ISAKMP_NPTYPE_NONE;
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				((struct isakmp_pl_t *)bp)->h.len = htons(trnslen);
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				bp += trnslen;
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pair != NULL)
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(pair);
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (newsa != NULL) {
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(newsa);
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			newsa = NULL;
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return newsa;
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * If some error happens then return 0.  Although 0 means that lifetime is zero,
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * such a value should not be accepted.
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Also 0 of lifebyte should not be included in a packet although 0 means not
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * to care of it.
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_int32_t
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_set_ld(buf)
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t ld;
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf == 0)
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (buf->l) {
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 2:
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ld = ntohs(*(u_int16_t *)buf->v);
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 4:
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ld = ntohl(*(u_int32_t *)buf->v);
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"length %zu of life duration "
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"isn't supported.\n", buf->l);
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ld;
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1701f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/*
1702f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh * parse responder-lifetime attributes from payload
1703f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh */
1704f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehint
1705f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehipsecdoi_parse_responder_lifetime(notify, lifetime_sec, lifetime_kb)
1706f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmp_pl_n *notify;
1707f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t *lifetime_sec;
1708f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t *lifetime_kb;
1709f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
1710f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct isakmp_data *d;
1711f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	int flag, type, tlen, ld_type = -1;
1712f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int16_t lorv;
1713f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	u_int32_t value;
1714f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1715f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	tlen = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
1716f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        d = (struct isakmp_data *)((char *)(notify + 1) +
1717f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		notify->spi_size);
1718f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1719f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	while (tlen >= sizeof(struct isakmp_data)) {
1720f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
1721f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
1722f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		lorv = ntohs(d->lorv);
1723f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1724f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		plog(LLV_DEBUG, LOCATION, NULL,
1725f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			"type=%s, flag=0x%04x, lorv=%s\n",
1726f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			s_ipsecdoi_attr(type), flag,
1727f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			s_ipsecdoi_attr_v(type, lorv));
1728f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1729f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		switch (type) {
1730f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		case IPSECDOI_ATTR_SA_LD_TYPE:
1731f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			if (! flag) {
1732f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
1733f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"must be TV when LD_TYPE.\n");
1734f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				return -1;
1735f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			}
1736f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			ld_type = lorv;
1737f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			break;
1738f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		case IPSECDOI_ATTR_SA_LD:
1739f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			if (flag)
1740f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				value = lorv;
1741f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			else if (lorv == 2)
1742f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				value = ntohs(*(u_int16_t *)(d + 1));
1743f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			else if (lorv == 4)
1744f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				value = ntohl(*(u_int32_t *)(d + 1));
1745f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			else {
1746f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
1747f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"payload length %d for lifetime "
1748f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"data length is unsupported.\n", lorv);
1749f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				return -1;
1750f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			}
1751f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1752f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			switch (ld_type) {
1753f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
1754f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				if (lifetime_sec != NULL)
1755f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					*lifetime_sec = value;
1756f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				plog(LLV_INFO, LOCATION, NULL,
1757f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"received RESPONDER-LIFETIME: %d "
1758f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"seconds\n", value);
1759f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				break;
1760f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
1761f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				if (lifetime_kb != NULL)
1762f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					*lifetime_kb = value;
1763f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				plog(LLV_INFO, LOCATION, NULL,
1764f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"received RESPONDER-LIFETIME: %d "
1765f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"kbytes\n", value);
1766f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				break;
1767f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			default:
1768f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				plog(LLV_ERROR, LOCATION, NULL,
1769f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"lifetime data received without "
1770f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh					"lifetime data type.\n");
1771f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				return -1;
1772f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			}
1773f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			break;
1774f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		}
1775f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1776f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (flag) {
1777f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			tlen -= sizeof(*d);
1778f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			d = (struct isakmp_data *)((char *)d
1779f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				+ sizeof(*d));
1780f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		} else {
1781f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			tlen -= (sizeof(*d) + lorv);
1782f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			d = (struct isakmp_data *)((char *)d
1783f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				+ sizeof(*d) + lorv);
1784f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		}
1785f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	}
1786f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1787f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	return 0;
1788f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
1789f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1790f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
17910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*%%%*/
17920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
17930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check DOI
17940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
17950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
17960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_doi(doi)
17970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t doi;
17980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
17990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (doi) {
18000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSEC_DOI:
18010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid value of DOI 0x%08x.\n", doi);
18050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check situation
18120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_situation(sit)
18150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t sit;
18160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (sit) {
18180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_IDENTITY_ONLY:
18190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_SECRECY:
18220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_SIT_INTEGRITY:
18230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"situation 0x%08x unsupported yet.\n", sit);
18250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid situation 0x%08x.\n", sit);
18300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check protocol id in main mode
18370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_prot_main(proto_id)
18400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
18410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
18430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_ISAKMP:
18440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Illegal protocol id=%u.\n", proto_id);
18490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
18550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check protocol id in quick mode
18560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
18570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_prot_quick(proto_id)
18590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
18600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
18620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
18630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
18640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
18670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
18700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
18710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid protocol id %d.\n", proto_id);
18720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
18730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
18740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
18750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
18760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
18780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_spi_size(proto_id, size)
18790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id, size;
18800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
18810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
18820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_ISAKMP:
18830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 0) {
18840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* WARNING */
18850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
18860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"SPI size isn't zero, but IKE proposal.\n");
18870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
18900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
18910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
18920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 4) {
18930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
18940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid SPI size=%d for IPSEC proposal.\n",
18950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size);
18960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
18970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
18980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
18990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
19010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (size != 2 && size != 4) {
19020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
19030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid SPI size=%d for IPCOMP proposal.\n",
19040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size);
19050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
19060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
19070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ??? */
19110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in ISAKMP.
19180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_isakmp(t_id)
19210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
19220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
19240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_KEY_IKE:
19250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in proto_id=%u.\n",
19290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			t_id, IPSECDOI_KEY_IKE);
19300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in AH.
19370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_ah(t_id)
19400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
19410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
19430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_MD5:
19440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA:
19450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA256:
19460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA384:
19470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_SHA512:
19480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_AH_DES:
19500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"not support transform-id=%u in AH.\n", t_id);
19520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in AH.\n", t_id);
19560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in ESP.
19630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_esp(t_id)
19660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
19670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
19680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
19690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES:
19700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3DES:
19710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_NULL:
19720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC5:
19730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAST:
19740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_BLOWFISH:
19750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_AES:
19760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_TWOFISH:
19770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_CAMELLIA:
19780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
19790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV32:
19800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_DES_IV64:
19810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_IDEA:
19820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_3IDEA:
19830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ESP_RC4:
19840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"not support transform-id=%u in ESP.\n", t_id);
19860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
19880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
19890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in ESP.\n", t_id);
19900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
19910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
19920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
19930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
19940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
19950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
19960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check transform ID in IPCOMP.
19970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
19980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
19990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_trns_ipcomp(t_id)
20000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int t_id;
20010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (t_id) {
20030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_OUI:
20040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_DEFLATE:
20050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_IPCOMP_LZS:
20060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
20070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
20080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
20090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid transform-id=%u in IPCOMP.\n", t_id);
20100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
20110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
20120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* NOT REACHED */
20130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
20140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
20160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check data attributes in IKE.
20170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
20180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
20190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_isakmp(trns)
20200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
20210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
20220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
20230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
20240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
20250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
20260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
20280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
20290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
20310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
20320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
20330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
20340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
20360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
20370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr(type), flag,
20380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_oakley_attr_v(type, lorv));
20390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
20410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * some of the attributes must be encoded in TV.
20420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * see RFC2409 Appendix A "Attribute Classes".
20430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
20440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
20450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
20460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
20470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
20480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
20490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
20500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
20510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
20520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
20530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
20540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!flag) {	/* TLV*/
20550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
20560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"oakley attribute %d must be TV.\n",
20570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					type);
20580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
20590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
20600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
20610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
20620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check for TLV.  length must be specified. */
20640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!flag && lorv == 0) {	/*TLV*/
20650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
20660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid length %d for TLV attribute %d.\n",
20670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				lorv, type);
20680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
20690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
20700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
20720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_ENC_ALG:
20730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_encdef_ok(lorv)) {
20740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
20750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalied encryption algorithm=%d.\n",
20760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
20770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
20780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
20790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
20800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_HASH_ALG:
20820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_hashdef_ok(lorv)) {
20830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
20840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalied hash algorithm=%d.\n",
20850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
20860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
20870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
20880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
20890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
20900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD:
20910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
20920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
20930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
20940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
20950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
20960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
20970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2098f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#if defined(ENABLE_HYBRID) || defined(HAVE_GSSAPI)
2099f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				/* These two authentication method IDs overlap. */
2100f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
2101f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			/*case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:*/
21020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
21040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
21050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
21060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
21070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
21080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
21090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
21100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
21110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
21120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
21130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
21140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
21150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
21160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
21170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
21180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
21190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
21200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"auth method %s isn't supported.\n",
21220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					s_oakley_attr_method(lorv));
21230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
21250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid auth method %d.\n",
21270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_DESC:
21330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
21340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid DH group %d.\n",
21360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_TYPE:
21420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
21430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_GRP_TYPE_MODP:
21440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
21450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
21460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"unsupported DH group type %d.\n",
21480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
21490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_PI:
21540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_ONE:
21550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* sanity checks? */
21560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_GEN_TWO:
21590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_A:
21600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_CURVE_B:
21610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
21630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
21640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD_TYPE:
21660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
21670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_SEC:
21680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_SA_LD_TYPE_KB:
21690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
21700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
21710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
21720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
21730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
21740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
21750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_SA_LD:
21780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* should check the value */
21790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_PRF:
21820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_KEY_LEN:
21830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_FIELD_SIZE:
21860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
21880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
21890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GRP_ORDER:
21910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_GSS_ID:
21940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
21950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
21960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
21970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
21980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
21990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
22000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
22030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
22040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
22050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
22060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
22070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
22080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
22090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
22100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
22110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
22120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
22140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
22170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check data attributes in IPSEC AH/ESP.
22180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
22190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ah(trns)
22210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_AH, trns);
22240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_esp(trns)
22280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return check_attr_ipsec(IPSECDOI_PROTO_IPSEC_ESP, trns);
22310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
22320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
22340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ipsec(proto_id, trns)
22350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id;
22360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
22370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
22380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
22390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
22400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type = 0;
22410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
22420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrseen[16];	/* XXX magic number */
22430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
22450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
22460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attrseen, 0, sizeof(attrseen));
22470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
22490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
22500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
22510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
22520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
22540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
22550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr(type), flag,
22560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(type, lorv));
22570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (type < sizeof(attrseen)/sizeof(attrseen[0]))
22590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrseen[type]++;
22600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
22620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
22630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
22640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
22650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when ENC_MODE.\n");
22660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
22670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
22680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
22700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
22710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TRNS:
22720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
22730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
22740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
22750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
22760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
22770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
22780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
22790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "UDP encapsulation requested\n");
22800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
22810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
22820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
22830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
22840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid encryption mode=%u.\n",
22850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
22860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
22870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
22880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
22890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
22910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
22920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
22930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when AUTH.\n");
22940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
22950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
22960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
22970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
22980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_HMAC_MD5:
22990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (proto_id == IPSECDOI_PROTO_IPSEC_AH &&
23000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    trns->t_id != IPSECDOI_AH_MD5) {
23010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangahmismatch:
23020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
23030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"auth algorithm %u conflicts "
23040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"with transform %u.\n",
23050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						lorv, trns->t_id);
23060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
23070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
23080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
23100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (trns->t_id != IPSECDOI_AH_SHA)
23120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						goto ahmismatch;
23130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
23140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
23160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA256)
23180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 						goto ahmismatch;
2319f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh 				}
23200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
23220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA384)
23240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 						goto ahmismatch;
23250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				}
23260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
23280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				if (proto_id == IPSECDOI_PROTO_IPSEC_AH) {
23290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					if (trns->t_id != IPSECDOI_AH_SHA512)
23300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 					goto ahmismatch;
23310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				}
23320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 				break;
23330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_DES_MAC:
23340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_AUTH_KPDK:
23350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"auth algorithm %u isn't supported.\n",
23370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
23400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid auth algorithm=%u.\n",
23420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
23480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when LD_TYPE.\n");
23510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
23550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
23560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
23570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
23580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
23590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
23610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
23660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
23670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
23680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
23690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"life duration was in TLV.\n");
23700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
23710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
23720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (lorv == 0) {
23730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
23740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid length of LD\n");
23750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
23760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
23770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
23810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when GRP_DESC.\n");
23840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
23880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid group description=%u.\n",
23900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
23910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
23920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
23930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
23940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
23950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
23960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
23970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
23980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when KEY_LENGTH.\n");
23990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
24020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
24040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SECCTX:
24050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
24060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"SECCTX must be in TLV.\n");
24080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
24110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
24120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
24140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
24150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
24160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
24170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
24180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
24190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
24210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
24220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
24230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
24240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
24250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
24270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
24280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
24290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
24300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
24310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
24320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d
24330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
24340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
24350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPSEC_AH &&
24380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
24390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"attr AUTH must be present for AH.\n");
24410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPSEC_ESP &&
24450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    trns->t_id == IPSECDOI_ESP_NULL &&
24460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
24470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
24480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "attr AUTH must be present for ESP NULL encryption.\n");
24490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
24500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
24510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
24530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
24540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
24560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcheck_attr_ipcomp(trns)
24570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
24580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
24590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d;
24600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
24610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type = 0;
24620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t lorv;
24630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrseen[16];	/* XXX magic number */
24640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
24660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
24670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attrseen, 0, sizeof(attrseen));
24680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
24700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
24710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
24720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		lorv = ntohs(d->lorv);
24730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
24750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%d, flag=0x%04x, lorv=0x%04x\n",
24760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type, flag, lorv);
24770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (type < sizeof(attrseen)/sizeof(attrseen[0]))
24790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrseen[type]++;
24800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
24820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
24830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
24840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
24850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when ENC_MODE.\n");
24860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
24870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
24880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
24890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
24900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
24910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_TRNS:
24920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
24930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
24940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
24950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
24960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
24970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
24980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
24990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     "UDP encapsulation requested\n");
25000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
25010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
25030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid encryption mode=%u.\n",
25050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
25060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
25110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
25120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when LD_TYPE.\n");
25140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (lorv) {
25180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
25190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
25200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
25210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
25220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type %d.\n", lorv);
25240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
25290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
25300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
25310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, NULL,
25320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"life duration was in TLV.\n");
25330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
25340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
25350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (lorv == 0) {
25360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
25370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid length of LD\n");
25380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
25390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
25400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
25440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (! flag) {
25450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"must be TV when GRP_DESC.\n");
25470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (!alg_oakley_dhdef_ok(lorv)) {
25510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
25520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid group description=%u.\n",
25530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					lorv);
25540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
25550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
25560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
25570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
25590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
25600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attr type=%u.\n", type);
25610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
25620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
25640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
25650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
25660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
25670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
25680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"attr type=%u isn't supported.\n", type);
25690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
25700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
25720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
25730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid attribute type %d.\n", type);
25740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
25750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
25760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
25780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
25790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d
25800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d));
25810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
25820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + lorv);
25830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d
25840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(*d) + lorv);
25850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
25860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0
25890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (proto_id == IPSECDOI_PROTO_IPCOMP &&
25900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    !attrseen[IPSECDOI_ATTR_AUTH]) {
25910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
25920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"attr AUTH must be present for AH.\n", type);
25930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
25940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
25950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
25960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
25970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
25980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
25990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* %%% */
26010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
26020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create phase1 proposal from remote configuration.
26030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header of SA payload
26040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
26050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
2606f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehipsecdoi_setph1proposal(rmconf, props)
2607f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct remoteconf *rmconf;
26080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *props;
26090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *mysa;
26110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int sablen;
26120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* count total size of SA minus isakmp general header */
26140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not including isakmp general header of SA payload */
26150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sablen = sizeof(struct ipsecdoi_sa_b);
26160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sablen += setph1prop(props, NULL);
26170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mysa = vmalloc(sablen);
26190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mysa == NULL) {
26200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
26210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate my sa buffer\n");
26220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
26230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create SA payload */
26260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* not including isakmp general header */
2627f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	((struct ipsecdoi_sa_b *)mysa->v)->doi = htonl(rmconf->doitype);
2628f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	((struct ipsecdoi_sa_b *)mysa->v)->sit = htonl(rmconf->sittype);
26290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)setph1prop(props, mysa->v + sizeof(struct ipsecdoi_sa_b));
26310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return mysa;
26330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1prop(props, buf)
26370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *props;
26380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
26390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop = NULL;
26410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *s = NULL;
26420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proplen, trnslen;
26430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_t; /* pointer next trns type in previous header */
26440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trns_num;
26450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
26460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proplen = sizeof(*prop);
26480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
26490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create proposal */
26500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)p;
26510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->h.np = ISAKMP_NPTYPE_NONE;
26520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->p_no = props->prop_no;
26530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->proto_id = IPSECDOI_PROTO_ISAKMP;
26540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = 0;
26550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += sizeof(*prop);
26560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np_t = NULL;
26590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trns_num = 0;
26600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (s = props; s != NULL; s = s->next) {
26620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_t)
26630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_t = ISAKMP_NPTYPE_T;
26640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnslen = setph1trns(s, p);
26660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		proplen += trnslen;
26670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
26680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* save buffer to pre-next payload */
26690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			np_t = &((struct isakmp_pl_t *)p)->h.np;
26700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p += trnslen;
26710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* count up transform length */
26730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			trns_num++;
26740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
26750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update proposal length */
26780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
26790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->h.len = htons(proplen);
26800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->num_t = trns_num;
26810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
26820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return proplen;
26840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
26850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
26870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1trns(sa, buf)
26880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
26890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
26900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
26910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns = NULL;
26920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int trnslen, attrlen;
26930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
26940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
26950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnslen = sizeof(*trns);
26960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf) {
26970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* create transform */
26980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)p;
26990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.np  = ISAKMP_NPTYPE_NONE;
27000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_no  = sa->trns_no;
27010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_id  = IPSECDOI_KEY_IKE;
27020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += sizeof(*trns);
27030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attrlen = setph1attr(sa, p);
27060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnslen += attrlen;
27070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
27080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p += attrlen;
27090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf)
27110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.len = htons(trnslen);
27120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return trnslen;
27140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
27150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
27170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph1attr(sa, buf)
27180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmpsa *sa;
27190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t buf;
27200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
27210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t p = buf;
27220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrlen = 0;
27230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->lifetime) {
27250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t lifetime = htonl((u_int32_t)sa->lifetime);
27260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data)
27280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct isakmp_data);
27290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->lifetime > 0xffff)
27300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(lifetime);
27310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
27320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
27330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						OAKLEY_ATTR_SA_LD_TYPE_SEC);
27340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sa->lifetime > 0xffff) {
27350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
2736f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						(caddr_t)&lifetime,
27370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						sizeof(lifetime));
27380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
27390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
27400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sa->lifetime);
27410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
27420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
27430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->lifebyte) {
27460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t lifebyte = htonl((u_int32_t)sa->lifebyte);
2747f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
27480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data)
27490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct isakmp_data);
27500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa->lifebyte > 0xffff)
27510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(lifebyte);
27520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
27530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD_TYPE,
27540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						OAKLEY_ATTR_SA_LD_TYPE_KB);
27550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (sa->lifebyte > 0xffff) {
27560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_SA_LD,
27570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&lifebyte,
27580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sizeof(lifebyte));
27590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
27600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_l(p, OAKLEY_ATTR_SA_LD,
27610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							sa->lifebyte);
27620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
27630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
27640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
27660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->enctype) {
27670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
27680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
27690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_ENC_ALG, sa->enctype);
27700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->encklen) {
27720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
27730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
27740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_KEY_LEN, sa->encklen);
27750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->authmethod) {
27770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int authmethod;
27780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2779f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		authmethod = isakmpsa_switch_authmethod(sa->authmethod);
2780f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		authmethod &= 0xffff;
27810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
27820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
27830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_AUTH_METHOD, authmethod);
27840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->hashtype) {
27860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
27870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf)
27880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_HASH_ALG, sa->hashtype);
27890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
27900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (sa->dh_group) {
27910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP768:
27920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP1024:
27930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP1536:
27940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP2048:
27950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP3072:
27960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP4096:
27970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP6144:
27980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_MODP8192:
27990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't attach group type for known groups */
28000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_DESC,
28030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sa->dh_group);
28040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_EC2N155:
28070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_GRP_DESC_EC2N185:
28080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't attach group type for known groups */
28090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = isakmp_set_attr_l(p, OAKLEY_ATTR_GRP_TYPE,
28120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				OAKLEY_ATTR_GRP_TYPE_EC2N);
28130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case 0:
28160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
28170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
28180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
28210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
28220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    sa->gssid != NULL) {
28230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);
28240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
28250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Older versions of racoon just placed the ISO-Latin-1
28260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * string on the wire directly.  Check to see if we are
28270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * configured to be compatible with this behavior.  Otherwise,
28280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we encode the GSS ID as UTF-16LE for Windows 2000
28290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * compatibility, which requires twice the number of octets.
28300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
28310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (lcconf->gss_id_enc == LC_GSSENC_LATIN1)
28320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sa->gssid->l;
28330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
28340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sa->gssid->l * 2;
28350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf) {
28360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "gss id attr: len %zu, "
28370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "val '%.*s'\n", sa->gssid->l, (int)sa->gssid->l,
28380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    sa->gssid->v);
28390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (lcconf->gss_id_enc == LC_GSSENC_LATIN1) {
28400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID,
28410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(caddr_t)sa->gssid->v,
28420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sa->gssid->l);
28430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
28440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t dstleft = sa->gssid->l * 2;
28450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t srcleft = sa->gssid->l;
28460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				const char *src = (const char *)sa->gssid->v;
28470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				char *odst, *dst = racoon_malloc(dstleft);
28480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iconv_t cd;
28490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				size_t rv;
28500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				cd = iconv_open("utf-16le", "latin1");
28520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (cd == (iconv_t) -1) {
28530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
28540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "unable to initialize "
28550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "latin1 -> utf-16le "
28560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "converstion descriptor: %s\n",
28570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    strerror(errno));
28580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					attrlen -= sa->gssid->l * 2;
28590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto gssid_done;
28600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
28610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				odst = dst;
2862f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				rv = iconv(cd, (__iconv_const char **)&src,
28630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    &srcleft, &dst, &dstleft);
28640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (rv != 0) {
28650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					if (rv == -1) {
28660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						plog(LLV_ERROR, LOCATION, NULL,
28670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "unable to convert GSS ID "
28680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "from latin1 -> utf-16le: "
28690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "%s\n", strerror(errno));
28700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					} else {
28710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						/* should never happen */
28720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						plog(LLV_ERROR, LOCATION, NULL,
28730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "%zd character%s in GSS ID "
28740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "cannot be represented "
28750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    "in utf-16le\n",
28760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						    rv, rv == 1 ? "" : "s");
28770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					}
28780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					(void) iconv_close(cd);
28790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					attrlen -= sa->gssid->l * 2;
28800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto gssid_done;
28810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
28820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				(void) iconv_close(cd);
28830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* XXX Check srcleft and dstleft? */
28850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				p = isakmp_set_attr_v(p, OAKLEY_ATTR_GSS_ID,
28870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					odst, sa->gssid->l * 2);
28880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(odst);
28900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
28910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
28920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
28930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang gssid_done:
28940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_GSSAPI */
28950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return attrlen;
28970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
28980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
28990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic vchar_t *
29000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangsetph2proposal0(iph2, pp, pr)
29010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct ph2handle *iph2;
29020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saprop *pp;
29030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct saproto *pr;
29040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
29050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *p;
29060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
29070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *trns;
29080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
29090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int attrlen;
29100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t trnsoff;
29110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t x0, x;
29120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *np_t; /* pointer next trns type in previous header */
29130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const u_int8_t *spi;
29140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
29150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int truectxlen = 0;
29160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
29170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	p = vmalloc(sizeof(*prop) + sizeof(pr->spi));
29190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (p == NULL)
29200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
29210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create proposal */
29230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop = (struct isakmp_pl_p *)p->v;
29240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->h.np = ISAKMP_NPTYPE_NONE;
29250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->p_no = pp->prop_no;
29260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->proto_id = pr->proto_id;
29270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->num_t = 1;
29280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	spi = (const u_int8_t *)&pr->spi;
29300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (pr->proto_id) {
29310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
29320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
29330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * draft-shacham-ippcp-rfc2393bis-05.txt:
29340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * construct 16bit SPI (CPI).
29350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX we may need to provide a configuration option to
29360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * generate 32bit SPI.  otherwise we cannot interoeprate
29370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with nodes that uses 32bit SPI, in case we are initiator.
29380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
29390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = sizeof(u_int16_t);
29400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		spi += sizeof(pr->spi) - sizeof(u_int16_t);
29410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->l -= sizeof(pr->spi);
29420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p->l += sizeof(u_int16_t);
29430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
29450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop->spi_size = sizeof(pr->spi);
29460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
29470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
29480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(prop + 1, spi, prop->spi_size);
29490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create transform */
29510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	trnsoff = sizeof(*prop) + prop->spi_size;
29520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	np_t = NULL;
29530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (tr = pr->head; tr; tr = tr->next) {
2955f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
29560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (pr->proto_id) {
29570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_ESP:
29580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
29590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * don't build a null encryption
29600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * with no authentication transform.
29610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
29620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->trns_id == IPSECDOI_ESP_NULL &&
29630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    tr->authtype == IPSECDOI_ATTR_AUTH_NONE)
29640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				continue;
29650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
29660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (np_t) {
29690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*np_t = ISAKMP_NPTYPE_T;
29700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			prop->num_t++;
29710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get attribute length */
29740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen = 0;
29750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifetime) {
29760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data)
29770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(struct isakmp_data);
29780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifetime > 0xffff)
29790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(u_int32_t);
29800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) {
29820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data)
29830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				+ sizeof(struct isakmp_data);
29840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifebyte > 0xffff)
29850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(u_int32_t);
29860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
29870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attrlen += sizeof(struct isakmp_data);	/* enc mode */
29880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr->encklen)
29890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
29900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
29910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (pr->proto_id) {
29920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_ESP:
29930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* non authentication mode ? */
29940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE)
29950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				attrlen += sizeof(struct isakmp_data);
29960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
29970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPSEC_AH:
29980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype == IPSECDOI_ATTR_AUTH_NONE) {
29990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
30000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"no authentication algorithm found "
30010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"but protocol is AH.\n");
30020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(p);
30030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
30040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
30060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_PROTO_IPCOMP:
30080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
30090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
30100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
30110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid protocol: %d\n", pr->proto_id);
30120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(p);
30130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
30140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group))
30170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data);
30180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
30200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* ctx_str is defined as char ctx_str[MAX_CTXSTR_SIZ].
30210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * The string may be smaller than MAX_CTXSTR_SIZ.
30220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
30230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*pp->sctx.ctx_str) {
30240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			truectxlen = sizeof(struct security_ctx) -
30250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				     (MAX_CTXSTR_SIZE - pp->sctx.ctx_strlen);
30260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			attrlen += sizeof(struct isakmp_data) + truectxlen;
30270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
30290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = vrealloc(p, p->l + sizeof(*trns) + attrlen);
30310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (p == NULL)
30320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
30330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prop = (struct isakmp_pl_p *)p->v;
30340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set transform's values */
30360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)(p->v + trnsoff);
30370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.np  = ISAKMP_NPTYPE_NONE;
30380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_no  = tr->trns_no;
30390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->t_id  = tr->trns_id;
30400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* set attributes */
30420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		x = x0 = p->v + trnsoff + sizeof(*trns);
30430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifetime) {
30450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE,
30460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						IPSECDOI_ATTR_SA_LD_TYPE_SEC);
30470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifetime > 0xffff) {
30480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int32_t v = htonl((u_int32_t)pp->lifetime);
30490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD,
30500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&v, sizeof(v));
30510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
30520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD,
30530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							pp->lifetime);
30540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (pp->lifebyte && pp->lifebyte != IPSECDOI_ATTR_SA_LD_KB_MAX) {
30580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD_TYPE,
30590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						IPSECDOI_ATTR_SA_LD_TYPE_KB);
30600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->lifebyte > 0xffff) {
30610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int32_t v = htonl((u_int32_t)pp->lifebyte);
30620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SA_LD,
30630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							(caddr_t)&v, sizeof(v));
30640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
30650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				x = isakmp_set_attr_l(x, IPSECDOI_ATTR_SA_LD,
30660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang							pp->lifebyte);
30670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
30680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		x = isakmp_set_attr_l(x, IPSECDOI_ATTR_ENC_MODE, pr->encmode);
30710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (tr->encklen)
30730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_KEY_LENGTH, tr->encklen);
30740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* mandatory check has done above. */
30760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((pr->proto_id == IPSECDOI_PROTO_IPSEC_ESP && tr->authtype != IPSECDOI_ATTR_AUTH_NONE)
30770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 || pr->proto_id == IPSECDOI_PROTO_IPSEC_AH)
30780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_AUTH, tr->authtype);
30790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (alg_oakley_dhdef_ok(iph2->sainfo->pfs_group))
30810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_l(x, IPSECDOI_ATTR_GRP_DESC,
30820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph2->sainfo->pfs_group);
30830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
30850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*pp->sctx.ctx_str) {
30860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct security_ctx secctx;
30870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			secctx = pp->sctx;
30880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			secctx.ctx_strlen = htons(pp->sctx.ctx_strlen);
30890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			x = isakmp_set_attr_v(x, IPSECDOI_ATTR_SECCTX,
30900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					     (caddr_t)&secctx, truectxlen);
30910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
30920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
30930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* update length of this transform. */
30940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns = (struct isakmp_pl_t *)(p->v + trnsoff);
30950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trns->h.len = htons(sizeof(*trns) + attrlen);
30960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* save buffer to pre-next payload */
30980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		np_t = &trns->h.np;
30990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		trnsoff += (sizeof(*trns) + attrlen);
31010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (np_t == NULL) {
31040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no suitable proposal was created.\n");
31060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
31070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* update length of this protocol. */
31100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop->h.len = htons(p->l);
31110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return p;
31130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
31160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create phase2 proposal from policy configuration.
31170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header of SA payload.
31180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * This function is called by initiator only.
31190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
31200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setph2proposal(iph2)
31220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
31230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *proposal, *a;
31250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *b = NULL;
31260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *q;
31270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_sa_b *sab;
31280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_p *prop;
31290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t propoff;	/* for previous field of type of next payload. */
31300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	proposal = iph2->proposal;
31320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->sa = vmalloc(sizeof(*sab));
31340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sa == NULL) {
31350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
31360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate my sa buffer\n");
31370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
31380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* create SA payload */
31410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab = (struct ipsecdoi_sa_b *)iph2->sa->v;
31420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab->doi = htonl(IPSEC_DOI);
31430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sab->sit = htonl(IPSECDOI_SIT_IDENTITY_ONLY);	/* XXX configurable ? */
31440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prop = NULL;
31460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	propoff = 0;
31470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (a = proposal; a; a = a->next) {
31480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (b = a->head; b; b = b->next) {
31490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
31500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->ph1->natt_flags & NAT_DETECTED) {
31510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  int udp_diff = iph2->ph1->natt_options->mode_udp_diff;
31520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  plog (LLV_INFO, LOCATION, NULL,
31530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"NAT detected -> UDP encapsulation "
31540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"(ENC_MODE %d->%d).\n",
31550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b->encmode,
31560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b->encmode+udp_diff);
31570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  /* Tunnel -> UDP-Tunnel, Transport -> UDP_Transport */
31580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  b->encmode += udp_diff;
31590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			  b->udp_encap = 1;
31600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
31610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
31620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			q = setph2proposal0(iph2, a, b);
31640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (q == NULL) {
31650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				VPTRINIT(iph2->sa);
31660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
31670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
31680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->sa = vrealloc(iph2->sa, iph2->sa->l + q->l);
31700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph2->sa == NULL) {
31710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
31720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to allocate my sa buffer\n");
31730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (q)
31740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					vfree(q);
31750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
31760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
31770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(iph2->sa->v + iph2->sa->l - q->l, q->v, q->l);
31780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (propoff != 0) {
31790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop = (struct isakmp_pl_p *)(iph2->sa->v +
31800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					propoff);
31810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				prop->h.np = ISAKMP_NPTYPE_P;
31820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
31830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			propoff = iph2->sa->l - q->l;
31840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree(q);
31860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
31870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
31880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
31900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
31910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
31920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
31930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * return 1 if all of the given protocols are transport mode.
31940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
31950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
31960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_transportmode(pp)
31970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
31980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
31990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr = NULL;
32000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (; pp; pp = pp->next) {
32020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (pr = pp->head; pr; pr = pr->next) {
3203f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			if (pr->encmode != IPSECDOI_ATTR_ENC_MODE_TRNS &&
3204f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			    pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC &&
3205f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			    pr->encmode != IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT)
32060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return 0;
32070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 1;
32110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_get_defaultlifetime()
32150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
32170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkalgtypes(proto_id, enc, auth, comp)
32210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto_id, enc, auth, comp;
32220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define TMPALGTYPE2STR(n) s_algtype(algclass_ipsec_##n, n)
32240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto_id) {
32250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
32260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc == 0 || comp != 0) {
32270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ESP enc=%s auth=%s comp=%s.\n",
32300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
32370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc != 0 || auth == 0 || comp != 0) {
32380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"AH enc=%s auth=%s comp=%s.\n",
32410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
32480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (enc != 0 || auth != 0 || comp == 0) {
32490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
32500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"illegal algorithm defined "
32510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"IPcomp enc=%s auth=%s comp=%s.\n",
32520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(enc),
32530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(auth),
32540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				TMPALGTYPE2STR(comp));
32550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
32560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
32570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
32580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
32590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
32600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid ipsec protocol %d\n", proto_id);
32610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
32620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#undef TMPALGTYPE2STR
32640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
32650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipproto2doi(proto)
32690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
32700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
32720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_AH:
32730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_AH;
32740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_ESP:
32750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPSEC_ESP;
32760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPPROTO_IPCOMP:
32770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_PROTO_IPCOMP;
32780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;	/* XXX */
32800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
32830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdoi2ipproto(proto)
32840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int proto;
32850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
32860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (proto) {
32870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_AH:
32880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_AH;
32890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPSEC_ESP:
32900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_ESP;
32910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_PROTO_IPCOMP:
32920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPPROTO_IPCOMP;
32930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
32940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;	/* XXX */
32950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
32960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
32970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
32980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Check if a subnet id is valid for comparison
32990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * with an address id ( address length mask )
33000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * and compare them
33010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return value
33020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  0 for match
33030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  1 for mismatch
33040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
33050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_subnetisaddr_v4( subnet, address )
33080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *subnet;
33090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *address;
33100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct in_addr *mask;
33120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (address->l != sizeof(struct in_addr))
33140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (subnet->l != (sizeof(struct in_addr)*2))
33170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mask = (struct in_addr*)(subnet->v + sizeof(struct in_addr));
33200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (mask->s_addr!=0xffffffff)
33220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return memcmp(subnet->v,address->v,address->l);
33250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
33280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_subnetisaddr_v6( subnet, address )
33310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *subnet;
33320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *address;
33330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct in6_addr *mask;
33350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
33360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (address->l != sizeof(struct in6_addr))
33380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (subnet->l != (sizeof(struct in6_addr)*2))
33410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
33420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	mask = (struct in6_addr*)(subnet->v + sizeof(struct in6_addr));
33440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i=0; i<16; i++)
33460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(mask->s6_addr[i]!=0xff)
33470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 1;
33480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return memcmp(subnet->v,address->v,address->l);
33500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
33510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
33530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
33550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Check and Compare two IDs
33560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - specify 0 for exact if wildcards are allowed
33570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Return value
33580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  0 for match
33590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * =  1 for misatch
33600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * = -1 for integrity error
33610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
33620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
33640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_chkcmpids( idt, ids, exact )
33650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *idt; /* id cmp target */
33660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *ids; /* id cmp source */
33670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int exact;
33680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
33690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_bt;
33700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_bs;
33710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t ident_t;
33720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t ident_s;
33730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int result;
33740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* handle wildcard IDs */
33760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (idt == NULL || ids == NULL)
33780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
33790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( !exact )
33800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
33810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
33820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : values matched (ANONYMOUS)\n" );
33830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
33840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
33850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
33860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
33870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
33880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : value mismatch (ANONYMOUS)\n" );
33890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
33900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
33910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
33920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* make sure the ids are of the same type */
33940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_bt = (struct ipsecdoi_id_b *) idt->v;
33960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_bs = (struct ipsecdoi_id_b *) ids->v;
33970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
33980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_t.v = idt->v + sizeof(*id_bt);
33990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_t.l = idt->l - sizeof(*id_bt);
34000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_s.v = ids->v + sizeof(*id_bs);
34010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident_s.l = ids->l - sizeof(*id_bs);
34020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (id_bs->type != id_bt->type)
34040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
34050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
34060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * special exception for comparing
34070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 * address to subnet id types when
34080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 * the netmask is address length
34090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang                 */
34100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&&
34120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) {
34130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s);
34140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&&
34180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) {
34190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t);
34200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&&
34250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
34260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s);
34270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&&
34310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) {
34320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t);
34330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
34350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"check and compare ids : id type mismatch %s != %s\n",
34380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_bs->type),
34390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_bt->type));
34400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
34420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(id_bs->proto_id != id_bt->proto_id){
34450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
34460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"check and compare ids : proto_id mismatch %d != %d\n",
34470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_bs->proto_id, id_bt->proto_id);
34480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
34500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
34510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* compare the ID data. */
34530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_bt->type) {
34550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	        case IPSECDOI_ID_DER_ASN1_DN:
34560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        	case IPSECDOI_ID_DER_ASN1_GN:
34570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* compare asn1 ids */
34580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			result = eay_cmp_asn1dn(&ident_t, &ident_s);
34590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto cmpid_result;
34600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR:
34620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
34630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != sizeof(struct in_addr))||
34640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != sizeof(struct in_addr)))
34650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
34660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
34690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_RANGE:
34700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
34710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != (sizeof(struct in_addr)*2))||
34720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != (sizeof(struct in_addr)*2)))
34730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
34740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
34770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR:
34780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
34790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != sizeof(struct in6_addr))||
34800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != sizeof(struct in6_addr)))
34810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
34820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
34850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_RANGE:
34860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* validate lengths */
34870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((ident_t.l != (sizeof(struct in6_addr)*2))||
34880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    (ident_s.l != (sizeof(struct in6_addr)*2)))
34890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto cmpid_invalid;
34900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
34920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_FQDN:
34930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_USER_FQDN:
34940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_KEY_ID:
34950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
34960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
34970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
34980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
34990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Unhandled id type %i specified for comparison\n",
35000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				id_bt->type);
35010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
35020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* validate matching data and length */
35050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident_t.l == ident_s.l)
35060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		result = memcmp(ident_t.v,ident_s.v,ident_t.l);
35070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
35080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		result = 1;
35090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpid_result:
35110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* debug level output */
35130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(loglevel >= LLV_DEBUG) {
35140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *idstrt = ipsecdoi_id2str(idt);
35150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *idstrs = ipsecdoi_id2str(ids);
35160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!result)
35180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 		plog(LLV_DEBUG, LOCATION, NULL,
35190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : values matched (%s)\n",
35200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 s_ipsecdoi_ident(id_bs->type) );
35210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
35220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 			plog(LLV_DEBUG, LOCATION, NULL,
35230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"check and compare ids : value mismatch (%s)\n",
35240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 s_ipsecdoi_ident(id_bs->type));
35250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: \'%s\'\n", idstrt );
35270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: \'%s\'\n", idstrs );
35280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(idstrs);
35300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(idstrt);
35310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* return result */
35340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if( !result )
35350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
35360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
35370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 1;
35380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangcmpid_invalid:
35400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* id integrity error */
35420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "check and compare ids : %s integrity error\n",
35430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(id_bs->type));
35440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "cmpid target: length = \'%zu\'\n", ident_t.l );
35450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "cmpid source: length = \'%zu\'\n", ident_s.l );
35460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
35480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
35490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
35510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * check the following:
35520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - In main mode with pre-shared key, only address type can be used.
35530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if proper type for phase 1 ?
35540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if phase 1 ID payload conformed RFC2407 4.6.2.
35550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *   (proto, port) must be (0, 0), (udp, 500) or (udp, [specified]).
35560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * - if ID payload sent from peer is equal to the ID expected by me.
35570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
35580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * both of "id" and "id_p" should be ID payload without general header,
35590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
35600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
35610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_checkid1(iph1)
35620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
35630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
35640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_b;
35650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->id_p == NULL) {
35670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid iph1 passed id_p == NULL\n");
35690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_INTERNAL_ERROR;
35700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->id_p->l < sizeof(*id_b)) {
35720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
35730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid value passed as \"ident\" (len=%lu)\n",
35740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(u_long)iph1->id_p->l);
35750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
35760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b = (struct ipsecdoi_id_b *)iph1->id_p->v;
35790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* In main mode with pre-shared key, only address type can be used. */
35810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->etype == ISAKMP_ETYPE_IDENT &&
35820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) {
35830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 if (id_b->type != IPSECDOI_ID_IPV4_ADDR
35840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		  && id_b->type != IPSECDOI_ID_IPV6_ADDR) {
35850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
35860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Expecting IP address type in main mode, "
35870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"but %s.\n", s_ipsecdoi_ident(id_b->type));
35880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
35890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
35900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
35910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
35920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if proper type for phase 1 ? */
35930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
35940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
35950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
35960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
35970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
35980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
35990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"such ID type %s is not proper.\n",
36000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(id_b->type));
36010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
36020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* if phase 1 ID payload conformed RFC2407 4.6.2. */
36050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (id_b->type == IPSECDOI_ID_IPV4_ADDR ||
36060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    id_b->type == IPSECDOI_ID_IPV6_ADDR) {
36070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (id_b->proto_id == 0 && ntohs(id_b->port) != 0) {
36090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
36100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"protocol ID and Port mismatched. "
36110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"proto_id:%d port:%d\n",
36120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				id_b->proto_id, ntohs(id_b->port));
36130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*FALLTHROUGH*/
36140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else if (id_b->proto_id == IPPROTO_UDP) {
36160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
36170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * copmaring with expecting port.
36180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * always permit if port is equal to PORT_ISAKMP
36190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
36200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (ntohs(id_b->port) != PORT_ISAKMP) {
36210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				u_int16_t port;
36220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				port = extract_port(iph1->remote);
36240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ntohs(id_b->port) != port) {
36250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_WARNING, LOCATION, NULL,
36260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"port %d expected, but %d\n",
36270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						port, ntohs(id_b->port));
36280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					/*FALLTHROUGH*/
36290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
36300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
36310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
36320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
36330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3634f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	/* resolve remote configuration if not done yet */
3635f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (resolveph1rmconf(iph1) < 0)
3636f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
3637f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
3638f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (iph1->rmconf == NULL)
3639f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
36400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
36420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
36430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
36450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create ID payload for phase 1 and set into iph1->id.
36460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header.
36470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
36480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
36490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
36500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setid1(iph1)
36510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
36520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
36530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ret = NULL;
36540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b id_b;
36550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *ident = NULL;
36560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *ipid = NULL;
36570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* init */
36590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b.proto_id = 0;
36600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	id_b.port = 0;
36610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ident = NULL;
36620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
36630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (iph1->rmconf->idvtype) {
36640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_FQDN:
36650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_FQDN;
3666f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		ident = vdup(iph1->rmconf->idv);
36670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
36680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_USERFQDN:
36690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_USER_FQDN;
3670f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		ident = vdup(iph1->rmconf->idv);
36710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
36720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_KEYID:
36730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_KEY_ID;
3674f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		ident = vdup(iph1->rmconf->idv);
36750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
36760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ASN1DN:
36770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.type = IPSECDOI_ID_DER_ASN1_DN;
36780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->idv) {
36790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* XXX it must be encoded to asn1dn. */
36800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ident = vdup(iph1->rmconf->idv);
36810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
36820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (oakley_getmycert(iph1) < 0) {
36830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
36840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to get own CERT.\n");
36850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto err;
36860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3687f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			ident = eay_get_x509asn1subjectname(iph1->cert);
36880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
36890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
36900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ADDRESS:
36910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
36920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * if the value of the id type was set by the configuration
36930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * file, then use it.  otherwise the value is get from local
36940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ip address by using ike negotiation.
36950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
36960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->idv)
36970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipid = (struct sockaddr *)iph1->rmconf->idv->v;
36980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*FALLTHROUGH*/
36990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
37000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
37010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int l;
37020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		caddr_t p;
37030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ipid == NULL)
37050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ipid = iph1->local;
37060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* use IP address */
37080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ipid->sa_family) {
37090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET:
37100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_b.type = IPSECDOI_ID_IPV4_ADDR;
37110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = sizeof(struct in_addr);
37120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (caddr_t)&((struct sockaddr_in *)ipid)->sin_addr;
37130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
37140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
37150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case AF_INET6:
37160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id_b.type = IPSECDOI_ID_IPV6_ADDR;
37170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = sizeof(struct in6_addr);
37180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			p = (caddr_t)&((struct sockaddr_in6 *)ipid)->sin6_addr;
37190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
37200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
37210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
37220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
37230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid address family.\n");
37240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto err;
37250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
37260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.proto_id = IPPROTO_UDP;
37270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		id_b.port = htons(PORT_ISAKMP);
37280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ident = vmalloc(l);
37290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!ident) {
37300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
37310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to get ID buffer.\n");
3732f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			return -1;
37330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
37340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(ident->v, p, ident->l);
37350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
37360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
37370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!ident) {
37380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
37390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
3740f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		return -1;
37410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
37420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = vmalloc(sizeof(id_b) + ident->l);
37440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret == NULL) {
37450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
37460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
37470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto err;
37480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
37490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(ret->v, &id_b, sizeof(id_b));
37510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(ret->v + sizeof(id_b), ident->v, ident->l);
37520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->id = ret;
37540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
37560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"use ID type of %s\n", s_ipsecdoi_ident(id_b.type));
37570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident)
37580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ident);
37590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
37600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangerr:
37620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ident)
37630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(ident);
37640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_ERROR, LOCATION, NULL, "failed get my ID\n");
37650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
37660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
37670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* it's only called by cfparse.y. */
37690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
37700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_identifier(vpp, type, value)
37710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **vpp, *value;
37720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
37730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
37740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return set_identifier_qual(vpp, type, value, IDQUAL_UNSPEC);
37750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
37760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
37780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangset_identifier_qual(vpp, type, value, qual)
37790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t **vpp, *value;
37800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
37810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int qual;
37820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
37830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new = NULL;
37840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* simply return if value is null. */
37860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!value){
37870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( type == IDTYPE_FQDN || type == IDTYPE_USERFQDN){
37880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
37890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "No %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn");
37900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
37910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
37920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
37930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
37940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
37950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (type) {
37960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_FQDN:
37970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_USERFQDN:
37980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(value->l <= 1){
37990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
38000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				 "Empty %s\n", type == IDTYPE_FQDN ? "fqdn":"user fqdn");
38010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* length is adjusted since QUOTEDSTRING teminates NULL. */
38040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new = vmalloc(value->l - 1);
38050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL)
38060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->v, value->v, new->l);
38080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
38090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_KEYID:
3810f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		/*
38110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * If no qualifier is specified: IDQUAL_UNSPEC. It means
3812f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * to use a file for backward compatibility sake.
38130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
38140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch(qual) {
38150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_FILE:
38160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_UNSPEC: {
38170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			FILE *fp;
38180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char b[512];
38190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int tlen, len;
38200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			fp = fopen(value->v, "r");
38220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (fp == NULL) {
38230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
38240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"can not open %s\n", value->v);
38250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
38260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
38270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen = 0;
38280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while ((len = fread(b, 1, sizeof(b), fp)) != 0) {
38290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				new = vrealloc(new, tlen + len);
38300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (!new) {
38310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					fclose(fp);
38320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
38330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
38340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(new->v + tlen, b, len);
38350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				tlen += len;
38360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
38374abdc9c18fe311d8bca8f9217b28e4669219da63robert_ch_chou			fclose(fp);
38380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
38390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IDQUAL_TAG:
38420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = vmalloc(value->l - 1);
38430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (new == NULL) {
38440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
38450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"can not allocate memory");
38460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
38470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
38480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(new->v, value->v, new->l);
38490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
38500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
38520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
38530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unknown qualifier");
38540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
3857f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
38580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ADDRESS: {
38590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct sockaddr *sa;
38600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* length is adjusted since QUOTEDSTRING teminates NULL. */
38620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (value->l == 0)
38630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
38640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = str2saddr(value->v, NULL);
38660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (sa == NULL) {
38670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
38680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid ip address %s\n", value->v);
38690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		new = vmalloc(sysdep_sa_len(sa));
38730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL) {
38740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(sa);
38750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
38770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(new->v, sa, new->l);
38780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(sa);
38790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
38800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
38810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IDTYPE_ASN1DN:
38820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (value->v[0] == '~')
38830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Hex-encoded ASN1 strings */
38840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = eay_hex2asn1dn(value->v + 1, - 1);
38850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		else
38860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* DN encoded strings */
38870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			new = eay_str2asn1dn(value->v, value->l - 1);
38880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (new == NULL)
38900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
38910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (loglevel >= LLV_DEBUG) {
38930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME *xn;
38940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO *bio;
38950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			unsigned char *ptr = (unsigned char *) new->v, *buf;
38960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			size_t len;
38970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char save;
38980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
38990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xn = d2i_X509_NAME(NULL, (void *)&ptr, new->l);
39000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bio = BIO_new(BIO_s_mem());
3901f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
39020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_print_ex(bio, xn, 0, 0);
39030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BIO_get_mem_data(bio, &ptr);
39040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			save = ptr[len];
39050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ptr[len] = 0;
39060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL, "Parsed DN: %s\n", ptr);
39070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ptr[len] = save;
39080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_free(xn);
39090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO_free(bio);
39100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
39110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
39130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*vpp = new;
39160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
39180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
39190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
39210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create ID payload for phase 2, and set into iph2->id and id_p.  There are
39220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING isakmp general header.
39230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * this function is for initiator.  responder will get to copy from payload.
39240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * responder ID type is always address type.
39250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
39260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
39270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
39280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_setid2(iph2)
39290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
39300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
39310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct secpolicy *sp;
39320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check there is phase 2 handler ? */
39340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sp = getspbyspid(iph2->spid);
39350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (sp == NULL) {
39360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
39370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no policy found for spid:%u.\n", iph2->spid);
39380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
39390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3941f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (!ipsecdoi_transportmode(iph2->proposal))
3942f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.src,
3943f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				sp->spidx.prefs, sp->spidx.ul_proto);
3944f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	else if (iph2->sa_src != NULL) {
3945f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		/* He have a specific hint indicating that the transport
3946f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * mode SA will be negotiated using addresses that differ
3947f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * with the one from the SA. We need to indicate that to
3948f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * our peer by setting the SA address as ID.
3949f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * This is typically the case for the bootstrapping of the
3950f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * transport mode SA protecting BU/BA for MIPv6 traffic
3951f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 *
3952f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		 * --arno*/
3953f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id = ipsecdoi_sockaddr2id(iph2->sa_src,
3954f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						IPSECDOI_PREFIX_HOST,
3955f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						sp->spidx.ul_proto);
3956f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	} else
3957f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id = ipsecdoi_sockaddr2id(iph2->src, IPSECDOI_PREFIX_HOST,
3958f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						sp->spidx.ul_proto);
3959f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
39600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id == NULL) {
39610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
39620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
39630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp->spidx));
39640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
39650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "use local ID type %s\n",
39670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id->v)->type));
39680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* remote side */
3970f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (!ipsecdoi_transportmode(iph2->proposal))
3971f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id_p = ipsecdoi_sockaddr2id((struct sockaddr *)&sp->spidx.dst,
39720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				sp->spidx.prefd, sp->spidx.ul_proto);
3973f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	else if (iph2->sa_dst != NULL) {
3974f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		/* See comment above for local side. */
3975f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id_p = ipsecdoi_sockaddr2id(iph2->sa_dst,
3976f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						  IPSECDOI_PREFIX_HOST,
3977f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh						  sp->spidx.ul_proto);
3978f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	} else
3979f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		iph2->id_p = ipsecdoi_sockaddr2id(iph2->dst, IPSECDOI_PREFIX_HOST,
3980f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			sp->spidx.ul_proto);
3981f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
39820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->id_p == NULL) {
39830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
39840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID for %s\n",
39850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			spidx2str(&sp->spidx));
39860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		VPTRINIT(iph2->id);
39870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
39880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
39890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
39900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"use remote ID type %s\n",
39910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_ipsecdoi_ident(((struct ipsecdoi_id_b *)iph2->id_p->v)->type));
39920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
39940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
39950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
39960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
39970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set address type of ID.
39980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOT INCLUDING general header.
39990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
40000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
40010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_sockaddr2id(saddr, prefixlen, ul_proto)
40020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *saddr;
40030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int prefixlen;
40040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int ul_proto;
40050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
40060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new;
40070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type, len1, len2;
40080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	caddr_t sa;
40090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
40100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
40120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Q. When type is SUBNET, is it allowed to be ::1/128.
40130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * A. Yes. (consensus at bake-off)
40140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
40150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (saddr->sa_family) {
40160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
40170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in_addr);
4018f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (prefixlen >= (sizeof(struct in_addr) << 3)) {
40190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV4_ADDR;
40200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = 0;
40210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
40220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV4_ADDR_SUBNET;
40230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = sizeof(struct in_addr);
40240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
40250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr;
40260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port = ((struct sockaddr_in *)(saddr))->sin_port;
40270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
40280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
40290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
40300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in6_addr);
4031f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		if (prefixlen >= (sizeof(struct in6_addr) << 3)) {
40320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV6_ADDR;
40330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = 0;
40340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
40350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			type = IPSECDOI_ID_IPV6_ADDR_SUBNET;
40360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len2 = sizeof(struct in6_addr);
40370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
40380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		sa = (caddr_t)&((struct sockaddr_in6 *)(saddr))->sin6_addr;
40390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port = ((struct sockaddr_in6 *)(saddr))->sin6_port;
40400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
40410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
40420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
40430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
40440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d.\n", saddr->sa_family);
40450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
40460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get ID buffer */
40490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2);
40500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
40510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
40520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
40530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
40540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(new->v, 0, new->l);
40570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set the part of header. */
40590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->type = type;
40600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set ul_proto and port */
40620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
40630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card
40640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 means port number of 0.  Instead of 0, we use IPSEC_*_ANY.
40650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
40660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->proto_id =
40670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto;
40680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->port =
40690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port == IPSEC_PORT_ANY ? 0 : port;
40700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(new->v + sizeof(struct ipsecdoi_id_b), sa, len1);
40710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set address */
40730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set prefix */
40750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len2) {
4076f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		u_char *p = (unsigned char *) new->v +
40770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct ipsecdoi_id_b) + len1;
40780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int bits = prefixlen;
40790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while (bits >= 8) {
40810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p++ = 0xff;
40820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			bits -= 8;
40830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
40840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (bits > 0)
40860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			*p = ~((1 << (8 - bits)) - 1);
40870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
40880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
40900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
40910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
40920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
40930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_sockrange2id(laddr, haddr, ul_proto)
40940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *laddr, *haddr;
40950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int ul_proto;
40960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
40970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *new;
40980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type, len1, len2;
40990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_short port;
41000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (laddr->sa_family != haddr->sa_family) {
41020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    plog(LLV_ERROR, LOCATION, NULL, "Address family mismatch\n");
41030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    return NULL;
41040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (laddr->sa_family) {
41070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET:
41080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    type = IPSECDOI_ID_IPV4_ADDR_RANGE;
41090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    len1 = sizeof(struct in_addr);
41100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    len2 = sizeof(struct in_addr);
41110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    break;
41120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
41130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case AF_INET6:
41140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = IPSECDOI_ID_IPV6_ADDR_RANGE;
41150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len1 = sizeof(struct in6_addr);
41160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len2 = sizeof(struct in6_addr);
41170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
41180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
41190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
41200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
41210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid family: %d.\n", laddr->sa_family);
41220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
41230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get ID buffer */
41260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	new = vmalloc(sizeof(struct ipsecdoi_id_b) + len1 + len2);
41270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (new == NULL) {
41280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
41290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to get ID buffer.\n");
41300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
41310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
41320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(new->v, 0, new->l);
41340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set the part of header. */
41350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->type = type;
41360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set ul_proto and port */
41380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
41390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * NOTE: we use both IPSEC_ULPROTO_ANY and IPSEC_PORT_ANY as wild card
41400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * because 0 means port number of 0.  Instead of 0, we use IPSEC_*_ANY.
41410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
41420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->proto_id =
41430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ul_proto == IPSEC_ULPROTO_ANY ? 0 : ul_proto;
41440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	port = ((struct sockaddr_in *)(laddr))->sin_port;
41450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	((struct ipsecdoi_id_b *)new->v)->port =
41460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		port == IPSEC_PORT_ANY ? 0 : port;
4147f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	memcpy(new->v + sizeof(struct ipsecdoi_id_b),
4148f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	       (caddr_t)&((struct sockaddr_in *)(laddr))->sin_addr,
41490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       len1);
4150f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	memcpy(new->v + sizeof(struct ipsecdoi_id_b) + len1,
41510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       (caddr_t)&((struct sockaddr_in *)haddr)->sin_addr,
41520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       len2);
41530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return new;
41540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
41550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
41570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
41580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * create sockaddr structure from ID payload (buf).
41590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * buffers (saddr, prefixlen, ul_proto) must be allocated.
41600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * see, RFC2407 4.6.2.1
41610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
41620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
41630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_id2sockaddr(buf, saddr, prefixlen, ul_proto)
41640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf;
41650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *saddr;
41660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t *prefixlen;
41670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int16_t *ul_proto;
41680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4169f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	struct ipsecdoi_id_b *id_b = NULL;
41700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int plen = 0;
41710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4172f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	if (buf == NULL)
4173f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		return ISAKMP_INTERNAL_ERROR;
4174f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
4175f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	id_b = (struct ipsecdoi_id_b *)buf->v;
4176f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
41770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
41780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * When a ID payload of subnet type with a IP address of full bit
41790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * masked, it has to be processed as host address.
41800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * e.g. below 2 type are same.
41810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *      type = ipv6 subnet, data = 2001::1/128
41820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 *      type = ipv6 address, data = 2001::1
41830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
41840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
41850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
41860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
41870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
41880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_len = sizeof(struct sockaddr_in);
41890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
41900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_family = AF_INET;
41910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct sockaddr_in *)saddr)->sin_port =
41920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(id_b->port == 0
41930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_PORT_ANY
41940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->port);		/* see sockaddr2id() */
41950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&((struct sockaddr_in *)saddr)->sin_addr,
41960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf->v + sizeof(*id_b), sizeof(struct in_addr));
41970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
41980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
41990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
42000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
42010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
42020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_len = sizeof(struct sockaddr_in6);
42030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		saddr->sa_family = AF_INET6;
42050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		((struct sockaddr_in6 *)saddr)->sin6_port =
42060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(id_b->port == 0
42070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_PORT_ANY
42080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->port);		/* see sockaddr2id() */
42090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr,
42100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			buf->v + sizeof(*id_b), sizeof(struct in6_addr));
4211f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		((struct sockaddr_in6 *)saddr)->sin6_scope_id =
4212f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			(IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)saddr)->sin6_addr)
4213f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
4214f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh				: 0);
4215f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
42160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
42190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
42200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported ID type %d\n", id_b->type);
42210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
42220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
42230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get prefix length */
42250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
42260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
42270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = sizeof(struct in_addr) << 3;
42280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
42300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
42310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = sizeof(struct in6_addr) << 3;
42320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
42350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
42360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
42370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
42390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_char *p;
42400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int max;
42410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int alen = sizeof(struct in_addr);
42420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (id_b->type) {
42440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
42450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in_addr);
42460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
42470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
42480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
42490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in6_addr);
42500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
42510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
42520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
42530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check */
42550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (buf->l < alen)
42560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return ISAKMP_INTERNAL_ERROR;
42570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get subnet mask length */
42590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = 0;
42600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		max = alen <<3;
42610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (unsigned char *) buf->v
42630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct ipsecdoi_id_b)
42640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ alen;
42650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (; *p == 0xff; p++) {
42670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += 8;
42680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (plen >= max)
42690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
42700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
42710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (plen < max) {
42730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int l = 0;
42740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_char b = ~(*p);
42750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (b) {
42770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b >>= 1;
42780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				l++;
42790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
42800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = 8 - l;
42820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += l;
42830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
42840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
42850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
42860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
42870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*prefixlen = plen;
42890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	*ul_proto = id_b->proto_id == 0
42900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				? IPSEC_ULPROTO_ANY
42910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				: id_b->proto_id;	/* see sockaddr2id() */
42920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
42940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
42950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
42960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
42970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * make printable string from ID payload except of general header.
42980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
42990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangchar *
43000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_id2str(id)
43010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const vchar_t *id;
43020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
43030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define BUFLEN 512
43040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * ret = NULL;
43050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0;
43060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *dat;
43070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	static char buf[BUFLEN];
43080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *)id->v;
4309f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	union sockaddr_any saddr;
43100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int plen = 0;
43110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
43130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
43140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
43150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
43160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4318f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_len = sizeof(struct sockaddr_in);
43190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4320f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_family = AF_INET;
4321f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin.sin_port = IPSEC_PORT_ANY;
4322f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		memcpy(&saddr.sin.sin_addr,
43230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b), sizeof(struct in_addr));
43240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
43270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
43280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
43290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4331f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_len = sizeof(struct sockaddr_in6);
43320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4333f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_family = AF_INET6;
4334f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin6.sin6_port = IPSEC_PORT_ANY;
4335f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		memcpy(&saddr.sin6.sin6_addr,
43360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b), sizeof(struct in6_addr));
4337f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin6.sin6_scope_id =
4338f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			(IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr)
4339051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
4340051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				: 0);
43410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
43440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (id_b->type) {
43460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
43470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
43490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4350f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr.sa));
43510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
43520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
43540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
43560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    {
43580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_char *p;
43590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int max;
43600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int alen = sizeof(struct in_addr);
43610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (id_b->type) {
43630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
43640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in_addr);
43650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
43660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
43670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
43680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			alen = sizeof(struct in6_addr);
43690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
43700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
43710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check */
43740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (id->l < alen) {
43750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = 0;
43760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
43770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* get subnet mask length */
43800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plen = 0;
43810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		max = alen <<3;
43820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		p = (unsigned char *) id->v
43840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ sizeof(struct ipsecdoi_id_b)
43850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			+ alen;
43860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		for (; *p == 0xff; p++) {
43880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += 8;
43890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (plen >= max)
43900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
43910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
43920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (plen < max) {
43940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int l = 0;
43950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_char b = ~(*p);
43960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
43970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			while (b) {
43980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				b >>= 1;
43990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				l++;
44000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
44010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			l = 8 - l;
44030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plen += l;
44040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
44050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4406f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr.sa), plen);
44070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    }
44080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_RANGE:
44110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4412f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa));
44130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4415f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_len = sizeof(struct sockaddr_in);
44160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4417f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_family = AF_INET;
4418f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin.sin_port = IPSEC_PORT_ANY;
4419f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		memcpy(&saddr.sin.sin_addr,
44200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b) + sizeof(struct in_addr),
44210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct in_addr));
44220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4423f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa));
44240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef INET6
44270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_RANGE:
4428f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len = snprintf( buf, BUFLEN, "%s-", saddrwop2str(&saddr.sa));
44290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef __linux__
4431f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_len = sizeof(struct sockaddr_in6);
44320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4433f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sa.sa_family = AF_INET6;
4434f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin6.sin6_port = IPSEC_PORT_ANY;
4435f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		memcpy(&saddr.sin6.sin6_addr,
44360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			id->v + sizeof(*id_b) + sizeof(struct in6_addr),
44370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			sizeof(struct in6_addr));
4438f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		saddr.sin6.sin6_scope_id =
4439f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh			(IN6_IS_ADDR_LINKLOCAL(&saddr.sin6.sin6_addr)
4440051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				? ((struct sockaddr_in6 *)id_b)->sin6_scope_id
4441051f86dfca525c160855397f7b6a4fb5ef8df2b5Chia-chi Yeh				: 0);
44420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4443f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh		len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa));
44440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
44460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_FQDN:
44480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_USER_FQDN:
44490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = id->l - sizeof(*id_b);
44500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (len > BUFLEN)
44510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BUFLEN;
44520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(buf, id->v + sizeof(*id_b), len);
44530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_DN:
44560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_GN:
44570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
44580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		X509_NAME *xn = NULL;
44590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dat = id->v + sizeof(*id_b);
44610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = id->l - sizeof(*id_b);
44620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (d2i_X509_NAME(&xn, (void*) &dat, len) != NULL) {
44640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO *bio = BIO_new(BIO_s_mem());
44650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_print_ex(bio, xn, 0, 0);
44660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = BIO_get_mem_data(bio, &dat);
44670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (len > BUFLEN)
44680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				len = BUFLEN;
44690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(buf,dat,len);
44700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			BIO_free(bio);
44710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			X509_NAME_free(xn);
44720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
44730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
44740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"unable to extract asn1dn from id\n");
44750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len = sprintf(buf, "<ASN1-DN>");
44770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
44780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
44810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* currently unhandled id types */
44830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_KEY_ID:
44840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sprintf( buf, "<KEY-ID>");
44850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
44860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
44880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
44890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unknown ID type %d\n", id_b->type);
44900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
44910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (!len)
44930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		len = sprintf( buf, "<?>");
44940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
44950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ret = racoon_malloc(len+1);
44960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ret != NULL) {
44970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(ret,buf,len);
44980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ret[len]=0;
44990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
45000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return ret;
45020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
45030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
45050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * set IPsec data attributes into a proposal.
45060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * NOTE: MUST called per a transform.
45070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
45080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
45090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_t2satrns(t, pp, pr, tr)
45100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_t *t;
45110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saprop *pp;
45120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct saproto *pr;
45130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct satrns *tr;
45140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
45150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *d, *prev;
45160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int flag, type;
45170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
45180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int life_t;
45190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tlen;
45200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->trns_no = t->t_no;
45220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->trns_id = t->t_id;
45230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = ntohs(t->h.len) - sizeof(*t);
45250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	prev = (struct isakmp_data *)NULL;
45260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	d = (struct isakmp_data *)(t + 1);
45270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* default */
45290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT;
45300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
45310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pp->lifebyte = 0;
45320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tr->authtype = IPSECDOI_ATTR_AUTH_NONE;
45330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while (tlen > 0) {
45350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
45370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		flag = ntohs(d->type) & ISAKMP_GEN_MASK;
45380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
45400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"type=%s, flag=0x%04x, lorv=%s\n",
45410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr(type), flag,
45420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_attr_v(type, ntohs(d->lorv)));
45430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (type) {
45450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD_TYPE:
45460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
45470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int type = ntohs(d->lorv);
45480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (type) {
45490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
45500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
45510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = type;
45520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
45530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
45540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, NULL,
45550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life duration type. "
45560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"use default\n");
45570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				life_t = IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT;
45580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
45590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
45600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
45610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
45620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SA_LD:
45630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (prev == NULL
45640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 || (ntohs(prev->type) & ~ISAKMP_GEN_MASK) !=
45650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					IPSECDOI_ATTR_SA_LD_TYPE) {
45660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
45670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "life duration must follow ltype\n");
45680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
45690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
45700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    {
45720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			u_int32_t t;
45730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vchar_t *ld_buf = NULL;
45740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
45750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (flag) {
45760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TV */
45770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ld_buf = vmalloc(sizeof(d->lorv));
45780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ld_buf == NULL) {
45790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
45800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to get LD buffer.\n");
45810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
45820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
45830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(ld_buf->v, &d->lorv, sizeof(d->lorv));
45840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			} else {
45850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				int len = ntohs(d->lorv);
45860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* i.e. ISAKMP_GEN_TLV */
45870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ld_buf = vmalloc(len);
45880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (ld_buf == NULL) {
45890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
45900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "failed to get LD buffer.\n");
45910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
45920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
45930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				memcpy(ld_buf->v, d + 1, len);
45940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
45950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (life_t) {
45960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
45970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t = ipsecdoi_set_ld(ld_buf);
45980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
45990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (t == 0) {
46000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
46020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* lifetime must be equal in a proposal. */
46050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (pp->lifetime == IPSECDOI_ATTR_SA_LD_SEC_DEFAULT)
46060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pp->lifetime = t;
46070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else if (pp->lifetime != t) {
46080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"lifetime mismatched "
46100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"in a proposal, "
46110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"prev:%ld curr:%u.\n",
46120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						(long)pp->lifetime, t);
46130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
46160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case IPSECDOI_ATTR_SA_LD_TYPE_KB:
46170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				t = ipsecdoi_set_ld(ld_buf);
46180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
46190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (t == 0) {
46200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"invalid life duration.\n");
46220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* lifebyte must be equal in a proposal. */
46250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (pp->lifebyte == 0)
46260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					pp->lifebyte = t;
46270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				else if (pp->lifebyte != t) {
46280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, NULL,
46290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"lifebyte mismatched "
46300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"in a proposal, "
46310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"prev:%d curr:%u.\n",
46320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						pp->lifebyte, t);
46330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					goto end;
46340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
46350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
46360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
46370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(ld_buf);
46380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"invalid life type: %d\n", life_t);
46400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
46410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    }
46430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_GRP_DESC:
46460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
46470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * RFC2407: 4.5 IPSEC Security Association Attributes
46480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   Specifies the Oakley Group to be used in a PFS QM
46490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   negotiation.  For a list of supported values, see
46500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 *   Appendix A of [IKE].
46510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
46520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pp->pfs_group == 0)
46530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				pp->pfs_group = (u_int16_t)ntohs(d->lorv);
46540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			else if (pp->pfs_group != (u_int16_t)ntohs(d->lorv)) {
46550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"pfs_group mismatched "
46570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a proposal.\n");
46580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
46590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_ENC_MODE:
46630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->encmode &&
46640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pr->encmode != (u_int16_t)ntohs(d->lorv)) {
46650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"multiple encmode exist "
46670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a transform.\n");
46680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
46690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pr->encmode = (u_int16_t)ntohs(d->lorv);
46710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_AUTH:
46740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (tr->authtype != IPSECDOI_ATTR_AUTH_NONE) {
46750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"multiple authtype exist "
46770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"in a transform.\n");
46780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
46790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr->authtype = (u_int16_t)ntohs(d->lorv);
46810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
46830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_LENGTH:
46840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (pr->proto_id != IPSECDOI_PROTO_IPSEC_ESP) {
46850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
46860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"key length defined but not ESP");
46870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				goto end;
46880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
46890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tr->encklen = ntohs(d->lorv);
46900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SECCTX
46920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_SECCTX:
46930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
46940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			int len = ntohs(d->lorv);
46950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			memcpy(&pp->sctx, d + 1, len);
46960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pp->sctx.ctx_strlen = ntohs(pp->sctx.ctx_strlen);
46970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
46980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
46990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* HAVE_SECCTX */
47000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_KEY_ROUNDS:
47010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_DICT_SIZE:
47020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case IPSECDOI_ATTR_COMP_PRIVALG:
47030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
47040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
47050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
47060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		prev = d;
47080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (flag) {
47090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= sizeof(*d);
47100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((char *)d + sizeof(*d));
47110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
47120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			tlen -= (sizeof(*d) + ntohs(d->lorv));
47130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			d = (struct isakmp_data *)((caddr_t)d + sizeof(*d) + ntohs(d->lorv));
47140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
47150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
47160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
47180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
47190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
47200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
47210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
47230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangipsecdoi_authalg2trnsid(alg)
47240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int alg;
47250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
47260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (alg) {
47270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_HMAC_MD5:
47280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_MD5;
47290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
47300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA;
47310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
47320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA256;
47330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
47340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA384;
47350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
47360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_SHA512;
47370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        case IPSECDOI_ATTR_AUTH_DES_MAC:
47380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_DES;
47390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ATTR_AUTH_KPDK:
47400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return IPSECDOI_AH_MD5;	/* XXX */
47410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
47420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
47430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid authentication algorithm:%d\n", alg);
47440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
47450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
47460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
47470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int rm_idtype2doi[] = {
47490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	255,				/* IDTYPE_UNDEFINED, 0 */
47500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_FQDN,		/* IDTYPE_FQDN, 1 */
47510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_USER_FQDN,		/* IDTYPE_USERFQDN, 2 */
47520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_KEY_ID,		/* IDTYPE_KEYID, 3 */
4753f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh	255,    /*			   IDTYPE_ADDRESS, 4
47540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * it expands into 4 types by another function. */
47550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	IPSECDOI_ID_DER_ASN1_DN,	/* IDTYPE_ASN1DN, 5 */
47560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
47570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
47590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * convert idtype to DOI value.
47600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT	255  : NG
47610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *	other: converted.
47620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
47630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
47640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangidtype2doi(idtype)
47650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int idtype;
47660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
47670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ARRAYLEN(rm_idtype2doi) > idtype)
47680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return rm_idtype2doi[idtype];
47690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 255;
47700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
47710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
47720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
47730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangdoi2idtype(doi)
47740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int doi;
47750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
47760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(doi) {
47770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_FQDN:
47780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_FQDN);
47790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_USER_FQDN:
47800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_USERFQDN);
47810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_KEY_ID:
47820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_KEYID);
47830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_DER_ASN1_DN:
47840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ASN1DN);
47850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR:
47860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV4_ADDR_SUBNET:
47870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR:
47880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case IPSECDOI_ID_IPV6_ADDR_SUBNET:
47890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ADDRESS);
47900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
47910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
47920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Inproper idtype:%s in this function.\n",
47930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			s_ipsecdoi_ident(doi));
47940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return(IDTYPE_ADDRESS);	/* XXX */
47950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
47960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*NOTREACHED*/
47970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4798