1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: isakmp.c,v 1.20.6.13 2008/09/25 09:34:39 vanhu Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: isakmp.c,v 1.74 2006/05/07 21:32:59 manubsd Exp */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
8c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
20c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/queue.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/inet.h>
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include PATH_IPSEC_H
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if TIME_WITH_SYS_TIME
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h>
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if HAVE_SYS_TIME_H
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <sys/time.h>
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# else
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <time.h>
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h>
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_UNISTD_H
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h>
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <resolv.h>
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h"
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "grabmyaddr.h"
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h"
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "privsep.h"
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "oakley.h"
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "evt.h"
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "pfkey.h"
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "policy.h"
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_ident.h"
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_agg.h"
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_base.h"
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_quick.h"
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_inf.h"
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_newg.h"
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vendorid.h"
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_xauth.h"
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_unity.h"
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_cfg.h"
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_frag.h"
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h"
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <fcntl.h>
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include "nattraversal.h"
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# ifdef __linux__
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <linux/udp.h>
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <linux/ip.h>
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  ifndef SOL_UDP
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#   define SOL_UDP 17
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  endif
119c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#ifdef ANDROID_CHANGES
120c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#define __linux
121c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif /* __linux__ */
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if defined(__NetBSD__) || defined(__FreeBSD__) ||	\
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  (defined(__APPLE__) && defined(__MACH__))
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/in.h>
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/udp.h>
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/in_systm.h>
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <netinet/ip.h>
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  define SOL_UDP IPPROTO_UDP
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif /* __NetBSD__ / __FreeBSD__ */
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nostate1 __P((struct ph1handle *, vchar_t *));
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int nostate2 __P((struct ph2handle *, vchar_t *));
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern caddr_t val2str(const char *, size_t);
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*ph1exchange[][2][PHASE1ST_MAX])
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct ph1handle *, vchar_t *)) = {
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* error */
140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh { {}, {}, },
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Identity Protection exchange */
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, ident_i1send, nostate1, ident_i2recv, ident_i2send,
144c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostate1, },
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send,
146c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    ident_r3recv, ident_r3send, nostate1, nostate1, nostate1, },
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Aggressive exchange */
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, agg_i1send, nostate1, agg_i2recv, agg_i2send,
151c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    nostate1, nostate1, nostate1, nostate1, nostate1, },
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, agg_r1recv, agg_r1send, agg_r2recv, agg_r2send,
153c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    nostate1, nostate1, nostate1, nostate1, nostate1, },
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Base exchange */
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, base_i1send, nostate1, base_i2recv, base_i2send,
158c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    base_i3recv, base_i3send, nostate1, nostate1, nostate1, },
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate1, base_r1recv, base_r1send, base_r2recv, base_r2send,
160c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh    nostate1, nostate1, nostate1, nostate1, nostate1, },
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int (*ph2exchange[][2][PHASE2ST_MAX])
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	__P((struct ph2handle *, vchar_t *)) = {
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* error */
167c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh { {}, {}, },
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Quick mode for IKE */
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang {
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate2, nostate2, quick_i1prep, nostate2, quick_i1send,
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang  { nostate2, quick_r1recv, quick_r1prep, nostate2, quick_r2send,
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, }
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang },
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang};
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic u_char r_ck0[] = { 0,0,0,0,0,0,0,0 }; /* used to verify the r_ck. */
178c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_main __P((vchar_t *, struct sockaddr *, struct sockaddr *));
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int ph1_main __P((struct ph1handle *, vchar_t *));
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int quick_main __P((struct ph2handle *, vchar_t *));
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph1begin_r __P((vchar_t *,
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *, struct sockaddr *, u_int8_t));
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph2begin_i __P((struct ph1handle *, struct ph2handle *));
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int etypesw1 __P((int));
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int etypesw2 __P((int));
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
189c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehstatic int frag_handler(struct ph1handle *,
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    vchar_t *, struct sockaddr *, struct sockaddr *);
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * isakmp packet handler
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
196c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
197c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehisakmp_handler(so_isakmp)
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int so_isakmp;
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp isakmp;
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	union {
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char		buf[sizeof (isakmp) + 4];
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		u_int32_t	non_esp[2];
204c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		char		lbuf[sizeof(struct udphdr) +
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux
206c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				     sizeof(struct iphdr) +
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
208c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				     sizeof(struct ip) +
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
210c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				     sizeof(isakmp) + 4];
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	} x;
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage remote;
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr_storage local;
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int remote_len = sizeof(remote);
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	unsigned int local_len = sizeof(local);
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int len = 0, extralen = 0;
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buf = NULL, *tmpbuf = NULL;
2181c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	int error = -1, res;
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read message by MSG_PEEK */
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfromto(so_isakmp, x.buf, sizeof(x),
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    MSG_PEEK, (struct sockaddr *)&remote, &remote_len,
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    (struct sockaddr *)&local, &local_len)) < 0) {
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to receive isakmp packet: %s\n",
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror (errno));
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* keep-alive packet - ignore */
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len == 1 && (x.buf[0]&0xff) == 0xff) {
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Pull the keep-alive packet */
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)x.buf, 1,
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    0, (struct sockaddr *)&remote, &remote_len)) != 1) {
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "failed to receive keep alive packet: %s\n",
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    strerror (errno));
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Lucent IKE in UDP encapsulation */
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
246c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct udphdr *udp;
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef __linux__
248c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct iphdr *ip;
249c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
250c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		udp = (struct udphdr *)&x.lbuf[0];
251c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (ntohs(udp->dest) == 501) {
252c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ip = (struct iphdr *)(x.lbuf + sizeof(*udp));
253c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			extralen += sizeof(*udp) + ip->ihl;
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
256c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		struct ip *ip;
257c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
258c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		udp = (struct udphdr *)&x.lbuf[0];
259c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (ntohs(udp->uh_dport) == 501) {
260c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			ip = (struct ip *)(x.lbuf + sizeof(*udp));
261c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			extralen += sizeof(*udp) + ip->ip_hl;
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
264c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
267c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* we don't know about portchange yet,
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   look for non-esp marker instead */
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (x.non_esp[0] == 0 && x.non_esp[1] != 0)
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		extralen = NON_ESP_MARKER_LEN;
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
273c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* now we know if there is an extra non-esp
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   marker at the beginning or not */
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy ((char *)&isakmp, x.buf + extralen, sizeof (isakmp));
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check isakmp header length, as well as sanity of header length */
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len < sizeof(isakmp) || ntohl(isakmp.len) < sizeof(isakmp)) {
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"packet shorter than isakmp header size (%u, %u, %zu)\n",
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len, ntohl(isakmp.len), sizeof(isakmp));
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* dummy receive */
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to receive isakmp packet: %s\n",
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* reject it if the size is tooooo big. */
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ntohl(isakmp.len) > 0xffff) {
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the length in the isakmp header is too big.\n");
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"failed to receive isakmp packet: %s\n",
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* read real message */
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((tmpbuf = vmalloc(ntohl(isakmp.len) + extralen)) == NULL) {
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate reading buffer (%u Bytes)\n",
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ntohl(isakmp.len) + extralen);
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* dummy receive */
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    0, (struct sockaddr *)&remote, &remote_len)) < 0) {
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
314c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"failed to receive isakmp packet: %s\n",
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				strerror (errno));
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((len = recvfromto(so_isakmp, (char *)tmpbuf->v, tmpbuf->l,
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                    0, (struct sockaddr *)&remote, &remote_len,
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                    (struct sockaddr *)&local, &local_len)) < 0) {
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (errno == EINTR)
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			continue;
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to receive isakmp packet: %s\n",
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			strerror (errno));
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buf = vmalloc(len - extralen)) == NULL) {
3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate reading buffer (%u Bytes)\n",
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(len - extralen));
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
337c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy (buf->v, tmpbuf->v + extralen, buf->l);
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	len -= extralen;
341c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (len != buf->l) {
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"received invalid length (%d != %zu), why ?\n",
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			len, buf->l);
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL,
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"%d bytes message received %s\n",
352c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		len, saddr2str_fromto("from %s to %s",
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&remote,
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&local));
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plogdump(LLV_DEBUG, buf->v, buf->l);
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* avoid packets with malicious port/address */
3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (extract_port((struct sockaddr *)&remote) == 0) {
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"src port == 0 (valid as UDP but not with IKE)\n");
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX: check sender whether to be allowed or not to accept */
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX: I don't know how to check isakmp half connection attack. */
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* simply reply if the packet was processed. */
3691c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	res=check_recvdpkt((struct sockaddr *)&remote,(struct sockaddr *)&local, buf);
3701c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	if (res) {
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_NOTIFY, LOCATION, NULL,
3721c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			"the packet is retransmitted by %s (%d).\n",
3731c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			 saddr2str((struct sockaddr *)&remote), res);
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		error = 0;
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto end;
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* isakmp main routine */
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_main(buf, (struct sockaddr *)&remote,
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			(struct sockaddr *)&local) != 0) goto end;
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend:
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (tmpbuf != NULL)
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(tmpbuf);
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (buf != NULL)
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(buf);
389c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
390c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return(error);
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main processing to handle isakmp payload
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_main(msg, remote, local)
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_index *index = (isakmp_index *)isakmp;
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int32_t msgid = isakmp->msgid;
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_PRINT_ISAKMP_C
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_printpacket(msg, remote, local, 0);
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* the initiator's cookie must not be zero */
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (memcmp(&isakmp->i_ck, r_ck0, sizeof(cookie_t)) == 0) {
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"malformed cookie received.\n");
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Check the Major and Minor Version fields. */
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * XXX Is is right to check version here ?
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * I think it may no be here because the version depends
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * on exchange status.
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp->v < ISAKMP_VERSION_NUMBER) {
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISAKMP_GETMAJORV(isakmp->v) < ISAKMP_MAJOR_VERSION) {
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid major version %d.\n",
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_GETMAJORV(isakmp->v));
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if ISAKMP_MINOR_VERSION > 0
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISAKMP_GETMINORV(isakmp->v) < ISAKMP_MINOR_VERSION) {
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"invalid minor version %d.\n",
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_GETMINORV(isakmp->v));
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check the Flags field. */
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX How is the exclusive check, E and A ? */
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp->flags & ~(ISAKMP_FLAG_E | ISAKMP_FLAG_C | ISAKMP_FLAG_A)) {
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"invalid flag 0x%02x.\n", isakmp->flags);
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore commit bit. */
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ISSET(isakmp->flags, ISAKMP_FLAG_C)) {
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->msgid == 0) {
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_nx(isakmp, remote, local,
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_NTYPE_INVALID_FLAGS, NULL);
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Commit bit on phase1 forbidden.\n");
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = getph1byindex(index);
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 != NULL) {
4610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* validity check */
4620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (memcmp(&isakmp->r_ck, r_ck0, sizeof(cookie_t)) == 0 &&
4630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->side == INITIATOR) {
4640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, remote,
4650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"malformed cookie received or "
4660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"the initiator's cookies collide.\n");
4670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Floating ports for NAT-T */
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (NATT_AVAILABLE(iph1) &&
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    ! (iph1->natt_flags & NAT_PORTS_CHANGED) &&
474c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    ((cmpsaddrstrict(iph1->remote, remote) != 0) ||
475c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    (cmpsaddrstrict(iph1->local, local) != 0)))
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		{
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* prevent memory leak */
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(iph1->remote);
4790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(iph1->local);
4800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->remote = NULL;
4810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->local = NULL;
4820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* copy-in new addresses */
4840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->remote = dupsaddr(remote);
4850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->remote == NULL) {
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang           			plog(LLV_ERROR, LOCATION, iph1->remote,
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "phase1 failed: dupsaddr failed.\n");
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				remph1(iph1);
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				delph1(iph1);
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->local = dupsaddr(local);
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->local == NULL) {
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang           			plog(LLV_ERROR, LOCATION, iph1->remote,
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				   "phase1 failed: dupsaddr failed.\n");
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				remph1(iph1);
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				delph1(iph1);
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* set the flag to prevent further port floating
502c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			   (FIXME: should we allow it? E.g. when the NAT gw
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    is rebooted?) */
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
505c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* print some neat info */
507c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog (LLV_INFO, LOCATION, NULL,
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			      "NAT-T: ports changed to: %s\n",
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			      saddr2str_fromto ("%s<->%s", iph1->remote, iph1->local));
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			natt_keepalive_add_ph1 (iph1);
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* must be same addresses in one stream of a phase at least. */
516c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (cmpsaddrstrict(iph1->remote, remote) != 0) {
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *saddr_db, *saddr_act;
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr_db = racoon_strdup(saddr2str(iph1->remote));
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			saddr_act = racoon_strdup(saddr2str(remote));
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			STRDUP_FATAL(saddr_db);
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			STRDUP_FATAL(saddr_act);
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, remote,
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"remote address mismatched. db=%s, act=%s\n",
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				saddr_db, saddr_act);
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(saddr_db);
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(saddr_act);
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * don't check of exchange type here because other type will be
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with same index, for example, informational exchange.
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX more acceptable check */
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (isakmp->etype) {
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_IDENT:
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AGG:
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_BASE:
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* phase 1 validity check */
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->msgid != 0) {
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"message id should be zero in phase1.\n");
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* search for isakmp status record of phase 1 */
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * the packet must be the 1st message from a initiator
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * or the 2nd message from the responder.
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* search for phase1 handle by index without r_ck */
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1 = getph1byindex0(index);
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1 == NULL) {
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*it must be the 1st message from a initiator.*/
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (memcmp(&isakmp->r_ck, r_ck0,
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					sizeof(cookie_t)) != 0) {
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_DEBUG, LOCATION, remote,
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"malformed cookie received "
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang						"or the spi expired.\n");
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* it must be responder's 1st exchange. */
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				if (isakmp_ph1begin_r(msg, remote, local,
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp->etype) < 0)
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return -1;
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/*NOTREACHED*/
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it must be the 2nd message from the responder. */
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1->side != INITIATOR) {
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_DEBUG, LOCATION, remote,
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"malformed cookie received. "
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"it has to be as the initiator.  %s\n",
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp_pindex(&iph1->index, 0));
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Don't delete phase 1 handler when the exchange type
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * in handler is not equal to packet's one because of no
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * authencication completed.
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->etype != isakmp->etype) {
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"exchange type is mismatched: "
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"db=%s packet=%s, ignore it.\n",
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_isakmp_etype(iph1->etype),
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				s_isakmp_etype(isakmp->etype));
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* call main process of phase 1 */
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ph1_main(iph1, msg) < 0) {
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"phase1 negotiation failed.\n");
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph1(iph1);
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph1(iph1);
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_AUTH:
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, remote,
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unsupported exchange %d received.\n",
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->etype);
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_INFO:
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_ACKINFO:
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * iph1 must be present for Information message.
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * if iph1 is null then trying to get the phase1 status
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * as the packet from responder againt initiator's 1st
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * exchange in phase 1.
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * NOTE: We think such informational exchange should be ignored.
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1 = getph1byindex0(index);
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (iph1 == NULL) {
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, remote,
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"unknown Informational "
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"exchange received.\n");
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
642c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if (cmpsaddrstrict(iph1->remote, remote) != 0) {
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_WARNING, LOCATION, remote,
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"remote address mismatched. "
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"db=%s\n",
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					saddr2str(iph1->remote));
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_info_recv(iph1, msg) < 0)
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_QUICK:
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		struct ph2handle *iph2;
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_nx(isakmp, remote, local,
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				ISAKMP_NTYPE_INVALID_COOKIE, NULL);
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"can't start the quick mode, "
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no ISAKMP-SA, %s\n",
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex((isakmp_index *)&isakmp->i_ck,
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					isakmp->msgid));
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
674c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/* Reinit the IVM if it's still there */
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			oakley_delivm(iph1->mode_cfg->ivm);
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->mode_cfg->ivm = NULL;
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check status of phase 1 whether negotiated or not. */
686c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph1->status != PHASE1ST_ESTABLISHED) {
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"can't start the quick mode, "
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no valid ISAKMP-SA, %s\n",
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_pindex(&iph1->index, iph1->msgid));
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* search isakmp phase 2 stauts record. */
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph2 = getph2bymsgid(iph1, msgid);
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph2 == NULL) {
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* it must be new negotiation as responder */
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (isakmp_ph2begin_r(iph1, msg) < 0)
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return -1;
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*NOTREACHED*/
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* commit bit. */
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we keep to set commit bit during negotiation.
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * When SA is configured, bit will be reset.
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * XXX
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * don't initiate commit bit.  should be fixed in the future.
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph2->flags |= ISAKMP_FLAG_C;
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* call main process of quick mode */
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (quick_main(iph2, msg) < 0) {
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, iph1->remote,
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"phase2 negotiation failed.\n");
718c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			unbindph12(iph2);
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			remph2(iph2);
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			delph2(iph2);
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_NEWGRP:
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, remote,
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"Unknown new group mode exchange, "
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"there is no ISAKMP-SA.\n");
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_newgroup_r(iph1, msg);
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_CFG:
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1 == NULL) {
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "mode config %d from %s, "
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     "but we have no ISAKMP-SA.\n",
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			     isakmp->etype, saddr2str(remote));
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp->np == ISAKMP_NPTYPE_FRAG)
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return frag_handler(iph1, msg, remote, local);
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_cfg_r(iph1, msg);
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
759c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case ISAKMP_ETYPE_NONE:
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"Invalid exchange type %d from %s.\n",
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp->etype, saddr2str(remote));
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main function of phase 1.
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangph1_main(iph1, msg)
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore a packet */
786c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph1->status == PHASE1ST_ESTABLISHED)
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* receive */
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ph1exchange[etypesw1(iph1->etype)]
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph1->side]
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph1->status] == NULL) {
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"why isn't the function defined.\n");
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph1exchange[etypesw1(iph1->etype)]
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph1->side]
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph1->status])(iph1, msg);
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
8041c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* XXX
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * When an invalid packet is received on phase1, it should
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * be selected to process this packet.  That is to respond
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * with a notify and delete phase 1 handler, OR not to respond
8091c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * and keep phase 1 handler. However, in PHASE1ST_START when
8101c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * acting as RESPONDER we must not keep phase 1 handler or else
8111c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		 * it will stay forever.
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
8131c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh
8141c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
8151c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			plog(LLV_ERROR, LOCATION, iph1->remote,
816c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh				"failed to pre-process packet.\n");
8171c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			return -1;
8181c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		} else {
8191c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			/* ignore the error and keep phase 1 handler */
8201c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh			return 0;
8211c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh		}
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef ENABLE_FRAG
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free resend buffer */
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->sendbuf == NULL) {
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
828c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"no buffer found as sendbuf\n");
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	VPTRINIT(iph1->sendbuf);
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
836c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph1->scr);
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, msg) != 0) {
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph1->remote,
844c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to process packet.\n");
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status),
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1->status == PHASE1ST_ESTABLISHED) {
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		gettimeofday(&iph1->end, NULL);
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		syslog(LOG_NOTICE, "%s(%s): %8.6f",
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"phase1", s_isakmp_etype(iph1->etype),
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			timedelta(&iph1->start, &iph1->end));
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* save created date. */
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)time(&iph1->created);
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* add to the schedule to expire, and seve back pointer. */
867c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		iph1->sce = sched_new(iph1->approval->lifetime,
868c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    isakmp_ph1expire_stub, iph1);
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
871c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			switch(AUTHMETHOD(iph1)) {
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				xauth_sendreq(iph1);
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* XXX Don't process INITIAL_CONTACT */
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->rmconf->ini_contact = 0;
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_DPD
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Schedule the r_u_there.... */
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(iph1->dpd_support && iph1->rmconf->dpd_interval)
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_sched_r_u(iph1, 0);
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* INITIAL-CONTACT processing */
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* don't anything if local test mode. */
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!f_local
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* send INITIAL-CONTACT */
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_n1(iph1,
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* insert a node into contacted list. */
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (inscontacted(iph1->remote) == -1) {
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, iph1->remote,
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"failed to add contacted list.\n");
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* ignore */
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		log_ph1established(iph1);
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL, "===\n");
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
912c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		/*
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * SA up shell script hook: do it now,except if
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * ISAKMP mode config was requested. In the later
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * case it is done when we receive the configuration.
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((iph1->status == PHASE1ST_ESTABLISHED) &&
918c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		    !iph1->rmconf->mode_cfg) {
919c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			switch (AUTHMETHOD(iph1)) {
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Unimplemeted... */
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				script_hook(iph1, SCRIPT_PHASE1_UP);
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * main function of quick mode.
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangquick_main(iph2, msg)
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* ignore a packet */
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ESTABLISHED
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || iph2->status == PHASE2ST_GETSPISENT)
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* receive */
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ph2exchange[etypesw2(isakmp->etype)]
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph2->side]
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		       [iph2->status] == NULL) {
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"why isn't the function defined.\n");
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = (ph2exchange[etypesw2(isakmp->etype)]
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph2->side]
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    [iph2->status])(iph2, msg);
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
977c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to pre-process packet.\n");
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (error == ISAKMP_INTERNAL_ERROR)
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		isakmp_info_send_n1(iph2->ph1, error, NULL);
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* when using commit bit, status will be reached here. */
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->status == PHASE2ST_ADDSA)
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free resend buffer */
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->sendbuf == NULL) {
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
991c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"no buffer found as sendbuf\n");
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	VPTRINIT(iph2->sendbuf);
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* turn off schedule */
997c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	SCHED_KILL(iph2->scr);
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* send */
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(isakmp->etype)]
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->side]
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph2->status])(iph2, msg) != 0) {
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1005c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to process packet.\n");
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase2",
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 1 for initiator */
1021c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehint
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1begin_i(rmconf, remote, local)
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct remoteconf *rmconf;
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get new entry to isakmp status table. */
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = newph1();
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL)
1034c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_START;
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->rmconf = rmconf;
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->side = INITIATOR;
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->version = ISAKMP_VERSION_NUMBER;
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->msgid = 0;
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->flags = 0;
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->ph2cnt = 0;
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->gssapi_state = NULL;
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
1049c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(rmconf->ike_frag == ISAKMP_FRAG_FORCE)
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->frag = 1;
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->frag = 0;
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag_chain = NULL;
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->approval = NULL;
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* XXX copy remote address */
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
1065c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)insph1(iph1);
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start phase 1 exchange */
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->etype = rmconf->etypes->type;
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph1->local));
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"initiate new phase 1 negotiation: %s<=>%s\n",
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph1->remote));
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin %s mode.\n",
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_etype(iph1->etype));
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph1->start, NULL);
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start exchange */
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, NULL) != 0) {
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* failed to start phase 1 negotiation */
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1101c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1",
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(iph1->etype, iph1->side, iph1->status),
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1112c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return 0;
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 1 for responder */
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph1begin_r(msg, remote, local, etype)
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *remote, *local;
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	u_int8_t etype;
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
1123c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct remoteconf *rmconf;
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
1125c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct etypes *etypeok;
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1130c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* look for my configuration */
1131c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	rmconf = getrmconf(remote);
1132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (rmconf == NULL) {
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
1134c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"couldn't find "
1135c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"configuration.\n");
1136c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
1137c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1138c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
1139c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* check to be acceptable exchange type */
1140c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	etypeok = check_etypeok(rmconf, etype);
1141c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (etypeok == NULL) {
1142c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, remote,
1143c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"not acceptable %s mode\n", s_isakmp_etype(etype));
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* get new entry to isakmp status table. */
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1 = newph1();
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph1 == NULL)
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(iph1->index.i_ck));
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->status = PHASE1ST_START;
1154c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->rmconf = rmconf;
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->flags = 0;
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->side = RESPONDER;
1157c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph1->etype = etypeok->type;
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->version = isakmp->v;
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->msgid = 0;
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_GSSAPI
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->gssapi_state = NULL;
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL) {
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_FRAG
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag = 0;
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->frag_chain = NULL;
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->approval = NULL;
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_NATT
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* RFC3947 says that we MUST accept new phases1 on NAT-T floated port.
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * We have to setup this flag now to correctly generate the first reply.
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * Don't know if a better check could be done for that ?
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(extract_port(local) == lcconf->port_isakmp_natt)
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->natt_flags |= (NAT_PORTS_CHANGED);
11820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1184c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* copy remote address */
1185c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	(void)insph1(iph1);
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph1->local));
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"respond new phase 1 negotiation: %s<=>%s\n",
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph1->remote));
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"begin %s mode.\n", s_isakmp_etype(etype));
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph1->start, NULL);
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&start, NULL);
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef ENABLE_FRAG
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* start exchange */
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph1exchange[etypesw1(iph1->etype)]
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph1->side]
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	                [iph1->status])(iph1, msg) < 0
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 || (ph1exchange[etypesw1(iph1->etype)]
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->side]
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			[iph1->status])(iph1, msg) < 0) {
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, remote,
1221c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			"failed to process packet.\n");
12220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&end, NULL);
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syslog(LOG_NOTICE, "%s(%s): %8.6f",
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"phase1",
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		s_isakmp_state(iph1->etype, iph1->side, iph1->status),
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		timedelta(&start, &end));
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else /* ENABLE_FRAG */
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* now that we have a phase1 handle, feed back into our
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * main receive function to catch fragmented packets
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return isakmp_main(msg, remote, local);
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif /* ENABLE_FRAG */
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 2 for initiator */
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2begin_i(iph1, iph2)
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2;
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_check(iph1) != 0) {
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Attempt to start phase 2 whereas Xauth failed\n");
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* found ISAKMP-SA. */
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_DEBUG, LOCATION, NULL, "begin QUICK mode.\n");
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    {
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *a;
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	a = racoon_strdup(saddr2str(iph2->src));
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	STRDUP_FATAL(a);
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"initiate new phase 2 negotiation: %s<=>%s\n",
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		a, saddr2str(iph2->dst));
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(a);
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    }
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gettimeofday(&iph2->start, NULL);
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1280c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	/* found isakmp-sa */
1281c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	bindph12(iph1, iph2);
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_STATUS2;
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 [iph2->side]
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 [iph2->status])(iph2, NULL) < 0) {
1287c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		unbindph12(iph2);
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* release ipsecsa handler due to internal error. */
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph2(iph2);
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* new negotiation of phase 2 for responder */
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_ph2begin_r(iph1, msg)
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *msg;
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp *isakmp = (struct isakmp *)msg->v;
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph2handle *iph2 = 0;
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_STATS
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval start, end;
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ENABLE_HYBRID
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_check(iph1) != 0) {
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Attempt to start phase 2 whereas Xauth failed\n");
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2 = newph2();
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2 == NULL) {
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"failed to allocate phase2 entry.\n");
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1322c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	iph2->ph1 = iph1;
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->side = RESPONDER;
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->status = PHASE2ST_START;
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->flags = isakmp->flags;
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->msgid = isakmp->msgid;
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->seq = pk_getseq();
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->ivm == NULL) {
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->dst = dupsaddr(iph1->remote);	/* XXX should be considered */
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->dst == NULL) {
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph2->src = dupsaddr(iph1->local);	/* XXX should be considered */
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (iph2->src == NULL) {
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph2(iph2);
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1343c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1344c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (set_port(iph2->dst, 0) == NULL ||
1345c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	    set_port(iph2->src, 0) == NULL) {
1346c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		plog(LLV_ERROR, LOCATION, NULL,
1347c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		     "invalid family: %d\n", iph2->dst->sa_family);
1348c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		delph2(iph2);
1349c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		return -1;
1350c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	}
1351c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* add new entry to isakmp status table */
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	insph2(iph2);
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bindph12(iph1, iph2);
13560a1907d434839af6a9cb6329bbde6